Can't display contours

Hello!

I’m reading an rtstruct, getting the rois and then creating the contourSet in order to represent them, but I cannot make it work.

The process is to create the contourData, then add the segmentations and finally the representations to the viewport of the axial view where I want to see the contours

for (const roi of roisToBuild) {
    const ringsSorted = sortRingsByZ(roi.rings);
    if (!ringsSorted.length) continue;

    const resampled = resampleRings(ringsSorted, 200);
    if (!resampled.length) continue;

    

    

    

    const segIndex = segmentIndexFor(roi.roiName, filename, organToAnalyze);

    const surfId = `${segmentationPrefix}_${sanitizeId(roi.roiName)}_SURF_${uniqueId()}`;
    const cntId  = `${segmentationPrefix}_${sanitizeId(roi.roiName)}_CNT_${uniqueId()}`;


    const metaForThisGeom = {
      tipo: segmentationPrefix === 'GS' ? 'gs' : 'alumno',
      geomId: surfId,
      segIndex,
      roiKey: roiKeyFor(segIndex),
    };
    ((load_rtstruct_and_build_surfaces as any)._pendingMeta ||= []).push(metaForThisGeom);

    if (segIndex > highestSegIndex) highestSegIndex = segIndex;
    if (segIndex > maxSegIndex) maxSegIndex = segIndex;

    // ---------- create CONTOUR geometry (axial) ----------
    const rgb: Types.Point3 = [1, 0, 0];
    const contourData = resampled
      .map((ring) => {
        const zWorld = ring[0][2];
        const closest = findClosestImageIdByZ(zWorld, sopMap);
        if (!closest) return null;

        return {
          points: ring.map(p => [p[0], p[1], p[2]] as Types.Point3), // WORLD
          referencedImageId: closest.imageId, // 🔥 CLAVE
          type: csCore.Enums.ContourType.CLOSED_PLANAR,
          segmentIndex: segIndex,
          color: rgb,
        };
      })
      .filter(Boolean);

    const contourSetData: Types.ContourSetData = {
      id: cntId,
      frameOfReferenceUID,
      segmentIndex: segIndex,
      color: rgb,
      data: contourData as any,
    };

    await geometryLoader.createAndCacheGeometry(cntId, {
      type: csCore.Enums.GeometryType.CONTOUR,
      geometryData: contourSetData as any,
    });

    geometryIdsContour.push(cntId);

    console.log('[CNT check]', {
      cntGeom: geometryIdsContour[0],
      firstRingRef: (contourSetData.data as any)?.[0]?.referencedImageId,
      repEnum: CONTOUR_REP,
      viewportExists: !!csCore.getRenderingEngine(axialRenderingEngineId)?.getViewport(viewportAxialId),
    });
  }

  if (!geometryIdsSurface.length) {
    console.warn('[Review] Ninguna SURFACE válida generada, no se crea segmentación 3D');
    return;
  }

  // ============================================================
  // 3D: registrar segmentación Surface
  // ============================================================
  const segmentationId = `${segmentationPrefix}_importedContours_${++importCount}`;
  if (segmentationPrefix === 'GS') segmentationIdByTipo.gs = segmentationId;
  else segmentationIdByTipo.alumno = segmentationId;

  await segmentation.addSegmentations([
    {
      segmentationId,
      representation: {
        type: csToolsEnums.SegmentationRepresentations.Surface,
        data: { geometryIds: geometryIdsSurface },
      },
    },
  ]);

  const pending = (load_rtstruct_and_build_surfaces as any)._pendingMeta as GeoMeta[] || [];
  GEO_BY_SEGID[segmentationId] = pending.slice();
  (load_rtstruct_and_build_surfaces as any)._pendingMeta = [];

  console.log(`[Review] Segmentación 3D creada: ${segmentationId}`, { surfaces: geometryIdsSurface });

  await attachAndRender3D(segmentationId, viewport3DId, highestSegIndex);

  // ============================================================
  // AXIAL: registrar segmentación Contour en el AXIAL NUEVO
  // ============================================================
  if (geometryIdsContour.length && viewportAxialId) {
    const contourSegId = `${segmentationPrefix}_AXCNT_${importCount}`;

    // (si quieres conservar tu dummy, mantenlo, pero ojo con duplicados)
    // await ensureDummy2DSegmentation(viewportAxialId);

    await segmentation.addSegmentations([
      {
        segmentationId: contourSegId,
        representation: {
          type: CONTOUR_REP,
          data: { geometryIds: geometryIdsContour },
        },
      },
    ]);
    console.log(viewportAxialId);
    await segmentation.addContourRepresentationToViewport(
      viewportAxialId,
      [
        {
          segmentationId: contourSegId,
          type: CONTOUR_REP,
        },
      ]
    );

    segmentation.activeSegmentation.setActiveSegmentation(viewportAxialId, contourSegId);

    segmentation.config.visibility.setSegmentationVisibility?.(contourSegId, true);

    for (const roi of roisToBuild) {
      const segIdx = segmentIndexFor(roi.roiName, filename, organToAnalyze);
      segmentation.config.visibility.setSegmentVisibility?.(contourSegId, segIdx, true);
    }

    // 🔥 IMPORTANTE: renderizar el ENGINE del axial review, no el viejo
    const reAxial = csCore.getRenderingEngine(axialRenderingEngineId);
    const vpAxial = reAxial.getViewport(viewportAxialId) as any;
    reAxial?.renderViewports([viewportAxialId]);

    requestAnimationFrame(() => {
      reAxial?.resize(true);                 // recalcula tamaños
      reAxial?.renderViewports([viewportAxialId]); // vuelve a renderizar con tamaño real
    });

    console.log('✅ [Review] Contornos añadidos a axial', {
      contourSegId,
      viewportAxialId,
      axialRenderingEngineId,
      geometryIdsContourCount: geometryIdsContour.length,
    });
  }
}

function findClosestImageIdByZ(
  z: number,
  sopMap: Map<string, { imageId: string; z: number }>
) {
  let best = null;
  let minDiff = Infinity;

  for (const entry of sopMap.values()) {
    const diff = Math.abs(entry.z - z);
    if (diff < minDiff) {
      minDiff = diff;
      best = entry;
    }
  }

  return best;
}

Could anybody tell me what I’m doing wrong please?