@itwin/core-geometry 5.2.0-dev.2 → 5.2.0-dev.21
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.
- package/CHANGELOG.md +33 -1
- package/lib/cjs/Constant.js.map +1 -1
- package/lib/cjs/Geometry.js.map +1 -1
- package/lib/cjs/bspline/AkimaCurve3d.js.map +1 -1
- package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
- package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
- package/lib/cjs/bspline/BSplineCurve3dH.js.map +1 -1
- package/lib/cjs/bspline/BSplineCurveOps.js.map +1 -1
- package/lib/cjs/bspline/BSplineSurface.js.map +1 -1
- package/lib/cjs/bspline/Bezier1dNd.js.map +1 -1
- package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
- package/lib/cjs/bspline/BezierCurve3dH.js.map +1 -1
- package/lib/cjs/bspline/BezierCurveBase.js.map +1 -1
- package/lib/cjs/bspline/InterpolationCurve3d.js.map +1 -1
- package/lib/cjs/bspline/KnotVector.js.map +1 -1
- package/lib/cjs/bspline/SurfaceLocationDetail.js.map +1 -1
- package/lib/cjs/clipping/AlternatingConvexClipTree.js.map +1 -1
- package/lib/cjs/clipping/BooleanClipFactory.js.map +1 -1
- package/lib/cjs/clipping/BooleanClipNode.js.map +1 -1
- package/lib/cjs/clipping/ClipPlane.js.map +1 -1
- package/lib/cjs/clipping/ClipPrimitive.js.map +1 -1
- package/lib/cjs/clipping/ClipUtils.js.map +1 -1
- package/lib/cjs/clipping/ClipVector.js.map +1 -1
- package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/cjs/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
- package/lib/cjs/core-geometry.js.map +1 -1
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/curve/ConstructCurveBetweenCurves.js.map +1 -1
- package/lib/cjs/curve/CoordinateXYZ.js.map +1 -1
- package/lib/cjs/curve/CurveChainWithDistanceIndex.js.map +1 -1
- package/lib/cjs/curve/CurveCollection.js.map +1 -1
- package/lib/cjs/curve/CurveCurve.js.map +1 -1
- package/lib/cjs/curve/CurveExtendMode.js.map +1 -1
- package/lib/cjs/curve/CurveFactory.js.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
- package/lib/cjs/curve/CurveOps.js.map +1 -1
- package/lib/cjs/curve/CurvePrimitive.js.map +1 -1
- package/lib/cjs/curve/CurveProcessor.js.map +1 -1
- package/lib/cjs/curve/CurveTypes.js.map +1 -1
- package/lib/cjs/curve/CurveWireMomentsXYZ.js.map +1 -1
- package/lib/cjs/curve/GeometryQuery.js.map +1 -1
- package/lib/cjs/curve/LineSegment3d.js.map +1 -1
- package/lib/cjs/curve/LineString3d.js.map +1 -1
- package/lib/cjs/curve/Loop.js.map +1 -1
- package/lib/cjs/curve/OffsetOptions.js.map +1 -1
- package/lib/cjs/curve/ParityRegion.js.map +1 -1
- package/lib/cjs/curve/Path.js.map +1 -1
- package/lib/cjs/curve/PointString3d.js.map +1 -1
- package/lib/cjs/curve/ProxyCurve.js.map +1 -1
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/cjs/curve/Query/CurveSplitContext.js.map +1 -1
- package/lib/cjs/curve/Query/CylindricalRange.js.map +1 -1
- package/lib/cjs/curve/Query/InOutTests.js.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/cjs/curve/Query/StrokeCountChain.js.map +1 -1
- package/lib/cjs/curve/Query/StrokeCountMap.js.map +1 -1
- package/lib/cjs/curve/RegionMomentsXY.js.map +1 -1
- package/lib/cjs/curve/RegionOps.js.map +1 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/cjs/curve/StrokeOptions.js.map +1 -1
- package/lib/cjs/curve/UnionRegion.js.map +1 -1
- package/lib/cjs/curve/internalContexts/AnnounceTangentStrokeHandler.js.map +1 -1
- package/lib/cjs/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
- package/lib/cjs/curve/internalContexts/ChainCollectorContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CloneCurvesContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
- package/lib/cjs/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveLengthContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
- package/lib/cjs/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/GapSearchContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/MultiChainCollector.js.map +1 -1
- package/lib/cjs/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
- package/lib/cjs/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/SumLengthsContext.js.map +1 -1
- package/lib/cjs/curve/internalContexts/TransferWithSplitArcs.js.map +1 -1
- package/lib/cjs/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
- package/lib/cjs/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/ClothoidSeries.js.map +1 -1
- package/lib/cjs/curve/spiral/CubicEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/DirectSpiral3d.js.map +1 -1
- package/lib/cjs/curve/spiral/IntegratedSpiral3d.js.map +1 -1
- package/lib/cjs/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/NormalizedTransition.js.map +1 -1
- package/lib/cjs/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
- package/lib/cjs/curve/spiral/TransitionConditionalProperties.js.map +1 -1
- package/lib/cjs/curve/spiral/TransitionSpiral3d.js.map +1 -1
- package/lib/cjs/curve/spiral/XYCurveEvaluator.js.map +1 -1
- package/lib/cjs/geometry3d/Angle.js.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
- package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/cjs/geometry3d/BilinearPatch.js.map +1 -1
- package/lib/cjs/geometry3d/CoincidentGeometryOps.js.map +1 -1
- package/lib/cjs/geometry3d/Ellipsoid.js.map +1 -1
- package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/cjs/geometry3d/FrustumAnimation.js.map +1 -1
- package/lib/cjs/geometry3d/GeometryHandler.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableBlockedArray.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableFloat64Array.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedCollectionInterval.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYCollection.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/cjs/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
- package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
- package/lib/cjs/geometry3d/OrderedRotationAngles.js.map +1 -1
- package/lib/cjs/geometry3d/Plane3d.js.map +1 -1
- package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
- package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
- package/lib/cjs/geometry3d/Point2dArrayCarrier.js.map +1 -1
- package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
- package/lib/cjs/geometry3d/PointStreaming.js.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
- package/lib/cjs/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
- package/lib/cjs/geometry3d/Range.js.map +1 -1
- package/lib/cjs/geometry3d/Ray2d.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/cjs/geometry3d/ReusableObjectCache.js.map +1 -1
- package/lib/cjs/geometry3d/Segment1d.js.map +1 -1
- package/lib/cjs/geometry3d/SortablePolygon.js.map +1 -1
- package/lib/cjs/geometry3d/Transform.js.map +1 -1
- package/lib/cjs/geometry3d/UVSurfaceOps.js.map +1 -1
- package/lib/cjs/geometry3d/XYZProps.js.map +1 -1
- package/lib/cjs/geometry3d/YawPitchRollAngles.js.map +1 -1
- package/lib/cjs/geometry4d/Map4d.js.map +1 -1
- package/lib/cjs/geometry4d/Matrix4d.js.map +1 -1
- package/lib/cjs/geometry4d/MomentData.js.map +1 -1
- package/lib/cjs/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
- package/lib/cjs/geometry4d/Point4d.js.map +1 -1
- package/lib/cjs/numerics/BandedSystem.js.map +1 -1
- package/lib/cjs/numerics/BezierPolynomials.js.map +1 -1
- package/lib/cjs/numerics/ClusterableArray.js.map +1 -1
- package/lib/cjs/numerics/Complex.js.map +1 -1
- package/lib/cjs/numerics/ConvexPolygon2d.js.map +1 -1
- package/lib/cjs/numerics/Newton.js.map +1 -1
- package/lib/cjs/numerics/PascalCoefficients.js.map +1 -1
- package/lib/cjs/numerics/PolarData.js.map +1 -1
- package/lib/cjs/numerics/Polynomials.js.map +1 -1
- package/lib/cjs/numerics/Quadrature.js.map +1 -1
- package/lib/cjs/numerics/Range1dArray.js.map +1 -1
- package/lib/cjs/numerics/SmallSystem.js.map +1 -1
- package/lib/cjs/numerics/TriDiagonalSystem.js.map +1 -1
- package/lib/cjs/numerics/UnionFind.js.map +1 -1
- package/lib/cjs/numerics/UsageSums.js.map +1 -1
- package/lib/cjs/polyface/AuxData.js.map +1 -1
- package/lib/cjs/polyface/BoxTopology.js.map +1 -1
- package/lib/cjs/polyface/FacetFaceData.js.map +1 -1
- package/lib/cjs/polyface/FacetLocationDetail.js.map +1 -1
- package/lib/cjs/polyface/FacetOrientation.js.map +1 -1
- package/lib/cjs/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
- package/lib/cjs/polyface/IndexedEdgeMatcher.js.map +1 -1
- package/lib/cjs/polyface/IndexedPolyfaceVisitor.js.map +1 -1
- package/lib/cjs/polyface/IndexedPolyfaceWalker.js.map +1 -1
- package/lib/cjs/polyface/Polyface.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceClip.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceData.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/cjs/polyface/RangeLengthData.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/LineString3dRangeTreeContext.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/MinimumValueTester.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/Point3dArrayRangeTreeContext.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/PolyfaceRangeTreeContext.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/RangeTreeNode.js.map +1 -1
- package/lib/cjs/polyface/RangeTree/RangeTreeSearchHandlers.js.map +1 -1
- package/lib/cjs/polyface/TaggedNumericData.js.map +1 -1
- package/lib/cjs/polyface/TriangleCandidate.js.map +1 -1
- package/lib/cjs/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
- package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
- package/lib/cjs/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
- package/lib/cjs/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
- package/lib/cjs/polyface/multiclip/OffsetMeshContext.js.map +1 -1
- package/lib/cjs/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
- package/lib/cjs/polyface/multiclip/RangeSearch.js.map +1 -1
- package/lib/cjs/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
- package/lib/cjs/polyface/multiclip/XYPointBuckets.js.map +1 -1
- package/lib/cjs/serialization/BGFBAccessors.js.map +1 -1
- package/lib/cjs/serialization/BGFBReader.js.map +1 -1
- package/lib/cjs/serialization/BGFBWriter.js.map +1 -1
- package/lib/cjs/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
- package/lib/cjs/serialization/DeepCompare.js.map +1 -1
- package/lib/cjs/serialization/GeometrySamples.js.map +1 -1
- package/lib/cjs/serialization/IModelJsonSchema.js.map +1 -1
- package/lib/cjs/serialization/SerializationHelpers.js.map +1 -1
- package/lib/cjs/solid/Box.js.map +1 -1
- package/lib/cjs/solid/Cone.js.map +1 -1
- package/lib/cjs/solid/LinearSweep.js.map +1 -1
- package/lib/cjs/solid/RotationalSweep.js.map +1 -1
- package/lib/cjs/solid/RuledSweep.js.map +1 -1
- package/lib/cjs/solid/SolidPrimitive.js.map +1 -1
- package/lib/cjs/solid/Sphere.js.map +1 -1
- package/lib/cjs/solid/SweepContour.js.map +1 -1
- package/lib/cjs/solid/TorusPipe.js.map +1 -1
- package/lib/cjs/topology/ChainMerge.js.map +1 -1
- package/lib/cjs/topology/Graph.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphSearch.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphSpineContext.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeGraphValidation.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeMarkSet.js.map +1 -1
- package/lib/cjs/topology/HalfEdgeNodeXYZUV.js.map +1 -1
- package/lib/cjs/topology/HalfEdgePointInGraphSearch.js.map +1 -1
- package/lib/cjs/topology/HalfEdgePositionDetail.js.map +1 -1
- package/lib/cjs/topology/HalfEdgePriorityQueue.js.map +1 -1
- package/lib/cjs/topology/InsertAndRetriangulateContext.js.map +1 -1
- package/lib/cjs/topology/MaskManager.js.map +1 -1
- package/lib/cjs/topology/Merging.js.map +1 -1
- package/lib/cjs/topology/RegularizeFace.js.map +1 -1
- package/lib/cjs/topology/SignedDataSummary.js.map +1 -1
- package/lib/cjs/topology/SpaceTriangulation.js.map +1 -1
- package/lib/cjs/topology/Triangulation.js.map +1 -1
- package/lib/cjs/topology/XYParitySearchContext.js.map +1 -1
- package/lib/esm/Constant.js.map +1 -1
- package/lib/esm/Geometry.js.map +1 -1
- package/lib/esm/bspline/AkimaCurve3d.js.map +1 -1
- package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
- package/lib/esm/bspline/BSplineCurve.js.map +1 -1
- package/lib/esm/bspline/BSplineCurve3dH.js.map +1 -1
- package/lib/esm/bspline/BSplineCurveOps.js.map +1 -1
- package/lib/esm/bspline/BSplineSurface.js.map +1 -1
- package/lib/esm/bspline/Bezier1dNd.js.map +1 -1
- package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
- package/lib/esm/bspline/BezierCurve3dH.js.map +1 -1
- package/lib/esm/bspline/BezierCurveBase.js.map +1 -1
- package/lib/esm/bspline/InterpolationCurve3d.js.map +1 -1
- package/lib/esm/bspline/KnotVector.js.map +1 -1
- package/lib/esm/bspline/SurfaceLocationDetail.js.map +1 -1
- package/lib/esm/clipping/AlternatingConvexClipTree.js.map +1 -1
- package/lib/esm/clipping/BooleanClipFactory.js.map +1 -1
- package/lib/esm/clipping/BooleanClipNode.js.map +1 -1
- package/lib/esm/clipping/ClipPlane.js.map +1 -1
- package/lib/esm/clipping/ClipPrimitive.js.map +1 -1
- package/lib/esm/clipping/ClipUtils.js.map +1 -1
- package/lib/esm/clipping/ClipVector.js.map +1 -1
- package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/esm/clipping/internalContexts/LineStringOffsetClipperContext.js.map +1 -1
- package/lib/esm/core-geometry.js.map +1 -1
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/curve/ConstructCurveBetweenCurves.js.map +1 -1
- package/lib/esm/curve/CoordinateXYZ.js.map +1 -1
- package/lib/esm/curve/CurveChainWithDistanceIndex.js.map +1 -1
- package/lib/esm/curve/CurveCollection.js.map +1 -1
- package/lib/esm/curve/CurveCurve.js.map +1 -1
- package/lib/esm/curve/CurveExtendMode.js.map +1 -1
- package/lib/esm/curve/CurveFactory.js.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
- package/lib/esm/curve/CurveOps.js.map +1 -1
- package/lib/esm/curve/CurvePrimitive.js.map +1 -1
- package/lib/esm/curve/CurveProcessor.js.map +1 -1
- package/lib/esm/curve/CurveTypes.js.map +1 -1
- package/lib/esm/curve/CurveWireMomentsXYZ.js.map +1 -1
- package/lib/esm/curve/GeometryQuery.js.map +1 -1
- package/lib/esm/curve/LineSegment3d.js.map +1 -1
- package/lib/esm/curve/LineString3d.js.map +1 -1
- package/lib/esm/curve/Loop.js.map +1 -1
- package/lib/esm/curve/OffsetOptions.js.map +1 -1
- package/lib/esm/curve/ParityRegion.js.map +1 -1
- package/lib/esm/curve/Path.js.map +1 -1
- package/lib/esm/curve/PointString3d.js.map +1 -1
- package/lib/esm/curve/ProxyCurve.js.map +1 -1
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/esm/curve/Query/CurveSplitContext.js.map +1 -1
- package/lib/esm/curve/Query/CylindricalRange.js.map +1 -1
- package/lib/esm/curve/Query/InOutTests.js.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/esm/curve/Query/StrokeCountChain.js.map +1 -1
- package/lib/esm/curve/Query/StrokeCountMap.js.map +1 -1
- package/lib/esm/curve/RegionMomentsXY.js.map +1 -1
- package/lib/esm/curve/RegionOps.js.map +1 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/esm/curve/StrokeOptions.js.map +1 -1
- package/lib/esm/curve/UnionRegion.js.map +1 -1
- package/lib/esm/curve/internalContexts/AnnounceTangentStrokeHandler.js.map +1 -1
- package/lib/esm/curve/internalContexts/AppendPlaneIntersectionStrokeHandler.js.map +1 -1
- package/lib/esm/curve/internalContexts/ChainCollectorContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/CloneCurvesContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/CloneWithExpandedLineStrings.js.map +1 -1
- package/lib/esm/curve/internalContexts/ClosestPointStrokeHandler.js.map +1 -1
- package/lib/esm/curve/internalContexts/CountLinearPartsSearchContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveLengthContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveOffsetXYHandler.js.map +1 -1
- package/lib/esm/curve/internalContexts/EllipticalArcApproximationContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/GapSearchContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/MultiChainCollector.js.map +1 -1
- package/lib/esm/curve/internalContexts/NewtonRtoRStrokeHandler.js.map +1 -1
- package/lib/esm/curve/internalContexts/PlaneAltitudeRangeContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/PolygonOffsetContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/SumLengthsContext.js.map +1 -1
- package/lib/esm/curve/internalContexts/TransferWithSplitArcs.js.map +1 -1
- package/lib/esm/curve/internalContexts/TransformInPlaceContext.js.map +1 -1
- package/lib/esm/curve/spiral/AustralianRailCorpXYEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/ClothoidSeries.js.map +1 -1
- package/lib/esm/curve/spiral/CubicEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/CzechSpiralEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/DirectHalfCosineSpiralEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/DirectSpiral3d.js.map +1 -1
- package/lib/esm/curve/spiral/IntegratedSpiral3d.js.map +1 -1
- package/lib/esm/curve/spiral/MXCubicAlongArcSpiralEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/NormalizedTransition.js.map +1 -1
- package/lib/esm/curve/spiral/PolishCubicSpiralEvaluator.js.map +1 -1
- package/lib/esm/curve/spiral/TransitionConditionalProperties.js.map +1 -1
- package/lib/esm/curve/spiral/TransitionSpiral3d.js.map +1 -1
- package/lib/esm/curve/spiral/XYCurveEvaluator.js.map +1 -1
- package/lib/esm/geometry3d/Angle.js.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
- package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/esm/geometry3d/BilinearPatch.js.map +1 -1
- package/lib/esm/geometry3d/CoincidentGeometryOps.js.map +1 -1
- package/lib/esm/geometry3d/Ellipsoid.js.map +1 -1
- package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/esm/geometry3d/FrustumAnimation.js.map +1 -1
- package/lib/esm/geometry3d/GeometryHandler.js.map +1 -1
- package/lib/esm/geometry3d/GrowableBlockedArray.js.map +1 -1
- package/lib/esm/geometry3d/GrowableFloat64Array.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/esm/geometry3d/IndexedCollectionInterval.js.map +1 -1
- package/lib/esm/geometry3d/IndexedXYCollection.js.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/esm/geometry3d/LongitudeLatitudeAltitude.js.map +1 -1
- package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
- package/lib/esm/geometry3d/OrderedRotationAngles.js.map +1 -1
- package/lib/esm/geometry3d/Plane3d.js.map +1 -1
- package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
- package/lib/esm/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
- package/lib/esm/geometry3d/Point2dArrayCarrier.js.map +1 -1
- package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
- package/lib/esm/geometry3d/PointStreaming.js.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
- package/lib/esm/geometry3d/PolylineCompressionByEdgeOffset.js.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
- package/lib/esm/geometry3d/Range.js.map +1 -1
- package/lib/esm/geometry3d/Ray2d.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/geometry3d/ReusableObjectCache.js.map +1 -1
- package/lib/esm/geometry3d/Segment1d.js.map +1 -1
- package/lib/esm/geometry3d/SortablePolygon.js.map +1 -1
- package/lib/esm/geometry3d/Transform.js.map +1 -1
- package/lib/esm/geometry3d/UVSurfaceOps.js.map +1 -1
- package/lib/esm/geometry3d/XYZProps.js.map +1 -1
- package/lib/esm/geometry3d/YawPitchRollAngles.js.map +1 -1
- package/lib/esm/geometry4d/Map4d.js.map +1 -1
- package/lib/esm/geometry4d/Matrix4d.js.map +1 -1
- package/lib/esm/geometry4d/MomentData.js.map +1 -1
- package/lib/esm/geometry4d/PlaneByOriginAndVectors4d.js.map +1 -1
- package/lib/esm/geometry4d/Point4d.js.map +1 -1
- package/lib/esm/numerics/BandedSystem.js.map +1 -1
- package/lib/esm/numerics/BezierPolynomials.js.map +1 -1
- package/lib/esm/numerics/ClusterableArray.js.map +1 -1
- package/lib/esm/numerics/Complex.js.map +1 -1
- package/lib/esm/numerics/ConvexPolygon2d.js.map +1 -1
- package/lib/esm/numerics/Newton.js.map +1 -1
- package/lib/esm/numerics/PascalCoefficients.js.map +1 -1
- package/lib/esm/numerics/PolarData.js.map +1 -1
- package/lib/esm/numerics/Polynomials.js.map +1 -1
- package/lib/esm/numerics/Quadrature.js.map +1 -1
- package/lib/esm/numerics/Range1dArray.js.map +1 -1
- package/lib/esm/numerics/SmallSystem.js.map +1 -1
- package/lib/esm/numerics/TriDiagonalSystem.js.map +1 -1
- package/lib/esm/numerics/UnionFind.js.map +1 -1
- package/lib/esm/numerics/UsageSums.js.map +1 -1
- package/lib/esm/polyface/AuxData.js.map +1 -1
- package/lib/esm/polyface/BoxTopology.js.map +1 -1
- package/lib/esm/polyface/FacetFaceData.js.map +1 -1
- package/lib/esm/polyface/FacetLocationDetail.js.map +1 -1
- package/lib/esm/polyface/FacetOrientation.js.map +1 -1
- package/lib/esm/polyface/GreedyTriangulationBetweenLineStrings.js.map +1 -1
- package/lib/esm/polyface/IndexedEdgeMatcher.js.map +1 -1
- package/lib/esm/polyface/IndexedPolyfaceVisitor.js.map +1 -1
- package/lib/esm/polyface/IndexedPolyfaceWalker.js.map +1 -1
- package/lib/esm/polyface/Polyface.js.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/esm/polyface/PolyfaceClip.js.map +1 -1
- package/lib/esm/polyface/PolyfaceData.js.map +1 -1
- package/lib/esm/polyface/PolyfaceQuery.js.map +1 -1
- package/lib/esm/polyface/RangeLengthData.js.map +1 -1
- package/lib/esm/polyface/RangeTree/LineString3dRangeTreeContext.js.map +1 -1
- package/lib/esm/polyface/RangeTree/MinimumValueTester.js.map +1 -1
- package/lib/esm/polyface/RangeTree/Point3dArrayRangeTreeContext.js.map +1 -1
- package/lib/esm/polyface/RangeTree/PolyfaceRangeTreeContext.js.map +1 -1
- package/lib/esm/polyface/RangeTree/RangeTreeNode.js.map +1 -1
- package/lib/esm/polyface/RangeTree/RangeTreeSearchHandlers.js.map +1 -1
- package/lib/esm/polyface/TaggedNumericData.js.map +1 -1
- package/lib/esm/polyface/TriangleCandidate.js.map +1 -1
- package/lib/esm/polyface/multiclip/BuildAverageNormalsContext.js.map +1 -1
- package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSet.js.map +1 -1
- package/lib/esm/polyface/multiclip/GriddedRaggedRange2dSetWithOverflow.js.map +1 -1
- package/lib/esm/polyface/multiclip/LinearSearchRange2dArray.js.map +1 -1
- package/lib/esm/polyface/multiclip/OffsetMeshContext.js.map +1 -1
- package/lib/esm/polyface/multiclip/Range2dSearchInterface.js.map +1 -1
- package/lib/esm/polyface/multiclip/RangeSearch.js.map +1 -1
- package/lib/esm/polyface/multiclip/SweepLineStringToFacetContext.js.map +1 -1
- package/lib/esm/polyface/multiclip/XYPointBuckets.js.map +1 -1
- package/lib/esm/serialization/BGFBAccessors.js.map +1 -1
- package/lib/esm/serialization/BGFBReader.js.map +1 -1
- package/lib/esm/serialization/BGFBWriter.js.map +1 -1
- package/lib/esm/serialization/BentleyGeometryFlatBuffer.js.map +1 -1
- package/lib/esm/serialization/DeepCompare.js.map +1 -1
- package/lib/esm/serialization/GeometrySamples.js.map +1 -1
- package/lib/esm/serialization/IModelJsonSchema.js.map +1 -1
- package/lib/esm/serialization/SerializationHelpers.js.map +1 -1
- package/lib/esm/solid/Box.js.map +1 -1
- package/lib/esm/solid/Cone.js.map +1 -1
- package/lib/esm/solid/LinearSweep.js.map +1 -1
- package/lib/esm/solid/RotationalSweep.js.map +1 -1
- package/lib/esm/solid/RuledSweep.js.map +1 -1
- package/lib/esm/solid/SolidPrimitive.js.map +1 -1
- package/lib/esm/solid/Sphere.js.map +1 -1
- package/lib/esm/solid/SweepContour.js.map +1 -1
- package/lib/esm/solid/TorusPipe.js.map +1 -1
- package/lib/esm/topology/ChainMerge.js.map +1 -1
- package/lib/esm/topology/Graph.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphFromIndexedLoopsContext.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphSearch.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphSpineContext.js.map +1 -1
- package/lib/esm/topology/HalfEdgeGraphValidation.js.map +1 -1
- package/lib/esm/topology/HalfEdgeMarkSet.js.map +1 -1
- package/lib/esm/topology/HalfEdgeNodeXYZUV.js.map +1 -1
- package/lib/esm/topology/HalfEdgePointInGraphSearch.js.map +1 -1
- package/lib/esm/topology/HalfEdgePositionDetail.js.map +1 -1
- package/lib/esm/topology/HalfEdgePriorityQueue.js.map +1 -1
- package/lib/esm/topology/InsertAndRetriangulateContext.js.map +1 -1
- package/lib/esm/topology/MaskManager.js.map +1 -1
- package/lib/esm/topology/Merging.js.map +1 -1
- package/lib/esm/topology/RegularizeFace.js.map +1 -1
- package/lib/esm/topology/SignedDataSummary.js.map +1 -1
- package/lib/esm/topology/SpaceTriangulation.js.map +1 -1
- package/lib/esm/topology/Triangulation.js.map +1 -1
- package/lib/esm/topology/XYParitySearchContext.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OffsetMeshContext.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/OffsetMeshContext.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/** @packageDocumentation\n * @module Polyface\n */\n\nimport { Geometry } from \"../../Geometry\";\nimport { Angle } from \"../../geometry3d/Angle\";\nimport { GrowableXYZArray } from \"../../geometry3d/GrowableXYZArray\";\nimport { Point3d, Vector3d } from \"../../geometry3d/Point3dVector3d\";\nimport { PolygonOps } from \"../../geometry3d/PolygonOps\";\nimport { PolylineCompressionContext } from \"../../geometry3d/PolylineCompressionByEdgeOffset\";\nimport { Ray3d } from \"../../geometry3d/Ray3d\";\nimport { XYAndZ } from \"../../geometry3d/XYZProps\";\nimport { SmallSystem } from \"../../numerics/SmallSystem\";\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"../../topology/Graph\";\nimport { HalfEdgeGraphFromIndexedLoopsContext } from \"../../topology/HalfEdgeGraphFromIndexedLoopsContext\";\nimport { IndexedPolyface } from \"../Polyface\";\nimport { PolyfaceBuilder } from \"../PolyfaceBuilder\";\nimport { OffsetMeshOptions } from \"../PolyfaceQuery\";\n\nfunction isDefinedAndTrue(value: boolean | undefined): boolean {\n if (value === undefined)\n return false;\n return value;\n}\n/**\n * Function to be called for debugging observations at key times during offset computation.\n */\ntype FacetOffsetGraphDebugFunction = (message: string, Graph: HalfEdgeGraph, breakMaskA: HalfEdgeMask, breakMaskB: HalfEdgeMask) => void;\n\ntype FacetOffsetDebugString = (message: string) => void;\n\nclass AverageNormalData {\n constructor() {\n this.numActiveSectors = 0;\n this.numInactiveSectors = 0; // exterior and sling.\n this.averageNormal = Vector3d.create();\n this.radiansSum = 0.0;\n this.maxDeviationRadiansFromAverage = 0.0;\n }\n public clear() {\n this.numActiveSectors = 0;\n this.numInactiveSectors = 0; // exterior and sling.\n this.averageNormal.setZero();\n this.radiansSum = 0.0;\n this.maxDeviationRadiansFromAverage = 0.0;\n }\n public numActiveSectors: number;\n public numInactiveSectors: number;\n public averageNormal: Vector3d;\n public maxDeviationRadiansFromAverage: number;\n public radiansSum;\n /** Add a normal to the evolving sum, scaled by radians in the corner */\n public accumulateNormal(node: HalfEdge, normal: Vector3d, inactiveMask: HalfEdgeMask) {\n if (node.isMaskSet(inactiveMask)) {\n this.numInactiveSectors++;\n } else {\n const sectorSweepRadians = HalfEdge.sectorSweepRadiansXYZ(node, normal);\n this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);\n this.radiansSum += sectorSweepRadians;\n this.numActiveSectors++;\n }\n }\n /** normalize the accumulated normals. */\n public finishNormalAveraging(): boolean {\n if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {\n return true;\n }\n return false;\n }\n /** Compute the deviation from average. update max deviation member */\n public recordDeviation(normal: Vector3d, isActive: boolean) {\n if (isActive) {\n const radians = this.averageNormal.radiansTo(normal);\n this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);\n } else {\n }\n }\n /** Return the max deviation as computed on prior calls to recordDeviation */\n public get maxDeviationRadians(): number { return this.maxDeviationRadiansFromAverage; }\n}\nfunction emitSector(sector: SectorOffsetProperties) {\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);\n OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);\n }\n\n}\n\n// facet properties used during offset.\n//\nexport class FacetOffsetProperties {\n public constructor(facetIndex: number, normal: Ray3d) {\n this.facetIndex = facetIndex;\n this.facetNormal = normal;\n }\n public facetIndex: number;\n public facetNormal: Ray3d;\n}\n/**\n * Sector properties during offset.\n * * this.normal may be initially assigned as the facet normal but can mutate by\n * averaging with neighbors.\n * * this.xyz is initially the base mesh xyz but is expected to move along the normal.\n * * this.count is used locally in computations.\n */\nexport class SectorOffsetProperties {\n public constructor(normal: Vector3d, xyz: Point3d) {\n this.xyz = xyz;\n this.normal = normal;\n this.count = 0;\n }\n public normal: Vector3d;\n public xyz: Point3d;\n public count: number;\n /**\n * Compute the angle between plane normals on opposite sides of the edge.\n * * parallel normals have zero angle.\n * * if the edge cuts inward to the volume behind the faces, the angle is negative.\n * * if the edge is outward (a convex edge) the the volume, the angle is positive.\n * @param edgeNodeA node on one side of the edge\n * @param edgeVector pre-allocated vector to receive vector along edge.\n * @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.\n * @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.\n * @param radiansTolerance tolerance for large angle between normals.\n * @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.\n */\n public static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA: HalfEdge,\n edgeVector: Vector3d,\n averageNormal: Vector3d,\n offsetDistance: number,\n radiansTolerance: number = Math.PI * 0.5): boolean {\n const propsA = edgeNodeA.edgeTag as SectorOffsetProperties;\n const edgeNodeB = edgeNodeA.edgeMate;\n const propsB = edgeNodeB.edgeTag as SectorOffsetProperties;\n if (propsA !== undefined && propsB !== undefined) {\n edgeNodeA.vectorToFaceSuccessor(edgeVector);\n const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);\n if (Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {\n Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);\n if (averageNormal.normalizeInPlace())\n return true;\n }\n }\n return false;\n }\n\n public static almostEqualNormals(sectorA: SectorOffsetProperties, sectorB: SectorOffsetProperties, radiansTolerance: number = Geometry.smallAngleRadians): boolean {\n return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;\n }\n public static radiansBetweenNormals(sectorA: SectorOffsetProperties, sectorB: SectorOffsetProperties): number {\n return sectorA.normal.radiansTo(sectorB.normal);\n }\n // Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal\n public setOffsetPointAtDistanceAtHalfEdge(halfEdge: HalfEdge, distance: number) {\n halfEdge.getPoint3d(this.xyz);\n this.xyz.addScaledInPlace(this.normal, distance);\n }\n // Copy xyz from parameter into (preexisting object) xyz\n public static setXYZAtHalfEdge(halfEdge: HalfEdge, xyz: Vector3d | undefined) {\n const props = halfEdge.edgeTag as SectorOffsetProperties;\n if (props !== undefined && xyz !== undefined)\n props.xyz.set(xyz.x, xyz.y, xyz.z);\n }\n\n // Set the offset point this.xyz directly\n public setXYAndZ(xyz: XYAndZ) {\n this.xyz.set(xyz.x, xyz.y, xyz.z);\n }\n // Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance\n public static setNormalAtHalfEdge(halfEdge: HalfEdge, uvw: Vector3d, distance?: number) {\n const props = halfEdge.edgeTag as SectorOffsetProperties;\n if (props !== undefined) {\n props.normal.set(uvw.x, uvw.y, uvw.z);\n if (distance !== undefined)\n props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);\n }\n }\n // Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next\n public static sweepRadiansAroundNormal(nodeA: HalfEdge, upVector: Vector3d): number | undefined {\n const propsA = nodeA.edgeTag as SectorOffsetProperties;\n const propsB = nodeA.vertexSuccessor.edgeTag as SectorOffsetProperties;\n if (propsA !== undefined && propsB !== undefined) {\n return propsA.normal.planarRadiansTo(propsB.normal, upVector);\n }\n return undefined;\n }\n\n // Look through the half edge to its properties. return (if possible) the coordinates\n public static getSectorPointAtHalfEdge(halfEdge: HalfEdge, xyz: Point3d | undefined, xyzArray: GrowableXYZArray | undefined): boolean {\n const props = halfEdge.edgeTag as SectorOffsetProperties;\n if (props !== undefined) {\n if (xyz !== undefined)\n xyz.setFromPoint3d(props.xyz);\n if (xyzArray !== undefined)\n xyzArray.push(props.xyz);\n return true;\n }\n return false;\n }\n // access the XYZ and push to the array (which makes copies, not reference)\n // return pointer to the SectorOffsetProperties\n public static pushXYZ(xyzArray: GrowableXYZArray, halfEdge: HalfEdge): SectorOffsetProperties {\n const sector = halfEdge.edgeTag as SectorOffsetProperties;\n if (sector !== undefined)\n xyzArray.push(sector.xyz);\n return sector;\n }\n // Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale\n public static accumulateScaledNormalAtHalfEdge(halfEdge: HalfEdge, scale: number, accumulatingVector: Vector3d) {\n const sector = halfEdge.edgeTag as SectorOffsetProperties;\n if (sector !== undefined)\n accumulatingVector.addScaledInPlace(sector.normal, scale);\n }\n}\n/*\nAbout Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges\n\nWhen edge vertex X to vertex Y has a sharp angle between normals, a \"chamfer face\" must be created to \"fatten\" it.\n\nThe original half edges (nodes) for the edge are AX and AY. These are \"mates\" in the halfEdge mental model. As always,\nAX is (as needed)\n (i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)\n (ii) a part of the face loop for the face to the left when proceeding CCW around the face to the above the drawn edge\n (iii) a part of the vertex loop around X\nLikewise, AY is (as needed)\n (i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)\n (ii) a part of the face loop for the face to the left of the edge when proceeding CCW around the face below the edge.\n (iii) a part of the vertex loop around Y\n\n AX------>\nX______________________________________________________________________Y\n <---AY\n\nWhen the chamfer face is created, it needs to have a sliver face \"inside the edge\" -- something in the space here\n\n AX------>\n _____________________________________________________________________\n / \\\nX Y\n \\_____________________________________________________________________/\n <---AY\n\nThe chamfer face will have a plane normal is the average of the two faces' plane normals.\n\nThe creation sequence for the chamfer face puts a slit \"inside the edge\" as above HalfEdges AX and AY remain as parts\nof their respective face loops. In addition, at each end a singleton edge \"sling\" face is inserted at each\nend of the sliver face.\n\nThe sequence is:\n\n STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY\n STEP 2: splitEdge (with undefined as the \"prior\" edge) creates a sling with HalfEdge CX \"inside\" and BX \"outside\".\n (The sling face is not yet attached to X -- briefly floating in space)\n STEP 3: pinch of HalfEdges BX and DX inserts the sling face \"inside\" the slit face at the X end.\n\n Steps 2 and 3 are executed from each end. Due to the symmetric structure, a 2-pass loop can apply the logic at each end without distinct names in code.\n\n AX------>\n _______________________________________________________________\n / <---DY \\\n / \\\n / BX---> \\\n / _______________ _______________ \\\n| / \\ / <----CY \\ |\n|/ \\ / \\|\nX | | Y\n|\\ CX---> / \\ /|\n| \\_______________/ \\_______________/ |\n \\ <---BY /\n \\ /\n \\ DX---> /\n \\ ______________________________________________________________/\n <---AY\n\nDuring the construction, the letters ABCD are used as above, but with prefixes emphasizing their role\noutsideAX, outsideAY\nslingB, slingC, sliverD\n\nThe \"inside\" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.\nThe sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.\nEach of those 4 has its own SectorOffSetProperties.\n\nImportant properties during offset construction:\n1) the original graph always has original topology and coordinates\n2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.\n3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.\n 3.1 The first offset coordinates in each node are directly offset by face normal.\n 3.2 This creates mismatch across edges and around vertices.\n 3.3 Various sweeps \"around each vertex\" try to do intersections among appropriate offset planes to find\n common coordinates in place of the initial mismatches.\n4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.\n5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.\n6) At output time, there are three sweeps:\n 6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.\n 6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad\n 6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.\n*/\nexport class OffsetMeshContext {\n private constructor(basePolyface: IndexedPolyface, baseGraph: HalfEdgeGraph,\n options: OffsetMeshOptions) {\n this._basePolyface = basePolyface;\n this._baseGraph = baseGraph;\n this._breakMaskA = baseGraph.grabMask();\n this._breakMaskB = baseGraph.grabMask();\n\n this._insideOfChamferFace = baseGraph.grabMask();\n this._outsideOfChamferFace = baseGraph.grabMask();\n this._insideChamferSling = baseGraph.grabMask();\n this._outsideEndOfChamferFace = baseGraph.grabMask();\n this._exteriorMask = HalfEdgeMask.EXTERIOR;\n this._offsetCoordinatesReassigned = baseGraph.grabMask();\n this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;\n this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;\n this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;\n }\n private _basePolyface: IndexedPolyface;\n private _baseGraph: HalfEdgeGraph;\n /** \"Exterior\" side of a bare edge of the mesh */\n public get exteriorMask(): HalfEdgeMask { return this._exteriorMask; }\n private _exteriorMask: HalfEdgeMask;\n\n /** Mask indicating a a sector's coordinates have been reassigned at offset distance. */\n private _offsetCoordinatesReassigned: HalfEdgeMask;\n\n /** \"First\" sector of a smooth sequence. */\n public get breakMaskA(): HalfEdgeMask { return this._breakMaskA; }\n private _breakMaskA: HalfEdgeMask;\n\n /** \"Last\" sector of a smooth sequence. */\n public get breakMaskB(): HalfEdgeMask { return this._breakMaskB; }\n private _breakMaskB: HalfEdgeMask;\n\n /** This edge is on a chamfered face, and along the original edge */\n public get insideOfChamferFace(): HalfEdgeMask { return this._insideOfChamferFace; }\n private _insideOfChamferFace: HalfEdgeMask;\n\n /** This is the original edge of a chamfer face */\n public get outsideOfChamferFace(): HalfEdgeMask { return this._outsideOfChamferFace; }\n private _outsideOfChamferFace: HalfEdgeMask;\n\n /** This edge is on a chamfered face, and at the end -- other side may be a sling */\n public get insideChamferSling(): HalfEdgeMask { return this._insideChamferSling; }\n private _insideChamferSling: HalfEdgeMask;\n\n /** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */\n public get outsideEndOfChamferFace(): HalfEdgeMask { return this._outsideEndOfChamferFace; }\n private _outsideEndOfChamferFace: HalfEdgeMask;\n\n // On a CCW vertex loop, the mask sequence at a chamfered edge (which was expanded to a chamfer face) is\n // * the INBOUND edge of the original edge (at its far node !!) _outsideOfChamferFace\n // * the OUTBOUND edge inside the chamfer face has _insideOfChamferFace\n // * the inside of the sling face has _insideChamferSling\n // * the \"outside\" of the sling face - i.e. inside the chamfer face and at this vertex - has _outsideEndOfChamferFace\n // * the \"outside\" of the outgoing edge has _outsideOfChamferFace.\n private _smoothRadiansBetweenNormals: number;\n private _smoothAccumulatedRadiansBetweenNormals: number;\n private _chamferTurnRadians: number;\n public static graphDebugFunction?: FacetOffsetGraphDebugFunction;\n public static stringDebugFunction?: FacetOffsetDebugString;\n\n // At each node . .\n // * Find the sector data\n // * recompute the sector point using node XYZ and sectorData normal.\n private applyFaceNormalOffsetsToSectorData(distance: number) {\n this._baseGraph.announceNodes((_graph: HalfEdgeGraph, node: HalfEdge) => {\n const sectorData = node.edgeTag as SectorOffsetProperties;\n if (sectorData !== undefined) {\n sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);\n }\n return true;\n });\n }\n\n /**\n * * build a mesh offset by given distance.\n * * output the mesh to the given builder.\n * @param basePolyface original mesh\n * @param builder polyface builder to receive the new mesh.\n * @param distance signed offset distance.\n */\n public static buildOffsetMeshWithEdgeChamfers(\n basePolyface: IndexedPolyface,\n builder: PolyfaceBuilder,\n distance: number,\n options: OffsetMeshOptions) {\n const baseGraph = this.buildBaseGraph(basePolyface);\n if (baseGraph !== undefined) {\n const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);\n offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);\n if (OffsetMeshContext.graphDebugFunction !== undefined)\n OffsetMeshContext.graphDebugFunction(\"BaseGraph\", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);\n\n const outputSelector = options.outputSelector ? options.outputSelector : {\n outputOffsetsFromFaces: true,\n outputOffsetsFromEdges: true,\n outputOffsetsFromVertices: true,\n };\n\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);\n\n offsetBuilder.addChamferTopologyToAllEdges(options, distance);\n offsetBuilder.computeOffsetFacetIntersections(distance);\n\n if (OffsetMeshContext.graphDebugFunction !== undefined)\n OffsetMeshContext.graphDebugFunction(\"after computeEdgeChamfers\", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);\n\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);\n }\n }\n\n /**\n * For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet\n * @param polyfaceBuilder\n */\n public announceSimpleOffsetFromFaces(polyfaceBuilder: PolyfaceBuilder, offsetDistance: number) {\n const xyzLoop = new GrowableXYZArray();\n const xyz = Point3d.create(); // reused at each point around each facet.\n const uvw = Vector3d.create(); // reused once per facet\n const announceNodeAroundFace = (node: HalfEdge): number => {\n node.getPoint3d(xyz);\n xyz.addInPlace(uvw);\n xyzLoop.push(xyz);\n return 0;\n };\n this._baseGraph.announceFaceLoops(\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\n if (!seed.isMaskSet(HalfEdgeMask.EXTERIOR)) {\n const facetProperties = seed.faceTag as FacetOffsetProperties;\n uvw.setFromVector3d(facetProperties.facetNormal.direction);\n uvw.scaleInPlace(offsetDistance);\n xyzLoop.length = 0;\n seed.sumAroundFace(announceNodeAroundFace);\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\n }\n return true;\n });\n }\n\n /**\n * For each face of the graph, output the xyz of the sector data\n * @param polyfaceBuilder\n */\n public announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder: PolyfaceBuilder) {\n const xyzLoop = new GrowableXYZArray();\n // For face loop visits .. get the point from the sector data.\n const announceNodeAroundFace = (node: HalfEdge): number => {\n const sectorData = node.edgeTag as SectorOffsetProperties;\n if (sectorData !== undefined) {\n xyzLoop.push(sectorData.xyz);\n }\n return 0;\n };\n this._baseGraph.announceFaceLoops(\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\n if (!seed.isMaskSet(HalfEdgeMask.EXTERIOR)) {\n xyzLoop.length = 0;\n seed.sumAroundFace(announceNodeAroundFace);\n if (xyzLoop.length > 2)\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\n }\n return true;\n });\n }\n private countBits(mask: HalfEdgeMask): number {\n let n = 0;\n let mask1 = mask;\n while (mask1 !== 0) {\n if (mask1 & 0x01) n++;\n mask1 = mask1 >> 1;\n }\n return n;\n }\n /**\n * For each edge of the graph . .\n * * Collect coordinates in 4 sectors going around the edge\n * * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.\n * * Emit as a facet.\n * @param polyfaceBuilder\n */\n public announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder: PolyfaceBuilder) {\n const xyzLoop = new GrowableXYZArray();\n const primaryCompressionTolerance = Geometry.smallMetricDistance;\n const allMasksForEdgesToIgnore = this._exteriorMask\n | this._outsideEndOfChamferFace\n | this._outsideOfChamferFace\n | this._insideOfChamferFace\n | this._insideChamferSling;\n this._baseGraph.announceEdges(\n (_graph: HalfEdgeGraph, nodeA: HalfEdge): boolean => {\n // This starts by looking for EXTERIOR on both sides ...\n if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {\n return true;\n } else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above\n const nodeB = nodeA.faceSuccessor;\n const nodeC = nodeA.edgeMate;\n if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {\n const nodeD = nodeC.faceSuccessor;\n xyzLoop.clear();\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);\n if (xyzLoop.length > 2) {\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\n }\n }\n } else {\n return true;\n }\n return true;\n });\n }\n\n private getCoordinateString(node: HalfEdge, showXYZ: boolean = true, showFaceSuccessorXYZ: boolean = false): string {\n if (showXYZ) {\n if (showFaceSuccessorXYZ) {\n return `${HalfEdge.nodeToIdXYZString(node)} ==> ${HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;\n } else {\n return `${HalfEdge.nodeToIdXYZString(node)}`;\n }\n } else {\n if (showFaceSuccessorXYZ) {\n return `==> ${HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;\n } else {\n return \"\";\n }\n }\n\n }\n private inspectMasks(node: HalfEdge, showXYZ: boolean = true, showFaceSuccessorXYZ: boolean = false): string {\n const s = \"[\";\n const v = s.concat(\n node.id.toString(),\n node.isMaskSet(this._exteriorMask) ? \"X\" : \"\",\n node.isMaskSet(this.breakMaskA) ? \"A\" : \"\",\n node.isMaskSet(this.breakMaskB) ? \"B\" : \"\",\n node.isMaskSet(this.insideChamferSling) ? \"(sling)\" : \"\",\n node.isMaskSet(this.insideOfChamferFace) ? \"(in chamfer)\" : \"\",\n node.isMaskSet(this.outsideEndOfChamferFace) ? \"(@sling)\" : \"\",\n node.isMaskSet(this.outsideOfChamferFace) ? \"(@chamfer)\" : \"\",\n this.getCoordinateString(node, showXYZ, showFaceSuccessorXYZ),\n \"]\",\n );\n return v;\n }\n /**\n * For each face of the graph, output the xyz of the sector data\n * @param polyfaceBuilder\n */\n public announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder: PolyfaceBuilder) {\n const xyzLoop = new GrowableXYZArray();\n const primaryCompressionTolerance = Geometry.smallMetricDistance;\n this._baseGraph.announceVertexLoops(\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\n if (!seed.findMaskAroundVertex(this._exteriorMask)) {\n xyzLoop.length = 0;\n seed.sumAroundVertex((node: HalfEdge) => {\n if (!node.isMaskSet(this._insideChamferSling))\n SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);\n return 0.0;\n });\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);\n if (xyzLoop.length > 2) {\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\n }\n }\n return true;\n });\n }\n\n /**\n * * Exterior half edges have HalfEdgeMask.EXTERIOR\n * * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.\n * * the facetOffsetProperties object has the simple facet normal.\n * * Each half edge has edgeTag pointing to to a sectorOffsetProperties object\n * * the sectorOffsetProperties has a copy of the facet normal.\n * @param polyface\n * @returns graph\n */\n public static buildBaseGraph(polyface: IndexedPolyface): HalfEdgeGraph | undefined {\n const graphBuilder = new HalfEdgeGraphFromIndexedLoopsContext();\n const visitor = polyface.createVisitor();\n const xyzA = Point3d.create();\n const xyzB = Point3d.create();\n for (visitor.reset(); visitor.moveToNextFacet();) {\n const normal = PolygonOps.centroidAreaNormal(visitor.point);\n if (normal !== undefined) {\n const edgeA = graphBuilder.insertLoop(visitor.pointIndex,\n (insideHalfEdge: HalfEdge) => {\n const mate = insideHalfEdge.edgeMate;\n polyface.data.getPoint(insideHalfEdge.i, xyzA);\n insideHalfEdge.setXYZ(xyzA);\n polyface.data.getPoint(mate.i, xyzB);\n mate.setXYZ(xyzB);\n });\n const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);\n if (edgeA !== undefined) {\n edgeA.sumAroundFace(\n (edgeB: HalfEdge) => {\n edgeB.faceTag = facetProperties;\n edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());\n return 0;\n });\n }\n }\n }\n return graphBuilder.graph;\n }\n private setOffsetAtDistanceAroundVertex(vertexSeed: HalfEdge, distance: number, ignoreChamfers: boolean = false) {\n vertexSeed.sumAroundVertex((nodeAroundVertex: HalfEdge) => {\n const props = nodeAroundVertex.edgeTag as SectorOffsetProperties;\n if (props !== undefined) {\n if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {\n // SKIP !!\n } else {\n props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);\n }\n }\n return 0.0;\n },\n );\n }\n\n private setOffsetXYAndZAroundVertex(vertexSeed: HalfEdge, xyz: XYAndZ) {\n vertexSeed.sumAroundVertex((nodeAroundVertex: HalfEdge) => {\n const props = nodeAroundVertex.edgeTag as SectorOffsetProperties;\n if (props !== undefined) {\n props.setXYAndZ(xyz);\n nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);\n }\n return 0.0;\n },\n );\n }\n\n /**\n * * start at vertexSeed.\n * * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask\n * *\n * @param vertexSeed first node to mark.\n * @param f function to call to announce each node and its sector properties.\n * @returns number of nodes marked.\n */\n private announceNodeAndSectorPropertiesInSmoothSector(vertexSeed: HalfEdge, f: (node: HalfEdge, properties: SectorOffsetProperties) => void): number {\n let n = 0;\n for (let currentNode = vertexSeed; ; currentNode = currentNode.vertexSuccessor) {\n const props = currentNode.edgeTag as SectorOffsetProperties;\n if (props !== undefined) {\n f(currentNode, props);\n n++;\n }\n if (currentNode.isMaskSet(this._breakMaskB))\n return n;\n // REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.\n if (currentNode.isMaskSet(this._exteriorMask))\n return n;\n if (currentNode === vertexSeed && n === 0)\n return n;\n }\n }\n\n private computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed: HalfEdge, data: AverageNormalData): number | undefined {\n data.clear();\n const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\n const sectorData = node.edgeTag as SectorOffsetProperties;\n if (sectorData)\n data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);\n return 0.0;\n },\n );\n if (!data.finishNormalAveraging()) {\n return undefined;\n }\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\n const sectorData = node.edgeTag as SectorOffsetProperties;\n if (sectorData)\n data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));\n return 0.0;\n },\n );\n return data.maxDeviationRadians;\n }\n\n private assignOffsetByAverageNormalAroundVertex(vertexSeed: HalfEdge,\n maxAllowedDeviationRadians: number,\n data: AverageNormalData,\n distance: number): boolean {\n const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);\n if (OffsetMeshContext.stringDebugFunction) {\n OffsetMeshContext.stringDebugFunction(`XYZ ${HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${JSON.stringify(data.averageNormal.toJSON())}`);\n OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);\n }\n if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\n SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);\n return 0;\n });\n return true;\n }\n return false;\n }\n\n /** Search around a vertex for a sector which has a different normal from its vertexPredecessor.\n * * The seed will be the first candidate considered\n */\n private markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed: HalfEdge) {\n vertexSeed.clearMaskAroundVertex(this._breakMaskA);\n vertexSeed.clearMaskAroundVertex(this._breakMaskB);\n\n const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;\n const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;\n\n // Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.\n let numBreaks = 0;\n let nodeP = vertexSeed;\n let _numSmooth = 0;\n do {\n const nodeQ = nodeP.edgeMate;\n const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor\n if (nodeP.isMaskSet(this._exteriorMask)) {\n if (!nodeQ.isMaskSet(this._exteriorMask)) {\n nodeR.setMask(this._breakMaskB);\n numBreaks++;\n }\n } else {\n if (nodeP.isMaskSet(this._outsideOfChamferFace)) {\n nodeP.setMask(this._breakMaskA);\n } else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {\n nodeP.setMask(this._breakMaskA);\n nodeP.setMask(this._breakMaskB);\n } else if (nodeP.isMaskSet(this._insideChamferSling)) {\n // This is the sling. It's normal is along edge -- not really a break.\n } else if (nodeP.isMaskSet(this._insideOfChamferFace)) {\n nodeP.setMask(this._breakMaskA);\n nodeP.setMask(this._breakMaskB);\n nodeR.setMask(this._breakMaskB);\n } else if (nodeQ.isMaskSet(this._exteriorMask)) {\n numBreaks++;\n nodeP.setMask(this._breakMaskA);\n } else if (!SectorOffsetProperties.almostEqualNormals(\n nodeP.edgeTag as SectorOffsetProperties,\n nodeR.edgeTag as SectorOffsetProperties,\n smoothSingleSmoothRadiansBetweenNormals)) {\n nodeP.setMask(this._breakMaskA);\n numBreaks++;\n nodeR.setMask(this._breakMaskB);\n } else {\n _numSmooth++;\n }\n }\n nodeP = nodeP.vertexSuccessor;\n } while (nodeP !== vertexSeed);\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);\n if (numBreaks === 0) {\n // make the first vertex a break so subsequent searches have a place to start\n vertexSeed.setMask(this._breakMaskA);\n vertexSeed.vertexPredecessor.setMask(this._breakMaskB);\n numBreaks = 1;\n }\n // Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.\n // (minor TODO: for the insertion case, try to split more equally.)\n const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);\n if (nodeAStart !== undefined) {\n nodeP = nodeAStart;\n do {\n if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {\n let accumulatedRadians = 0.0;\n do {\n const nodeB = nodeP.vertexSuccessor;\n accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(\n nodeP.edgeTag as SectorOffsetProperties,\n nodeB.edgeTag as SectorOffsetProperties,\n );\n if (accumulatedRadians > accumulatedRadiansBetweenNormals) {\n nodeP.setMask(this._breakMaskB);\n nodeB.setMask(this._breakMaskA);\n numBreaks++;\n accumulatedRadians = 0.0;\n }\n nodeP = nodeB;\n } while (!nodeP.isMaskSet(this._breakMaskB));\n } else {\n nodeP = nodeP.vertexSuccessor;\n }\n } while (nodeP !== nodeAStart);\n }\n\n if (numBreaks > 0 && nodeAStart !== undefined) {\n // In each compound sector, accumulate and install average normal.\n nodeP = nodeAStart;\n const averageNormal = Vector3d.create();\n const edgeVectorU = Vector3d.create();\n const edgeVectorV = Vector3d.create();\n averageNormal.setZero();\n do {\n if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {\n let nodeQ = nodeP;\n averageNormal.setZero();\n for (; ;) {\n nodeQ.vectorToFaceSuccessor(edgeVectorU);\n nodeQ.vectorToFacePredecessor(edgeVectorV);\n let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, (nodeQ.faceTag as FacetOffsetProperties).facetNormal.direction);\n if (singleSectorRadians < 0.0)\n singleSectorRadians += Math.PI * 2;\n SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);\n if (nodeQ.isMaskSet(this._breakMaskB))\n break;\n nodeQ = nodeQ.vertexSuccessor;\n }\n if (averageNormal.normalizeInPlace()) {\n nodeQ = nodeP;\n for (; ;) {\n SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);\n if (nodeQ.isMaskSet(this._breakMaskB))\n break;\n nodeQ = nodeQ.vertexSuccessor;\n }\n }\n }\n nodeP = nodeP.vertexSuccessor;\n } while (nodeP !== nodeAStart);\n\n }\n }\n\n /** Compute the point of intersection of the planes in the sectors of 3 half edges */\n private compute3SectorIntersection(nodeA: HalfEdge, nodeB: HalfEdge, nodeC: HalfEdge, result?: Vector3d): Vector3d | undefined {\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\n const sectorC = nodeC.edgeTag as SectorOffsetProperties;\n const vector = SmallSystem.intersect3Planes(\n sectorA.xyz, sectorA.normal,\n sectorB.xyz, sectorB.normal,\n sectorC.xyz, sectorC.normal,\n result);\n return vector;\n }\n /** Compute the point of intersection of the planes in the sectors of 3 half edges */\n private compute3SectorIntersectionDebug(nodeA: HalfEdge, nodeB: HalfEdge, nodeC: HalfEdge, result?: Vector3d): Vector3d | undefined {\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\n const sectorC = nodeC.edgeTag as SectorOffsetProperties;\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);\n for (const sector of [sectorA, sectorB, sectorC])\n emitSector(sector);\n }\n\n const vector = SmallSystem.intersect3Planes(\n sectorA.xyz, sectorA.normal,\n sectorB.xyz, sectorB.normal,\n sectorC.xyz, sectorC.normal,\n result);\n\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n if (vector === undefined)\n OffsetMeshContext.stringDebugFunction(\" NO INTERSECTION\");\n else\n OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);\n }\n return vector;\n }\n\n /** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */\n private compute2SectorIntersection(nodeA: HalfEdge, nodeB: HalfEdge, result?: Vector3d): Vector3d | undefined {\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\n const normalC = sectorA.normal.crossProduct(sectorB.normal);\n return SmallSystem.intersect3Planes(\n sectorA.xyz, sectorA.normal,\n sectorB.xyz, sectorB.normal,\n sectorB.xyz, normalC,\n result);\n }\n /**\n * * at input, graph has all original faces and edges\n * * each sector points to a faceProperties with original facet normal\n * * at exit:\n * * new \"chamfer faces\" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals\n * * the original edge is split along its length to create space\n * * one edge \"along\" each direction inside the slit.\n * * a sling edge at each end of the slit.\n * * outside of the sling is part of the slit face loop.\n * * inside is a single-node face\n * * thus the slit itself has 4 nodes.\n * * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.\n * * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.\n * * the inside of each sling face has\n * * original vertex coordinates in the node\n * * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer\n * * the two points at each end of the chamfer are computed as the intersection of\n * * chamfer plane\n * * sling plane\n * * adjacent plane of the face on the other side of the edge being chamfered.\n * @param distance distance to offset. The sign of this is important in the chamfer construction.\n */\n private addChamferTopologyToAllEdges(options: OffsetMeshOptions, distance: number) {\n const edgesToChamfer: HalfEdge[] = [];\n const chamferRadians = options.chamferAngleBetweenNormals.radians;\n const vertexXYZ = Point3d.create(); // reuse\n const edgeVector = Vector3d.create(); // reuse\n const outwardEdgeVector = Vector3d.create(); // reuse\n const averageNormal = Vector3d.create(); // reuse\n // collect all the edges with sharp turn angle.\n this._baseGraph.announceEdges(\n (_graph: HalfEdgeGraph, edgeNode: HalfEdge) => {\n if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal,\n distance,\n chamferRadians)) {\n edgesToChamfer.push(edgeNode);\n return true;\n }\n return true;\n });\n // Create sliver faces.\n // Sliver face gets an average normal from its neighbors.\n // outsideA is the HalfEdge labeled A in the diagram.\n // sliverDX and sliverDY are the edges \"inside the sliver\" at the respective X and Y ends.\n for (const outsideA of edgesToChamfer) {\n // remark: this recomputes as in collection round.\n if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {\n // This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.\n // The returned HalfEdge is labeled D in the diagram\n const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);\n const sliverDY = sliverDX.facePredecessor;\n const offsetPoint = sliverDX.getPoint3d();\n offsetPoint.addScaledInPlace(averageNormal, distance);\n const ray = Ray3d.createCapture(offsetPoint, averageNormal.clone());\n const facetProperties = new FacetOffsetProperties(-1, ray);\n // for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face\n // new node names in the loop omit X or Y suffix because that is implied by which pass is running.\n let s = -1.0;\n for (const sliverD of [sliverDX, sliverDY]) {\n edgeVector.scale(s, outwardEdgeVector);\n sliverD.getPoint3d(vertexXYZ);\n sliverD.setMask(this._insideOfChamferFace);\n sliverD.edgeMate.setMask(this._outsideOfChamferFace);\n // mark and reference the chamfer face.\n sliverD.faceTag = facetProperties;\n // sling at this end\n const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);\n const slingC = slingB.edgeMate;\n slingB.setMask(this._outsideEndOfChamferFace);\n slingB.faceTag = facetProperties;\n slingC.setMask(this._insideChamferSling);\n HalfEdge.pinch(sliverD, slingB);\n const endNormal = Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs\n const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);\n slingC.faceTag = slingFaceProperties;\n // initialize sectors with existing vertex point.\n sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());\n slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());\n slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());\n // OffsetMeshContext.stringDebugFunction(\"Chamfer Setup\");\n const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);\n const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);\n // sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());\n SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);\n SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);\n s *= -1.0;\n }\n }\n }\n }\n\n /**\n * * at input:\n * * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)\n * * at exit:\n * * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.\n * @param distance distance to offset.\n */\n private computeOffsetFacetIntersections(distance: number) {\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(\"***** recompute intersections\");\n const breakEdges: HalfEdge[] = [];\n const vertexXYZ = Point3d.create();\n const chamferXYZ = Point3d.create();\n const maxVertexMove = 2.0 * distance;\n const averageNormalData = new AverageNormalData();\n const maxAllowedNormalDeviationRadians = Angle.degreesToRadians(25.0);\n //\n // FOR EACH VERTEX\n //\n this._baseGraph.announceVertexLoops((_graph: HalfEdgeGraph, vertexSeedA: HalfEdge) => {\n // reposition to an important vertex.\n // first choice: a chamfer face.\n let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);\n if (vertexSeed === undefined)\n vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);\n if (vertexSeed === undefined)\n vertexSeed = vertexSeedA;\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n OffsetMeshContext.stringDebugFunction(\"\");\n OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${JSON.stringify(vertexSeed.getPoint3d().toJSON())} `);\n vertexSeed.sumAroundVertex(\n (node: HalfEdge) => { OffsetMeshContext.stringDebugFunction!(this.inspectMasks(node, false, true)); return 0; });\n }\n // Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections\n if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))\n return true;\n\n this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);\n this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);\n vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);\n for (const node of breakEdges) { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); }\n }\n if (breakEdges.length <= 1) {\n // just one smooth sequence.\n // everything is set already.\n } else if (breakEdges.length === 2) {\n // exterior vertex with two incident smooth\n const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);\n if (vectorFromOrigin !== undefined) {\n this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);\n }\n } else if (breakEdges.length === 3) {\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);\n if (vectorFromOrigin !== undefined) {\n this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);\n }\n // simple 3-face corner . . .\n } else {\n // Lots and Lots of edges\n // each set of 3 sectors independently generates an offset for its central sector.\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);\n vertexSeed.getPoint3d(vertexXYZ);\n // Pass 1 -- look for intersection among multiple chamfers\n for (let i = 0; i < breakEdges.length; i++) {\n const i0 = i;\n const i1 = (i0 + 1) % breakEdges.length;\n const i2 = (i1 + 1) % breakEdges.length;\n\n if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)\n && breakEdges[i1].isMaskSet(this._outsideOfChamferFace)\n && breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);\n if (vectorFromOrigin !== undefined) {\n // Treat all 3 spots as possibly compound sequences\n for (const iOutput of [i0, i1, i2]) {\n this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput],\n (node: HalfEdge, properties: SectorOffsetProperties) => {\n properties.setXYAndZ(vectorFromOrigin);\n node.setMask(this._offsetCoordinatesReassigned);\n });\n }\n // Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.\n i += 2;\n }\n }\n }\n\n // Pass 2 -- look for unassigned nodes just before or after a chamfer.\n // The chamfer wins\n for (let i = 0; i < breakEdges.length; i++) {\n const i0 = i;\n const i1 = (i0 + 1) % breakEdges.length;\n if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))\n continue;\n if (!this.isOffsetAssigned(breakEdges[i0])\n && breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {\n this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], \"push left from chamfer\", chamferXYZ);\n } else if (!this.isOffsetAssigned(breakEdges[i1])\n && breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {\n this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], \"push right from chamfer\", chamferXYZ);\n }\n\n }\n\n // Pass 3 -- look for unassigned nodes as middle of 3-face intersections\n for (let i = 0; i < breakEdges.length; i++) {\n const i0 = i;\n const i1 = (i0 + 1) % breakEdges.length;\n const i2 = (i1 + 1) % breakEdges.length;\n if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))\n continue;\n if (this.isOffsetAssigned(breakEdges[i1]))\n continue;\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);\n if (vectorFromOrigin !== undefined) {\n if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {\n this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1],\n (node: HalfEdge, properties: SectorOffsetProperties) => {\n properties.setXYAndZ(vectorFromOrigin);\n node.setMask(this._offsetCoordinatesReassigned);\n });\n }\n }\n }\n }\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\n const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);\n const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);\n const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;\n OffsetMeshContext.stringDebugFunction(message);\n }\n return true;\n });\n }\n // return true if any of these nodes is \"inside\" the sling at the end of a chamfer.\n private isInsideSling(node0: HalfEdge,\n node1?: HalfEdge,\n node2?: HalfEdge): boolean {\n return node0.isMaskSet(this._insideChamferSling)\n || (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))\n || (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));\n }\n // return true if any of these nodes is \"inside\" the sling at the end of a chamfer.\n private isInsideChamferOrSling(node0: HalfEdge): boolean {\n return node0.isMaskSet(this._insideChamferSling)\n || node0.isMaskSet(this._insideOfChamferFace)\n || node0.isMaskSet(this._outsideEndOfChamferFace);\n }\n private isOffsetAssigned(node0: HalfEdge,\n node1?: HalfEdge,\n node2?: HalfEdge): boolean {\n return node0.isMaskSet(this._offsetCoordinatesReassigned)\n || (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))\n || (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));\n }\n\n /**\n *\n * @param sourceNode node with good xyz\n * @param destinationStartNode first of a sequence of nodes to set (delimited by masks)\n * @param description string for debug\n * @param workPoint point to use for coordinate transfer.\n */\n private transferXYZFromNodeToSmoothSector(\n sourceNode: HalfEdge,\n destinationStartNode: HalfEdge,\n description: string,\n workPoint: Point3d,\n ) {\n if (OffsetMeshContext.stringDebugFunction !== undefined)\n OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);\n SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);\n this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode,\n (node: HalfEdge, properties: SectorOffsetProperties) => {\n properties.setXYAndZ(workPoint);\n node.setMask(this._offsetCoordinatesReassigned);\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"OffsetMeshContext.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/OffsetMeshContext.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/** @packageDocumentation\r\n * @module Polyface\r\n */\r\n\r\nimport { Geometry } from \"../../Geometry\";\r\nimport { Angle } from \"../../geometry3d/Angle\";\r\nimport { GrowableXYZArray } from \"../../geometry3d/GrowableXYZArray\";\r\nimport { Point3d, Vector3d } from \"../../geometry3d/Point3dVector3d\";\r\nimport { PolygonOps } from \"../../geometry3d/PolygonOps\";\r\nimport { PolylineCompressionContext } from \"../../geometry3d/PolylineCompressionByEdgeOffset\";\r\nimport { Ray3d } from \"../../geometry3d/Ray3d\";\r\nimport { XYAndZ } from \"../../geometry3d/XYZProps\";\r\nimport { SmallSystem } from \"../../numerics/SmallSystem\";\r\nimport { HalfEdge, HalfEdgeGraph, HalfEdgeMask } from \"../../topology/Graph\";\r\nimport { HalfEdgeGraphFromIndexedLoopsContext } from \"../../topology/HalfEdgeGraphFromIndexedLoopsContext\";\r\nimport { IndexedPolyface } from \"../Polyface\";\r\nimport { PolyfaceBuilder } from \"../PolyfaceBuilder\";\r\nimport { OffsetMeshOptions } from \"../PolyfaceQuery\";\r\n\r\nfunction isDefinedAndTrue(value: boolean | undefined): boolean {\r\n if (value === undefined)\r\n return false;\r\n return value;\r\n}\r\n/**\r\n * Function to be called for debugging observations at key times during offset computation.\r\n */\r\ntype FacetOffsetGraphDebugFunction = (message: string, Graph: HalfEdgeGraph, breakMaskA: HalfEdgeMask, breakMaskB: HalfEdgeMask) => void;\r\n\r\ntype FacetOffsetDebugString = (message: string) => void;\r\n\r\nclass AverageNormalData {\r\n constructor() {\r\n this.numActiveSectors = 0;\r\n this.numInactiveSectors = 0; // exterior and sling.\r\n this.averageNormal = Vector3d.create();\r\n this.radiansSum = 0.0;\r\n this.maxDeviationRadiansFromAverage = 0.0;\r\n }\r\n public clear() {\r\n this.numActiveSectors = 0;\r\n this.numInactiveSectors = 0; // exterior and sling.\r\n this.averageNormal.setZero();\r\n this.radiansSum = 0.0;\r\n this.maxDeviationRadiansFromAverage = 0.0;\r\n }\r\n public numActiveSectors: number;\r\n public numInactiveSectors: number;\r\n public averageNormal: Vector3d;\r\n public maxDeviationRadiansFromAverage: number;\r\n public radiansSum;\r\n /** Add a normal to the evolving sum, scaled by radians in the corner */\r\n public accumulateNormal(node: HalfEdge, normal: Vector3d, inactiveMask: HalfEdgeMask) {\r\n if (node.isMaskSet(inactiveMask)) {\r\n this.numInactiveSectors++;\r\n } else {\r\n const sectorSweepRadians = HalfEdge.sectorSweepRadiansXYZ(node, normal);\r\n this.averageNormal.addScaledInPlace(normal, sectorSweepRadians);\r\n this.radiansSum += sectorSweepRadians;\r\n this.numActiveSectors++;\r\n }\r\n }\r\n /** normalize the accumulated normals. */\r\n public finishNormalAveraging(): boolean {\r\n if (this.numActiveSectors > 0 && this.averageNormal.normalizeInPlace()) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n /** Compute the deviation from average. update max deviation member */\r\n public recordDeviation(normal: Vector3d, isActive: boolean) {\r\n if (isActive) {\r\n const radians = this.averageNormal.radiansTo(normal);\r\n this.maxDeviationRadiansFromAverage = Math.max(Math.abs(this.maxDeviationRadiansFromAverage), radians);\r\n } else {\r\n }\r\n }\r\n /** Return the max deviation as computed on prior calls to recordDeviation */\r\n public get maxDeviationRadians(): number { return this.maxDeviationRadiansFromAverage; }\r\n}\r\nfunction emitSector(sector: SectorOffsetProperties) {\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n OffsetMeshContext.stringDebugFunction(` Sector xyz ${sector.xyz.x},${sector.xyz.y},${sector.xyz.z} `);\r\n OffsetMeshContext.stringDebugFunction(` normal ${sector.normal.x},${sector.normal.y},${sector.normal.z} `);\r\n }\r\n\r\n}\r\n\r\n// facet properties used during offset.\r\n//\r\nexport class FacetOffsetProperties {\r\n public constructor(facetIndex: number, normal: Ray3d) {\r\n this.facetIndex = facetIndex;\r\n this.facetNormal = normal;\r\n }\r\n public facetIndex: number;\r\n public facetNormal: Ray3d;\r\n}\r\n/**\r\n * Sector properties during offset.\r\n * * this.normal may be initially assigned as the facet normal but can mutate by\r\n * averaging with neighbors.\r\n * * this.xyz is initially the base mesh xyz but is expected to move along the normal.\r\n * * this.count is used locally in computations.\r\n */\r\nexport class SectorOffsetProperties {\r\n public constructor(normal: Vector3d, xyz: Point3d) {\r\n this.xyz = xyz;\r\n this.normal = normal;\r\n this.count = 0;\r\n }\r\n public normal: Vector3d;\r\n public xyz: Point3d;\r\n public count: number;\r\n /**\r\n * Compute the angle between plane normals on opposite sides of the edge.\r\n * * parallel normals have zero angle.\r\n * * if the edge cuts inward to the volume behind the faces, the angle is negative.\r\n * * if the edge is outward (a convex edge) the the volume, the angle is positive.\r\n * @param edgeNodeA node on one side of the edge\r\n * @param edgeVector pre-allocated vector to receive vector along edge.\r\n * @param averageNormal pre-allocated vector to receive the average normal for a chamfer of the offset edge.\r\n * @param offsetDistance distance of offset being constructed. The sign of this resolves angle ambiguity.\r\n * @param radiansTolerance tolerance for large angle between normals.\r\n * @returns true if this edge has SectorOffsetProperties on both sides and the angle between normals angle exceeds radiansTolerance.\r\n */\r\n public static edgeHasLargeExteriorAngleBetweenNormals(edgeNodeA: HalfEdge,\r\n edgeVector: Vector3d,\r\n averageNormal: Vector3d,\r\n offsetDistance: number,\r\n radiansTolerance: number = Math.PI * 0.5): boolean {\r\n const propsA = edgeNodeA.edgeTag as SectorOffsetProperties;\r\n const edgeNodeB = edgeNodeA.edgeMate;\r\n const propsB = edgeNodeB.edgeTag as SectorOffsetProperties;\r\n if (propsA !== undefined && propsB !== undefined) {\r\n edgeNodeA.vectorToFaceSuccessor(edgeVector);\r\n const radians = propsA.normal.signedRadiansTo(propsB.normal, edgeVector);\r\n if (Geometry.split3WaySign(offsetDistance, -1, 1, 1) * radians >= radiansTolerance) {\r\n Vector3d.createAdd2Scaled(propsA.normal, 1.0, propsB.normal, 1.0, averageNormal);\r\n if (averageNormal.normalizeInPlace())\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n public static almostEqualNormals(sectorA: SectorOffsetProperties, sectorB: SectorOffsetProperties, radiansTolerance: number = Geometry.smallAngleRadians): boolean {\r\n return sectorA.normal.radiansTo(sectorB.normal) <= radiansTolerance;\r\n }\r\n public static radiansBetweenNormals(sectorA: SectorOffsetProperties, sectorB: SectorOffsetProperties): number {\r\n return sectorA.normal.radiansTo(sectorB.normal);\r\n }\r\n // Set the offset point this.xyz as sum of the nodeXyz + distance * this.normal\r\n public setOffsetPointAtDistanceAtHalfEdge(halfEdge: HalfEdge, distance: number) {\r\n halfEdge.getPoint3d(this.xyz);\r\n this.xyz.addScaledInPlace(this.normal, distance);\r\n }\r\n // Copy xyz from parameter into (preexisting object) xyz\r\n public static setXYZAtHalfEdge(halfEdge: HalfEdge, xyz: Vector3d | undefined) {\r\n const props = halfEdge.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined && xyz !== undefined)\r\n props.xyz.set(xyz.x, xyz.y, xyz.z);\r\n }\r\n\r\n // Set the offset point this.xyz directly\r\n public setXYAndZ(xyz: XYAndZ) {\r\n this.xyz.set(xyz.x, xyz.y, xyz.z);\r\n }\r\n // Look through the half edge to its properties. Set the normal there. Optionally set xyz from node xyz and offset distance\r\n public static setNormalAtHalfEdge(halfEdge: HalfEdge, uvw: Vector3d, distance?: number) {\r\n const props = halfEdge.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined) {\r\n props.normal.set(uvw.x, uvw.y, uvw.z);\r\n if (distance !== undefined)\r\n props.setOffsetPointAtDistanceAtHalfEdge(halfEdge, distance);\r\n }\r\n }\r\n // Look through the half edge and its vertex successor to properties. Get the two normals. Return the angle sweeping from one to the next\r\n public static sweepRadiansAroundNormal(nodeA: HalfEdge, upVector: Vector3d): number | undefined {\r\n const propsA = nodeA.edgeTag as SectorOffsetProperties;\r\n const propsB = nodeA.vertexSuccessor.edgeTag as SectorOffsetProperties;\r\n if (propsA !== undefined && propsB !== undefined) {\r\n return propsA.normal.planarRadiansTo(propsB.normal, upVector);\r\n }\r\n return undefined;\r\n }\r\n\r\n // Look through the half edge to its properties. return (if possible) the coordinates\r\n public static getSectorPointAtHalfEdge(halfEdge: HalfEdge, xyz: Point3d | undefined, xyzArray: GrowableXYZArray | undefined): boolean {\r\n const props = halfEdge.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined) {\r\n if (xyz !== undefined)\r\n xyz.setFromPoint3d(props.xyz);\r\n if (xyzArray !== undefined)\r\n xyzArray.push(props.xyz);\r\n return true;\r\n }\r\n return false;\r\n }\r\n // access the XYZ and push to the array (which makes copies, not reference)\r\n // return pointer to the SectorOffsetProperties\r\n public static pushXYZ(xyzArray: GrowableXYZArray, halfEdge: HalfEdge): SectorOffsetProperties {\r\n const sector = halfEdge.edgeTag as SectorOffsetProperties;\r\n if (sector !== undefined)\r\n xyzArray.push(sector.xyz);\r\n return sector;\r\n }\r\n // Dereference to execute: accumulatingVector += halfEdge.edgeTag.normal * scale\r\n public static accumulateScaledNormalAtHalfEdge(halfEdge: HalfEdge, scale: number, accumulatingVector: Vector3d) {\r\n const sector = halfEdge.edgeTag as SectorOffsetProperties;\r\n if (sector !== undefined)\r\n accumulatingVector.addScaledInPlace(sector.normal, scale);\r\n }\r\n}\r\n/*\r\nAbout Chamfer Edges ..... as constructed in addChamferTopologyToAllEdges\r\n\r\nWhen edge vertex X to vertex Y has a sharp angle between normals, a \"chamfer face\" must be created to \"fatten\" it.\r\n\r\nThe original half edges (nodes) for the edge are AX and AY. These are \"mates\" in the halfEdge mental model. As always,\r\nAX is (as needed)\r\n (i) the preferred half edge for the left side of the edge moving from X to Y. (i.e. above the edge)\r\n (ii) a part of the face loop for the face to the left when proceeding CCW around the face to the above the drawn edge\r\n (iii) a part of the vertex loop around X\r\nLikewise, AY is (as needed)\r\n (i) the preferred half edge for the left side of the edge moving from Y to X (i.e. below the edge)\r\n (ii) a part of the face loop for the face to the left of the edge when proceeding CCW around the face below the edge.\r\n (iii) a part of the vertex loop around Y\r\n\r\n AX------>\r\nX______________________________________________________________________Y\r\n <---AY\r\n\r\nWhen the chamfer face is created, it needs to have a sliver face \"inside the edge\" -- something in the space here\r\n\r\n AX------>\r\n _____________________________________________________________________\r\n / \\\r\nX Y\r\n \\_____________________________________________________________________/\r\n <---AY\r\n\r\nThe chamfer face will have a plane normal is the average of the two faces' plane normals.\r\n\r\nThe creation sequence for the chamfer face puts a slit \"inside the edge\" as above HalfEdges AX and AY remain as parts\r\nof their respective face loops. In addition, at each end a singleton edge \"sling\" face is inserted at each\r\nend of the sliver face.\r\n\r\nThe sequence is:\r\n\r\n STEP 1: splitEdgeCreateSliver creates the sliver face with 2 half edges DX and DY\r\n STEP 2: splitEdge (with undefined as the \"prior\" edge) creates a sling with HalfEdge CX \"inside\" and BX \"outside\".\r\n (The sling face is not yet attached to X -- briefly floating in space)\r\n STEP 3: pinch of HalfEdges BX and DX inserts the sling face \"inside\" the slit face at the X end.\r\n\r\n Steps 2 and 3 are executed from each end. Due to the symmetric structure, a 2-pass loop can apply the logic at each end without distinct names in code.\r\n\r\n AX------>\r\n _______________________________________________________________\r\n / <---DY \\\r\n / \\\r\n / BX---> \\\r\n / _______________ _______________ \\\r\n| / \\ / <----CY \\ |\r\n|/ \\ / \\|\r\nX | | Y\r\n|\\ CX---> / \\ /|\r\n| \\_______________/ \\_______________/ |\r\n \\ <---BY /\r\n \\ /\r\n \\ DX---> /\r\n \\ ______________________________________________________________/\r\n <---AY\r\n\r\nDuring the construction, the letters ABCD are used as above, but with prefixes emphasizing their role\r\noutsideAX, outsideAY\r\nslingB, slingC, sliverD\r\n\r\nThe \"inside\" sling faces (CX and CY) each have their own FacetOffsetProperties and SectorOffsetProperties.\r\nThe sliver face has its own FacetOffsetProperties which are referenced by DX, BY, DY, BX.\r\nEach of those 4 has its own SectorOffSetProperties.\r\n\r\nImportant properties during offset construction:\r\n1) the original graph always has original topology and coordinates\r\n2) Each face of the original graph has a FacetOffsetProperties with a representative point and a normal. These are unchanged during the computation.\r\n3) Each node has its own SectorOffsetProperties with a coordinate and normal independent of the parent node.\r\n 3.1 The first offset coordinates in each node are directly offset by face normal.\r\n 3.2 This creates mismatch across edges and around vertices.\r\n 3.3 Various sweeps \"around each vertex\" try to do intersections among appropriate offset planes to find\r\n common coordinates in place of the initial mismatches.\r\n4) The independence of all the sectors allows the offset construction to fix things up in any order it chooses.\r\n5) During the construction, the xyz in SectorOffsetProperties around a single vertex do NOT have to match.\r\n6) At output time, there are three sweeps:\r\n 6.1: By face: Go around the face and output a facet with the coordinates in the various sectors.\r\n 6.2: By edge: For each edge, if the sector xyz match across both ends output nothing. If not, output a triangle or quad\r\n 6.3: By vertex: At each vertex, if all vertex coordinates match output nothing. Otherwise output a facet with all the coordinates.\r\n*/\r\nexport class OffsetMeshContext {\r\n private constructor(basePolyface: IndexedPolyface, baseGraph: HalfEdgeGraph,\r\n options: OffsetMeshOptions) {\r\n this._basePolyface = basePolyface;\r\n this._baseGraph = baseGraph;\r\n this._breakMaskA = baseGraph.grabMask();\r\n this._breakMaskB = baseGraph.grabMask();\r\n\r\n this._insideOfChamferFace = baseGraph.grabMask();\r\n this._outsideOfChamferFace = baseGraph.grabMask();\r\n this._insideChamferSling = baseGraph.grabMask();\r\n this._outsideEndOfChamferFace = baseGraph.grabMask();\r\n this._exteriorMask = HalfEdgeMask.EXTERIOR;\r\n this._offsetCoordinatesReassigned = baseGraph.grabMask();\r\n this._smoothRadiansBetweenNormals = options.smoothSingleAngleBetweenNormals.radians;\r\n this._chamferTurnRadians = options.chamferAngleBetweenNormals.radians;\r\n this._smoothAccumulatedRadiansBetweenNormals = options.smoothAccumulatedAngleBetweenNormals.radians;\r\n }\r\n private _basePolyface: IndexedPolyface;\r\n private _baseGraph: HalfEdgeGraph;\r\n /** \"Exterior\" side of a bare edge of the mesh */\r\n public get exteriorMask(): HalfEdgeMask { return this._exteriorMask; }\r\n private _exteriorMask: HalfEdgeMask;\r\n\r\n /** Mask indicating a a sector's coordinates have been reassigned at offset distance. */\r\n private _offsetCoordinatesReassigned: HalfEdgeMask;\r\n\r\n /** \"First\" sector of a smooth sequence. */\r\n public get breakMaskA(): HalfEdgeMask { return this._breakMaskA; }\r\n private _breakMaskA: HalfEdgeMask;\r\n\r\n /** \"Last\" sector of a smooth sequence. */\r\n public get breakMaskB(): HalfEdgeMask { return this._breakMaskB; }\r\n private _breakMaskB: HalfEdgeMask;\r\n\r\n /** This edge is on a chamfered face, and along the original edge */\r\n public get insideOfChamferFace(): HalfEdgeMask { return this._insideOfChamferFace; }\r\n private _insideOfChamferFace: HalfEdgeMask;\r\n\r\n /** This is the original edge of a chamfer face */\r\n public get outsideOfChamferFace(): HalfEdgeMask { return this._outsideOfChamferFace; }\r\n private _outsideOfChamferFace: HalfEdgeMask;\r\n\r\n /** This edge is on a chamfered face, and at the end -- other side may be a sling */\r\n public get insideChamferSling(): HalfEdgeMask { return this._insideChamferSling; }\r\n private _insideChamferSling: HalfEdgeMask;\r\n\r\n /** This is the outside of the end of a chamfer face -- i.e. the inside of a new face-at-vertex */\r\n public get outsideEndOfChamferFace(): HalfEdgeMask { return this._outsideEndOfChamferFace; }\r\n private _outsideEndOfChamferFace: HalfEdgeMask;\r\n\r\n // On a CCW vertex loop, the mask sequence at a chamfered edge (which was expanded to a chamfer face) is\r\n // * the INBOUND edge of the original edge (at its far node !!) _outsideOfChamferFace\r\n // * the OUTBOUND edge inside the chamfer face has _insideOfChamferFace\r\n // * the inside of the sling face has _insideChamferSling\r\n // * the \"outside\" of the sling face - i.e. inside the chamfer face and at this vertex - has _outsideEndOfChamferFace\r\n // * the \"outside\" of the outgoing edge has _outsideOfChamferFace.\r\n private _smoothRadiansBetweenNormals: number;\r\n private _smoothAccumulatedRadiansBetweenNormals: number;\r\n private _chamferTurnRadians: number;\r\n public static graphDebugFunction?: FacetOffsetGraphDebugFunction;\r\n public static stringDebugFunction?: FacetOffsetDebugString;\r\n\r\n // At each node . .\r\n // * Find the sector data\r\n // * recompute the sector point using node XYZ and sectorData normal.\r\n private applyFaceNormalOffsetsToSectorData(distance: number) {\r\n this._baseGraph.announceNodes((_graph: HalfEdgeGraph, node: HalfEdge) => {\r\n const sectorData = node.edgeTag as SectorOffsetProperties;\r\n if (sectorData !== undefined) {\r\n sectorData.setOffsetPointAtDistanceAtHalfEdge(node, distance);\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * * build a mesh offset by given distance.\r\n * * output the mesh to the given builder.\r\n * @param basePolyface original mesh\r\n * @param builder polyface builder to receive the new mesh.\r\n * @param distance signed offset distance.\r\n */\r\n public static buildOffsetMeshWithEdgeChamfers(\r\n basePolyface: IndexedPolyface,\r\n builder: PolyfaceBuilder,\r\n distance: number,\r\n options: OffsetMeshOptions) {\r\n const baseGraph = this.buildBaseGraph(basePolyface);\r\n if (baseGraph !== undefined) {\r\n const offsetBuilder = new OffsetMeshContext(basePolyface, baseGraph, options);\r\n offsetBuilder.applyFaceNormalOffsetsToSectorData(distance);\r\n if (OffsetMeshContext.graphDebugFunction !== undefined)\r\n OffsetMeshContext.graphDebugFunction(\"BaseGraph\", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);\r\n\r\n const outputSelector = options.outputSelector ? options.outputSelector : {\r\n outputOffsetsFromFaces: true,\r\n outputOffsetsFromEdges: true,\r\n outputOffsetsFromVertices: true,\r\n };\r\n\r\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromFacesBeforeChamfers))\r\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);\r\n\r\n offsetBuilder.addChamferTopologyToAllEdges(options, distance);\r\n offsetBuilder.computeOffsetFacetIntersections(distance);\r\n\r\n if (OffsetMeshContext.graphDebugFunction !== undefined)\r\n OffsetMeshContext.graphDebugFunction(\"after computeEdgeChamfers\", baseGraph, offsetBuilder._breakMaskA, offsetBuilder._breakMaskB);\r\n\r\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromFaces))\r\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundFaces(builder);\r\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromEdges))\r\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundEdges(builder);\r\n if (isDefinedAndTrue(outputSelector.outputOffsetsFromVertices))\r\n offsetBuilder.announceFacetsWithSectorCoordinatesAroundVertices(builder);\r\n }\r\n }\r\n\r\n /**\r\n * For each face of the graph, shift vertices by offsetDistance and emit to the builder as a facet\r\n * @param polyfaceBuilder\r\n */\r\n public announceSimpleOffsetFromFaces(polyfaceBuilder: PolyfaceBuilder, offsetDistance: number) {\r\n const xyzLoop = new GrowableXYZArray();\r\n const xyz = Point3d.create(); // reused at each point around each facet.\r\n const uvw = Vector3d.create(); // reused once per facet\r\n const announceNodeAroundFace = (node: HalfEdge): number => {\r\n node.getPoint3d(xyz);\r\n xyz.addInPlace(uvw);\r\n xyzLoop.push(xyz);\r\n return 0;\r\n };\r\n this._baseGraph.announceFaceLoops(\r\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\r\n if (!seed.isMaskSet(HalfEdgeMask.EXTERIOR)) {\r\n const facetProperties = seed.faceTag as FacetOffsetProperties;\r\n uvw.setFromVector3d(facetProperties.facetNormal.direction);\r\n uvw.scaleInPlace(offsetDistance);\r\n xyzLoop.length = 0;\r\n seed.sumAroundFace(announceNodeAroundFace);\r\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * For each face of the graph, output the xyz of the sector data\r\n * @param polyfaceBuilder\r\n */\r\n public announceFacetsWithSectorCoordinatesAroundFaces(polyfaceBuilder: PolyfaceBuilder) {\r\n const xyzLoop = new GrowableXYZArray();\r\n // For face loop visits .. get the point from the sector data.\r\n const announceNodeAroundFace = (node: HalfEdge): number => {\r\n const sectorData = node.edgeTag as SectorOffsetProperties;\r\n if (sectorData !== undefined) {\r\n xyzLoop.push(sectorData.xyz);\r\n }\r\n return 0;\r\n };\r\n this._baseGraph.announceFaceLoops(\r\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\r\n if (!seed.isMaskSet(HalfEdgeMask.EXTERIOR)) {\r\n xyzLoop.length = 0;\r\n seed.sumAroundFace(announceNodeAroundFace);\r\n if (xyzLoop.length > 2)\r\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\r\n }\r\n return true;\r\n });\r\n }\r\n private countBits(mask: HalfEdgeMask): number {\r\n let n = 0;\r\n let mask1 = mask;\r\n while (mask1 !== 0) {\r\n if (mask1 & 0x01) n++;\r\n mask1 = mask1 >> 1;\r\n }\r\n return n;\r\n }\r\n /**\r\n * For each edge of the graph . .\r\n * * Collect coordinates in 4 sectors going around the edge\r\n * * Compress with tight tolerance so adjacent sectors with clean point match reduce to a single point.\r\n * * Emit as a facet.\r\n * @param polyfaceBuilder\r\n */\r\n public announceFacetsWithSectorCoordinatesAroundEdges(polyfaceBuilder: PolyfaceBuilder) {\r\n const xyzLoop = new GrowableXYZArray();\r\n const primaryCompressionTolerance = Geometry.smallMetricDistance;\r\n const allMasksForEdgesToIgnore = this._exteriorMask\r\n | this._outsideEndOfChamferFace\r\n | this._outsideOfChamferFace\r\n | this._insideOfChamferFace\r\n | this._insideChamferSling;\r\n this._baseGraph.announceEdges(\r\n (_graph: HalfEdgeGraph, nodeA: HalfEdge): boolean => {\r\n // This starts by looking for EXTERIOR on both sides ...\r\n if (nodeA.findMaskAroundEdge(this._exteriorMask) !== undefined) {\r\n return true;\r\n } else if (!nodeA.isMaskSet(allMasksForEdgesToIgnore)) { // By design, we believe that these two test for allMasksForEdgesToIgnore condition would catch the EXTERIOR case above\r\n const nodeB = nodeA.faceSuccessor;\r\n const nodeC = nodeA.edgeMate;\r\n if (!nodeC.isMaskSet(allMasksForEdgesToIgnore)) {\r\n const nodeD = nodeC.faceSuccessor;\r\n xyzLoop.clear();\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeA, undefined, xyzLoop);\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeB, undefined, xyzLoop);\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeC, undefined, xyzLoop);\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(nodeD, undefined, xyzLoop);\r\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);\r\n if (xyzLoop.length > 2) {\r\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\r\n }\r\n }\r\n } else {\r\n return true;\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n private getCoordinateString(node: HalfEdge, showXYZ: boolean = true, showFaceSuccessorXYZ: boolean = false): string {\r\n if (showXYZ) {\r\n if (showFaceSuccessorXYZ) {\r\n return `${HalfEdge.nodeToIdXYZString(node)} ==> ${HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;\r\n } else {\r\n return `${HalfEdge.nodeToIdXYZString(node)}`;\r\n }\r\n } else {\r\n if (showFaceSuccessorXYZ) {\r\n return `==> ${HalfEdge.nodeToIdXYZString(node.faceSuccessor)}`;\r\n } else {\r\n return \"\";\r\n }\r\n }\r\n\r\n }\r\n private inspectMasks(node: HalfEdge, showXYZ: boolean = true, showFaceSuccessorXYZ: boolean = false): string {\r\n const s = \"[\";\r\n const v = s.concat(\r\n node.id.toString(),\r\n node.isMaskSet(this._exteriorMask) ? \"X\" : \"\",\r\n node.isMaskSet(this.breakMaskA) ? \"A\" : \"\",\r\n node.isMaskSet(this.breakMaskB) ? \"B\" : \"\",\r\n node.isMaskSet(this.insideChamferSling) ? \"(sling)\" : \"\",\r\n node.isMaskSet(this.insideOfChamferFace) ? \"(in chamfer)\" : \"\",\r\n node.isMaskSet(this.outsideEndOfChamferFace) ? \"(@sling)\" : \"\",\r\n node.isMaskSet(this.outsideOfChamferFace) ? \"(@chamfer)\" : \"\",\r\n this.getCoordinateString(node, showXYZ, showFaceSuccessorXYZ),\r\n \"]\",\r\n );\r\n return v;\r\n }\r\n /**\r\n * For each face of the graph, output the xyz of the sector data\r\n * @param polyfaceBuilder\r\n */\r\n public announceFacetsWithSectorCoordinatesAroundVertices(polyfaceBuilder: PolyfaceBuilder) {\r\n const xyzLoop = new GrowableXYZArray();\r\n const primaryCompressionTolerance = Geometry.smallMetricDistance;\r\n this._baseGraph.announceVertexLoops(\r\n (_graph: HalfEdgeGraph, seed: HalfEdge): boolean => {\r\n if (!seed.findMaskAroundVertex(this._exteriorMask)) {\r\n xyzLoop.length = 0;\r\n seed.sumAroundVertex((node: HalfEdge) => {\r\n if (!node.isMaskSet(this._insideChamferSling))\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(node, undefined, xyzLoop);\r\n return 0.0;\r\n });\r\n PolylineCompressionContext.compressInPlaceByShortEdgeLength(xyzLoop, primaryCompressionTolerance);\r\n if (xyzLoop.length > 2) {\r\n polyfaceBuilder.addPolygonGrowableXYZArray(xyzLoop);\r\n }\r\n }\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * * Exterior half edges have HalfEdgeMask.EXTERIOR\r\n * * All interior half edge around a facet have facetTag pointing to a facetProperties object for that facet.\r\n * * the facetOffsetProperties object has the simple facet normal.\r\n * * Each half edge has edgeTag pointing to to a sectorOffsetProperties object\r\n * * the sectorOffsetProperties has a copy of the facet normal.\r\n * @param polyface\r\n * @returns graph\r\n */\r\n public static buildBaseGraph(polyface: IndexedPolyface): HalfEdgeGraph | undefined {\r\n const graphBuilder = new HalfEdgeGraphFromIndexedLoopsContext();\r\n const visitor = polyface.createVisitor();\r\n const xyzA = Point3d.create();\r\n const xyzB = Point3d.create();\r\n for (visitor.reset(); visitor.moveToNextFacet();) {\r\n const normal = PolygonOps.centroidAreaNormal(visitor.point);\r\n if (normal !== undefined) {\r\n const edgeA = graphBuilder.insertLoop(visitor.pointIndex,\r\n (insideHalfEdge: HalfEdge) => {\r\n const mate = insideHalfEdge.edgeMate;\r\n polyface.data.getPoint(insideHalfEdge.i, xyzA);\r\n insideHalfEdge.setXYZ(xyzA);\r\n polyface.data.getPoint(mate.i, xyzB);\r\n mate.setXYZ(xyzB);\r\n });\r\n const facetProperties = new FacetOffsetProperties(visitor.currentReadIndex(), normal);\r\n if (edgeA !== undefined) {\r\n edgeA.sumAroundFace(\r\n (edgeB: HalfEdge) => {\r\n edgeB.faceTag = facetProperties;\r\n edgeB.edgeTag = new SectorOffsetProperties(normal.direction.clone(), edgeB.getPoint3d());\r\n return 0;\r\n });\r\n }\r\n }\r\n }\r\n return graphBuilder.graph;\r\n }\r\n private setOffsetAtDistanceAroundVertex(vertexSeed: HalfEdge, distance: number, ignoreChamfers: boolean = false) {\r\n vertexSeed.sumAroundVertex((nodeAroundVertex: HalfEdge) => {\r\n const props = nodeAroundVertex.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined) {\r\n if (ignoreChamfers && this.isInsideChamferOrSling(vertexSeed)) {\r\n // SKIP !!\r\n } else {\r\n props.setOffsetPointAtDistanceAtHalfEdge(nodeAroundVertex, distance);\r\n }\r\n }\r\n return 0.0;\r\n },\r\n );\r\n }\r\n\r\n private setOffsetXYAndZAroundVertex(vertexSeed: HalfEdge, xyz: XYAndZ) {\r\n vertexSeed.sumAroundVertex((nodeAroundVertex: HalfEdge) => {\r\n const props = nodeAroundVertex.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined) {\r\n props.setXYAndZ(xyz);\r\n nodeAroundVertex.setMask(this._offsetCoordinatesReassigned);\r\n }\r\n return 0.0;\r\n },\r\n );\r\n }\r\n\r\n /**\r\n * * start at vertexSeed.\r\n * * set the offset point at up to (and including) one with (a) this._breakMaskB or (b) this._exteriorMask\r\n * *\r\n * @param vertexSeed first node to mark.\r\n * @param f function to call to announce each node and its sector properties.\r\n * @returns number of nodes marked.\r\n */\r\n private announceNodeAndSectorPropertiesInSmoothSector(vertexSeed: HalfEdge, f: (node: HalfEdge, properties: SectorOffsetProperties) => void): number {\r\n let n = 0;\r\n for (let currentNode = vertexSeed; ; currentNode = currentNode.vertexSuccessor) {\r\n const props = currentNode.edgeTag as SectorOffsetProperties;\r\n if (props !== undefined) {\r\n f(currentNode, props);\r\n n++;\r\n }\r\n if (currentNode.isMaskSet(this._breakMaskB))\r\n return n;\r\n // REMARK: these additional exit conditions should not happen if (a) the graph is properly marked and (b) the start node is not exterior.\r\n if (currentNode.isMaskSet(this._exteriorMask))\r\n return n;\r\n if (currentNode === vertexSeed && n === 0)\r\n return n;\r\n }\r\n }\r\n\r\n private computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed: HalfEdge, data: AverageNormalData): number | undefined {\r\n data.clear();\r\n const inactiveNodeMask = this._exteriorMask | this._insideChamferSling;\r\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\r\n const sectorData = node.edgeTag as SectorOffsetProperties;\r\n if (sectorData)\r\n data.accumulateNormal(node, sectorData.normal, inactiveNodeMask);\r\n return 0.0;\r\n },\r\n );\r\n if (!data.finishNormalAveraging()) {\r\n return undefined;\r\n }\r\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\r\n const sectorData = node.edgeTag as SectorOffsetProperties;\r\n if (sectorData)\r\n data.recordDeviation(sectorData.normal, !node.isMaskSet(inactiveNodeMask));\r\n return 0.0;\r\n },\r\n );\r\n return data.maxDeviationRadians;\r\n }\r\n\r\n private assignOffsetByAverageNormalAroundVertex(vertexSeed: HalfEdge,\r\n maxAllowedDeviationRadians: number,\r\n data: AverageNormalData,\r\n distance: number): boolean {\r\n const maxDeviationRadians = this.computeAverageNormalAndMaxDeviationAroundVertex(vertexSeed, data);\r\n if (OffsetMeshContext.stringDebugFunction) {\r\n OffsetMeshContext.stringDebugFunction(`XYZ ${HalfEdge.nodeToIdXYZString(vertexSeed)} Average Normal ${JSON.stringify(data.averageNormal.toJSON())}`);\r\n OffsetMeshContext.stringDebugFunction(` angle ratio ${data.radiansSum / (2 * Math.PI)} maxDeviation ${data.maxDeviationRadiansFromAverage}`);\r\n }\r\n if (maxDeviationRadians !== undefined && maxDeviationRadians <= maxAllowedDeviationRadians) {\r\n vertexSeed.sumAroundVertex((node: HalfEdge) => {\r\n SectorOffsetProperties.setNormalAtHalfEdge(node, data.averageNormal, distance);\r\n return 0;\r\n });\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /** Search around a vertex for a sector which has a different normal from its vertexPredecessor.\r\n * * The seed will be the first candidate considered\r\n */\r\n private markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed: HalfEdge) {\r\n vertexSeed.clearMaskAroundVertex(this._breakMaskA);\r\n vertexSeed.clearMaskAroundVertex(this._breakMaskB);\r\n\r\n const smoothSingleSmoothRadiansBetweenNormals = this._smoothRadiansBetweenNormals;\r\n const accumulatedRadiansBetweenNormals = this._smoothAccumulatedRadiansBetweenNormals;\r\n\r\n // Step 1: Examine the edge between nodeA and the sector on its vertex predecessor side. This (alone) determines single angle breaks.\r\n let numBreaks = 0;\r\n let nodeP = vertexSeed;\r\n let _numSmooth = 0;\r\n do {\r\n const nodeQ = nodeP.edgeMate;\r\n const nodeR = nodeQ.faceSuccessor; // same as nodeA.vertexPredecessor\r\n if (nodeP.isMaskSet(this._exteriorMask)) {\r\n if (!nodeQ.isMaskSet(this._exteriorMask)) {\r\n nodeR.setMask(this._breakMaskB);\r\n numBreaks++;\r\n }\r\n } else {\r\n if (nodeP.isMaskSet(this._outsideOfChamferFace)) {\r\n nodeP.setMask(this._breakMaskA);\r\n } else if (nodeP.isMaskSet(this._outsideEndOfChamferFace)) {\r\n nodeP.setMask(this._breakMaskA);\r\n nodeP.setMask(this._breakMaskB);\r\n } else if (nodeP.isMaskSet(this._insideChamferSling)) {\r\n // This is the sling. It's normal is along edge -- not really a break.\r\n } else if (nodeP.isMaskSet(this._insideOfChamferFace)) {\r\n nodeP.setMask(this._breakMaskA);\r\n nodeP.setMask(this._breakMaskB);\r\n nodeR.setMask(this._breakMaskB);\r\n } else if (nodeQ.isMaskSet(this._exteriorMask)) {\r\n numBreaks++;\r\n nodeP.setMask(this._breakMaskA);\r\n } else if (!SectorOffsetProperties.almostEqualNormals(\r\n nodeP.edgeTag as SectorOffsetProperties,\r\n nodeR.edgeTag as SectorOffsetProperties,\r\n smoothSingleSmoothRadiansBetweenNormals)) {\r\n nodeP.setMask(this._breakMaskA);\r\n numBreaks++;\r\n nodeR.setMask(this._breakMaskB);\r\n } else {\r\n _numSmooth++;\r\n }\r\n }\r\n nodeP = nodeP.vertexSuccessor;\r\n } while (nodeP !== vertexSeed);\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` numSkip ${_numSmooth} `);\r\n if (numBreaks === 0) {\r\n // make the first vertex a break so subsequent searches have a place to start\r\n vertexSeed.setMask(this._breakMaskA);\r\n vertexSeed.vertexPredecessor.setMask(this._breakMaskB);\r\n numBreaks = 1;\r\n }\r\n // Step 2: At each single break, sweep forward to its closing breakB. Insert breaks at accumulated angles.\r\n // (minor TODO: for the insertion case, try to split more equally.)\r\n const nodeAStart = nodeP.findMaskAroundVertex(this._breakMaskA);\r\n if (nodeAStart !== undefined) {\r\n nodeP = nodeAStart;\r\n do {\r\n if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {\r\n let accumulatedRadians = 0.0;\r\n do {\r\n const nodeB = nodeP.vertexSuccessor;\r\n accumulatedRadians += SectorOffsetProperties.radiansBetweenNormals(\r\n nodeP.edgeTag as SectorOffsetProperties,\r\n nodeB.edgeTag as SectorOffsetProperties,\r\n );\r\n if (accumulatedRadians > accumulatedRadiansBetweenNormals) {\r\n nodeP.setMask(this._breakMaskB);\r\n nodeB.setMask(this._breakMaskA);\r\n numBreaks++;\r\n accumulatedRadians = 0.0;\r\n }\r\n nodeP = nodeB;\r\n } while (!nodeP.isMaskSet(this._breakMaskB));\r\n } else {\r\n nodeP = nodeP.vertexSuccessor;\r\n }\r\n } while (nodeP !== nodeAStart);\r\n }\r\n\r\n if (numBreaks > 0 && nodeAStart !== undefined) {\r\n // In each compound sector, accumulate and install average normal.\r\n nodeP = nodeAStart;\r\n const averageNormal = Vector3d.create();\r\n const edgeVectorU = Vector3d.create();\r\n const edgeVectorV = Vector3d.create();\r\n averageNormal.setZero();\r\n do {\r\n if (nodeP.isMaskSet(this._breakMaskA) && !nodeP.isMaskSet(this._breakMaskB)) {\r\n let nodeQ = nodeP;\r\n averageNormal.setZero();\r\n for (; ;) {\r\n nodeQ.vectorToFaceSuccessor(edgeVectorU);\r\n nodeQ.vectorToFacePredecessor(edgeVectorV);\r\n let singleSectorRadians = edgeVectorU.signedRadiansTo(edgeVectorV, (nodeQ.faceTag as FacetOffsetProperties).facetNormal.direction);\r\n if (singleSectorRadians < 0.0)\r\n singleSectorRadians += Math.PI * 2;\r\n SectorOffsetProperties.accumulateScaledNormalAtHalfEdge(nodeQ, singleSectorRadians, averageNormal);\r\n if (nodeQ.isMaskSet(this._breakMaskB))\r\n break;\r\n nodeQ = nodeQ.vertexSuccessor;\r\n }\r\n if (averageNormal.normalizeInPlace()) {\r\n nodeQ = nodeP;\r\n for (; ;) {\r\n SectorOffsetProperties.setNormalAtHalfEdge(nodeQ, averageNormal);\r\n if (nodeQ.isMaskSet(this._breakMaskB))\r\n break;\r\n nodeQ = nodeQ.vertexSuccessor;\r\n }\r\n }\r\n }\r\n nodeP = nodeP.vertexSuccessor;\r\n } while (nodeP !== nodeAStart);\r\n\r\n }\r\n }\r\n\r\n /** Compute the point of intersection of the planes in the sectors of 3 half edges */\r\n private compute3SectorIntersection(nodeA: HalfEdge, nodeB: HalfEdge, nodeC: HalfEdge, result?: Vector3d): Vector3d | undefined {\r\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\r\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\r\n const sectorC = nodeC.edgeTag as SectorOffsetProperties;\r\n const vector = SmallSystem.intersect3Planes(\r\n sectorA.xyz, sectorA.normal,\r\n sectorB.xyz, sectorB.normal,\r\n sectorC.xyz, sectorC.normal,\r\n result);\r\n return vector;\r\n }\r\n /** Compute the point of intersection of the planes in the sectors of 3 half edges */\r\n private compute3SectorIntersectionDebug(nodeA: HalfEdge, nodeB: HalfEdge, nodeC: HalfEdge, result?: Vector3d): Vector3d | undefined {\r\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\r\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\r\n const sectorC = nodeC.edgeTag as SectorOffsetProperties;\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n OffsetMeshContext.stringDebugFunction(`compute3${this.inspectMasks(nodeA)}${this.inspectMasks(nodeB)}${this.inspectMasks(nodeC)} `);\r\n for (const sector of [sectorA, sectorB, sectorC])\r\n emitSector(sector);\r\n }\r\n\r\n const vector = SmallSystem.intersect3Planes(\r\n sectorA.xyz, sectorA.normal,\r\n sectorB.xyz, sectorB.normal,\r\n sectorC.xyz, sectorC.normal,\r\n result);\r\n\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n if (vector === undefined)\r\n OffsetMeshContext.stringDebugFunction(\" NO INTERSECTION\");\r\n else\r\n OffsetMeshContext.stringDebugFunction(` ComputedVector ${vector.x},${vector.y},${vector.z} `);\r\n }\r\n return vector;\r\n }\r\n\r\n /** Compute the point of intersection of the planes in the sectors of 2 half edges, using cross product of their normals to resolve */\r\n private compute2SectorIntersection(nodeA: HalfEdge, nodeB: HalfEdge, result?: Vector3d): Vector3d | undefined {\r\n const sectorA = nodeA.edgeTag as SectorOffsetProperties;\r\n const sectorB = nodeB.edgeTag as SectorOffsetProperties;\r\n const normalC = sectorA.normal.crossProduct(sectorB.normal);\r\n return SmallSystem.intersect3Planes(\r\n sectorA.xyz, sectorA.normal,\r\n sectorB.xyz, sectorB.normal,\r\n sectorB.xyz, normalC,\r\n result);\r\n }\r\n /**\r\n * * at input, graph has all original faces and edges\r\n * * each sector points to a faceProperties with original facet normal\r\n * * at exit:\r\n * * new \"chamfer faces\" are added outside of edges with angle between normal sin excess of options.chamferTurnAngleBetweenNormals\r\n * * the original edge is split along its length to create space\r\n * * one edge \"along\" each direction inside the slit.\r\n * * a sling edge at each end of the slit.\r\n * * outside of the sling is part of the slit face loop.\r\n * * inside is a single-node face\r\n * * thus the slit itself has 4 nodes.\r\n * * the two nodes at each end can thus contain the two distinct points at that end of the chamfer.\r\n * * all 4 nodes of the slit face point to a new FacetOffsetProperties with the average normal.\r\n * * the inside of each sling face has\r\n * * original vertex coordinates in the node\r\n * * face properties with a normal pointing outward from that end of the original edge -- hence define a plane that can clip the chamfer\r\n * * the two points at each end of the chamfer are computed as the intersection of\r\n * * chamfer plane\r\n * * sling plane\r\n * * adjacent plane of the face on the other side of the edge being chamfered.\r\n * @param distance distance to offset. The sign of this is important in the chamfer construction.\r\n */\r\n private addChamferTopologyToAllEdges(options: OffsetMeshOptions, distance: number) {\r\n const edgesToChamfer: HalfEdge[] = [];\r\n const chamferRadians = options.chamferAngleBetweenNormals.radians;\r\n const vertexXYZ = Point3d.create(); // reuse\r\n const edgeVector = Vector3d.create(); // reuse\r\n const outwardEdgeVector = Vector3d.create(); // reuse\r\n const averageNormal = Vector3d.create(); // reuse\r\n // collect all the edges with sharp turn angle.\r\n this._baseGraph.announceEdges(\r\n (_graph: HalfEdgeGraph, edgeNode: HalfEdge) => {\r\n if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(edgeNode, edgeVector, averageNormal,\r\n distance,\r\n chamferRadians)) {\r\n edgesToChamfer.push(edgeNode);\r\n return true;\r\n }\r\n return true;\r\n });\r\n // Create sliver faces.\r\n // Sliver face gets an average normal from its neighbors.\r\n // outsideA is the HalfEdge labeled A in the diagram.\r\n // sliverDX and sliverDY are the edges \"inside the sliver\" at the respective X and Y ends.\r\n for (const outsideA of edgesToChamfer) {\r\n // remark: this recomputes as in collection round.\r\n if (SectorOffsetProperties.edgeHasLargeExteriorAngleBetweenNormals(outsideA, edgeVector, averageNormal, chamferRadians)) {\r\n // This copies coordinates and vertex id .... sectorOffsetProperties are delayed until late in the 2-pass loop below.\r\n // The returned HalfEdge is labeled D in the diagram\r\n const sliverDX = this._baseGraph.splitEdgeCreateSliverFace(outsideA);\r\n const sliverDY = sliverDX.facePredecessor;\r\n const offsetPoint = sliverDX.getPoint3d();\r\n offsetPoint.addScaledInPlace(averageNormal, distance);\r\n const ray = Ray3d.createCapture(offsetPoint, averageNormal.clone());\r\n const facetProperties = new FacetOffsetProperties(-1, ray);\r\n // for each side (hence end) of the sliver face, set mask and install a sling loop for the anticipated end of the chamfer face\r\n // new node names in the loop omit X or Y suffix because that is implied by which pass is running.\r\n let s = -1.0;\r\n for (const sliverD of [sliverDX, sliverDY]) {\r\n edgeVector.scale(s, outwardEdgeVector);\r\n sliverD.getPoint3d(vertexXYZ);\r\n sliverD.setMask(this._insideOfChamferFace);\r\n sliverD.edgeMate.setMask(this._outsideOfChamferFace);\r\n // mark and reference the chamfer face.\r\n sliverD.faceTag = facetProperties;\r\n // sling at this end\r\n const slingB = this._baseGraph.splitEdge(undefined, vertexXYZ.x, vertexXYZ.y, vertexXYZ.z, sliverD.i);\r\n const slingC = slingB.edgeMate;\r\n slingB.setMask(this._outsideEndOfChamferFace);\r\n slingB.faceTag = facetProperties;\r\n slingC.setMask(this._insideChamferSling);\r\n HalfEdge.pinch(sliverD, slingB);\r\n const endNormal = Ray3d.create(vertexXYZ, outwardEdgeVector); // clones the inputs\r\n const slingFaceProperties = new FacetOffsetProperties(-1, endNormal);\r\n slingC.faceTag = slingFaceProperties;\r\n // initialize sectors with existing vertex point.\r\n sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());\r\n slingB.edgeTag = new SectorOffsetProperties(averageNormal.clone(), offsetPoint.clone());\r\n slingC.edgeTag = new SectorOffsetProperties(outwardEdgeVector.clone(), vertexXYZ.clone());\r\n // OffsetMeshContext.stringDebugFunction(\"Chamfer Setup\");\r\n const chamferPointE = this.compute3SectorIntersection(sliverD, sliverD.edgeMate, slingC);\r\n const chamferPointF = this.compute3SectorIntersection(slingB, slingB.vertexSuccessor, slingC);\r\n // sliverD.edgeTag = new SectorOffsetProperties(averageNormal.clone(), vertexXYZ.clone());\r\n SectorOffsetProperties.setXYZAtHalfEdge(sliverD, chamferPointE);\r\n SectorOffsetProperties.setXYZAtHalfEdge(slingB, chamferPointF);\r\n s *= -1.0;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * * at input:\r\n * * Each node points to sectorOffsetProperties with previously computed XYZ (presumably mismatched)\r\n * * at exit:\r\n * * Each sectorOffsetProperties has an offset point computed with consideration of offset planes in the neighborhood.\r\n * @param distance distance to offset.\r\n */\r\n private computeOffsetFacetIntersections(distance: number) {\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(\"***** recompute intersections\");\r\n const breakEdges: HalfEdge[] = [];\r\n const vertexXYZ = Point3d.create();\r\n const chamferXYZ = Point3d.create();\r\n const maxVertexMove = 2.0 * distance;\r\n const averageNormalData = new AverageNormalData();\r\n const maxAllowedNormalDeviationRadians = Angle.degreesToRadians(25.0);\r\n //\r\n // FOR EACH VERTEX\r\n //\r\n this._baseGraph.announceVertexLoops((_graph: HalfEdgeGraph, vertexSeedA: HalfEdge) => {\r\n // reposition to an important vertex.\r\n // first choice: a chamfer face.\r\n let vertexSeed = vertexSeedA.findMaskAroundVertex(this._outsideEndOfChamferFace);\r\n if (vertexSeed === undefined)\r\n vertexSeed = vertexSeedA.findMaskAroundVertex(this._breakMaskA);\r\n if (vertexSeed === undefined)\r\n vertexSeed = vertexSeedA;\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n OffsetMeshContext.stringDebugFunction(\"\");\r\n OffsetMeshContext.stringDebugFunction(` VERTEX LOOP ${JSON.stringify(vertexSeed.getPoint3d().toJSON())} `);\r\n vertexSeed.sumAroundVertex(\r\n (node: HalfEdge) => { OffsetMeshContext.stringDebugFunction!(this.inspectMasks(node, false, true)); return 0; });\r\n }\r\n // Take care of the easiest vertices directly . . . note that this returns from the lambda, not computeOffsetFacetIntersections\r\n if (this.assignOffsetByAverageNormalAroundVertex(vertexSeed, maxAllowedNormalDeviationRadians, averageNormalData, distance))\r\n return true;\r\n\r\n this.markBreakEdgesAndSaveAverageNormalsAroundVertex(vertexSeed);\r\n this.setOffsetAtDistanceAroundVertex(vertexSeed, distance, true);\r\n vertexSeed.collectMaskedEdgesAroundVertex(this._breakMaskA, true, breakEdges);\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n OffsetMeshContext.stringDebugFunction(` BREAK EDGES from ${this.inspectMasks(vertexSeed, true, false)}`);\r\n for (const node of breakEdges) { OffsetMeshContext.stringDebugFunction(this.inspectMasks(node, false, true)); }\r\n }\r\n if (breakEdges.length <= 1) {\r\n // just one smooth sequence.\r\n // everything is set already.\r\n } else if (breakEdges.length === 2) {\r\n // exterior vertex with two incident smooth\r\n const vectorFromOrigin = this.compute2SectorIntersection(breakEdges[0], breakEdges[1]);\r\n if (vectorFromOrigin !== undefined) {\r\n this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);\r\n }\r\n } else if (breakEdges.length === 3) {\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` Vertex Update just ${breakEdges.length} `);\r\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[0], breakEdges[1], breakEdges[2]);\r\n if (vectorFromOrigin !== undefined) {\r\n this.setOffsetXYAndZAroundVertex(vertexSeed, vectorFromOrigin);\r\n }\r\n // simple 3-face corner . . .\r\n } else {\r\n // Lots and Lots of edges\r\n // each set of 3 sectors independently generates an offset for its central sector.\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` Vertex Update breakEdges ${breakEdges.length} `);\r\n vertexSeed.getPoint3d(vertexXYZ);\r\n // Pass 1 -- look for intersection among multiple chamfers\r\n for (let i = 0; i < breakEdges.length; i++) {\r\n const i0 = i;\r\n const i1 = (i0 + 1) % breakEdges.length;\r\n const i2 = (i1 + 1) % breakEdges.length;\r\n\r\n if (breakEdges[i0].isMaskSet(this._outsideEndOfChamferFace)\r\n && breakEdges[i1].isMaskSet(this._outsideOfChamferFace)\r\n && breakEdges[i2].isMaskSet(this._insideOfChamferFace)) {\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` ChamferChamfer Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);\r\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);\r\n if (vectorFromOrigin !== undefined) {\r\n // Treat all 3 spots as possibly compound sequences\r\n for (const iOutput of [i0, i1, i2]) {\r\n this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[iOutput],\r\n (node: HalfEdge, properties: SectorOffsetProperties) => {\r\n properties.setXYAndZ(vectorFromOrigin);\r\n node.setMask(this._offsetCoordinatesReassigned);\r\n });\r\n }\r\n // Since all three were reset, skip past. This is done on the acyclic integer that controls the loop.\r\n i += 2;\r\n }\r\n }\r\n }\r\n\r\n // Pass 2 -- look for unassigned nodes just before or after a chamfer.\r\n // The chamfer wins\r\n for (let i = 0; i < breakEdges.length; i++) {\r\n const i0 = i;\r\n const i1 = (i0 + 1) % breakEdges.length;\r\n if (this.isInsideSling(breakEdges[i0], breakEdges[i1]))\r\n continue;\r\n if (!this.isOffsetAssigned(breakEdges[i0])\r\n && breakEdges[i1].isMaskSet(this.insideOfChamferFace)) {\r\n this.transferXYZFromNodeToSmoothSector(breakEdges[i1], breakEdges[i0], \"push left from chamfer\", chamferXYZ);\r\n } else if (!this.isOffsetAssigned(breakEdges[i1])\r\n && breakEdges[i0].isMaskSet(this.outsideEndOfChamferFace)) {\r\n this.transferXYZFromNodeToSmoothSector(breakEdges[i0], breakEdges[i1], \"push right from chamfer\", chamferXYZ);\r\n }\r\n\r\n }\r\n\r\n // Pass 3 -- look for unassigned nodes as middle of 3-face intersections\r\n for (let i = 0; i < breakEdges.length; i++) {\r\n const i0 = i;\r\n const i1 = (i0 + 1) % breakEdges.length;\r\n const i2 = (i1 + 1) % breakEdges.length;\r\n if (this.isInsideSling(breakEdges[i0], breakEdges[i1], breakEdges[i2]))\r\n continue;\r\n if (this.isOffsetAssigned(breakEdges[i1]))\r\n continue;\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` Intersection Fixup ${this.inspectMasks(breakEdges[i0])} ${this.inspectMasks(breakEdges[i1])} ${this.inspectMasks(breakEdges[i2])} `);\r\n const vectorFromOrigin = this.compute3SectorIntersection(breakEdges[i0], breakEdges[i1], breakEdges[i2]);\r\n if (vectorFromOrigin !== undefined) {\r\n if (vertexXYZ.distance(vectorFromOrigin) < maxVertexMove) {\r\n this.announceNodeAndSectorPropertiesInSmoothSector(breakEdges[i1],\r\n (node: HalfEdge, properties: SectorOffsetProperties) => {\r\n properties.setXYAndZ(vectorFromOrigin);\r\n node.setMask(this._offsetCoordinatesReassigned);\r\n });\r\n }\r\n }\r\n }\r\n }\r\n if (OffsetMeshContext.stringDebugFunction !== undefined) {\r\n const n0 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, false);\r\n const n1 = vertexSeed.countMaskAroundVertex(this._offsetCoordinatesReassigned, true);\r\n const message = ` **** Vertex offset mask counts(TRUE ${n1})(FALSE ${n0})`;\r\n OffsetMeshContext.stringDebugFunction(message);\r\n }\r\n return true;\r\n });\r\n }\r\n // return true if any of these nodes is \"inside\" the sling at the end of a chamfer.\r\n private isInsideSling(node0: HalfEdge,\r\n node1?: HalfEdge,\r\n node2?: HalfEdge): boolean {\r\n return node0.isMaskSet(this._insideChamferSling)\r\n || (node1 !== undefined && node1.isMaskSet(this._insideChamferSling))\r\n || (node2 !== undefined && node2.isMaskSet(this._insideChamferSling));\r\n }\r\n // return true if any of these nodes is \"inside\" the sling at the end of a chamfer.\r\n private isInsideChamferOrSling(node0: HalfEdge): boolean {\r\n return node0.isMaskSet(this._insideChamferSling)\r\n || node0.isMaskSet(this._insideOfChamferFace)\r\n || node0.isMaskSet(this._outsideEndOfChamferFace);\r\n }\r\n private isOffsetAssigned(node0: HalfEdge,\r\n node1?: HalfEdge,\r\n node2?: HalfEdge): boolean {\r\n return node0.isMaskSet(this._offsetCoordinatesReassigned)\r\n || (node1 !== undefined && node1.isMaskSet(this._offsetCoordinatesReassigned))\r\n || (node2 !== undefined && node2.isMaskSet(this._offsetCoordinatesReassigned));\r\n }\r\n\r\n /**\r\n *\r\n * @param sourceNode node with good xyz\r\n * @param destinationStartNode first of a sequence of nodes to set (delimited by masks)\r\n * @param description string for debug\r\n * @param workPoint point to use for coordinate transfer.\r\n */\r\n private transferXYZFromNodeToSmoothSector(\r\n sourceNode: HalfEdge,\r\n destinationStartNode: HalfEdge,\r\n description: string,\r\n workPoint: Point3d,\r\n ) {\r\n if (OffsetMeshContext.stringDebugFunction !== undefined)\r\n OffsetMeshContext.stringDebugFunction(` ${description} ${this.inspectMasks(sourceNode)} to ${this.inspectMasks(destinationStartNode)}} `);\r\n SectorOffsetProperties.getSectorPointAtHalfEdge(sourceNode, workPoint, undefined);\r\n this.announceNodeAndSectorPropertiesInSmoothSector(destinationStartNode,\r\n (node: HalfEdge, properties: SectorOffsetProperties) => {\r\n properties.setXYAndZ(workPoint);\r\n node.setMask(this._offsetCoordinatesReassigned);\r\n });\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Range2dSearchInterface.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/Range2dSearchInterface.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG","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/** @packageDocumentation\n * @module RangeSearch\n */\n\nimport { Range2d } from \"../../geometry3d/Range\";\nimport { LowAndHighXY } from \"../../geometry3d/XYZProps\";\n\n/**\n * Interface for classes that implement optimized search of 2D ranges.\n * * Each range is associated with user data of type `T`.\n * @public\n */\nexport interface Range2dSearchInterface<T> {\n /**\n * * Search for ranges containing the xy-coordinates.\n * * Pass each range and tag to handler.\n * * Terminate search if handler returns false.\n * @param testRange search range.\n * @param handler function to receive range hits, and their associated user data. Returning \"true\" means continue the search.\n * @returns false if any handler call returned false. Otherwise return true.\n */\n searchXY(x: number, y: number, handler: (range: Range2d, tag: T) => boolean): boolean;\n /**\n * * Search for ranges overlapping testRange.\n * * Pass each range and tag to handler.\n * * Terminate search if handler returns false.\n * @param testRange search range.\n * @param handler function to receive range hits, and their associated user data. Returning \"true\" means continue the search.\n * @returns false if any handler call returned false. Otherwise return true.\n */\n searchRange2d(testRange: LowAndHighXY, handler: (range: Range2d, tag: T) => boolean): boolean;\n /** Add a range to the search set, and associate the range with user data `tag`. */\n addRange(range: LowAndHighXY, tag: T): void;\n /** Return the overall range of all members. */\n totalRange(result?: Range2d): Range2d;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Range2dSearchInterface.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/Range2dSearchInterface.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG","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/** @packageDocumentation\r\n * @module RangeSearch\r\n */\r\n\r\nimport { Range2d } from \"../../geometry3d/Range\";\r\nimport { LowAndHighXY } from \"../../geometry3d/XYZProps\";\r\n\r\n/**\r\n * Interface for classes that implement optimized search of 2D ranges.\r\n * * Each range is associated with user data of type `T`.\r\n * @public\r\n */\r\nexport interface Range2dSearchInterface<T> {\r\n /**\r\n * * Search for ranges containing the xy-coordinates.\r\n * * Pass each range and tag to handler.\r\n * * Terminate search if handler returns false.\r\n * @param testRange search range.\r\n * @param handler function to receive range hits, and their associated user data. Returning \"true\" means continue the search.\r\n * @returns false if any handler call returned false. Otherwise return true.\r\n */\r\n searchXY(x: number, y: number, handler: (range: Range2d, tag: T) => boolean): boolean;\r\n /**\r\n * * Search for ranges overlapping testRange.\r\n * * Pass each range and tag to handler.\r\n * * Terminate search if handler returns false.\r\n * @param testRange search range.\r\n * @param handler function to receive range hits, and their associated user data. Returning \"true\" means continue the search.\r\n * @returns false if any handler call returned false. Otherwise return true.\r\n */\r\n searchRange2d(testRange: LowAndHighXY, handler: (range: Range2d, tag: T) => boolean): boolean;\r\n /** Add a range to the search set, and associate the range with user data `tag`. */\r\n addRange(range: LowAndHighXY, tag: T): void;\r\n /** Return the overall range of all members. */\r\n totalRange(result?: Range2d): Range2d;\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RangeSearch.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/RangeSearch.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,sEAAsE;AACtE,MAAM,OAAO,WAAW;IACf,MAAM,CAAU,eAAe,GAAG,EAAE,CAAC;IAC5C,sFAAsF;IAC/E,MAAM,CAAU,yBAAyB,GAAG,CAAC,CAAC;IACrD,oGAAoG;IAC7F,MAAM,CAAU,kCAAkC,GAAG,GAAG,CAAC;IAChE,gGAAgG;IACzF,MAAM,CAAC,kCAAkC,CAAI,eAAgC,EAAE,qBAA6B,WAAW,CAAC,yBAAyB,EAAE,8BAAsC,WAAW,CAAC,kCAAkC;QAC5O,gDAAgD;QAChD,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,eAAe;YAC3D,OAAO,IAAI,wBAAwB,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;QACvJ,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;QACvJ,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC;YAChC,OAAO,IAAI,wBAAwB,EAAE,CAAC;QACxC,OAAO,mCAAmC,CAAC,MAAM,CAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACxH,CAAC;IACD;;;;;;;;OAQG;IACI,MAAM,CAAC,sBAAsB,CAAC,WAAmB,EAAE,IAAe,EAAE,qBAA6B,WAAW,CAAC,yBAAyB,EAAE,8BAAsC,WAAW,CAAC,kCAAkC;QACjO,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,MAAM,yBAAyB,GAAG,kBAAkB,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,2BAA2B,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1H,MAAM,cAAc,GAAG,QAAQ,CAAC,yBAAyB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC;QAClG,IAAI,cAAc,KAAK,SAAS;YAC9B,OAAO,CAAC,CAAC;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC","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/** @packageDocumentation\n * @module RangeSearch\n */\n\nimport { Geometry } from \"../../Geometry\";\nimport { Range2d } from \"../../geometry3d/Range\";\nimport { UsageSums } from \"../../numerics/UsageSums\";\nimport { RangeLengthData } from \"../RangeLengthData\";\nimport { GriddedRaggedRange2dSetWithOverflow } from \"./GriddedRaggedRange2dSetWithOverflow\";\nimport { LinearSearchRange2dArray } from \"./LinearSearchRange2dArray\";\nimport { Range2dSearchInterface } from \"./Range2dSearchInterface\";\n\n/** Class with static members to work with various range searchers. */\nexport class RangeSearch {\n public static readonly smallCountLimit = 40;\n /** Target size for grid block size divided by representative per-entry range size. */\n public static readonly defaultRangesPerBlockEdge = 4;\n /** the \"representative range size\"is the mean range size plus this number of standard deviations */\n public static readonly defaultStandardDeviationAdjustment = 1.0;\n /** Based on range count and distribution, return an object which can answer 2d range queries */\n public static create2dSearcherForRangeLengthData<T>(rangeLengthData: RangeLengthData, rangesPerBlockEdge: number = RangeSearch.defaultRangesPerBlockEdge, standardDeviationAdjustment: number = RangeSearch.defaultStandardDeviationAdjustment): Range2dSearchInterface<T> | undefined {\n // for smallish sets, just linear search . . ..\n if (rangeLengthData.xSums.count < RangeSearch.smallCountLimit)\n return new LinearSearchRange2dArray();\n const numXBlock = this.estimateGridBlockCount(rangeLengthData.range.xLength(), rangeLengthData.xSums, rangesPerBlockEdge, standardDeviationAdjustment);\n const numYBlock = this.estimateGridBlockCount(rangeLengthData.range.yLength(), rangeLengthData.ySums, rangesPerBlockEdge, standardDeviationAdjustment);\n if (numXBlock < 2 && numYBlock < 2)\n return new LinearSearchRange2dArray();\n return GriddedRaggedRange2dSetWithOverflow.create<T>(Range2d.createFrom(rangeLengthData.range), numXBlock, numYBlock);\n }\n /** Return the number of grid bocks (in one direction) for\n * * The total range length in this direction\n * * individual ranges whose count, mean and standard deviation are available in the sums.\n * @param totalRange the total range being searched (in this direction)\n * @param sums source for mean, count, and standard deviation of individual ranges\n * @param rangesPerBlockEdge target ratio of edge length in search blocks divided by representative length of individual range edges\n * @param standardDeviationAdjustment the number of standard deviations above the mean to be applied to convert mean to representative length. Typically 0 to 1.\n * @returns number of blocks in grid.\n */\n public static estimateGridBlockCount(totalLength: number, sums: UsageSums, rangesPerBlockEdge: number = RangeSearch.defaultRangesPerBlockEdge, standardDeviationAdjustment: number = RangeSearch.defaultStandardDeviationAdjustment): number {\n if (sums.count < 1)\n return 1;\n const representativeRangeLength = rangesPerBlockEdge * (sums.mean + standardDeviationAdjustment * sums.standardDeviation);\n const gridEdgeLength = Geometry.conditionalDivideFraction(totalLength, representativeRangeLength);\n if (gridEdgeLength === undefined)\n return 1;\n return Math.ceil(gridEdgeLength);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"RangeSearch.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/RangeSearch.ts"],"names":[],"mappings":"AAAA;;;+FAG+F;AAC/F;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGjD,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAC5F,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAGtE,sEAAsE;AACtE,MAAM,OAAO,WAAW;IACf,MAAM,CAAU,eAAe,GAAG,EAAE,CAAC;IAC5C,sFAAsF;IAC/E,MAAM,CAAU,yBAAyB,GAAG,CAAC,CAAC;IACrD,oGAAoG;IAC7F,MAAM,CAAU,kCAAkC,GAAG,GAAG,CAAC;IAChE,gGAAgG;IACzF,MAAM,CAAC,kCAAkC,CAAI,eAAgC,EAAE,qBAA6B,WAAW,CAAC,yBAAyB,EAAE,8BAAsC,WAAW,CAAC,kCAAkC;QAC5O,gDAAgD;QAChD,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,eAAe;YAC3D,OAAO,IAAI,wBAAwB,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;QACvJ,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;QACvJ,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,CAAC;YAChC,OAAO,IAAI,wBAAwB,EAAE,CAAC;QACxC,OAAO,mCAAmC,CAAC,MAAM,CAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACxH,CAAC;IACD;;;;;;;;OAQG;IACI,MAAM,CAAC,sBAAsB,CAAC,WAAmB,EAAE,IAAe,EAAE,qBAA6B,WAAW,CAAC,yBAAyB,EAAE,8BAAsC,WAAW,CAAC,kCAAkC;QACjO,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,MAAM,yBAAyB,GAAG,kBAAkB,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,2BAA2B,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC1H,MAAM,cAAc,GAAG,QAAQ,CAAC,yBAAyB,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC;QAClG,IAAI,cAAc,KAAK,SAAS;YAC9B,OAAO,CAAC,CAAC;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC","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/** @packageDocumentation\r\n * @module RangeSearch\r\n */\r\n\r\nimport { Geometry } from \"../../Geometry\";\r\nimport { Range2d } from \"../../geometry3d/Range\";\r\nimport { UsageSums } from \"../../numerics/UsageSums\";\r\nimport { RangeLengthData } from \"../RangeLengthData\";\r\nimport { GriddedRaggedRange2dSetWithOverflow } from \"./GriddedRaggedRange2dSetWithOverflow\";\r\nimport { LinearSearchRange2dArray } from \"./LinearSearchRange2dArray\";\r\nimport { Range2dSearchInterface } from \"./Range2dSearchInterface\";\r\n\r\n/** Class with static members to work with various range searchers. */\r\nexport class RangeSearch {\r\n public static readonly smallCountLimit = 40;\r\n /** Target size for grid block size divided by representative per-entry range size. */\r\n public static readonly defaultRangesPerBlockEdge = 4;\r\n /** the \"representative range size\"is the mean range size plus this number of standard deviations */\r\n public static readonly defaultStandardDeviationAdjustment = 1.0;\r\n /** Based on range count and distribution, return an object which can answer 2d range queries */\r\n public static create2dSearcherForRangeLengthData<T>(rangeLengthData: RangeLengthData, rangesPerBlockEdge: number = RangeSearch.defaultRangesPerBlockEdge, standardDeviationAdjustment: number = RangeSearch.defaultStandardDeviationAdjustment): Range2dSearchInterface<T> | undefined {\r\n // for smallish sets, just linear search . . ..\r\n if (rangeLengthData.xSums.count < RangeSearch.smallCountLimit)\r\n return new LinearSearchRange2dArray();\r\n const numXBlock = this.estimateGridBlockCount(rangeLengthData.range.xLength(), rangeLengthData.xSums, rangesPerBlockEdge, standardDeviationAdjustment);\r\n const numYBlock = this.estimateGridBlockCount(rangeLengthData.range.yLength(), rangeLengthData.ySums, rangesPerBlockEdge, standardDeviationAdjustment);\r\n if (numXBlock < 2 && numYBlock < 2)\r\n return new LinearSearchRange2dArray();\r\n return GriddedRaggedRange2dSetWithOverflow.create<T>(Range2d.createFrom(rangeLengthData.range), numXBlock, numYBlock);\r\n }\r\n /** Return the number of grid bocks (in one direction) for\r\n * * The total range length in this direction\r\n * * individual ranges whose count, mean and standard deviation are available in the sums.\r\n * @param totalRange the total range being searched (in this direction)\r\n * @param sums source for mean, count, and standard deviation of individual ranges\r\n * @param rangesPerBlockEdge target ratio of edge length in search blocks divided by representative length of individual range edges\r\n * @param standardDeviationAdjustment the number of standard deviations above the mean to be applied to convert mean to representative length. Typically 0 to 1.\r\n * @returns number of blocks in grid.\r\n */\r\n public static estimateGridBlockCount(totalLength: number, sums: UsageSums, rangesPerBlockEdge: number = RangeSearch.defaultRangesPerBlockEdge, standardDeviationAdjustment: number = RangeSearch.defaultStandardDeviationAdjustment): number {\r\n if (sums.count < 1)\r\n return 1;\r\n const representativeRangeLength = rangesPerBlockEdge * (sums.mean + standardDeviationAdjustment * sums.standardDeviation);\r\n const gridEdgeLength = Geometry.conditionalDivideFraction(totalLength, representativeRangeLength);\r\n if (gridEdgeLength === undefined)\r\n return 1;\r\n return Math.ceil(gridEdgeLength);\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SweepLineStringToFacetContext.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/SweepLineStringToFacetContext.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/** @packageDocumentation\n * @module Polyface\n */\n\nimport { ClipPlane } from \"../../clipping/ClipPlane\";\nimport { ConvexClipPlaneSet } from \"../../clipping/ConvexClipPlaneSet\";\nimport { Geometry } from \"../../Geometry\";\nimport { GrowableXYZArray } from \"../../geometry3d/GrowableXYZArray\";\nimport { IndexedXYZCollection } from \"../../geometry3d/IndexedXYZCollection\";\nimport { Matrix3d } from \"../../geometry3d/Matrix3d\";\nimport { Point3d, Vector3d } from \"../../geometry3d/Point3dVector3d\";\nimport { IndexedXYZCollectionPolygonOps, Point3dArrayPolygonOps } from \"../../geometry3d/PolygonOps\";\nimport { Range3d } from \"../../geometry3d/Range\";\nimport { Segment1d } from \"../../geometry3d/Segment1d\";\nimport { Transform } from \"../../geometry3d/Transform\";\nimport { Polyface } from \"../Polyface\";\nimport { AnnounceDrapePanel } from \"../PolyfaceQuery\";\n\nexport class SweepLineStringToFacetContext {\n private _spacePoints: IndexedXYZCollection;\n private _spacePointsRange: Range3d;\n private _numSpacePoints: number;\n private constructor(spacePoints: IndexedXYZCollection) {\n this._spacePoints = spacePoints;\n this._spacePointsRange = spacePoints.getRange();\n this._numSpacePoints = this._spacePoints.length;\n }\n public static create(xyz: IndexedXYZCollection): SweepLineStringToFacetContext | undefined {\n if (xyz.length > 1) {\n return new SweepLineStringToFacetContext(xyz);\n }\n return undefined;\n }\n\n // temporaries reused over multiple calls to process a single facet . ..\n private _segmentPoint0 = Point3d.create();\n private _segmentPoint1 = Point3d.create();\n private _localSegmentPoint0 = Point3d.create();\n private _localSegmentPoint1 = Point3d.create();\n private _clipFractions = Segment1d.create(0, 1);\n private _localFrame = Transform.createIdentity();\n private _polygonRange = Range3d.create();\n\n /** process a single polygon.\n * @returns number crudely indicating how much work was done.\n */\n public projectToPolygon(polygon: GrowableXYZArray, announce: AnnounceDrapePanel, polyface: Polyface, readIndex: number): number {\n polygon.setRange(this._polygonRange);\n let workCounter = 0;\n if (!this._polygonRange.intersectsRangeXY(this._spacePointsRange))\n return workCounter;\n // numTest++;\n // For each triangle within the facet ...\n // remark: this loop only runs once in triangle mesh, twice in quads ...\n for (let k1 = 1; k1 + 1 < polygon.length; k1++) {\n workCounter++;\n const frame = polygon.fillLocalXYTriangleFrame(0, k1, k1 + 1, this._localFrame);\n if (frame) {\n // For each stroke of the linestring ...\n for (let i1 = 1; i1 < this._numSpacePoints; i1++) {\n workCounter++;\n this._spacePoints.getPoint3dAtCheckedPointIndex(i1 - 1, this._segmentPoint0);\n this._spacePoints.getPoint3dAtCheckedPointIndex(i1, this._segmentPoint1);\n frame.multiplyInversePoint3d(this._segmentPoint0, this._localSegmentPoint0);\n frame.multiplyInversePoint3d(this._segmentPoint1, this._localSegmentPoint1);\n this._clipFractions.set(0, 1);\n /** (x,y,1-x-y) are barycentric coordinates in the triangle !!! */\n if (this._clipFractions.clipBy01FunctionValuesPositive(this._localSegmentPoint0.x, this._localSegmentPoint1.x)\n && this._clipFractions.clipBy01FunctionValuesPositive(this._localSegmentPoint0.y, this._localSegmentPoint1.y)\n && this._clipFractions.clipBy01FunctionValuesPositive(\n 1 - this._localSegmentPoint0.x - this._localSegmentPoint0.y,\n 1 - this._localSegmentPoint1.x - this._localSegmentPoint1.y)) {\n /* project the local segment point to the plane. */\n workCounter++;\n const localClippedPointA = this._localSegmentPoint0.interpolate(this._clipFractions.x0, this._localSegmentPoint1);\n const localClippedPointB = this._localSegmentPoint0.interpolate(this._clipFractions.x1, this._localSegmentPoint1);\n const worldClippedPointA = this._localFrame.multiplyPoint3d(localClippedPointA);\n const worldClippedPointB = this._localFrame.multiplyPoint3d(localClippedPointB);\n const planePointA = this._localFrame.multiplyXYZ(localClippedPointA.x, localClippedPointA.y, 0.0);\n const planePointB = this._localFrame.multiplyXYZ(localClippedPointB.x, localClippedPointB.y, 0.0);\n const splitParameter = Geometry.inverseInterpolate01(this._localSegmentPoint0.z, this._localSegmentPoint1.z);\n // emit 1 or 2 panels, oriented so panel normal is always to the left of the line.\n if (splitParameter !== undefined && splitParameter > this._clipFractions.x0 && splitParameter < this._clipFractions.x1) {\n workCounter++;\n const piercePointX = this._segmentPoint0.interpolate(splitParameter, this._segmentPoint1);\n const piercePointY = piercePointX.clone(); // so points are distinct for the two triangle announcements.\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointA, piercePointX, planePointA], 2, 1);\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointB, piercePointY, planePointB], 1, 2);\n } else if (this._localSegmentPoint0.z > 0) { // segment is entirely above\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointA, worldClippedPointB, planePointB, planePointA], 3, 2);\n } else // segment is entirely under\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointB, worldClippedPointA, planePointA, planePointB], 2, 3);\n }\n }\n }\n }\n return workCounter;\n }\n}\n\n/**\n * Context for sweeping a line segment onto a convex polygon.\n * @internal\n */\nexport class EdgeClipData {\n /** Plane containing the edge and sweep vector */\n public edgePlane: ClipPlane;\n /** Two clip planes facing each other at each end of the edge */\n public clip: ConvexClipPlaneSet;\n /** work array for clipper method */\n private _crossingPoints: Point3d[];\n\n /** CAPTURE the planes */\n public constructor(edgePlane: ClipPlane, clip: ConvexClipPlaneSet) {\n this.edgePlane = edgePlane;\n this.clip = clip;\n this._crossingPoints = [];\n }\n /** create object from segment and sweep. Inputs are not captured. */\n public static createPointPointSweep(pointA: Point3d, pointB: Point3d, sweep: Vector3d): EdgeClipData | undefined {\n const edgeVector = Vector3d.createStartEnd(pointA, pointB);\n const fraction = edgeVector.fractionOfProjectionToVector(sweep);\n // The unbounded plane of the swept edge will intersect facets in lines that may extend beyond the swept bounded line.\n // That linework will be clipped between two facing planes with normal along the perpendicular dropped from the edge vector to the sweep vector.\n const clipNormal = edgeVector.plusScaled(sweep, -fraction);\n const planeA = ClipPlane.createNormalAndPoint(clipNormal, pointA);\n const planeB = ClipPlane.createNormalAndPoint(clipNormal, pointB);\n const edgePlane = ClipPlane.createOriginAndVectors(pointA, edgeVector, sweep);\n if (planeA !== undefined && planeB !== undefined && edgePlane !== undefined) {\n planeB.negateInPlace();\n const clipper = ConvexClipPlaneSet.createPlanes([planeA, planeB]);\n return new EdgeClipData(edgePlane, clipper);\n }\n return undefined;\n }\n\n /** Intersect this edge plane with the given convex polygon and announce the intersection segment to the callback. */\n public processPolygon(polygon: Point3d[] | IndexedXYZCollection, announceEdge: (pointA: Point3d, pointB: Point3d) => void) {\n this._crossingPoints.length = 0;\n if (Array.isArray(polygon))\n Point3dArrayPolygonOps.polygonPlaneCrossings(this.edgePlane, polygon, this._crossingPoints);\n else\n IndexedXYZCollectionPolygonOps.polygonPlaneCrossings(this.edgePlane, polygon, this._crossingPoints);\n if (this._crossingPoints.length === 2) {\n // use the end planes to clip the [0,1] swept edge to [f0,f1]\n this.clip.announceClippedSegmentIntervals(0, 1, this._crossingPoints[0], this._crossingPoints[1],\n (f0: number, f1: number) => {\n announceEdge(this._crossingPoints[0].interpolate(f0, this._crossingPoints[1]),\n this._crossingPoints[0].interpolate(f1, this._crossingPoints[1]));\n },\n );\n }\n }\n}\n/**\n * Context for sweeping a line string onto a convex polygon.\n * @internal\n */\nexport class ClipSweptLineStringContext {\n private _edgeClippers: EdgeClipData[];\n private _localToWorld?: Transform;\n private _worldToLocal?: Transform;\n private _localRange?: Range3d;\n private constructor(edgeData: EdgeClipData[], localData: undefined | { localToWorld: Transform, worldToLocal: Transform, localRange: Range3d }) {\n this._edgeClippers = edgeData;\n if (localData !== undefined) {\n this._localToWorld = localData.localToWorld;\n this._worldToLocal = localData.worldToLocal;\n this._localRange = localData.localRange;\n }\n }\n public static create(xyz: IndexedXYZCollection, sweepVector: Vector3d | undefined): ClipSweptLineStringContext | undefined {\n if (sweepVector === undefined)\n sweepVector = Vector3d.create(0, 0, 1);\n if (xyz.length > 1) {\n const point = Point3d.createZero();\n const newPoint = Point3d.createZero();\n const edgeData: EdgeClipData[] = [];\n xyz.getPoint3dAtUncheckedPointIndex(0, point);\n\n let localToWorldMatrix = Matrix3d.createRigidHeadsUp(sweepVector);\n if (localToWorldMatrix === undefined)\n localToWorldMatrix = Matrix3d.createIdentity();\n const localToWorld = Transform.createOriginAndMatrix(point, localToWorldMatrix);\n const worldToLocal = localToWorld.inverse()!;\n const localRange = xyz.getRange(worldToLocal);\n for (let i = 1; i < xyz.length; i++) {\n xyz.getPoint3dAtUncheckedPointIndex(i, newPoint);\n const clipper = EdgeClipData.createPointPointSweep(point, newPoint, sweepVector);\n if (clipper !== undefined) {\n point.setFrom(newPoint);\n edgeData.push(clipper);\n }\n }\n return new ClipSweptLineStringContext(edgeData, { localToWorld, worldToLocal, localRange });\n }\n return undefined;\n }\n /**\n * Intersect a polygon with each of the edgeClippers.\n * * If transforms and local range are defined, test the polygon's local range to see if it offers a quick exit.\n */\n public processPolygon(polygon: Point3d[], announceEdge: (pointA: Point3d, pointB: Point3d) => void) {\n if (this._worldToLocal !== undefined && this._localRange !== undefined) {\n const polygonRange = Range3d.createTransformedArray(this._worldToLocal, polygon);\n if (!polygonRange.intersectsRangeXY(this._localRange))\n return;\n }\n for (const clipper of this._edgeClippers) {\n clipper.processPolygon(polygon, announceEdge);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SweepLineStringToFacetContext.js","sourceRoot":"","sources":["../../../../src/polyface/multiclip/SweepLineStringToFacetContext.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/** @packageDocumentation\r\n * @module Polyface\r\n */\r\n\r\nimport { ClipPlane } from \"../../clipping/ClipPlane\";\r\nimport { ConvexClipPlaneSet } from \"../../clipping/ConvexClipPlaneSet\";\r\nimport { Geometry } from \"../../Geometry\";\r\nimport { GrowableXYZArray } from \"../../geometry3d/GrowableXYZArray\";\r\nimport { IndexedXYZCollection } from \"../../geometry3d/IndexedXYZCollection\";\r\nimport { Matrix3d } from \"../../geometry3d/Matrix3d\";\r\nimport { Point3d, Vector3d } from \"../../geometry3d/Point3dVector3d\";\r\nimport { IndexedXYZCollectionPolygonOps, Point3dArrayPolygonOps } from \"../../geometry3d/PolygonOps\";\r\nimport { Range3d } from \"../../geometry3d/Range\";\r\nimport { Segment1d } from \"../../geometry3d/Segment1d\";\r\nimport { Transform } from \"../../geometry3d/Transform\";\r\nimport { Polyface } from \"../Polyface\";\r\nimport { AnnounceDrapePanel } from \"../PolyfaceQuery\";\r\n\r\nexport class SweepLineStringToFacetContext {\r\n private _spacePoints: IndexedXYZCollection;\r\n private _spacePointsRange: Range3d;\r\n private _numSpacePoints: number;\r\n private constructor(spacePoints: IndexedXYZCollection) {\r\n this._spacePoints = spacePoints;\r\n this._spacePointsRange = spacePoints.getRange();\r\n this._numSpacePoints = this._spacePoints.length;\r\n }\r\n public static create(xyz: IndexedXYZCollection): SweepLineStringToFacetContext | undefined {\r\n if (xyz.length > 1) {\r\n return new SweepLineStringToFacetContext(xyz);\r\n }\r\n return undefined;\r\n }\r\n\r\n // temporaries reused over multiple calls to process a single facet . ..\r\n private _segmentPoint0 = Point3d.create();\r\n private _segmentPoint1 = Point3d.create();\r\n private _localSegmentPoint0 = Point3d.create();\r\n private _localSegmentPoint1 = Point3d.create();\r\n private _clipFractions = Segment1d.create(0, 1);\r\n private _localFrame = Transform.createIdentity();\r\n private _polygonRange = Range3d.create();\r\n\r\n /** process a single polygon.\r\n * @returns number crudely indicating how much work was done.\r\n */\r\n public projectToPolygon(polygon: GrowableXYZArray, announce: AnnounceDrapePanel, polyface: Polyface, readIndex: number): number {\r\n polygon.setRange(this._polygonRange);\r\n let workCounter = 0;\r\n if (!this._polygonRange.intersectsRangeXY(this._spacePointsRange))\r\n return workCounter;\r\n // numTest++;\r\n // For each triangle within the facet ...\r\n // remark: this loop only runs once in triangle mesh, twice in quads ...\r\n for (let k1 = 1; k1 + 1 < polygon.length; k1++) {\r\n workCounter++;\r\n const frame = polygon.fillLocalXYTriangleFrame(0, k1, k1 + 1, this._localFrame);\r\n if (frame) {\r\n // For each stroke of the linestring ...\r\n for (let i1 = 1; i1 < this._numSpacePoints; i1++) {\r\n workCounter++;\r\n this._spacePoints.getPoint3dAtCheckedPointIndex(i1 - 1, this._segmentPoint0);\r\n this._spacePoints.getPoint3dAtCheckedPointIndex(i1, this._segmentPoint1);\r\n frame.multiplyInversePoint3d(this._segmentPoint0, this._localSegmentPoint0);\r\n frame.multiplyInversePoint3d(this._segmentPoint1, this._localSegmentPoint1);\r\n this._clipFractions.set(0, 1);\r\n /** (x,y,1-x-y) are barycentric coordinates in the triangle !!! */\r\n if (this._clipFractions.clipBy01FunctionValuesPositive(this._localSegmentPoint0.x, this._localSegmentPoint1.x)\r\n && this._clipFractions.clipBy01FunctionValuesPositive(this._localSegmentPoint0.y, this._localSegmentPoint1.y)\r\n && this._clipFractions.clipBy01FunctionValuesPositive(\r\n 1 - this._localSegmentPoint0.x - this._localSegmentPoint0.y,\r\n 1 - this._localSegmentPoint1.x - this._localSegmentPoint1.y)) {\r\n /* project the local segment point to the plane. */\r\n workCounter++;\r\n const localClippedPointA = this._localSegmentPoint0.interpolate(this._clipFractions.x0, this._localSegmentPoint1);\r\n const localClippedPointB = this._localSegmentPoint0.interpolate(this._clipFractions.x1, this._localSegmentPoint1);\r\n const worldClippedPointA = this._localFrame.multiplyPoint3d(localClippedPointA);\r\n const worldClippedPointB = this._localFrame.multiplyPoint3d(localClippedPointB);\r\n const planePointA = this._localFrame.multiplyXYZ(localClippedPointA.x, localClippedPointA.y, 0.0);\r\n const planePointB = this._localFrame.multiplyXYZ(localClippedPointB.x, localClippedPointB.y, 0.0);\r\n const splitParameter = Geometry.inverseInterpolate01(this._localSegmentPoint0.z, this._localSegmentPoint1.z);\r\n // emit 1 or 2 panels, oriented so panel normal is always to the left of the line.\r\n if (splitParameter !== undefined && splitParameter > this._clipFractions.x0 && splitParameter < this._clipFractions.x1) {\r\n workCounter++;\r\n const piercePointX = this._segmentPoint0.interpolate(splitParameter, this._segmentPoint1);\r\n const piercePointY = piercePointX.clone(); // so points are distinct for the two triangle announcements.\r\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointA, piercePointX, planePointA], 2, 1);\r\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointB, piercePointY, planePointB], 1, 2);\r\n } else if (this._localSegmentPoint0.z > 0) { // segment is entirely above\r\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointA, worldClippedPointB, planePointB, planePointA], 3, 2);\r\n } else // segment is entirely under\r\n announce(this._spacePoints, i1 - 1, polyface, readIndex, [worldClippedPointB, worldClippedPointA, planePointA, planePointB], 2, 3);\r\n }\r\n }\r\n }\r\n }\r\n return workCounter;\r\n }\r\n}\r\n\r\n/**\r\n * Context for sweeping a line segment onto a convex polygon.\r\n * @internal\r\n */\r\nexport class EdgeClipData {\r\n /** Plane containing the edge and sweep vector */\r\n public edgePlane: ClipPlane;\r\n /** Two clip planes facing each other at each end of the edge */\r\n public clip: ConvexClipPlaneSet;\r\n /** work array for clipper method */\r\n private _crossingPoints: Point3d[];\r\n\r\n /** CAPTURE the planes */\r\n public constructor(edgePlane: ClipPlane, clip: ConvexClipPlaneSet) {\r\n this.edgePlane = edgePlane;\r\n this.clip = clip;\r\n this._crossingPoints = [];\r\n }\r\n /** create object from segment and sweep. Inputs are not captured. */\r\n public static createPointPointSweep(pointA: Point3d, pointB: Point3d, sweep: Vector3d): EdgeClipData | undefined {\r\n const edgeVector = Vector3d.createStartEnd(pointA, pointB);\r\n const fraction = edgeVector.fractionOfProjectionToVector(sweep);\r\n // The unbounded plane of the swept edge will intersect facets in lines that may extend beyond the swept bounded line.\r\n // That linework will be clipped between two facing planes with normal along the perpendicular dropped from the edge vector to the sweep vector.\r\n const clipNormal = edgeVector.plusScaled(sweep, -fraction);\r\n const planeA = ClipPlane.createNormalAndPoint(clipNormal, pointA);\r\n const planeB = ClipPlane.createNormalAndPoint(clipNormal, pointB);\r\n const edgePlane = ClipPlane.createOriginAndVectors(pointA, edgeVector, sweep);\r\n if (planeA !== undefined && planeB !== undefined && edgePlane !== undefined) {\r\n planeB.negateInPlace();\r\n const clipper = ConvexClipPlaneSet.createPlanes([planeA, planeB]);\r\n return new EdgeClipData(edgePlane, clipper);\r\n }\r\n return undefined;\r\n }\r\n\r\n /** Intersect this edge plane with the given convex polygon and announce the intersection segment to the callback. */\r\n public processPolygon(polygon: Point3d[] | IndexedXYZCollection, announceEdge: (pointA: Point3d, pointB: Point3d) => void) {\r\n this._crossingPoints.length = 0;\r\n if (Array.isArray(polygon))\r\n Point3dArrayPolygonOps.polygonPlaneCrossings(this.edgePlane, polygon, this._crossingPoints);\r\n else\r\n IndexedXYZCollectionPolygonOps.polygonPlaneCrossings(this.edgePlane, polygon, this._crossingPoints);\r\n if (this._crossingPoints.length === 2) {\r\n // use the end planes to clip the [0,1] swept edge to [f0,f1]\r\n this.clip.announceClippedSegmentIntervals(0, 1, this._crossingPoints[0], this._crossingPoints[1],\r\n (f0: number, f1: number) => {\r\n announceEdge(this._crossingPoints[0].interpolate(f0, this._crossingPoints[1]),\r\n this._crossingPoints[0].interpolate(f1, this._crossingPoints[1]));\r\n },\r\n );\r\n }\r\n }\r\n}\r\n/**\r\n * Context for sweeping a line string onto a convex polygon.\r\n * @internal\r\n */\r\nexport class ClipSweptLineStringContext {\r\n private _edgeClippers: EdgeClipData[];\r\n private _localToWorld?: Transform;\r\n private _worldToLocal?: Transform;\r\n private _localRange?: Range3d;\r\n private constructor(edgeData: EdgeClipData[], localData: undefined | { localToWorld: Transform, worldToLocal: Transform, localRange: Range3d }) {\r\n this._edgeClippers = edgeData;\r\n if (localData !== undefined) {\r\n this._localToWorld = localData.localToWorld;\r\n this._worldToLocal = localData.worldToLocal;\r\n this._localRange = localData.localRange;\r\n }\r\n }\r\n public static create(xyz: IndexedXYZCollection, sweepVector: Vector3d | undefined): ClipSweptLineStringContext | undefined {\r\n if (sweepVector === undefined)\r\n sweepVector = Vector3d.create(0, 0, 1);\r\n if (xyz.length > 1) {\r\n const point = Point3d.createZero();\r\n const newPoint = Point3d.createZero();\r\n const edgeData: EdgeClipData[] = [];\r\n xyz.getPoint3dAtUncheckedPointIndex(0, point);\r\n\r\n let localToWorldMatrix = Matrix3d.createRigidHeadsUp(sweepVector);\r\n if (localToWorldMatrix === undefined)\r\n localToWorldMatrix = Matrix3d.createIdentity();\r\n const localToWorld = Transform.createOriginAndMatrix(point, localToWorldMatrix);\r\n const worldToLocal = localToWorld.inverse()!;\r\n const localRange = xyz.getRange(worldToLocal);\r\n for (let i = 1; i < xyz.length; i++) {\r\n xyz.getPoint3dAtUncheckedPointIndex(i, newPoint);\r\n const clipper = EdgeClipData.createPointPointSweep(point, newPoint, sweepVector);\r\n if (clipper !== undefined) {\r\n point.setFrom(newPoint);\r\n edgeData.push(clipper);\r\n }\r\n }\r\n return new ClipSweptLineStringContext(edgeData, { localToWorld, worldToLocal, localRange });\r\n }\r\n return undefined;\r\n }\r\n /**\r\n * Intersect a polygon with each of the edgeClippers.\r\n * * If transforms and local range are defined, test the polygon's local range to see if it offers a quick exit.\r\n */\r\n public processPolygon(polygon: Point3d[], announceEdge: (pointA: Point3d, pointB: Point3d) => void) {\r\n if (this._worldToLocal !== undefined && this._localRange !== undefined) {\r\n const polygonRange = Range3d.createTransformedArray(this._worldToLocal, polygon);\r\n if (!polygonRange.intersectsRangeXY(this._localRange))\r\n return;\r\n }\r\n for (const clipper of this._edgeClippers) {\r\n clipper.processPolygon(polygon, announceEdge);\r\n }\r\n }\r\n}\r\n"]}
|