@itwin/core-geometry 3.0.0-dev.84 → 3.0.0-dev.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +1049 -1049
  2. package/LICENSE.md +9 -9
  3. package/README.md +17 -17
  4. package/lib/cjs/Constant.js.map +1 -1
  5. package/lib/cjs/clipping/ClipVector.d.ts +0 -1
  6. package/lib/cjs/clipping/ClipVector.d.ts.map +1 -1
  7. package/lib/cjs/clipping/ClipVector.js +0 -1
  8. package/lib/cjs/clipping/ClipVector.js.map +1 -1
  9. package/lib/cjs/core-geometry.js.map +1 -1
  10. package/lib/cjs/geometry3d/Point3dArrayCarrier.d.ts +2 -2
  11. package/lib/cjs/geometry3d/Point3dArrayCarrier.js +2 -2
  12. package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
  13. package/lib/cjs/topology/ChainMerge.js.map +1 -1
  14. package/lib/cjs/topology/Graph.d.ts +35 -6
  15. package/lib/cjs/topology/Graph.d.ts.map +1 -1
  16. package/lib/cjs/topology/Graph.js +90 -10
  17. package/lib/cjs/topology/Graph.js.map +1 -1
  18. package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
  19. package/lib/cjs/topology/HalfEdgeGraphValidation.js.map +1 -1
  20. package/lib/cjs/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  21. package/lib/cjs/topology/HalfEdgePriorityQueue.js.map +1 -1
  22. package/lib/cjs/topology/MaskManager.js.map +1 -1
  23. package/lib/cjs/topology/Merging.d.ts +44 -9
  24. package/lib/cjs/topology/Merging.d.ts.map +1 -1
  25. package/lib/cjs/topology/Merging.js +110 -22
  26. package/lib/cjs/topology/Merging.js.map +1 -1
  27. package/lib/cjs/topology/RegularizeFace.js.map +1 -1
  28. package/lib/cjs/topology/Triangulation.js.map +1 -1
  29. package/lib/esm/Constant.js.map +1 -1
  30. package/lib/esm/clipping/ClipVector.d.ts +0 -1
  31. package/lib/esm/clipping/ClipVector.d.ts.map +1 -1
  32. package/lib/esm/clipping/ClipVector.js +0 -1
  33. package/lib/esm/clipping/ClipVector.js.map +1 -1
  34. package/lib/esm/core-geometry.js.map +1 -1
  35. package/lib/esm/geometry3d/Point3dArrayCarrier.d.ts +2 -2
  36. package/lib/esm/geometry3d/Point3dArrayCarrier.js +2 -2
  37. package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
  38. package/lib/esm/topology/ChainMerge.js.map +1 -1
  39. package/lib/esm/topology/Graph.d.ts +35 -6
  40. package/lib/esm/topology/Graph.d.ts.map +1 -1
  41. package/lib/esm/topology/Graph.js +90 -10
  42. package/lib/esm/topology/Graph.js.map +1 -1
  43. package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
  44. package/lib/esm/topology/HalfEdgeGraphValidation.js.map +1 -1
  45. package/lib/esm/topology/HalfEdgePointInGraphSearch.js.map +1 -1
  46. package/lib/esm/topology/HalfEdgePriorityQueue.js.map +1 -1
  47. package/lib/esm/topology/MaskManager.js.map +1 -1
  48. package/lib/esm/topology/Merging.d.ts +44 -9
  49. package/lib/esm/topology/Merging.d.ts.map +1 -1
  50. package/lib/esm/topology/Merging.js +110 -22
  51. package/lib/esm/topology/Merging.js.map +1 -1
  52. package/lib/esm/topology/RegularizeFace.js.map +1 -1
  53. package/lib/esm/topology/Triangulation.js.map +1 -1
  54. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"Merging.js","sourceRoot":"","sources":["../../../src/topology/Merging.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Topology\n */\n\nimport { LineSegment3d } from \"../curve/LineSegment3d\";\nimport { Geometry } from \"../Geometry\";\nimport { Angle } from \"../geometry3d/Angle\";\nimport { Point2d, Vector2d } from \"../geometry3d/Point2dVector2d\";\nimport { Range3d } from \"../geometry3d/Range\";\nimport { ClusterableArray } from \"../numerics/ClusterableArray\";\nimport { SmallSystem } from \"../numerics/Polynomials\";\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\nimport { HalfEdgePriorityQueueWithPartnerArray } from \"./HalfEdgePriorityQueue\";\nimport { RegularizationContext } from \"./RegularizeFace\";\nimport { MultiLineStringDataVariant, Triangulator } from \"./Triangulation\";\n\nexport class GraphSplitData {\n public numUpEdge = 0;\n public numIntersectionTest = 0;\n public numSplit = 0;\n public numPopOut = 0;\n public numA0B0 = 0;\n public numA0B1 = 0;\n public constructor() {\n }\n}\n\n/**\n * * Assorted methods used in algorithms on HalfEdgeGraph.\n * @internal\n */\nexport class HalfEdgeGraphOps {\n\n /** Compare function for sorting with primary y compare, secondary x compare. */\n public static compareNodesYXUp(a: HalfEdge, b: HalfEdge) {\n // Check y's\n // if (!Geometry.isSameCoordinate(a.y, b.y))\n if (a.y < b.y)\n return -1;\n else if (a.y > b.y)\n return 1;\n // Check x's\n // if (!Geometry.isSameCoordinate(a.x, b.x))\n if (a.x < b.x)\n return -1;\n else if (a.x > b.x)\n return 1;\n return 0;\n }\n\n /** Return true if nodeB (a) is lower than both its neighbors and (b) inflects as a downward peak (rather than an upward trough) */\n public static isDownPeak(nodeB: HalfEdge) {\n const nodeA = nodeB.facePredecessor;\n const nodeC = nodeB.faceSuccessor;\n return this.compareNodesYXUp(nodeB, nodeA) < 0\n && this.compareNodesYXUp(nodeB, nodeC) < 0\n && this.crossProductToTargets(nodeB, nodeA, nodeC) > 0;\n }\n\n /** return the cross product of vectors from base to targetA and base to targetB\n * @param base base vertex of both vectors.\n * @param targetA target vertex of first vector\n * @param targetB target vertex of second vector\n */\n public static crossProductToTargets(base: HalfEdge, targetA: HalfEdge, targetB: HalfEdge): number {\n return Geometry.crossProductXYXY(targetA.x - base.x, targetA.y - base.y, targetB.x - base.x, targetB.y - base.y);\n }\n\n // ---------------------------------------------------------------------------------------------------------------------\n // ----------------------------------------------------------------------------------------------------------------------\n\n public static graphRange(graph: HalfEdgeGraph): Range3d {\n const range = Range3d.create();\n for (const node of graph.allHalfEdges) {\n range.extendXYZ(node.x, node.y, node.z);\n }\n return range;\n }\n /** Returns an array of a all nodes (both ends) of edges created from segments. */\n public static segmentArrayToGraphEdges(segments: LineSegment3d[], returnGraph: HalfEdgeGraph, mask: HalfEdgeMask): HalfEdge[] {\n const result = [];\n let idxCounter = 0;\n\n // Push the endpoints of each segment onto arr[] in the form {(x, y, theta), Node}\n for (const segment of segments) {\n\n const node0 = returnGraph.createEdgeXYZXYZ(\n segment.point0Ref.x, segment.point0Ref.y, segment.point0Ref.z,\n idxCounter,\n segment.point1Ref.x, segment.point1Ref.y, segment.point1Ref.z,\n idxCounter + 1);\n\n const node1 = node0.edgeMate;\n idxCounter += 2;\n\n node0.setMaskAroundFace(mask); // Original given coordinates must be part of boundary\n result.push(node0);\n result.push(node1);\n }\n\n return result;\n }\n\n /**\n * * For each face with positive area . . . add edges as needed so that each face has one definitely lower node and one definite upper node.\n * * Hence tracing edges from the low node, there is a sequence of upward edges, reaching the upper, then a sequence of downward edges reaching the low node.\n * * This is an essential step for subsequent triangulation.\n *\n * @param graph\n */\n public static formMonotoneFaces(graph: HalfEdgeGraph) {\n\n const allFaces = graph.collectFaceLoops();\n graph.clearMask(HalfEdgeMask.VISITED);\n // For every face, break the face down into monotone sections\n for (const node of allFaces) {\n if (node.isMaskSet(HalfEdgeMask.VISITED))\n continue;\n const area = node.signedFaceArea();\n if (area <= 0.0) {\n node.setMaskAroundFace(HalfEdgeMask.VISITED);\n continue;\n }\n\n }\n }\n\n /**\n * * Visit all nodes in `graph`.\n * * invoke `pinch(node, vertexPredecessor)`\n * * this leaves the graph as isolated edges.\n * @param graph graph to modify\n */\n public static isolateAllEdges(graph: HalfEdgeGraph) {\n for (const nodeA of graph.allHalfEdges) {\n const nodeB = nodeA.vertexPredecessor;\n HalfEdge.pinch(nodeA, nodeB);\n }\n }\n\n}\n/**\n * @internal\n */\nexport class HalfEdgeGraphMerge {\n /** Simplest merge algorithm:\n * * collect array of (x,y,theta) at all nodes\n * * lexical sort of the array.\n * * twist all vertices together.\n * * This effectively creates valid face loops for a planar subdivision if there are no edge crossings.\n * * If there are edge crossings, the graph can be a (highly complicated) Klein bottle topology.\n * * Mask.NULL_FACE is cleared throughout and applied within null faces.\n */\n public static clusterAndMergeXYTheta(graph: HalfEdgeGraph, outboundRadiansFunction?: (he: HalfEdge) => number) {\n const allNodes = graph.allHalfEdges;\n const numNodes = allNodes.length;\n graph.clearMask(HalfEdgeMask.NULL_FACE);\n const clusters = new ClusterableArray(2, 2, numNodes); // data order: x,y,theta, nodeIndex. But theta is not set in first round.\n for (let i = 0; i < numNodes; i++) {\n const nodeA = allNodes[i];\n const xA = nodeA.x;\n const yA = nodeA.y;\n HalfEdge.pinch(nodeA, nodeA.vertexSuccessor); // pull it out of its current vertex loop.\n clusters.addDirect(xA, yA, 0.0, i);\n }\n const order = clusters.clusterIndicesLexical();\n let k0 = 0;\n const numK = order.length;\n for (let k1 = 0; k1 < numK; k1++) {\n if (order[k1] === ClusterableArray.clusterTerminator) {\n // nodes identified in order[k0]..order[k1] are properly sorted around a vertex.\n if (k1 > k0) {\n const iA = clusters.getExtraData(order[k0], 1);\n const nodeA0 = allNodes[iA];\n for (let k = k0 + 1; k < k1; k++) {\n const iB = clusters.getExtraData(order[k], 1);\n const nodeB = allNodes[iB];\n nodeB.x = nodeA0.x;\n nodeB.y = nodeA0.y;\n }\n }\n k0 = k1 + 1;\n }\n }\n // NOW\n // 1) There are identical coordinates at all nodes around each vertex loop.\n // 2) Hence ready do sort (at each vertex) by theta.\n\n // insert theta as extra data in the sort table . . .\n for (const clusterTableIndex of order) {\n if (clusterTableIndex !== ClusterableArray.clusterTerminator) {\n const nodeA = allNodes[clusterTableIndex];\n const nodeB = nodeA.faceSuccessor;\n let radians = outboundRadiansFunction ? outboundRadiansFunction(nodeA) : Math.atan2(nodeB.y - nodeA.y, nodeB.x - nodeA.x);\n if (Angle.isAlmostEqualRadiansAllowPeriodShift(radians, -Math.PI))\n radians = Math.PI;\n clusters.setExtraData(clusterTableIndex, 0, radians);\n }\n }\n clusters.sortSubsetsBySingleKey(order, 2);\n const unmatchedNullFaceNodes: HalfEdge[] = [];\n k0 = 0;\n let thetaA, thetaB;\n // now pinch each neighboring pair together\n for (let k1 = 0; k1 < numK; k1++) {\n if (order[k1] === ClusterableArray.clusterTerminator) {\n // nodes identified in order[k0]..order[k1] are properly sorted around a vertex.\n if (k1 > k0) {\n const iA = clusters.getExtraData(order[k0], 1);\n thetaA = clusters.getExtraData(order[k0], 0);\n const nodeA0 = allNodes[iA];\n let nodeA = nodeA0;\n for (let k = k0 + 1; k < k1; k++) {\n const iB = clusters.getExtraData(order[k], 1);\n thetaB = clusters.getExtraData(order[k], 0);\n const nodeB = allNodes[iB];\n if (nodeA.isMaskSet(HalfEdgeMask.NULL_FACE)) {\n // nope, this edge was flagged and pinched from the other end.\n const j = unmatchedNullFaceNodes.findIndex((node: HalfEdge) => nodeA === node);\n if (j >= 0) {\n unmatchedNullFaceNodes[j] = unmatchedNullFaceNodes[unmatchedNullFaceNodes.length - 1];\n unmatchedNullFaceNodes.pop();\n }\n nodeA = nodeB;\n thetaA = thetaB;\n } else if (nodeB.isMaskSet(HalfEdgeMask.NULL_FACE)) {\n const j = unmatchedNullFaceNodes.findIndex((node: HalfEdge) => nodeA === node);\n if (j >= 0) {\n unmatchedNullFaceNodes[j] = unmatchedNullFaceNodes[unmatchedNullFaceNodes.length - 1];\n unmatchedNullFaceNodes.pop();\n }\n // NO leave nodeA and thetaA ignore nodeB -- later step will get the outside of its banana.\n } else {\n HalfEdge.pinch(nodeA, nodeB);\n if (Angle.isAlmostEqualRadiansAllowPeriodShift(thetaA, thetaB)) {\n const nodeA1 = nodeA.faceSuccessor;\n const nodeB1 = nodeB.edgeMate;\n // WE TRUST -- nodeA1 and node B1 must have identical xy.\n // pinch them together and mark the face loop as null ..\n HalfEdge.pinch(nodeA1, nodeB1);\n nodeA.setMask(HalfEdgeMask.NULL_FACE);\n nodeB1.setMask(HalfEdgeMask.NULL_FACE);\n unmatchedNullFaceNodes.push(nodeB1);\n }\n nodeA = nodeB;\n thetaA = thetaB;\n }\n }\n }\n k0 = k1 + 1;\n }\n }\n }\n\n private static buildVerticalSweepPriorityQueue(graph: HalfEdgeGraph): HalfEdgePriorityQueueWithPartnerArray {\n const sweepHeap = new HalfEdgePriorityQueueWithPartnerArray();\n for (const p of graph.allHalfEdges) {\n\n if (HalfEdgeGraphOps.compareNodesYXUp(p, p.faceSuccessor) < 0) {\n sweepHeap.priorityQueue.push(p);\n }\n }\n return sweepHeap;\n }\n private static snapFractionToNode(xy: Point2d, fraction: number, node: HalfEdge, nodeFraction: number): number{\n if (Geometry.isSameCoordinate(xy.x, node.x) && Geometry.isSameCoordinate(xy.y, node.y))\n return nodeFraction;\n return fraction;\n}\n private static computeIntersectionFractionsOnEdges(nodeA0: HalfEdge, nodeB0: HalfEdge, fractions: Vector2d, pointA: Point2d, pointB: Point2d): boolean {\n const nodeA1 = nodeA0.faceSuccessor;\n const ax0 = nodeA0.x;\n const ay0 = nodeA0.y;\n const ux = nodeA1.x - ax0;\n const uy = nodeA1.y - ay0;\n const nodeB1 = nodeB0.faceSuccessor;\n const bx0 = nodeB0.x;\n const by0 = nodeB0.y;\n const vx = nodeB1.x - bx0;\n const vy = nodeB1.y - by0;\n if (SmallSystem.lineSegmentXYUVTransverseIntersectionUnbounded(ax0, ay0, ux, uy,\n bx0, by0, vx, vy, fractions)) {\n pointA.x = ax0 + fractions.x * ux;\n pointA.y = ay0 + fractions.x * uy;\n pointB.x = bx0 + fractions.y * vx;\n pointB.y = by0 + fractions.y * vy;\n fractions.x = this.snapFractionToNode(pointA, fractions.x, nodeA0, 0.0);\n fractions.x = this.snapFractionToNode(pointA, fractions.x, nodeA1, 1.0);\n fractions.y = this.snapFractionToNode(pointB, fractions.y, nodeB0, 0.0);\n fractions.y = this.snapFractionToNode(pointB, fractions.y, nodeB1, 1.0);\n return Geometry.isIn01(fractions.x) && Geometry.isIn01(fractions.y);\n }\n return false;\n }\n /**\n * Split edges at intersections.\n * * This is a large operation.\n * @param graph\n */\n public static splitIntersectingEdges(graph: HalfEdgeGraph): GraphSplitData {\n const data = new GraphSplitData();\n const sweepHeap = this.buildVerticalSweepPriorityQueue(graph);\n let nodeA0, nodeB1;\n const smallFraction = 1.0e-8;\n const largeFraction = 1.0 - smallFraction;\n let i;\n const fractions = Vector2d.create();\n const pointA = Point2d.create();\n const pointB = Point2d.create();\n let nodeB0;\n const popTolerance = Geometry.smallMetricDistance;\n while (undefined !== (nodeA0 = sweepHeap.priorityQueue.pop())) {\n data.numUpEdge++;\n const n0 = sweepHeap.activeEdges.length;\n sweepHeap.removeArrayMembersWithY1Below(nodeA0.y - popTolerance);\n data.numPopOut += n0 - sweepHeap.activeEdges.length;\n for (i = 0; i < sweepHeap.activeEdges.length; i++) {\n nodeB0 = sweepHeap.activeEdges[i];\n nodeB1 = nodeB0.faceSuccessor;\n // const nodeB1 = nodeB0.faceSuccessor;\n if (Geometry.isSameCoordinateXY(nodeA0.x, nodeA0.y, nodeB0.x, nodeB0.y)) {\n data.numA0B0++;\n } else if (Geometry.isSameCoordinateXY(nodeB1.x, nodeB1.y, nodeA0.x, nodeA0.y)) {\n data.numA0B1++;\n } else {\n data.numIntersectionTest++;\n if (this.computeIntersectionFractionsOnEdges(nodeA0, nodeB0, fractions, pointA, pointB)) {\n if (fractions.x > smallFraction && fractions.x < largeFraction) {\n const nodeC0 = graph.splitEdgeAtFraction(nodeA0, fractions.x);\n sweepHeap.priorityQueue.push(nodeC0); // The upper portion will be reviewed as a nodeA0 later !!!\n data.numSplit++;\n }\n if (fractions.y > smallFraction && fractions.y < largeFraction) {\n const nodeD0 = graph.splitEdgeAtFraction(nodeB0, fractions.y);\n sweepHeap.priorityQueue.push(nodeD0); // The upper portion will be reviewed as a nodeA0 later !!!\n data.numSplit++;\n }\n // existing nodeA0 and its shortened edge remain for further intersections\n }\n }\n }\n sweepHeap.activeEdges.push(nodeA0);\n }\n return data;\n }\n\n /**\n * Returns a graph structure formed from the given LineSegment array\n *\n * * Find all intersections among segments, and split them if necessary\n * * Record endpoints of every segment in the form X, Y, Theta; This information is stored as a new node and sorted to match up\n * vertices.\n * * For vertices that match up, pinch the nodes to create vertex loops, which in closed objects, will also eventually form face\n * loops\n */\n public static formGraphFromSegments(lineSegments: LineSegment3d[]): HalfEdgeGraph {\n // Structure of an index of the array: { xyTheta: Point3d, node: Node }\n const graph = new HalfEdgeGraph();\n HalfEdgeGraphOps.segmentArrayToGraphEdges(lineSegments, graph, HalfEdgeMask.BOUNDARY_EDGE);\n this.splitIntersectingEdges(graph);\n this.clusterAndMergeXYTheta(graph);\n\n return graph;\n }\n\n /**\n * * Input is random linestrings, not necessarily loops\n * * Graph gets full splitEdges, regularize, and triangulate.\n * @returns triangulated graph, or undefined if bad data.\n */\n public static formGraphFromChains(chains: MultiLineStringDataVariant, regularize: boolean = true, mask: HalfEdgeMask = HalfEdgeMask.PRIMARY_EDGE): HalfEdgeGraph | undefined {\n if (chains.length < 1)\n return undefined;\n const graph = new HalfEdgeGraph();\n const chainSeeds = Triangulator.directCreateChainsFromCoordinates(graph, chains);\n for (const seed of chainSeeds)\n seed.setMaskAroundFace(mask);\n\n this.splitIntersectingEdges(graph);\n this.clusterAndMergeXYTheta(graph);\n if (regularize) {\n const context = new RegularizationContext(graph);\n context.regularizeGraph(true, true);\n }\n return graph;\n }\n\n}\n"]}
1
+ {"version":3,"file":"Merging.js","sourceRoot":"","sources":["../../../src/topology/Merging.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\n\r\nimport { LineSegment3d } from \"../curve/LineSegment3d\";\r\nimport { Geometry } from \"../Geometry\";\r\nimport { Angle } from \"../geometry3d/Angle\";\r\nimport { Point2d, Vector2d } from \"../geometry3d/Point2dVector2d\";\r\nimport { Range3d } from \"../geometry3d/Range\";\r\nimport { ClusterableArray } from \"../numerics/ClusterableArray\";\r\nimport { SmallSystem } from \"../numerics/Polynomials\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\nimport { HalfEdgePriorityQueueWithPartnerArray } from \"./HalfEdgePriorityQueue\";\r\nimport { RegularizationContext } from \"./RegularizeFace\";\r\nimport { MultiLineStringDataVariant, Triangulator } from \"./Triangulation\";\r\n\r\nexport class GraphSplitData {\r\n public numUpEdge = 0;\r\n public numIntersectionTest = 0;\r\n public numSplit = 0;\r\n public numPopOut = 0;\r\n public numA0B0 = 0;\r\n public numA0B1 = 0;\r\n public constructor() {\r\n }\r\n}\r\n\r\n/**\r\n * * Assorted methods used in algorithms on HalfEdgeGraph.\r\n * @internal\r\n */\r\nexport class HalfEdgeGraphOps {\r\n\r\n /** Compare function for sorting with primary y compare, secondary x compare. */\r\n public static compareNodesYXUp(a: HalfEdge, b: HalfEdge) {\r\n // Check y's\r\n // if (!Geometry.isSameCoordinate(a.y, b.y))\r\n if (a.y < b.y)\r\n return -1;\r\n else if (a.y > b.y)\r\n return 1;\r\n // Check x's\r\n // if (!Geometry.isSameCoordinate(a.x, b.x))\r\n if (a.x < b.x)\r\n return -1;\r\n else if (a.x > b.x)\r\n return 1;\r\n return 0;\r\n }\r\n\r\n /** Return true if nodeB (a) is lower than both its neighbors and (b) inflects as a downward peak (rather than an upward trough) */\r\n public static isDownPeak(nodeB: HalfEdge) {\r\n const nodeA = nodeB.facePredecessor;\r\n const nodeC = nodeB.faceSuccessor;\r\n return this.compareNodesYXUp(nodeB, nodeA) < 0\r\n && this.compareNodesYXUp(nodeB, nodeC) < 0\r\n && this.crossProductToTargets(nodeB, nodeA, nodeC) > 0;\r\n }\r\n\r\n /** return the cross product of vectors from base to targetA and base to targetB\r\n * @param base base vertex of both vectors.\r\n * @param targetA target vertex of first vector\r\n * @param targetB target vertex of second vector\r\n */\r\n public static crossProductToTargets(base: HalfEdge, targetA: HalfEdge, targetB: HalfEdge): number {\r\n return Geometry.crossProductXYXY(targetA.x - base.x, targetA.y - base.y, targetB.x - base.x, targetB.y - base.y);\r\n }\r\n\r\n // ---------------------------------------------------------------------------------------------------------------------\r\n // ----------------------------------------------------------------------------------------------------------------------\r\n\r\n public static graphRange(graph: HalfEdgeGraph): Range3d {\r\n const range = Range3d.create();\r\n for (const node of graph.allHalfEdges) {\r\n range.extendXYZ(node.x, node.y, node.z);\r\n }\r\n return range;\r\n }\r\n /** Returns an array of all nodes (both ends) of edges created from segments. */\r\n public static segmentArrayToGraphEdges(segments: LineSegment3d[], returnGraph: HalfEdgeGraph, mask: HalfEdgeMask): HalfEdge[] {\r\n const result = [];\r\n let idxCounter = 0;\r\n\r\n // Push the endpoints of each segment onto arr[] in the form {(x, y, theta), Node}\r\n for (const segment of segments) {\r\n\r\n const node0 = returnGraph.createEdgeXYZXYZ(\r\n segment.point0Ref.x, segment.point0Ref.y, segment.point0Ref.z,\r\n idxCounter,\r\n segment.point1Ref.x, segment.point1Ref.y, segment.point1Ref.z,\r\n idxCounter + 1);\r\n\r\n const node1 = node0.edgeMate;\r\n idxCounter += 2;\r\n\r\n node0.setMaskAroundFace(mask); // Original given coordinates must be part of boundary\r\n result.push(node0);\r\n result.push(node1);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * * Visit all nodes in `graph`.\r\n * * invoke `pinch(node, vertexPredecessor)`\r\n * * this leaves the graph as isolated edges.\r\n * @param graph graph to modify\r\n */\r\n public static isolateAllEdges(graph: HalfEdgeGraph) {\r\n for (const nodeA of graph.allHalfEdges) {\r\n const nodeB = nodeA.vertexPredecessor;\r\n HalfEdge.pinch(nodeA, nodeB);\r\n }\r\n }\r\n\r\n /**\r\n * Compute convexity of a sector of a super-face.\r\n * @param base node whose edge is to be tested for removal\r\n * @param ignore edges with this mask (on either side) are ignored for the purposes of computing convexity\r\n * @param barrier edges with this mask (on either side) will not be removed\r\n * @return whether removing the edge at base would create a convex sector in the super-face\r\n */\r\n private static isSectorConvexAfterEdgeRemoval(base: HalfEdge, ignore: HalfEdgeMask, barrier: HalfEdgeMask): boolean {\r\n let vs = base;\r\n do { // loop ccw around vertex looking for a super-face predecessor\r\n if (vs.isMaskSet(barrier) || vs.edgeMate.isMaskSet(barrier))\r\n break;\r\n vs = vs.vertexSuccessor;\r\n } while (vs !== base && vs.isMaskSet(ignore));\r\n if (vs === base)\r\n return false;\r\n let vp = base;\r\n do { // loop cw around vertex looking for a super-face successor\r\n if (vp.isMaskSet(barrier) || vp.edgeMate.isMaskSet(barrier))\r\n break;\r\n vp = vp.vertexPredecessor;\r\n } while (vp !== base && vp.isMaskSet(ignore));\r\n if (vp === base)\r\n return false;\r\n return HalfEdge.isSectorConvex(vs.edgeMate, base, vp.faceSuccessor);\r\n }\r\n\r\n /**\r\n * Mask edges between faces if the union of the faces is convex.\r\n * Uses a greedy algorithm with no regard to quality of resulting convex faces.\r\n * Best results when input faces are convex.\r\n * @param graph graph to examine and mark\r\n * @param mark the mask used to mark (both sides of) removable edges\r\n * @param barrier edges with this mask (on either side) will not be marked. Defaults to HalfEdgeMask.BOUNDARY_EDGE.\r\n * @return number of edges masked (half the number of HalfEdges masked)\r\n */\r\n public static markRemovableEdgesToExpandConvexFaces(graph: HalfEdgeGraph, mark: HalfEdgeMask, barrier: HalfEdgeMask = HalfEdgeMask.BOUNDARY_EDGE): number {\r\n if (HalfEdgeMask.NULL_MASK === mark)\r\n return 0;\r\n const visit = graph.grabMask(true);\r\n let numMarked = 0;\r\n for (const node of graph.allHalfEdges) {\r\n if (!node.isMaskSet(visit)) {\r\n if (!node.isMaskSet(barrier) && !node.edgeMate.isMaskSet(barrier)) {\r\n if (this.isSectorConvexAfterEdgeRemoval(node, mark, barrier) && this.isSectorConvexAfterEdgeRemoval(node.edgeMate, mark, barrier)) {\r\n node.setMaskAroundEdge(mark);\r\n ++numMarked;\r\n }\r\n }\r\n }\r\n node.setMaskAroundEdge(visit);\r\n }\r\n return numMarked;\r\n }\r\n\r\n /**\r\n * Collect edges between faces if the union of the faces is convex.\r\n * Uses a greedy algorithm with no regard to quality of resulting convex faces.\r\n * Best results when input faces are convex.\r\n * @param graph graph to examine\r\n * @param barrier edges with this mask (on either side) will not be collected. Defaults to HalfEdgeMask.BOUNDARY_EDGE.\r\n * @return one HalfEdge per removable edge\r\n */\r\n public static collectRemovableEdgesToExpandConvexFaces(graph: HalfEdgeGraph, barrier: HalfEdgeMask = HalfEdgeMask.BOUNDARY_EDGE): HalfEdge[] | undefined {\r\n const removable: HalfEdge[] = [];\r\n const mark = graph.grabMask(true);\r\n if (0 < this.markRemovableEdgesToExpandConvexFaces(graph, mark, barrier)) {\r\n const visited = graph.grabMask(true);\r\n for (const node of graph.allHalfEdges) {\r\n if (node.isMaskSet(mark) && !node.isMaskSet(visited)) {\r\n node.setMaskAroundEdge(visited);\r\n removable.push(node);\r\n }\r\n }\r\n graph.dropMask(visited);\r\n }\r\n graph.dropMask(mark);\r\n return removable;\r\n }\r\n\r\n /**\r\n * Remove edges between faces if the union of the faces is convex.\r\n * Uses a greedy algorithm with no regard to quality of resulting convex faces.\r\n * Best results when input faces are convex.\r\n * @param graph graph to modify\r\n * @param barrier edges with this mask (on either side) will not be removed. Defaults to HalfEdgeMask.BOUNDARY_EDGE.\r\n * @return number of edges deleted\r\n */\r\n public static expandConvexFaces(graph: HalfEdgeGraph, barrier: HalfEdgeMask = HalfEdgeMask.BOUNDARY_EDGE): number {\r\n const mark = graph.grabMask(true);\r\n const numRemovedEdges = this.markRemovableEdgesToExpandConvexFaces(graph, mark, barrier);\r\n if (numRemovedEdges > 0)\r\n graph.yankAndDeleteEdges((node: HalfEdge) => node.getMask(mark));\r\n graph.dropMask(mark);\r\n return numRemovedEdges;\r\n }\r\n\r\n /**\r\n * Test desired faces for convexity.\r\n * @param graph graph to examine\r\n * @param avoid faces with this mask will not be examined. Defaults to HalfEdgeMask.EXTERIOR.\r\n * @return whether every face in the graph is convex\r\n */\r\n public static isEveryFaceConvex(graph: HalfEdgeGraph, avoid: HalfEdgeMask = HalfEdgeMask.EXTERIOR): boolean {\r\n const allFaces = graph.collectFaceLoops();\r\n for (const node of allFaces) {\r\n if (node.isMaskedAroundFace(avoid))\r\n continue;\r\n if (!node.isFaceConvex())\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport class HalfEdgeGraphMerge {\r\n /** Simplest merge algorithm:\r\n * * collect array of (x,y,theta) at all nodes\r\n * * lexical sort of the array.\r\n * * twist all vertices together.\r\n * * This effectively creates valid face loops for a planar subdivision if there are no edge crossings.\r\n * * If there are edge crossings, the graph can be a (highly complicated) Klein bottle topology.\r\n * * Mask.NULL_FACE is cleared throughout and applied within null faces.\r\n */\r\n public static clusterAndMergeXYTheta(graph: HalfEdgeGraph, outboundRadiansFunction?: (he: HalfEdge) => number) {\r\n const allNodes = graph.allHalfEdges;\r\n const numNodes = allNodes.length;\r\n graph.clearMask(HalfEdgeMask.NULL_FACE);\r\n const clusters = new ClusterableArray(2, 2, numNodes); // data order: x,y,theta, nodeIndex. But theta is not set in first round.\r\n for (let i = 0; i < numNodes; i++) {\r\n const nodeA = allNodes[i];\r\n const xA = nodeA.x;\r\n const yA = nodeA.y;\r\n HalfEdge.pinch(nodeA, nodeA.vertexSuccessor); // pull it out of its current vertex loop.\r\n clusters.addDirect(xA, yA, 0.0, i);\r\n }\r\n const order = clusters.clusterIndicesLexical();\r\n let k0 = 0;\r\n const numK = order.length;\r\n for (let k1 = 0; k1 < numK; k1++) {\r\n if (order[k1] === ClusterableArray.clusterTerminator) {\r\n // nodes identified in order[k0]..order[k1] are properly sorted around a vertex.\r\n if (k1 > k0) {\r\n const iA = clusters.getExtraData(order[k0], 1);\r\n const nodeA0 = allNodes[iA];\r\n for (let k = k0 + 1; k < k1; k++) {\r\n const iB = clusters.getExtraData(order[k], 1);\r\n const nodeB = allNodes[iB];\r\n nodeB.x = nodeA0.x;\r\n nodeB.y = nodeA0.y;\r\n }\r\n }\r\n k0 = k1 + 1;\r\n }\r\n }\r\n // NOW\r\n // 1) There are identical coordinates at all nodes around each vertex loop.\r\n // 2) Hence ready do sort (at each vertex) by theta.\r\n\r\n // insert theta as extra data in the sort table . . .\r\n for (const clusterTableIndex of order) {\r\n if (clusterTableIndex !== ClusterableArray.clusterTerminator) {\r\n const nodeA = allNodes[clusterTableIndex];\r\n const nodeB = nodeA.faceSuccessor;\r\n let radians = outboundRadiansFunction ? outboundRadiansFunction(nodeA) : Math.atan2(nodeB.y - nodeA.y, nodeB.x - nodeA.x);\r\n if (Angle.isAlmostEqualRadiansAllowPeriodShift(radians, -Math.PI))\r\n radians = Math.PI;\r\n clusters.setExtraData(clusterTableIndex, 0, radians);\r\n }\r\n }\r\n clusters.sortSubsetsBySingleKey(order, 2);\r\n const unmatchedNullFaceNodes: HalfEdge[] = [];\r\n k0 = 0;\r\n let thetaA, thetaB;\r\n // now pinch each neighboring pair together\r\n for (let k1 = 0; k1 < numK; k1++) {\r\n if (order[k1] === ClusterableArray.clusterTerminator) {\r\n // nodes identified in order[k0]..order[k1] are properly sorted around a vertex.\r\n if (k1 > k0) {\r\n const iA = clusters.getExtraData(order[k0], 1);\r\n thetaA = clusters.getExtraData(order[k0], 0);\r\n const nodeA0 = allNodes[iA];\r\n let nodeA = nodeA0;\r\n for (let k = k0 + 1; k < k1; k++) {\r\n const iB = clusters.getExtraData(order[k], 1);\r\n thetaB = clusters.getExtraData(order[k], 0);\r\n const nodeB = allNodes[iB];\r\n if (nodeA.isMaskSet(HalfEdgeMask.NULL_FACE)) {\r\n // nope, this edge was flagged and pinched from the other end.\r\n const j = unmatchedNullFaceNodes.findIndex((node: HalfEdge) => nodeA === node);\r\n if (j >= 0) {\r\n unmatchedNullFaceNodes[j] = unmatchedNullFaceNodes[unmatchedNullFaceNodes.length - 1];\r\n unmatchedNullFaceNodes.pop();\r\n }\r\n nodeA = nodeB;\r\n thetaA = thetaB;\r\n } else if (nodeB.isMaskSet(HalfEdgeMask.NULL_FACE)) {\r\n const j = unmatchedNullFaceNodes.findIndex((node: HalfEdge) => nodeA === node);\r\n if (j >= 0) {\r\n unmatchedNullFaceNodes[j] = unmatchedNullFaceNodes[unmatchedNullFaceNodes.length - 1];\r\n unmatchedNullFaceNodes.pop();\r\n }\r\n // NO leave nodeA and thetaA ignore nodeB -- later step will get the outside of its banana.\r\n } else {\r\n HalfEdge.pinch(nodeA, nodeB);\r\n if (Angle.isAlmostEqualRadiansAllowPeriodShift(thetaA, thetaB)) {\r\n const nodeA1 = nodeA.faceSuccessor;\r\n const nodeB1 = nodeB.edgeMate;\r\n // WE TRUST -- nodeA1 and node B1 must have identical xy.\r\n // pinch them together and mark the face loop as null ..\r\n HalfEdge.pinch(nodeA1, nodeB1);\r\n nodeA.setMask(HalfEdgeMask.NULL_FACE);\r\n nodeB1.setMask(HalfEdgeMask.NULL_FACE);\r\n unmatchedNullFaceNodes.push(nodeB1);\r\n }\r\n nodeA = nodeB;\r\n thetaA = thetaB;\r\n }\r\n }\r\n }\r\n k0 = k1 + 1;\r\n }\r\n }\r\n }\r\n\r\n private static buildVerticalSweepPriorityQueue(graph: HalfEdgeGraph): HalfEdgePriorityQueueWithPartnerArray {\r\n const sweepHeap = new HalfEdgePriorityQueueWithPartnerArray();\r\n for (const p of graph.allHalfEdges) {\r\n\r\n if (HalfEdgeGraphOps.compareNodesYXUp(p, p.faceSuccessor) < 0) {\r\n sweepHeap.priorityQueue.push(p);\r\n }\r\n }\r\n return sweepHeap;\r\n }\r\n private static snapFractionToNode(xy: Point2d, fraction: number, node: HalfEdge, nodeFraction: number): number{\r\n if (Geometry.isSameCoordinate(xy.x, node.x) && Geometry.isSameCoordinate(xy.y, node.y))\r\n return nodeFraction;\r\n return fraction;\r\n}\r\n private static computeIntersectionFractionsOnEdges(nodeA0: HalfEdge, nodeB0: HalfEdge, fractions: Vector2d, pointA: Point2d, pointB: Point2d): boolean {\r\n const nodeA1 = nodeA0.faceSuccessor;\r\n const ax0 = nodeA0.x;\r\n const ay0 = nodeA0.y;\r\n const ux = nodeA1.x - ax0;\r\n const uy = nodeA1.y - ay0;\r\n const nodeB1 = nodeB0.faceSuccessor;\r\n const bx0 = nodeB0.x;\r\n const by0 = nodeB0.y;\r\n const vx = nodeB1.x - bx0;\r\n const vy = nodeB1.y - by0;\r\n if (SmallSystem.lineSegmentXYUVTransverseIntersectionUnbounded(ax0, ay0, ux, uy,\r\n bx0, by0, vx, vy, fractions)) {\r\n pointA.x = ax0 + fractions.x * ux;\r\n pointA.y = ay0 + fractions.x * uy;\r\n pointB.x = bx0 + fractions.y * vx;\r\n pointB.y = by0 + fractions.y * vy;\r\n fractions.x = this.snapFractionToNode(pointA, fractions.x, nodeA0, 0.0);\r\n fractions.x = this.snapFractionToNode(pointA, fractions.x, nodeA1, 1.0);\r\n fractions.y = this.snapFractionToNode(pointB, fractions.y, nodeB0, 0.0);\r\n fractions.y = this.snapFractionToNode(pointB, fractions.y, nodeB1, 1.0);\r\n return Geometry.isIn01(fractions.x) && Geometry.isIn01(fractions.y);\r\n }\r\n return false;\r\n }\r\n /**\r\n * Split edges at intersections.\r\n * * This is a large operation.\r\n * @param graph\r\n */\r\n public static splitIntersectingEdges(graph: HalfEdgeGraph): GraphSplitData {\r\n const data = new GraphSplitData();\r\n const sweepHeap = this.buildVerticalSweepPriorityQueue(graph);\r\n let nodeA0, nodeB1;\r\n const smallFraction = 1.0e-8;\r\n const largeFraction = 1.0 - smallFraction;\r\n let i;\r\n const fractions = Vector2d.create();\r\n const pointA = Point2d.create();\r\n const pointB = Point2d.create();\r\n let nodeB0;\r\n const popTolerance = Geometry.smallMetricDistance;\r\n while (undefined !== (nodeA0 = sweepHeap.priorityQueue.pop())) {\r\n data.numUpEdge++;\r\n const n0 = sweepHeap.activeEdges.length;\r\n sweepHeap.removeArrayMembersWithY1Below(nodeA0.y - popTolerance);\r\n data.numPopOut += n0 - sweepHeap.activeEdges.length;\r\n for (i = 0; i < sweepHeap.activeEdges.length; i++) {\r\n nodeB0 = sweepHeap.activeEdges[i];\r\n nodeB1 = nodeB0.faceSuccessor;\r\n // const nodeB1 = nodeB0.faceSuccessor;\r\n if (Geometry.isSameCoordinateXY(nodeA0.x, nodeA0.y, nodeB0.x, nodeB0.y)) {\r\n data.numA0B0++;\r\n } else if (Geometry.isSameCoordinateXY(nodeB1.x, nodeB1.y, nodeA0.x, nodeA0.y)) {\r\n data.numA0B1++;\r\n } else {\r\n data.numIntersectionTest++;\r\n if (this.computeIntersectionFractionsOnEdges(nodeA0, nodeB0, fractions, pointA, pointB)) {\r\n if (fractions.x > smallFraction && fractions.x < largeFraction) {\r\n const nodeC0 = graph.splitEdgeAtFraction(nodeA0, fractions.x);\r\n sweepHeap.priorityQueue.push(nodeC0); // The upper portion will be reviewed as a nodeA0 later !!!\r\n data.numSplit++;\r\n }\r\n if (fractions.y > smallFraction && fractions.y < largeFraction) {\r\n const nodeD0 = graph.splitEdgeAtFraction(nodeB0, fractions.y);\r\n sweepHeap.priorityQueue.push(nodeD0); // The upper portion will be reviewed as a nodeA0 later !!!\r\n data.numSplit++;\r\n }\r\n // existing nodeA0 and its shortened edge remain for further intersections\r\n }\r\n }\r\n }\r\n sweepHeap.activeEdges.push(nodeA0);\r\n }\r\n return data;\r\n }\r\n\r\n /**\r\n * Returns a graph structure formed from the given LineSegment array\r\n *\r\n * * Find all intersections among segments, and split them if necessary\r\n * * Record endpoints of every segment in the form X, Y, Theta; This information is stored as a new node and sorted to match up\r\n * vertices.\r\n * * For vertices that match up, pinch the nodes to create vertex loops, which in closed objects, will also eventually form face\r\n * loops\r\n */\r\n public static formGraphFromSegments(lineSegments: LineSegment3d[]): HalfEdgeGraph {\r\n // Structure of an index of the array: { xyTheta: Point3d, node: Node }\r\n const graph = new HalfEdgeGraph();\r\n HalfEdgeGraphOps.segmentArrayToGraphEdges(lineSegments, graph, HalfEdgeMask.BOUNDARY_EDGE);\r\n this.splitIntersectingEdges(graph);\r\n this.clusterAndMergeXYTheta(graph);\r\n\r\n return graph;\r\n }\r\n\r\n /**\r\n * * Input is random linestrings, not necessarily loops\r\n * * Graph gets full splitEdges, regularize, and triangulate.\r\n * @returns triangulated graph, or undefined if bad data.\r\n */\r\n public static formGraphFromChains(chains: MultiLineStringDataVariant, regularize: boolean = true, mask: HalfEdgeMask = HalfEdgeMask.PRIMARY_EDGE): HalfEdgeGraph | undefined {\r\n if (chains.length < 1)\r\n return undefined;\r\n const graph = new HalfEdgeGraph();\r\n const chainSeeds = Triangulator.directCreateChainsFromCoordinates(graph, chains);\r\n for (const seed of chainSeeds)\r\n seed.setMaskAroundFace(mask);\r\n\r\n this.splitIntersectingEdges(graph);\r\n this.clusterAndMergeXYTheta(graph);\r\n if (regularize) {\r\n const context = new RegularizationContext(graph);\r\n context.regularizeGraph(true, true);\r\n }\r\n return graph;\r\n }\r\n\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RegularizeFace.js","sourceRoot":"","sources":["../../../src/topology/RegularizeFace.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Topology\n */\n\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\nimport { HalfEdgeGraphOps } from \"./Merging\";\n\n// /* eslint-disable no-console */\n/**\n * * Context for regularizing single faces.\n * @internal\n */\nexport class RegularizationContext {\n // For debugging use ... \"almost always\" undefined.\n // If defined, it is called with each inserted node pair.\n // scale will be either plus or minus one.\n // when it is negative, the node coordinates (both x and y) have been negated.\n // The call is made after full insertion into vertex loop.\n public static announceEdge?: (graph: HalfEdgeGraph, nodeA: HalfEdge, nodeB: HalfEdge, scale: number) => void;\n public constructor(graph: HalfEdgeGraph) {\n this.graph = graph;\n this.upEdges = [];\n this.downEdges = [];\n this.bottomPeaks = [];\n this.topPeaks = [];\n this.localMin = [];\n this.localMax = [];\n }\n\n /**\n * These are public only for testing.\n */\n public graph: HalfEdgeGraph;\n /** array of edges directed upward. Turn can be left or right, but is not large enough to be a min or max */\n public upEdges: HalfEdge[];\n /** array of edges directed downward, Turn can be left or right, but is not large enough to be a min or max */\n public downEdges: HalfEdge[];\n /** Array of edges whose start is an upward peak (right turn, inbound up, outbound down) */\n public topPeaks: HalfEdge[];\n /** Array of edges whose start is an downward peak (right turn, inbound down, outbound up) */\n public bottomPeaks: HalfEdge[];\n\n /** Array of edges at local minima (left turn, inbound down, outbound up). Ensuing chain is up */\n public localMin: HalfEdge[];\n /** Array of edges at local maxima (left turn, inbound up, outbound down). Ensuing chain is down */\n public localMax: HalfEdge[];\n /**\n * Collect (and classify) all the edges around a single face.\n * * The various arrays are collected: upEdges, downEdges, topPeaks, bottomPeaks, upChains, downChains\n * @param faceSeed face to examine\n */\n public collectVerticalEventsAroundFace(faceSeed: HalfEdge) {\n let nodeA = faceSeed;\n let nodeB;\n let nodeC;\n let abUp;\n let bcUp;\n this.upEdges.length = 0;\n this.downEdges.length = 0;\n this.topPeaks.length = 0;\n this.bottomPeaks.length = 0;\n this.localMin.length = 0;\n this.localMax.length = 0;\n do {\n nodeB = nodeA.faceSuccessor;\n nodeC = nodeB.faceSuccessor;\n abUp = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB) < 0;\n bcUp = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC) < 0;\n if (abUp) {\n this.upEdges.push(nodeA);\n if (!bcUp) {\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) < 0)\n this.localMax.push(nodeB);\n else\n this.topPeaks.push(nodeB);\n }\n\n } else { // ab is DOWN\n this.downEdges.push(nodeA);\n if (bcUp) {\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) > 0)\n this.bottomPeaks.push(nodeB);\n else\n this.localMin.push(nodeB);\n }\n }\n nodeA = nodeB;\n } while (nodeA !== faceSeed);\n }\n\n /**\n * Collect (and classify) all the edges in an array.\n * * The various arrays are collected: upEdges, downEdges, topPeaks, bottomPeaks, upChains, downChains\n * @param candidateEdges array of edges.\n */\n public collectVerticalEventFromEdgesInAndArray(candidateEdges: HalfEdge[]) {\n let nodeA;\n let nodeB;\n let nodeC;\n let abUp;\n let bcUp;\n this.upEdges.length = 0;\n this.downEdges.length = 0;\n this.topPeaks.length = 0;\n this.bottomPeaks.length = 0;\n this.localMin.length = 0;\n this.localMax.length = 0;\n for (nodeA of candidateEdges) {\n nodeB = nodeA.faceSuccessor;\n nodeC = nodeB.faceSuccessor;\n abUp = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB) < 0;\n bcUp = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC) < 0;\n if (abUp) {\n this.upEdges.push(nodeA);\n if (!bcUp) {\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) < 0)\n this.localMax.push(nodeB);\n else\n this.topPeaks.push(nodeB);\n }\n\n } else { // ab is DOWN\n this.downEdges.push(nodeA);\n if (bcUp) {\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) > 0)\n this.bottomPeaks.push(nodeB);\n else\n this.localMin.push(nodeB);\n }\n }\n }\n }\n\n private swapArrays() {\n let save = this.downEdges; this.downEdges = this.upEdges; this.upEdges = save;\n save = this.localMax; this.localMax = this.localMin; this.localMin = save;\n save = this.topPeaks; this.topPeaks = this.bottomPeaks; this.bottomPeaks = save;\n }\n\n /**\n * Find the edge (among candidates) which is first struck by a \"rightward\" scan from node\n * * comparisonFunction determines scan sense\n * * HalfEdge.compareNodeYXTheta is an upward scan.\n * * HalfEdge.compareNodeYXThetaDownward is a downward scan.\n * @param node\n * @param candidates Array of nodes to search\n * @param nodeComparisonFunction function for lexical comparison.\n */\n private findTopVisibleEdge(node: HalfEdge, candidates: HalfEdge[],\n directionSign: number) {\n const y0 = node.y;\n const x0 = node.x;\n let dx;\n let distanceRight = Number.MAX_SAFE_INTEGER;\n let result: HalfEdge | undefined;\n for (const rightBase of candidates) {\n const rightTop = rightBase.faceSuccessor;\n if (rightBase === node || rightTop === node)\n continue;\n // for horizontal edge cases -- require edges ends to have strict sign change (no zeros!!)\n const cRight = HalfEdgeGraphOps.compareNodesYXUp(node, rightBase);\n const cTop = HalfEdgeGraphOps.compareNodesYXUp(node, rightTop);\n // console.log(node.id, rightBase.id, rightTop.id, cRight, cTop);\n if (cRight * cTop >= 0)\n continue;\n const fraction = HalfEdge.horizontalScanFraction01(rightBase, y0);\n if (fraction !== undefined) {\n dx = directionSign * (rightBase.fractionToX(fraction) - x0);\n if (dx > 0 && dx < distanceRight) {\n result = rightBase;\n distanceRight = dx;\n }\n }\n }\n return result;\n }\n /**\n *\n * @param downPeak a \"bottom\" node where the interior CCW loop has a local min\n * @param downEdgeStart (optional) node at the start (heading downwards!) of an edge that brackets downPeak on the left.\n * @param upEdgeStart (optional) node at the start (heading up!) of the edge that brackets downPeak on the right.\n */\n private highestUpPeakConnection(downPeak: HalfEdge, downEdgeStart: HalfEdge | undefined, upEdgeStart: HalfEdge | undefined): HalfEdge | undefined {\n let highestPeak;\n\n for (const upPeak of this.topPeaks) {\n const y0 = upPeak.y;\n const x0 = upPeak.x;\n // is upPeak higher than prior upPeak?\n if (highestPeak !== undefined && HalfEdgeGraphOps.compareNodesYXUp(upPeak, highestPeak) < 0)\n continue;\n // is upPeak BELOW downPeak, ABOVE both limit edges lower node, and between limit edge interiors.\n if (HalfEdgeGraphOps.compareNodesYXUp(upPeak, downPeak) < 0) {\n if (downEdgeStart) {\n const fraction = HalfEdge.horizontalScanFraction01(downEdgeStart, y0);\n if (fraction === undefined)\n continue;\n if (x0 <= downEdgeStart.fractionToX(fraction))\n continue;\n }\n if (upEdgeStart) {\n const fraction = HalfEdge.horizontalScanFraction01(upEdgeStart, y0);\n if (fraction === undefined)\n continue;\n if (upEdgeStart.fractionToX(fraction) <= x0)\n continue;\n }\n highestPeak = upPeak;\n }\n }\n return highestPeak;\n }\n\n private updateMaxNode(maxNode: HalfEdge | undefined, candidate: HalfEdge | undefined, compare: (a: HalfEdge, b: HalfEdge) => number): HalfEdge | undefined {\n if (!maxNode)\n return candidate;\n if (!candidate)\n return maxNode;\n // both are defined .. look for positive compare ...\n if (compare(maxNode, candidate) < 0)\n return candidate;\n return maxNode;\n }\n private negateXY() {\n for (const node of this.graph.allHalfEdges) {\n node.x *= -1;\n node.y *= -1;\n }\n }\n private downwardConnectionFromBottomPeak(node: HalfEdge): HalfEdge | undefined {\n let connectTo;\n const upFunction = HalfEdgeGraphOps.compareNodesYXUp;\n const upEdgeBase = this.findTopVisibleEdge(node, this.upEdges, 1.0)!;\n const downEdgeBase = this.findTopVisibleEdge(node, this.downEdges, -1.0)!;\n connectTo = this.updateMaxNode(connectTo, upEdgeBase, upFunction);\n if (downEdgeBase)\n connectTo = this.updateMaxNode(connectTo, downEdgeBase.faceSuccessor, upFunction);\n const upPeakConnection = this.highestUpPeakConnection(node, downEdgeBase, upEdgeBase);\n if (upPeakConnection !== undefined)\n connectTo = this.updateMaxNode(connectTo, upPeakConnection, upFunction);\n return connectTo;\n }\n /** Search around the vertex of nodeA for a nodeA1 such that nodeB is visible in the sector at nodeA1 */\n private findVisibleSector(nodeA: HalfEdge, nodeB: HalfEdge): HalfEdge | undefined {\n let nodeA1 = nodeA;\n do {\n if (HalfEdge.isNodeVisibleInSector(nodeB, nodeA1))\n return nodeA1;\n nodeA1 = nodeA1.vertexSuccessor;\n } while (nodeA1 !== nodeA);\n return undefined;\n }\n /**\n * Create an edge from (some node around the vertex of) nodeA to (some node around the vertex of) nodeB.\n * * looking around the vertex for alternate insertion corrects cusp insertion errors.\n * @param nodeA\n * @param nodeB\n */\n private joinNodes(nodeA: HalfEdge, nodeB: HalfEdge, direction: number): HalfEdge | undefined {\n const nodeC = this.graph.createEdgeXYZXYZ(nodeA.x, nodeA.y, nodeA.z, 0, nodeB.x, nodeB.y, nodeB.z, 0);\n const nodeA1 = this.findVisibleSector(nodeA, nodeB);\n const nodeB1 = this.findVisibleSector(nodeB, nodeA);\n if (nodeA1 !== undefined && nodeB1 !== undefined) {\n HalfEdge.pinch(nodeA1, nodeC);\n HalfEdge.pinch(nodeB1, nodeC.edgeMate);\n if (RegularizationContext.announceEdge)\n RegularizationContext.announceEdge(this.graph, nodeA, nodeB, direction);\n return nodeC;\n }\n return undefined;\n }\n /**\n * Regularize a single face.\n * * Insert edge from any downward interior vertex to something lower\n * * Insert an edge from each upward interior vertex to something higher.\n * * The face is split into smaller faces\n * * Each final face has at most one \"min\" and one \"max\", and is easy to triangulate with a bottom to top sweep.\n * * Normal usage is to sweep in both directions, i.e. use the default (true,true) for the upSweep and downSweep parameters.\n * @param faceSeed any representative half edge on the face\n * @param upSweep true to do the upward sweep.\n * @param downSweep true to do the downward sweep.\n */\n private runRegularization(upSweep: boolean = true, downSweep: boolean = true) {\n if (upSweep) {\n this.bottomPeaks.sort(HalfEdgeGraphOps.compareNodesYXUp);\n for (const bottomPeak of this.bottomPeaks) {\n // console.log(\"SEARCH\", bottomPeak.id, [bottomPeak.x, bottomPeak.y]);\n if (!HalfEdgeGraphOps.isDownPeak(bottomPeak))\n continue;\n const target = this.downwardConnectionFromBottomPeak(bottomPeak);\n if (target !== undefined) {\n // console.log(\"join\", bottomPeak.id, [bottomPeak.x, bottomPeak.y], target.id, [target.x, target.y]);\n this.joinNodes(bottomPeak, target, 1);\n }\n }\n }\n if (downSweep) {\n // flip the whole graph (ouch)\n this.negateXY();\n // swap the various p and down seeds ....\n this.swapArrays();\n this.bottomPeaks.sort(HalfEdgeGraphOps.compareNodesYXUp);\n for (const bottomPeak of this.bottomPeaks) {\n if (!HalfEdgeGraphOps.isDownPeak(bottomPeak))\n continue;\n const target = this.downwardConnectionFromBottomPeak(bottomPeak);\n if (target !== undefined) {\n this.joinNodes(bottomPeak, target, -1);\n }\n }\n this.negateXY();\n this.swapArrays();\n }\n }\n\n /**\n * Regularize a single face.\n * * Insert edge from any downward interior vertex to something lower\n * * Insert an edge from each upward interior vertex to something higher.\n * * The face is split into smaller faces\n * * Each final face has at most one \"min\" and one \"max\", and is easy to triangulate with a bottom to top sweep.\n * * Normal usage is to sweep in both directions, i.e. use the default (true,true) for the upSweep and downSweep parameters.\n * @param faceSeed any representative half edge on the face\n * @param upSweep true to do the upward sweep.\n * @param downSweep true to do the downward sweep.\n */\n public regularizeFace(faceSeed: HalfEdge, upSweep: boolean = true, downSweep: boolean = true) {\n this.collectVerticalEventsAroundFace(faceSeed);\n this.runRegularization(upSweep, downSweep);\n }\n\n public regularizeGraph(upSweep: boolean = true, downSweep: boolean = true) {\n this.collectVerticalEventFromEdgesInAndArray(this.graph.allHalfEdges);\n this.runRegularization(upSweep, downSweep);\n }\n\n /** test if a single face is monotone; if so, return its (single) min */\n public static isMonotoneFace(seed: HalfEdge): HalfEdge | undefined {\n let numMin = 0;\n let numMax = 0;\n let nodeMin: HalfEdge | undefined;\n let nodeA = seed;\n do {\n const nodeB = nodeA.faceSuccessor;\n const nodeC = nodeB.faceSuccessor;\n const ab = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB);\n const bc = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC);\n if (ab * bc <= 0) {\n if (ab > 0) {\n numMin++;\n nodeMin = nodeB;\n }\n if (bc > 0) {\n numMax++;\n }\n }\n } while ((nodeA = nodeA.faceSuccessor) !== seed);\n return numMin === 1 && numMax === 1 ? nodeMin : undefined;\n }\n /** Return faces filtered by area and test function.\n * * find one arbitrary representative of each face\n * * offer the candidate to the mutate function.\n * * collect results\n * @param mappedSeeds when filter returns a HalfEdge, collect it here\n * @param unmappedSeeds when filter does not return a half edge, collect the candidate.\n */\n public static collectMappedFaceRepresentatives(\n graph: HalfEdgeGraph,\n positiveAreaOnly: boolean,\n mutate: (seed: HalfEdge) => HalfEdge | undefined,\n mappedEdges: HalfEdge[] | undefined,\n unMappedSeeds: HalfEdge[] | undefined) {\n if (mappedEdges)\n mappedEdges.length = 0;\n if (unMappedSeeds)\n unMappedSeeds.length = 0;\n const mask = HalfEdgeMask.VISITED;\n graph.clearMask(mask);\n for (const seed of graph.allHalfEdges) {\n if (!seed.getMask(mask)) {\n seed.setMaskAroundFace(mask);\n if (!positiveAreaOnly || seed.signedFaceArea() > 0) {\n const edge = mutate(seed);\n if (edge) {\n if (mappedEdges)\n mappedEdges.push(edge);\n } else {\n if (unMappedSeeds)\n unMappedSeeds.push(seed);\n }\n }\n }\n }\n }\n\n}\n"]}
1
+ {"version":3,"file":"RegularizeFace.js","sourceRoot":"","sources":["../../../src/topology/RegularizeFace.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n/** @packageDocumentation\r\n * @module Topology\r\n */\r\n\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"./Graph\";\r\nimport { HalfEdgeGraphOps } from \"./Merging\";\r\n\r\n// /* eslint-disable no-console */\r\n/**\r\n * * Context for regularizing single faces.\r\n * @internal\r\n */\r\nexport class RegularizationContext {\r\n // For debugging use ... \"almost always\" undefined.\r\n // If defined, it is called with each inserted node pair.\r\n // scale will be either plus or minus one.\r\n // when it is negative, the node coordinates (both x and y) have been negated.\r\n // The call is made after full insertion into vertex loop.\r\n public static announceEdge?: (graph: HalfEdgeGraph, nodeA: HalfEdge, nodeB: HalfEdge, scale: number) => void;\r\n public constructor(graph: HalfEdgeGraph) {\r\n this.graph = graph;\r\n this.upEdges = [];\r\n this.downEdges = [];\r\n this.bottomPeaks = [];\r\n this.topPeaks = [];\r\n this.localMin = [];\r\n this.localMax = [];\r\n }\r\n\r\n /**\r\n * These are public only for testing.\r\n */\r\n public graph: HalfEdgeGraph;\r\n /** array of edges directed upward. Turn can be left or right, but is not large enough to be a min or max */\r\n public upEdges: HalfEdge[];\r\n /** array of edges directed downward, Turn can be left or right, but is not large enough to be a min or max */\r\n public downEdges: HalfEdge[];\r\n /** Array of edges whose start is an upward peak (right turn, inbound up, outbound down) */\r\n public topPeaks: HalfEdge[];\r\n /** Array of edges whose start is an downward peak (right turn, inbound down, outbound up) */\r\n public bottomPeaks: HalfEdge[];\r\n\r\n /** Array of edges at local minima (left turn, inbound down, outbound up). Ensuing chain is up */\r\n public localMin: HalfEdge[];\r\n /** Array of edges at local maxima (left turn, inbound up, outbound down). Ensuing chain is down */\r\n public localMax: HalfEdge[];\r\n /**\r\n * Collect (and classify) all the edges around a single face.\r\n * * The various arrays are collected: upEdges, downEdges, topPeaks, bottomPeaks, upChains, downChains\r\n * @param faceSeed face to examine\r\n */\r\n public collectVerticalEventsAroundFace(faceSeed: HalfEdge) {\r\n let nodeA = faceSeed;\r\n let nodeB;\r\n let nodeC;\r\n let abUp;\r\n let bcUp;\r\n this.upEdges.length = 0;\r\n this.downEdges.length = 0;\r\n this.topPeaks.length = 0;\r\n this.bottomPeaks.length = 0;\r\n this.localMin.length = 0;\r\n this.localMax.length = 0;\r\n do {\r\n nodeB = nodeA.faceSuccessor;\r\n nodeC = nodeB.faceSuccessor;\r\n abUp = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB) < 0;\r\n bcUp = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC) < 0;\r\n if (abUp) {\r\n this.upEdges.push(nodeA);\r\n if (!bcUp) {\r\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) < 0)\r\n this.localMax.push(nodeB);\r\n else\r\n this.topPeaks.push(nodeB);\r\n }\r\n\r\n } else { // ab is DOWN\r\n this.downEdges.push(nodeA);\r\n if (bcUp) {\r\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) > 0)\r\n this.bottomPeaks.push(nodeB);\r\n else\r\n this.localMin.push(nodeB);\r\n }\r\n }\r\n nodeA = nodeB;\r\n } while (nodeA !== faceSeed);\r\n }\r\n\r\n /**\r\n * Collect (and classify) all the edges in an array.\r\n * * The various arrays are collected: upEdges, downEdges, topPeaks, bottomPeaks, upChains, downChains\r\n * @param candidateEdges array of edges.\r\n */\r\n public collectVerticalEventFromEdgesInAndArray(candidateEdges: HalfEdge[]) {\r\n let nodeA;\r\n let nodeB;\r\n let nodeC;\r\n let abUp;\r\n let bcUp;\r\n this.upEdges.length = 0;\r\n this.downEdges.length = 0;\r\n this.topPeaks.length = 0;\r\n this.bottomPeaks.length = 0;\r\n this.localMin.length = 0;\r\n this.localMax.length = 0;\r\n for (nodeA of candidateEdges) {\r\n nodeB = nodeA.faceSuccessor;\r\n nodeC = nodeB.faceSuccessor;\r\n abUp = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB) < 0;\r\n bcUp = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC) < 0;\r\n if (abUp) {\r\n this.upEdges.push(nodeA);\r\n if (!bcUp) {\r\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) < 0)\r\n this.localMax.push(nodeB);\r\n else\r\n this.topPeaks.push(nodeB);\r\n }\r\n\r\n } else { // ab is DOWN\r\n this.downEdges.push(nodeA);\r\n if (bcUp) {\r\n if (HalfEdgeGraphOps.crossProductToTargets(nodeB, nodeA, nodeC) > 0)\r\n this.bottomPeaks.push(nodeB);\r\n else\r\n this.localMin.push(nodeB);\r\n }\r\n }\r\n }\r\n }\r\n\r\n private swapArrays() {\r\n let save = this.downEdges; this.downEdges = this.upEdges; this.upEdges = save;\r\n save = this.localMax; this.localMax = this.localMin; this.localMin = save;\r\n save = this.topPeaks; this.topPeaks = this.bottomPeaks; this.bottomPeaks = save;\r\n }\r\n\r\n /**\r\n * Find the edge (among candidates) which is first struck by a \"rightward\" scan from node\r\n * * comparisonFunction determines scan sense\r\n * * HalfEdge.compareNodeYXTheta is an upward scan.\r\n * * HalfEdge.compareNodeYXThetaDownward is a downward scan.\r\n * @param node\r\n * @param candidates Array of nodes to search\r\n * @param nodeComparisonFunction function for lexical comparison.\r\n */\r\n private findTopVisibleEdge(node: HalfEdge, candidates: HalfEdge[],\r\n directionSign: number) {\r\n const y0 = node.y;\r\n const x0 = node.x;\r\n let dx;\r\n let distanceRight = Number.MAX_SAFE_INTEGER;\r\n let result: HalfEdge | undefined;\r\n for (const rightBase of candidates) {\r\n const rightTop = rightBase.faceSuccessor;\r\n if (rightBase === node || rightTop === node)\r\n continue;\r\n // for horizontal edge cases -- require edges ends to have strict sign change (no zeros!!)\r\n const cRight = HalfEdgeGraphOps.compareNodesYXUp(node, rightBase);\r\n const cTop = HalfEdgeGraphOps.compareNodesYXUp(node, rightTop);\r\n // console.log(node.id, rightBase.id, rightTop.id, cRight, cTop);\r\n if (cRight * cTop >= 0)\r\n continue;\r\n const fraction = HalfEdge.horizontalScanFraction01(rightBase, y0);\r\n if (fraction !== undefined) {\r\n dx = directionSign * (rightBase.fractionToX(fraction) - x0);\r\n if (dx > 0 && dx < distanceRight) {\r\n result = rightBase;\r\n distanceRight = dx;\r\n }\r\n }\r\n }\r\n return result;\r\n }\r\n /**\r\n *\r\n * @param downPeak a \"bottom\" node where the interior CCW loop has a local min\r\n * @param downEdgeStart (optional) node at the start (heading downwards!) of an edge that brackets downPeak on the left.\r\n * @param upEdgeStart (optional) node at the start (heading up!) of the edge that brackets downPeak on the right.\r\n */\r\n private highestUpPeakConnection(downPeak: HalfEdge, downEdgeStart: HalfEdge | undefined, upEdgeStart: HalfEdge | undefined): HalfEdge | undefined {\r\n let highestPeak;\r\n\r\n for (const upPeak of this.topPeaks) {\r\n const y0 = upPeak.y;\r\n const x0 = upPeak.x;\r\n // is upPeak higher than prior upPeak?\r\n if (highestPeak !== undefined && HalfEdgeGraphOps.compareNodesYXUp(upPeak, highestPeak) < 0)\r\n continue;\r\n // is upPeak BELOW downPeak, ABOVE both limit edges lower node, and between limit edge interiors.\r\n if (HalfEdgeGraphOps.compareNodesYXUp(upPeak, downPeak) < 0) {\r\n if (downEdgeStart) {\r\n const fraction = HalfEdge.horizontalScanFraction01(downEdgeStart, y0);\r\n if (fraction === undefined)\r\n continue;\r\n if (x0 <= downEdgeStart.fractionToX(fraction))\r\n continue;\r\n }\r\n if (upEdgeStart) {\r\n const fraction = HalfEdge.horizontalScanFraction01(upEdgeStart, y0);\r\n if (fraction === undefined)\r\n continue;\r\n if (upEdgeStart.fractionToX(fraction) <= x0)\r\n continue;\r\n }\r\n highestPeak = upPeak;\r\n }\r\n }\r\n return highestPeak;\r\n }\r\n\r\n private updateMaxNode(maxNode: HalfEdge | undefined, candidate: HalfEdge | undefined, compare: (a: HalfEdge, b: HalfEdge) => number): HalfEdge | undefined {\r\n if (!maxNode)\r\n return candidate;\r\n if (!candidate)\r\n return maxNode;\r\n // both are defined .. look for positive compare ...\r\n if (compare(maxNode, candidate) < 0)\r\n return candidate;\r\n return maxNode;\r\n }\r\n private negateXY() {\r\n for (const node of this.graph.allHalfEdges) {\r\n node.x *= -1;\r\n node.y *= -1;\r\n }\r\n }\r\n private downwardConnectionFromBottomPeak(node: HalfEdge): HalfEdge | undefined {\r\n let connectTo;\r\n const upFunction = HalfEdgeGraphOps.compareNodesYXUp;\r\n const upEdgeBase = this.findTopVisibleEdge(node, this.upEdges, 1.0)!;\r\n const downEdgeBase = this.findTopVisibleEdge(node, this.downEdges, -1.0)!;\r\n connectTo = this.updateMaxNode(connectTo, upEdgeBase, upFunction);\r\n if (downEdgeBase)\r\n connectTo = this.updateMaxNode(connectTo, downEdgeBase.faceSuccessor, upFunction);\r\n const upPeakConnection = this.highestUpPeakConnection(node, downEdgeBase, upEdgeBase);\r\n if (upPeakConnection !== undefined)\r\n connectTo = this.updateMaxNode(connectTo, upPeakConnection, upFunction);\r\n return connectTo;\r\n }\r\n /** Search around the vertex of nodeA for a nodeA1 such that nodeB is visible in the sector at nodeA1 */\r\n private findVisibleSector(nodeA: HalfEdge, nodeB: HalfEdge): HalfEdge | undefined {\r\n let nodeA1 = nodeA;\r\n do {\r\n if (HalfEdge.isNodeVisibleInSector(nodeB, nodeA1))\r\n return nodeA1;\r\n nodeA1 = nodeA1.vertexSuccessor;\r\n } while (nodeA1 !== nodeA);\r\n return undefined;\r\n }\r\n /**\r\n * Create an edge from (some node around the vertex of) nodeA to (some node around the vertex of) nodeB.\r\n * * looking around the vertex for alternate insertion corrects cusp insertion errors.\r\n * @param nodeA\r\n * @param nodeB\r\n */\r\n private joinNodes(nodeA: HalfEdge, nodeB: HalfEdge, direction: number): HalfEdge | undefined {\r\n const nodeC = this.graph.createEdgeXYZXYZ(nodeA.x, nodeA.y, nodeA.z, 0, nodeB.x, nodeB.y, nodeB.z, 0);\r\n const nodeA1 = this.findVisibleSector(nodeA, nodeB);\r\n const nodeB1 = this.findVisibleSector(nodeB, nodeA);\r\n if (nodeA1 !== undefined && nodeB1 !== undefined) {\r\n HalfEdge.pinch(nodeA1, nodeC);\r\n HalfEdge.pinch(nodeB1, nodeC.edgeMate);\r\n if (RegularizationContext.announceEdge)\r\n RegularizationContext.announceEdge(this.graph, nodeA, nodeB, direction);\r\n return nodeC;\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Regularize a single face.\r\n * * Insert edge from any downward interior vertex to something lower\r\n * * Insert an edge from each upward interior vertex to something higher.\r\n * * The face is split into smaller faces\r\n * * Each final face has at most one \"min\" and one \"max\", and is easy to triangulate with a bottom to top sweep.\r\n * * Normal usage is to sweep in both directions, i.e. use the default (true,true) for the upSweep and downSweep parameters.\r\n * @param faceSeed any representative half edge on the face\r\n * @param upSweep true to do the upward sweep.\r\n * @param downSweep true to do the downward sweep.\r\n */\r\n private runRegularization(upSweep: boolean = true, downSweep: boolean = true) {\r\n if (upSweep) {\r\n this.bottomPeaks.sort(HalfEdgeGraphOps.compareNodesYXUp);\r\n for (const bottomPeak of this.bottomPeaks) {\r\n // console.log(\"SEARCH\", bottomPeak.id, [bottomPeak.x, bottomPeak.y]);\r\n if (!HalfEdgeGraphOps.isDownPeak(bottomPeak))\r\n continue;\r\n const target = this.downwardConnectionFromBottomPeak(bottomPeak);\r\n if (target !== undefined) {\r\n // console.log(\"join\", bottomPeak.id, [bottomPeak.x, bottomPeak.y], target.id, [target.x, target.y]);\r\n this.joinNodes(bottomPeak, target, 1);\r\n }\r\n }\r\n }\r\n if (downSweep) {\r\n // flip the whole graph (ouch)\r\n this.negateXY();\r\n // swap the various p and down seeds ....\r\n this.swapArrays();\r\n this.bottomPeaks.sort(HalfEdgeGraphOps.compareNodesYXUp);\r\n for (const bottomPeak of this.bottomPeaks) {\r\n if (!HalfEdgeGraphOps.isDownPeak(bottomPeak))\r\n continue;\r\n const target = this.downwardConnectionFromBottomPeak(bottomPeak);\r\n if (target !== undefined) {\r\n this.joinNodes(bottomPeak, target, -1);\r\n }\r\n }\r\n this.negateXY();\r\n this.swapArrays();\r\n }\r\n }\r\n\r\n /**\r\n * Regularize a single face.\r\n * * Insert edge from any downward interior vertex to something lower\r\n * * Insert an edge from each upward interior vertex to something higher.\r\n * * The face is split into smaller faces\r\n * * Each final face has at most one \"min\" and one \"max\", and is easy to triangulate with a bottom to top sweep.\r\n * * Normal usage is to sweep in both directions, i.e. use the default (true,true) for the upSweep and downSweep parameters.\r\n * @param faceSeed any representative half edge on the face\r\n * @param upSweep true to do the upward sweep.\r\n * @param downSweep true to do the downward sweep.\r\n */\r\n public regularizeFace(faceSeed: HalfEdge, upSweep: boolean = true, downSweep: boolean = true) {\r\n this.collectVerticalEventsAroundFace(faceSeed);\r\n this.runRegularization(upSweep, downSweep);\r\n }\r\n\r\n public regularizeGraph(upSweep: boolean = true, downSweep: boolean = true) {\r\n this.collectVerticalEventFromEdgesInAndArray(this.graph.allHalfEdges);\r\n this.runRegularization(upSweep, downSweep);\r\n }\r\n\r\n /** test if a single face is monotone; if so, return its (single) min */\r\n public static isMonotoneFace(seed: HalfEdge): HalfEdge | undefined {\r\n let numMin = 0;\r\n let numMax = 0;\r\n let nodeMin: HalfEdge | undefined;\r\n let nodeA = seed;\r\n do {\r\n const nodeB = nodeA.faceSuccessor;\r\n const nodeC = nodeB.faceSuccessor;\r\n const ab = HalfEdgeGraphOps.compareNodesYXUp(nodeA, nodeB);\r\n const bc = HalfEdgeGraphOps.compareNodesYXUp(nodeB, nodeC);\r\n if (ab * bc <= 0) {\r\n if (ab > 0) {\r\n numMin++;\r\n nodeMin = nodeB;\r\n }\r\n if (bc > 0) {\r\n numMax++;\r\n }\r\n }\r\n } while ((nodeA = nodeA.faceSuccessor) !== seed);\r\n return numMin === 1 && numMax === 1 ? nodeMin : undefined;\r\n }\r\n /** Return faces filtered by area and test function.\r\n * * find one arbitrary representative of each face\r\n * * offer the candidate to the mutate function.\r\n * * collect results\r\n * @param mappedSeeds when filter returns a HalfEdge, collect it here\r\n * @param unmappedSeeds when filter does not return a half edge, collect the candidate.\r\n */\r\n public static collectMappedFaceRepresentatives(\r\n graph: HalfEdgeGraph,\r\n positiveAreaOnly: boolean,\r\n mutate: (seed: HalfEdge) => HalfEdge | undefined,\r\n mappedEdges: HalfEdge[] | undefined,\r\n unMappedSeeds: HalfEdge[] | undefined) {\r\n if (mappedEdges)\r\n mappedEdges.length = 0;\r\n if (unMappedSeeds)\r\n unMappedSeeds.length = 0;\r\n const mask = HalfEdgeMask.VISITED;\r\n graph.clearMask(mask);\r\n for (const seed of graph.allHalfEdges) {\r\n if (!seed.getMask(mask)) {\r\n seed.setMaskAroundFace(mask);\r\n if (!positiveAreaOnly || seed.signedFaceArea() > 0) {\r\n const edge = mutate(seed);\r\n if (edge) {\r\n if (mappedEdges)\r\n mappedEdges.push(edge);\r\n } else {\r\n if (unMappedSeeds)\r\n unMappedSeeds.push(seed);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n}\r\n"]}