Skip to content

Commit

Permalink
fix(splineSegROI): fix for CCW splines
Browse files Browse the repository at this point in the history
  • Loading branch information
lscoder committed Aug 11, 2024
1 parent 642bbba commit 5eac830
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 20 deletions.
14 changes: 13 additions & 1 deletion packages/tools/examples/splineContourSegmentationTools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,19 @@ createInfoSection(content, { ordered: true })
'Notice that each segment index has a different color assigned to it'
)
.addInstruction('Change the style for the segmentation')
.addInstruction('Confirm the style is applied properly');
.addInstruction('Confirm the style is applied properly')
.addInstruction('You can draw overlapping splines to:')
.openNestedSection()
.addInstruction(
'Merge both splines when the first point of the second spline is inside the first spline'
)
.addInstruction(
'Subctract the second spline from the first spline when the first point of the second spline is outside the first spline'
)
.closeNestedSection()
.addInstruction(
'The resulting contour is converted to freehand ROI when splines are merged/subtracted'
);

function updateInputsForCurrentSegmentation() {
// We can use any toolGroupId because they are all configured in the same way
Expand Down
3 changes: 2 additions & 1 deletion packages/tools/src/tools/annotation/SplineROITool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ class SplineROITool extends ContourSegmentationBaseTool {
closed: data.contour.closed,
targetWindingDirection: ContourWindingDirection.Clockwise,
},
viewport
viewport,
{ updateWindingDirection: data.contour.closed }
);
});

Expand Down
4 changes: 4 additions & 0 deletions packages/tools/src/tools/base/ContourBaseTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ abstract class ContourBaseTool extends AnnotationTool {
transforms: {
canvasToWorld: (point: Types.Point2) => Types.Point3;
worldToCanvas: (point: Types.Point3) => Types.Point2;
},
options?: {
updateWindingDirection?: boolean;
}
) {
const decimateConfig = this.configuration?.decimate || {};
Expand All @@ -229,6 +232,7 @@ abstract class ContourBaseTool extends AnnotationTool {
enabled: !!decimateConfig.enabled,
epsilon: decimateConfig.epsilon,
},
updateWindingDirection: options?.updateWindingDirection,
});
}

Expand Down
40 changes: 22 additions & 18 deletions packages/tools/src/utilities/contours/updateContourPolyline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default function updateContourPolyline(
worldToCanvas: (point: Types.Point3) => Types.Point2;
},
options?: {
updateWindingDirection?: boolean;
decimate?: {
enabled?: boolean;
epsilon?: number;
Expand All @@ -55,8 +56,7 @@ export default function updateContourPolyline(
let { closed } = polylineData;
const numPoints = polyline.length;
const polylineWorldPoints = new Array(numPoints);
const currentPolylineWindingDirection =
math.polyline.getWindingDirection(polyline);
let windingDirection = math.polyline.getWindingDirection(polyline);
const parentAnnotation = getParentAnnotation(annotation) as ContourAnnotation;

if (closed === undefined) {
Expand All @@ -75,28 +75,32 @@ export default function updateContourPolyline(
closed = currentClosedState;
}

// It must be in the opposite direction if it is a child annotation (hole)
let windingDirection = parentAnnotation
? parentAnnotation.data.contour.windingDirection * -1
: targetWindingDirection;
if (options?.updateWindingDirection !== false) {
// It must be in the opposite direction if it is a child annotation (hole)
let updatedWindingDirection = parentAnnotation
? parentAnnotation.data.contour.windingDirection * -1
: targetWindingDirection;

if (windingDirection === undefined) {
windingDirection = currentPolylineWindingDirection;
}
if (updatedWindingDirection === undefined) {
updatedWindingDirection = windingDirection;
}

if (windingDirection !== currentPolylineWindingDirection) {
polyline.reverse();
}
if (updatedWindingDirection !== windingDirection) {
polyline.reverse();
}

const handlePoints = data.handles.points.map((p) => worldToCanvas(p));
const handlePoints = data.handles.points.map((p) => worldToCanvas(p));

if (handlePoints.length > 2) {
const currentHandlesWindingDirection =
math.polyline.getWindingDirection(handlePoints);
if (handlePoints.length > 2) {
const currentHandlesWindingDirection =
math.polyline.getWindingDirection(handlePoints);

if (currentHandlesWindingDirection !== windingDirection) {
data.handles.points.reverse();
if (currentHandlesWindingDirection !== updatedWindingDirection) {
data.handles.points.reverse();
}
}

windingDirection = updatedWindingDirection;
}

for (let i = 0; i < numPoints; i++) {
Expand Down

0 comments on commit 5eac830

Please sign in to comment.