diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 357 |
1 files changed, 239 insertions, 118 deletions
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 70b21309e..76e1646e2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -846,171 +846,292 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection */ @action segmentInkStroke = (ink: DocumentView, excludeT: number): Segment[] => { - // const segments: Segment[] = []; - // var segment: Segment = []; - // var segment2: Segment = []; - // var startSegmentT = 0; - // const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData(); + + const segments: Segment[] = []; + var segment1: Segment = []; + var segment2: Segment = []; + const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData(); // This iterates through all segments of the curve and splits them where they intersect another curve. // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted) - // var hasSplit = false; - // var continueErasing = false; + // find all t values of the curve's intersections + var intersections: number[] = []; + var segmentIndexes: number[] = []; + for (var i = 0; i < inkData.length - 3; i += 4) { + const inkSegment: Bezier = InkField.Segment(inkData, i); + var currIntersects = this.getInkIntersections(i, ink, inkSegment).sort(); + // get current segments intersections (if any) and add the curve index + currIntersects = currIntersects.map(tVal => tVal + Math.floor(i/4)); + if (currIntersects.length) { + intersections = [...intersections, ...currIntersects]; + // segmentIndexes is to keep track of the segment index that corresponds to an intersection + for (var j = 0; j < currIntersects.length; j++) { + segmentIndexes.push(Math.floor(i / 4)); + } + } + } + + if (intersections.length) { + // this is the indexes of the closest Ts + const closestTs = this.getClosestTs(intersections, excludeT, 0, intersections.length - 1); + + // find the segments that need to be split + var splitSegment1 = -1; // stays -1 if left end is deleted + var splitSegment2 = -1; // stays -1 if right end is deleted + if (closestTs[0] !== -1 && closestTs[1] !== -1) { + // if not on the ends + splitSegment1 = segmentIndexes[closestTs[0]]; + splitSegment2 = segmentIndexes[closestTs[1]]; + } else if (closestTs[0] === -1) { // for a curve left of intersection + splitSegment2 = segmentIndexes[closestTs[1]]; + } else { // for a curve right of intersection + splitSegment1 = segmentIndexes[closestTs[0]]; + } + + // so here splitSegment1 and splitSegment2 will be the index(es) of the segment(s) to split + + var hasSplit = false; + var continueErasing = false; + // loop through segments again and split if they match the split segments + for (var i = 0; i < inkData.length - 3; i += 4) { + const currCurveT = Math.floor(i / 4); + const inkSegment: Bezier = InkField.Segment(inkData, i); + + // case where the current curve is the first to split + if (splitSegment1 !== -1 && splitSegment2 !== -1) { + if (splitSegment1 === splitSegment2 && splitSegment1 === currCurveT) { + // if it's the same segment + segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT)); + segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1)); + hasSplit = true; + } else if (splitSegment1 === currCurveT) { + segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT)); + continueErasing = true; + } else if (splitSegment2 === currCurveT) { + segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1)); + continueErasing = false; + hasSplit = true; + } else { + if (!continueErasing && !hasSplit) { + // segment doesn't get pushed if continueErasing is true + segment1.push(inkSegment); + } else if (!continueErasing && hasSplit) { + segment2.push(inkSegment); + } + } + } else if (splitSegment1 === -1) { // case where left end is erased + if (currCurveT === splitSegment2) { + segment2.push(inkSegment.split(intersections[closestTs[1]] - currCurveT, 1)); + hasSplit = true; + } else { + if (hasSplit) { + segment2.push(inkSegment); + } + } + } else { // case where right end is erased + if (currCurveT === splitSegment1) { + segment1.push(inkSegment.split(0, intersections[closestTs[0]] - currCurveT)); + hasSplit = true; + } else { + if (!hasSplit) { + segment1.push(inkSegment); + } + } + } + } + } + + // push 1 or both segments if they are not empty + if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) { + segments.push(segment1); + } + if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) { + segments.push(segment2); + } + + return segments; + + // var deletedSegments = []; // for (var i = 0; i < inkData.length - 3; i += 4) { + // const segmentStartT = Math.floor(i/4); // const inkSegment: Bezier = InkField.Segment(inkData, i); // const tVals: number[] = this.getInkIntersections(i, ink, inkSegment).sort(); - // console.log("TVALS", tVals); - // if (tVals.length) { - // if ((!hasSplit) && ((excludeT <= tVals[0]) || - // (excludeT > tVals[0] && excludeT < tVals.lastElement()) || continueErasing)) { + // if (excludeT > segmentStartT && excludeT < segmentStartT + 1) { + // if (tVals.length) { // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1); // if (closestTs[0] != -1 && closestTs[1] != -1) { // segment1.push(inkSegment.split(0, closestTs[0])); // segment2.push(inkSegment.split(closestTs[1]).right); + // deletedSegments.push(inkSegment.split(closestTs[0], closestTs[1])); // } else if (closestTs[0] == -1) { // segment2.push(inkSegment.split(closestTs[1]).right); - // continueErasing = !continueErasing; + // deletedSegments.push(inkSegment.split(closestTs[1]).left); + // if (excludeT > tVals[0]) { + // continueErasing = !continueErasing; + // } // } else { - // segment1.push(inkSegment.split(0, closestTs[0])); + // continueErasing ? segment2.push(inkSegment.split(closestTs[0]).right) : segment1.push(inkSegment.split(0, closestTs[0])); + // continueErasing ? deletedSegments.push(inkSegment.split(closestTs[0]).left) : deletedSegments.push(inkSegment.split(closestTs[0]).right); // continueErasing = !continueErasing; // } // if (!continueErasing) { // hasSplit = true; // } - // // segment1 = []; - // // segment2 = []; + // } else if (hasSplit) { + // segment2.push(inkSegment); + // } else { + // continueErasing = true; // } - // else { - // if (hasSplit) { - // segment2.push(inkSegment); - // } else { - // segment1.push(inkSegment); - // } - // } - // } else if (hasSplit) { - // segment2.push(inkSegment); // } else { - // continueErasing = true; + // hasSplit ? segment1.push(inkSegment) : segment2.push(inkSegment); // } - // } + + // if (tVals.length) { + // if (!hasSplit) { + // if (excludeT <= tVals[0] || (excludeT > tVals[0] && excludeT < tVals.lastElement()) || excludeT > tVals.lastElement() || continueErasing) { + // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1); + // if (closestTs[0] != -1 && closestTs[1] != -1) { + // segment1.push(inkSegment.split(0, closestTs[0])); + // segment2.push(inkSegment.split(closestTs[1]).right); + // deletedSegments.push(inkSegment.split(closestTs[0], closestTs[1])); + // } else if (closestTs[0] == -1) { + // segment2.push(inkSegment.split(closestTs[1]).right); + // deletedSegments.push(inkSegment.split(closestTs[1]).left); + // if (excludeT > tVals[0]) { + // continueErasing = !continueErasing; + // } + // } else { + // continueErasing ? segment2.push(inkSegment.split(closestTs[0]).right) : segment1.push(inkSegment.split(0, closestTs[0])); + // continueErasing ? deletedSegments.push(inkSegment.split(closestTs[0]).left) : deletedSegments.push(inkSegment.split(closestTs[0]).right); + // continueErasing = !continueErasing; + // } + // if (!continueErasing) { + // hasSplit = true; + // } + // } else { + // if (hasSplit) { + // segment2.push(inkSegment); + // } else { + // segment1.push(inkSegment); + // } + // } + // } else if (excludeT > tVals[0] && excludeT < tVals.lastElement()) { + // // here we know hasSplit is true (but it shouldnt be!) + // segment1 = [...deletedSegments]; + // deletedSegments = []; + // hasSplit = false; + // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1); + // if (closestTs[0] != -1 && closestTs[1] != -1) { + // segment1.push(inkSegment.split(0, closestTs[0])); + // segment2.push(inkSegment.split(closestTs[1]).right); + // } else if (closestTs[0] == -1) { + // segment2.push(inkSegment.split(closestTs[1]).right); + // if (excludeT > tVals[0]) { + // continueErasing = !continueErasing; + // } + // } + // } else { + // segment2.push(inkSegment); + // } + // } else if (hasSplit) { + // segment2.push(inkSegment); + // } else { + // continueErasing = true; + // } - // if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) { - // segments.push(segment1); - // } - // if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) { - // segments.push(segment2); - // } - // if (excludeT < startSegmentT || excludeT > inkData.length / 4) { - // segment1.length && segments.push(segment1); + + + + // if (hasSplit && i + 4 >= lastIteration && ((excludeT > tVals[0] && excludeT < tVals.lastElement()) || (excludeT > tVals.lastElement()))) { + // // here we know hasSplit is true (but it shouldnt be!) + // segment1 = [...deletedSegments]; + // deletedSegments = []; + // hasSplit = false; + // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1); + // if (closestTs[0] != -1 && closestTs[1] != -1) { + // segment1.push(inkSegment.split(0, closestTs[0])); + // segment2.push(inkSegment.split(closestTs[1]).right); + // } else if (closestTs[0] == -1) { + // segment2.push(inkSegment.split(closestTs[1]).right); + // if (excludeT > tVals[0]) { + // continueErasing = !continueErasing; + // } + // } + // } // } - // const tVals = [] + + + // const segments: Segment[] = []; + // var segment1: Segment = []; + // var segment2: Segment = []; + // var startSegmentT = 0; + // var hasSplit = false; + // const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData(); + // // This iterates through all segments of the curve and splits them where they intersect another curve. + // // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted) // for (var i = 0; i < inkData.length - 3; i += 4) { // const inkSegment = InkField.Segment(inkData, i); // // Getting all t-value intersections of the current curve with all other curves. - // tVals.push(this.getInkIntersections(i, ink, inkSegment)); - // tVals.sort(); - - // if (tVals.length) { - // const docCurveTVal = tVals.lastElement() + Math.floor(i / 4); - // if (excludeT > docCurveTVal) { - // continue; - // } else { - // const closestTs = this.getClosestTs(tVals, excludeT, 0, tVals.length - 1); - // segment.push(inkSegment.split(0, closestTs[0])); - // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) { - // segments.push(segment); - // } - // } - - // const closestT = this.getClosestT(tVals, excludeT, 0, tVals.length - 1); - // if (closestT != undefined) { - // var startSegmentT = closestT[0] - // const localStartTVal = startSegmentT - Math.floor(i / 4); - // segment.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, startSegmentT)) - // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) { - // segments.push(segment); + // const tVals = this.getInkIntersections(i, ink, inkSegment).sort(); + // if (tVals.length) { + // tVals.forEach((t, index) => { + // const docCurveTVal = t + Math.floor(i / 4); + // if (excludeT < startSegmentT || excludeT > docCurveTVal) { + // const localStartTVal = startSegmentT - Math.floor(i / 4); + // if (!hasSplit) { + // t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment1.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t)); + // } else { + // t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment2.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t)); + // } + // // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) segments.push(segment); // } - // const split = inkSegment.split(closestT[1]).right; - // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) { - // segments.push([split]); + // // start a new segment from the intersection t value + // if (tVals.length - 1 === index) { + // const split = inkSegment.split(t).right; + // if (!hasSplit) { + // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment1.push(split); + // } else { + // if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment2.push(split); + // } // } - // } + // startSegmentT = docCurveTVal; + // }); // } else { - // segment.push(inkSegment); - // segments.push(segment); + // if (!hasSplit) { + // segment1.push(inkSegment); + // } else { + // segment2.push(inkSegment); + // } // } // } - const segments: Segment[] = []; - var segment1: Segment = []; - var segment2: Segment = []; - var startSegmentT = 0; - var hasSplit = false; - const { inkData } = (ink?.ComponentView as InkingStroke).inkScaledData(); - // This iterates through all segments of the curve and splits them where they intersect another curve. - // if 'excludeT' is specified, then any segment containing excludeT will be skipped (ie, deleted) - for (var i = 0; i < inkData.length - 3; i += 4) { - const inkSegment = InkField.Segment(inkData, i); - // Getting all t-value intersections of the current curve with all other curves. - const tVals = this.getInkIntersections(i, ink, inkSegment).sort(); - if (tVals.length) { - tVals.forEach((t, index) => { - const docCurveTVal = t + Math.floor(i / 4); - if (excludeT < startSegmentT || excludeT > docCurveTVal) { - const localStartTVal = startSegmentT - Math.floor(i / 4); - if (!hasSplit) { - t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment1.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t)); - } else { - t !== (localStartTVal < 0 ? 0 : localStartTVal) && segment2.push(inkSegment.split(localStartTVal < 0 ? 0 : localStartTVal, t)); - } - // if (segment.length && (Math.abs(segment[0].points[0].x - segment[0].points.lastElement().x) > 0.5 || Math.abs(segment[0].points[0].y - segment[0].points.lastElement().y) > 0.5)) segments.push(segment); - } - // start a new segment from the intersection t value - if (tVals.length - 1 === index) { - const split = inkSegment.split(t).right; - if (!hasSplit) { - if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment1.push(split); - } else { - if (split && (Math.abs(split.points[0].x - split.points.lastElement().x) > 0.5 || Math.abs(split.points[0].y - split.points.lastElement().y) > 0.5)) segment2.push(split); - } - } - startSegmentT = docCurveTVal; - }); - } else { - if (!hasSplit) { - segment1.push(inkSegment); - } else { - segment2.push(inkSegment); - } - } - } - if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) { - segments.push(segment1); - } - if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) { - segments.push(segment2); - } + // if (segment1.length && (Math.abs(segment1[0].points[0].x - segment1[0].points.lastElement().x) > 0.5 || Math.abs(segment1[0].points[0].y - segment1[0].points.lastElement().y) > 0.5)) { + // segments.push(segment1); + // } + // if (segment2.length && (Math.abs(segment2[0].points[0].x - segment2[0].points.lastElement().x) > 0.5 || Math.abs(segment2[0].points[0].y - segment2[0].points.lastElement().y) > 0.5)) { + // segments.push(segment2); + // } return segments; }; getClosestTs = (tVals: number[], excludeT: number, startIndex: number, endIndex: number): number[] => { if (tVals[startIndex] >= excludeT) { - return [-1, tVals[startIndex]]; + return [-1, startIndex]; } else if (tVals[endIndex] < excludeT) { - return [tVals[endIndex], -1]; + return [endIndex, -1]; } else { - const mid = Math.floor(startIndex + endIndex / 2); + const mid = Math.floor((startIndex + endIndex) / 2); if (excludeT >= tVals[mid]) { if (mid + 1 <= endIndex && tVals[mid + 1] > excludeT) { - return [tVals[mid], tVals[mid + 1]]; + return [mid, mid + 1]; } else { return this.getClosestTs(tVals, excludeT, mid + 1, endIndex); } } else { - if (mid - 1 <= startIndex && tVals[mid - 1] < excludeT) { - return [tVals[mid - 1], tVals[mid]]; + if (mid - 1 >= startIndex && tVals[mid - 1] < excludeT) { + return [mid - 1, mid]; } else { return this.getClosestTs(tVals, excludeT, startIndex, mid - 1); } |