@kitware/vtk.js 28.10.2 → 28.11.0
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/Common/Core/Base64.js +53 -82
- package/Common/Core/CellArray.js +52 -60
- package/Common/Core/ClassHierarchy.js +8 -36
- package/Common/Core/DataArray/Constants.js +6 -6
- package/Common/Core/DataArray.js +185 -270
- package/Common/Core/Endian.js +14 -17
- package/Common/Core/HalfFloat.js +17 -34
- package/Common/Core/ImageHelper.js +17 -25
- package/Common/Core/LookupTable.js +131 -144
- package/Common/Core/Math/Constants.js +8 -8
- package/Common/Core/Math/index.js +754 -942
- package/Common/Core/Math.js +2 -4
- package/Common/Core/MatrixBuilder.js +99 -151
- package/Common/Core/Points.js +43 -43
- package/Common/Core/PriorityQueue.js +30 -28
- package/Common/Core/ProgressHandler.js +31 -32
- package/Common/Core/ScalarsToColors/Constants.js +4 -4
- package/Common/Core/ScalarsToColors.js +196 -253
- package/Common/Core/StringArray.js +48 -73
- package/Common/Core/URLExtract.js +10 -29
- package/Common/Core/VariantArray.js +48 -73
- package/Common/Core.js +11 -11
- package/Common/DataModel/AbstractPointLocator.js +19 -17
- package/Common/DataModel/BoundingBox.js +322 -490
- package/Common/DataModel/Box.js +46 -63
- package/Common/DataModel/CardinalSpline1D.js +92 -102
- package/Common/DataModel/Cell.js +41 -61
- package/Common/DataModel/CellLinks.js +91 -127
- package/Common/DataModel/CellTypes/Constants.js +7 -6
- package/Common/DataModel/CellTypes.js +55 -74
- package/Common/DataModel/Collection.js +45 -61
- package/Common/DataModel/Cone.js +28 -20
- package/Common/DataModel/Cylinder.js +41 -35
- package/Common/DataModel/DataSet/Constants.js +11 -5
- package/Common/DataModel/DataSet.js +37 -25
- package/Common/DataModel/DataSetAttributes/Constants.js +18 -18
- package/Common/DataModel/DataSetAttributes/FieldData.js +103 -194
- package/Common/DataModel/DataSetAttributes.js +96 -138
- package/Common/DataModel/EdgeLocator.js +45 -70
- package/Common/DataModel/ITKHelper.js +67 -137
- package/Common/DataModel/ImageData.js +115 -172
- package/Common/DataModel/ImplicitBoolean/Constants.js +2 -2
- package/Common/DataModel/ImplicitBoolean.js +66 -96
- package/Common/DataModel/IncrementalOctreeNode.js +201 -231
- package/Common/DataModel/IncrementalOctreePointLocator.js +160 -198
- package/Common/DataModel/KochanekSpline1D.js +78 -81
- package/Common/DataModel/Line/Constants.js +2 -2
- package/Common/DataModel/Line.js +82 -105
- package/Common/DataModel/Locator.js +17 -10
- package/Common/DataModel/Molecule.js +26 -17
- package/Common/DataModel/PiecewiseFunction.js +218 -239
- package/Common/DataModel/Plane.js +90 -113
- package/Common/DataModel/PointSet.js +30 -26
- package/Common/DataModel/PolyData/Constants.js +2 -2
- package/Common/DataModel/PolyData.js +95 -120
- package/Common/DataModel/PolyLine.js +44 -61
- package/Common/DataModel/Polygon/Constants.js +4 -4
- package/Common/DataModel/Polygon.js +128 -169
- package/Common/DataModel/Quad/Constants.js +2 -2
- package/Common/DataModel/Quad.js +61 -100
- package/Common/DataModel/SelectionNode/Constants.js +5 -4
- package/Common/DataModel/SelectionNode.js +25 -21
- package/Common/DataModel/Sphere.js +40 -35
- package/Common/DataModel/Spline1D/Constants.js +3 -2
- package/Common/DataModel/Spline1D.js +34 -18
- package/Common/DataModel/Spline3D/Constants.js +2 -2
- package/Common/DataModel/Spline3D.js +46 -41
- package/Common/DataModel/StructuredData/Constants.js +2 -2
- package/Common/DataModel/StructuredData.js +9 -20
- package/Common/DataModel/Triangle.js +207 -250
- package/Common/DataModel.js +19 -19
- package/Common/System/MobileVR.js +56 -61
- package/Common/System/TimerLog.js +1 -1
- package/Common/System.js +2 -2
- package/Common/Transform/LandmarkTransform/Constants.js +2 -2
- package/Common/Transform/LandmarkTransform.js +133 -117
- package/Common/Transform/Transform.js +42 -57
- package/Common/Transform.js +2 -2
- package/Common/index.js +4 -4
- package/Filters/Core/Cutter.js +134 -146
- package/Filters/Core/PolyDataNormals.js +44 -50
- package/Filters/Core.js +2 -2
- package/Filters/Cornerstone/ImageDataToCornerstoneImage.js +45 -33
- package/Filters/Cornerstone.js +1 -1
- package/Filters/General/AppendPolyData.js +84 -100
- package/Filters/General/Calculator.js +95 -163
- package/Filters/General/ClipClosedSurface/Constants.js +2 -2
- package/Filters/General/ClipClosedSurface.js +341 -416
- package/Filters/General/ClosedPolyLineToSurfaceFilter.js +141 -156
- package/Filters/General/ContourTriangulator/Constants.js +2 -2
- package/Filters/General/ContourTriangulator/helper.js +684 -812
- package/Filters/General/ContourTriangulator.js +92 -89
- package/Filters/General/ImageCropFilter.js +77 -78
- package/Filters/General/ImageDataOutlineFilter.js +42 -36
- package/Filters/General/ImageMarchingCubes/caseTable.js +9 -521
- package/Filters/General/ImageMarchingCubes.js +99 -112
- package/Filters/General/ImageMarchingSquares/caseTable.js +9 -41
- package/Filters/General/ImageMarchingSquares.js +93 -118
- package/Filters/General/ImageOutlineFilter.js +53 -54
- package/Filters/General/ImageSliceFilter.js +39 -30
- package/Filters/General/ImageStreamline.js +107 -124
- package/Filters/General/LineFilter.js +26 -15
- package/Filters/General/MoleculeToRepresentation.js +136 -149
- package/Filters/General/OBBTree/OBBNode.js +36 -34
- package/Filters/General/OBBTree/helper.js +19 -24
- package/Filters/General/OBBTree.js +396 -488
- package/Filters/General/OutlineFilter.js +52 -34
- package/Filters/General/PaintFilter/PaintFilter.worker.js +93 -130
- package/Filters/General/PaintFilter.js +150 -162
- package/Filters/General/ScalarToRGBA.js +38 -33
- package/Filters/General/TriangleFilter.js +65 -62
- package/Filters/General/TubeFilter/Constants.js +4 -4
- package/Filters/General/TubeFilter.js +376 -496
- package/Filters/General/WarpScalar.js +58 -60
- package/Filters/General/WindowedSincPolyDataFilter.js +258 -330
- package/Filters/General.js +21 -21
- package/Filters/Sources/Arrow2DSource/Constants.js +2 -2
- package/Filters/Sources/Arrow2DSource.js +56 -56
- package/Filters/Sources/ArrowSource.js +39 -29
- package/Filters/Sources/CircleSource.js +43 -43
- package/Filters/Sources/ConcentricCylinderSource.js +151 -174
- package/Filters/Sources/ConeSource.js +51 -42
- package/Filters/Sources/CubeSource.js +75 -96
- package/Filters/Sources/Cursor3D.js +94 -109
- package/Filters/Sources/CylinderSource.js +90 -90
- package/Filters/Sources/ImageGridSource.js +43 -43
- package/Filters/Sources/LineSource.js +49 -39
- package/Filters/Sources/PlaneSource.js +97 -104
- package/Filters/Sources/PointSource.js +46 -37
- package/Filters/Sources/RTAnalyticSource.js +50 -48
- package/Filters/Sources/SLICSource.js +63 -73
- package/Filters/Sources/SphereSource.js +88 -78
- package/Filters/Sources/ViewFinderSource.js +26 -23
- package/Filters/Sources.js +14 -14
- package/Filters/Texture/TextureMapToPlane.js +95 -97
- package/Filters/Texture/TextureMapToSphere.js +46 -54
- package/Filters/Texture.js +2 -2
- package/Filters/index.js +5 -5
- package/IO/Core/BinaryHelper.js +12 -18
- package/IO/Core/DataAccessHelper/HtmlDataAccessHelper.js +43 -59
- package/IO/Core/DataAccessHelper/HttpDataAccessHelper.js +76 -113
- package/IO/Core/DataAccessHelper/JSZipDataAccessHelper.js +62 -112
- package/IO/Core/DataAccessHelper/LiteHttpDataAccessHelper.js +76 -113
- package/IO/Core/DataAccessHelper.js +6 -6
- package/IO/Core/HttpDataSetReader.js +136 -139
- package/IO/Core/HttpDataSetSeriesReader.js +64 -75
- package/IO/Core/HttpSceneLoader.js +130 -179
- package/IO/Core/ImageStream/DefaultProtocol.js +29 -43
- package/IO/Core/ImageStream/ViewStream.js +100 -103
- package/IO/Core/ImageStream.js +62 -54
- package/IO/Core/ResourceLoader.js +10 -9
- package/IO/Core/Serializer/ArraySerializer.js +40 -40
- package/IO/Core/Serializer/FieldDataSerializer.js +18 -28
- package/IO/Core/Serializer/ImageDataSerializer.js +22 -23
- package/IO/Core/Serializer/PolyDataSerializer.js +17 -21
- package/IO/Core/Serializer.js +6 -13
- package/IO/Core/WSLinkClient.js +90 -76
- package/IO/Core/ZipMultiDataSetReader.js +46 -44
- package/IO/Core/ZipMultiDataSetWriter.js +43 -34
- package/IO/Core.js +7 -7
- package/IO/Geometry/DracoReader.js +118 -121
- package/IO/Geometry/PLYReader.js +163 -223
- package/IO/Geometry/PLYWriter/Constants.js +5 -5
- package/IO/Geometry/PLYWriter.js +139 -154
- package/IO/Geometry/STLReader.js +123 -146
- package/IO/Geometry/STLWriter/Constants.js +2 -2
- package/IO/Geometry/STLWriter.js +83 -82
- package/IO/Geometry.js +5 -5
- package/IO/Legacy/LegacyAsciiParser.js +78 -139
- package/IO/Legacy/PolyDataReader.js +48 -36
- package/IO/Legacy.js +2 -2
- package/IO/Misc/ElevationReader.js +67 -60
- package/IO/Misc/HttpDataSetLODsLoader.js +41 -38
- package/IO/Misc/ITKImageReader.js +58 -45
- package/IO/Misc/ITKPolyDataReader.js +50 -38
- package/IO/Misc/JSONNucleoReader.js +49 -42
- package/IO/Misc/JSONReader.js +38 -33
- package/IO/Misc/MTLReader.js +74 -119
- package/IO/Misc/OBJReader.js +153 -206
- package/IO/Misc/PDBReader.js +70 -68
- package/IO/Misc/SkyboxReader.js +77 -82
- package/IO/Misc.js +9 -9
- package/IO/XML/XMLImageDataReader.js +36 -38
- package/IO/XML/XMLImageDataWriter.js +28 -21
- package/IO/XML/XMLPolyDataReader.js +49 -46
- package/IO/XML/XMLPolyDataWriter.js +43 -42
- package/IO/XML/XMLReader.js +262 -304
- package/IO/XML/XMLWriter/Constants.js +3 -3
- package/IO/XML/XMLWriter.js +70 -84
- package/IO/XML.js +6 -6
- package/IO/index.js +5 -5
- package/Imaging/Core/AbstractImageInterpolator/Constants.js +4 -4
- package/Imaging/Core/AbstractImageInterpolator/InterpolationInfo.js +30 -27
- package/Imaging/Core/AbstractImageInterpolator.js +74 -87
- package/Imaging/Core/ImageInterpolator.js +201 -252
- package/Imaging/Core/ImagePointDataIterator.js +96 -122
- package/Imaging/Core/ImageReslice/Constants.js +2 -2
- package/Imaging/Core/ImageReslice.js +327 -464
- package/Imaging/Core.js +4 -4
- package/Imaging/Hybrid/SampleFunction.js +58 -51
- package/Imaging/Hybrid.js +1 -1
- package/Imaging/index.js +2 -2
- package/Interaction/Animations/TimeStepBasedAnimationHandler.js +39 -54
- package/Interaction/Manipulators/CompositeCameraManipulator.js +22 -13
- package/Interaction/Manipulators/CompositeGestureManipulator.js +31 -43
- package/Interaction/Manipulators/CompositeKeyboardManipulator.js +15 -11
- package/Interaction/Manipulators/CompositeMouseManipulator.js +27 -33
- package/Interaction/Manipulators/CompositeVRManipulator.js +22 -15
- package/Interaction/Manipulators/GestureCameraManipulator.js +54 -36
- package/Interaction/Manipulators/KeyboardCameraManipulator.js +95 -97
- package/Interaction/Manipulators/MouseBoxSelectorManipulator.js +70 -89
- package/Interaction/Manipulators/MouseCameraAxisRotateManipulator.js +67 -54
- package/Interaction/Manipulators/MouseCameraSliceManipulator.js +40 -38
- package/Interaction/Manipulators/MouseCameraTrackballFirstPersonManipulator.js +83 -68
- package/Interaction/Manipulators/MouseCameraTrackballMultiRotateManipulator.js +32 -28
- package/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js +47 -40
- package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +55 -43
- package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +56 -46
- package/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.js +41 -46
- package/Interaction/Manipulators/MouseCameraTrackballZoomToMouseManipulator.js +29 -27
- package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +123 -146
- package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +144 -166
- package/Interaction/Manipulators/MouseRangeManipulator.js +127 -132
- package/Interaction/Manipulators/VRButtonPanManipulator.js +33 -23
- package/Interaction/Manipulators.js +21 -21
- package/Interaction/Misc/DeviceOrientationToCamera.js +25 -47
- package/Interaction/Misc.js +1 -1
- package/Interaction/Style/InteractorStyleImage.js +101 -121
- package/Interaction/Style/InteractorStyleMPRSlice.js +111 -128
- package/Interaction/Style/InteractorStyleManipulator/Presets.js +9 -17
- package/Interaction/Style/InteractorStyleManipulator.js +254 -329
- package/Interaction/Style/InteractorStyleRemoteMouse.js +195 -180
- package/Interaction/Style/InteractorStyleTrackballCamera.js +154 -157
- package/Interaction/Style/InteractorStyleUnicam.js +30 -38
- package/Interaction/Style.js +5 -5
- package/Interaction/UI/CornerAnnotation/CornerAnnotation.module.css.js +1 -1
- package/Interaction/UI/CornerAnnotation.js +65 -48
- package/Interaction/UI/FPSMonitor.js +104 -105
- package/Interaction/UI/Icons.js +1 -1
- package/Interaction/UI/Slider/Constants.js +2 -2
- package/Interaction/UI/Slider.js +78 -95
- package/Interaction/UI/VolumeController.js +104 -97
- package/Interaction/UI.js +5 -5
- package/Interaction/Widgets/OrientationMarkerWidget/Constants.js +2 -2
- package/Interaction/Widgets/OrientationMarkerWidget.js +90 -135
- package/Interaction/Widgets/PiecewiseGaussianWidget/ComputeHistogram.worker.js +0 -3
- package/Interaction/Widgets/PiecewiseGaussianWidget.js +381 -498
- package/Interaction/Widgets.js +2 -2
- package/Interaction/index.js +5 -5
- package/Proxy/Animation/AbstractAnimationProxy.js +22 -15
- package/Proxy/Animation/AnimationProxyManager.js +43 -51
- package/Proxy/Animation/TimeStepBasedAnimationHandlerProxy.js +26 -19
- package/Proxy/Core/AbstractRepresentationProxy.js +97 -151
- package/Proxy/Core/LookupTableProxy/Constants.js +4 -4
- package/Proxy/Core/LookupTableProxy.js +49 -52
- package/Proxy/Core/PiecewiseFunctionProxy/Constants.js +4 -4
- package/Proxy/Core/PiecewiseFunctionProxy.js +63 -72
- package/Proxy/Core/ProxyManager/core.js +83 -106
- package/Proxy/Core/ProxyManager/properties.js +53 -76
- package/Proxy/Core/ProxyManager/state.js +100 -110
- package/Proxy/Core/ProxyManager/view.js +45 -55
- package/Proxy/Core/ProxyManager.js +16 -8
- package/Proxy/Core/SourceProxy.js +41 -38
- package/Proxy/Core/View2DProxy.js +143 -199
- package/Proxy/Core/ViewProxy.js +223 -269
- package/Proxy/Core.js +7 -7
- package/Proxy/Representations/GeometryRepresentationProxy.js +34 -20
- package/Proxy/Representations/GlyphRepresentationProxy.js +42 -41
- package/Proxy/Representations/MoleculeRepresentationProxy.js +32 -22
- package/Proxy/Representations/ResliceRepresentationProxy.js +48 -32
- package/Proxy/Representations/SkyboxRepresentationProxy.js +30 -29
- package/Proxy/Representations/SliceRepresentationProxy.js +93 -112
- package/Proxy/Representations/SlicedGeometryRepresentationProxy.js +46 -42
- package/Proxy/Representations/VolumeRepresentationProxy.js +108 -133
- package/Proxy/Representations.js +7 -7
- package/Proxy/index.js +2 -2
- package/Rendering/Core/AbstractImageMapper/helper.js +44 -49
- package/Rendering/Core/AbstractImageMapper.js +18 -19
- package/Rendering/Core/AbstractMapper.js +39 -55
- package/Rendering/Core/AbstractMapper3D.js +26 -31
- package/Rendering/Core/AbstractPicker.js +25 -21
- package/Rendering/Core/Actor.js +71 -93
- package/Rendering/Core/Actor2D.js +64 -78
- package/Rendering/Core/AnnotatedCubeActor/Presets.js +5 -11
- package/Rendering/Core/AnnotatedCubeActor.js +94 -79
- package/Rendering/Core/AxesActor.js +65 -87
- package/Rendering/Core/Camera.js +246 -271
- package/Rendering/Core/CellPicker.js +125 -148
- package/Rendering/Core/ColorTransferFunction/ColorMaps.js +20 -21
- package/Rendering/Core/ColorTransferFunction/ColorMapsLite.js +20 -21
- package/Rendering/Core/ColorTransferFunction/Constants.js +4 -4
- package/Rendering/Core/ColorTransferFunction.js +460 -546
- package/Rendering/Core/Coordinate/Constants.js +2 -2
- package/Rendering/Core/Coordinate.js +119 -198
- package/Rendering/Core/CubeAxesActor.js +294 -320
- package/Rendering/Core/Follower.js +46 -45
- package/Rendering/Core/Glyph3DMapper/Constants.js +4 -4
- package/Rendering/Core/Glyph3DMapper.js +96 -148
- package/Rendering/Core/HardwareSelector.js +36 -69
- package/Rendering/Core/ImageArrayMapper.js +87 -126
- package/Rendering/Core/ImageCPRMapper.js +134 -209
- package/Rendering/Core/ImageMapper/Constants.js +2 -2
- package/Rendering/Core/ImageMapper.js +85 -144
- package/Rendering/Core/ImageProperty/Constants.js +2 -2
- package/Rendering/Core/ImageProperty.js +66 -81
- package/Rendering/Core/ImageResliceMapper/Constants.js +2 -2
- package/Rendering/Core/ImageResliceMapper.js +36 -29
- package/Rendering/Core/ImageSlice.js +85 -127
- package/Rendering/Core/InteractorObserver.js +82 -73
- package/Rendering/Core/InteractorStyle/Constants.js +2 -2
- package/Rendering/Core/InteractorStyle.js +56 -58
- package/Rendering/Core/Light.js +43 -49
- package/Rendering/Core/Mapper/CoincidentTopologyHelper.js +37 -48
- package/Rendering/Core/Mapper/Constants.js +6 -6
- package/Rendering/Core/Mapper/Static.js +15 -12
- package/Rendering/Core/Mapper.js +194 -259
- package/Rendering/Core/Mapper2D.js +61 -100
- package/Rendering/Core/Picker.js +124 -143
- package/Rendering/Core/PixelSpaceCallbackMapper.js +40 -37
- package/Rendering/Core/PointPicker.js +68 -79
- package/Rendering/Core/Prop/Constants.js +2 -2
- package/Rendering/Core/Prop.js +58 -106
- package/Rendering/Core/Prop3D.js +54 -83
- package/Rendering/Core/Property/Constants.js +6 -6
- package/Rendering/Core/Property.js +45 -74
- package/Rendering/Core/Property2D/Constants.js +2 -2
- package/Rendering/Core/Property2D.js +33 -42
- package/Rendering/Core/RenderWindow.js +70 -82
- package/Rendering/Core/RenderWindowInteractor/Constants.js +7 -7
- package/Rendering/Core/RenderWindowInteractor.js +324 -439
- package/Rendering/Core/Renderer.js +192 -256
- package/Rendering/Core/ScalarBarActor.js +267 -272
- package/Rendering/Core/Skybox.js +26 -24
- package/Rendering/Core/SphereMapper.js +22 -12
- package/Rendering/Core/StickMapper.js +22 -12
- package/Rendering/Core/SurfaceLICInterface/Constants.js +6 -6
- package/Rendering/Core/SurfaceLICInterface.js +13 -9
- package/Rendering/Core/SurfaceLICMapper.js +23 -15
- package/Rendering/Core/Texture.js +99 -141
- package/Rendering/Core/Viewport.js +60 -88
- package/Rendering/Core/Volume.js +55 -77
- package/Rendering/Core/VolumeMapper/Constants.js +4 -4
- package/Rendering/Core/VolumeMapper.js +59 -91
- package/Rendering/Core/VolumeProperty/Constants.js +4 -4
- package/Rendering/Core/VolumeProperty.js +78 -115
- package/Rendering/Core.js +47 -49
- package/Rendering/Misc/CanvasView.js +62 -61
- package/Rendering/Misc/FullScreenRenderWindow.js +60 -62
- package/Rendering/Misc/GenericRenderWindow.js +48 -37
- package/Rendering/Misc/RemoteView.js +86 -80
- package/Rendering/Misc/RenderWindowWithControlBar.js +54 -48
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager/CameraSynchronizer.js +43 -51
- package/Rendering/Misc/SynchronizableRenderWindow/BehaviorManager.js +52 -82
- package/Rendering/Misc/SynchronizableRenderWindow/ObjectManager.js +258 -308
- package/Rendering/Misc/SynchronizableRenderWindow.js +133 -163
- package/Rendering/Misc/TextureLODsDownloader.js +72 -74
- package/Rendering/Misc.js +7 -7
- package/Rendering/OpenGL/Actor.js +57 -68
- package/Rendering/OpenGL/Actor2D.js +56 -56
- package/Rendering/OpenGL/BufferObject/Constants.js +2 -2
- package/Rendering/OpenGL/BufferObject.js +50 -65
- package/Rendering/OpenGL/Camera.js +35 -29
- package/Rendering/OpenGL/CellArrayBufferObject.js +119 -149
- package/Rendering/OpenGL/Convolution2DPass.js +87 -81
- package/Rendering/OpenGL/CubeAxesActor.js +28 -21
- package/Rendering/OpenGL/ForwardPass.js +53 -64
- package/Rendering/OpenGL/Framebuffer.js +61 -101
- package/Rendering/OpenGL/Glyph3DMapper.js +165 -196
- package/Rendering/OpenGL/HardwareSelector/Constants.js +2 -2
- package/Rendering/OpenGL/HardwareSelector.js +272 -397
- package/Rendering/OpenGL/Helper.js +58 -73
- package/Rendering/OpenGL/ImageCPRMapper.js +339 -421
- package/Rendering/OpenGL/ImageMapper.js +268 -361
- package/Rendering/OpenGL/ImageResliceMapper.js +306 -438
- package/Rendering/OpenGL/ImageSlice.js +48 -54
- package/Rendering/OpenGL/OrderIndependentTranslucentPass.js +102 -84
- package/Rendering/OpenGL/PixelSpaceCallbackMapper.js +43 -42
- package/Rendering/OpenGL/PolyDataMapper.js +358 -492
- package/Rendering/OpenGL/PolyDataMapper2D.js +153 -205
- package/Rendering/OpenGL/RadialDistortionPass.js +86 -89
- package/Rendering/OpenGL/RenderWindow/Constants.js +2 -2
- package/Rendering/OpenGL/RenderWindow/ContextProxy.js +20 -29
- package/Rendering/OpenGL/RenderWindow.js +356 -510
- package/Rendering/OpenGL/Renderer.js +77 -89
- package/Rendering/OpenGL/ReplacementShaderMapper.js +28 -46
- package/Rendering/OpenGL/ScalarBarActor.js +28 -21
- package/Rendering/OpenGL/Shader.js +37 -31
- package/Rendering/OpenGL/ShaderCache.js +67 -74
- package/Rendering/OpenGL/ShaderProgram.js +136 -248
- package/Rendering/OpenGL/Skybox.js +99 -60
- package/Rendering/OpenGL/SphereMapper.js +94 -108
- package/Rendering/OpenGL/StickMapper.js +110 -114
- package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D/pingpong.js +91 -157
- package/Rendering/OpenGL/SurfaceLIC/LineIntegralConvolution2D.js +142 -151
- package/Rendering/OpenGL/SurfaceLIC/SurfaceLICInterface.js +142 -216
- package/Rendering/OpenGL/SurfaceLIC/SurfaceLICMapper.js +79 -100
- package/Rendering/OpenGL/SurfaceLIC.js +2 -2
- package/Rendering/OpenGL/Texture/Constants.js +4 -4
- package/Rendering/OpenGL/Texture.js +443 -608
- package/Rendering/OpenGL/TextureUnitManager.js +47 -43
- package/Rendering/OpenGL/VertexArrayObject.js +92 -131
- package/Rendering/OpenGL/ViewNodeFactory.js +25 -13
- package/Rendering/OpenGL/Volume.js +38 -34
- package/Rendering/OpenGL/VolumeMapper.js +437 -547
- package/Rendering/OpenGL.js +28 -28
- package/Rendering/SceneGraph/RenderPass.js +34 -31
- package/Rendering/SceneGraph/RenderWindowViewNode.js +68 -94
- package/Rendering/SceneGraph/ViewNode.js +82 -111
- package/Rendering/SceneGraph/ViewNodeFactory.js +31 -26
- package/Rendering/SceneGraph.js +4 -4
- package/Rendering/WebGPU/Actor.js +49 -49
- package/Rendering/WebGPU/Actor2D.js +45 -44
- package/Rendering/WebGPU/BindGroup.js +43 -50
- package/Rendering/WebGPU/Buffer.js +41 -50
- package/Rendering/WebGPU/BufferManager/Constants.js +4 -4
- package/Rendering/WebGPU/BufferManager.js +111 -141
- package/Rendering/WebGPU/Camera.js +65 -67
- package/Rendering/WebGPU/CellArrayMapper.js +621 -388
- package/Rendering/WebGPU/CubeAxesActor.js +28 -19
- package/Rendering/WebGPU/Device.js +78 -133
- package/Rendering/WebGPU/ForwardPass.js +75 -72
- package/Rendering/WebGPU/FullScreenQuad.js +25 -18
- package/Rendering/WebGPU/Glyph3DMapper.js +62 -74
- package/Rendering/WebGPU/HardwareSelectionPass.js +45 -38
- package/Rendering/WebGPU/HardwareSelector.js +200 -276
- package/Rendering/WebGPU/ImageMapper.js +180 -171
- package/Rendering/WebGPU/ImageSlice.js +45 -44
- package/Rendering/WebGPU/IndexBuffer.js +166 -200
- package/Rendering/WebGPU/OpaquePass.js +37 -36
- package/Rendering/WebGPU/OrderIndependentTranslucentPass.js +72 -45
- package/Rendering/WebGPU/Pipeline.js +37 -51
- package/Rendering/WebGPU/PixelSpaceCallbackMapper.js +27 -19
- package/Rendering/WebGPU/PolyDataMapper.js +50 -53
- package/Rendering/WebGPU/PolyDataMapper2D.js +39 -39
- package/Rendering/WebGPU/RenderEncoder.js +68 -88
- package/Rendering/WebGPU/RenderWindow.js +262 -376
- package/Rendering/WebGPU/Renderer.js +224 -208
- package/Rendering/WebGPU/Sampler.js +27 -21
- package/Rendering/WebGPU/ScalarBarActor.js +28 -19
- package/Rendering/WebGPU/ShaderCache.js +43 -41
- package/Rendering/WebGPU/ShaderDescription.js +52 -59
- package/Rendering/WebGPU/ShaderModule.js +26 -17
- package/Rendering/WebGPU/SimpleMapper.js +185 -121
- package/Rendering/WebGPU/SphereMapper.js +200 -130
- package/Rendering/WebGPU/StickMapper.js +289 -152
- package/Rendering/WebGPU/StorageBuffer.js +100 -115
- package/Rendering/WebGPU/Texture.js +79 -99
- package/Rendering/WebGPU/TextureManager.js +52 -54
- package/Rendering/WebGPU/TextureView.js +40 -43
- package/Rendering/WebGPU/Types.js +53 -70
- package/Rendering/WebGPU/UniformBuffer.js +158 -184
- package/Rendering/WebGPU/VertexInput.js +64 -90
- package/Rendering/WebGPU/ViewNodeFactory.js +25 -13
- package/Rendering/WebGPU/Volume.js +52 -51
- package/Rendering/WebGPU/VolumePass.js +218 -239
- package/Rendering/WebGPU/VolumePassFSQ.js +625 -306
- package/Rendering/WebGPU.js +1 -1
- package/Rendering/index.js +5 -5
- package/Widgets/Core/AbstractWidget/Constants.js +2 -2
- package/Widgets/Core/AbstractWidget.js +49 -58
- package/Widgets/Core/AbstractWidgetFactory.js +101 -122
- package/Widgets/Core/StateBuilder/boundsMixin.js +23 -28
- package/Widgets/Core/StateBuilder/color3Mixin.js +10 -7
- package/Widgets/Core/StateBuilder/colorMixin.js +10 -6
- package/Widgets/Core/StateBuilder/cornerMixin.js +16 -15
- package/Widgets/Core/StateBuilder/directionMixin.js +20 -18
- package/Widgets/Core/StateBuilder/manipulatorMixin.js +26 -18
- package/Widgets/Core/StateBuilder/nameMixin.js +10 -6
- package/Widgets/Core/StateBuilder/orientationMixin.js +19 -16
- package/Widgets/Core/StateBuilder/originMixin.js +25 -32
- package/Widgets/Core/StateBuilder/scale1Mixin.js +10 -6
- package/Widgets/Core/StateBuilder/scale3Mixin.js +10 -6
- package/Widgets/Core/StateBuilder/shapeMixin.js +12 -6
- package/Widgets/Core/StateBuilder/textMixin.js +10 -6
- package/Widgets/Core/StateBuilder/visibleMixin.js +10 -6
- package/Widgets/Core/StateBuilder.js +120 -149
- package/Widgets/Core/WidgetManager/Constants.js +7 -7
- package/Widgets/Core/WidgetManager.js +249 -421
- package/Widgets/Core/WidgetState.js +48 -57
- package/Widgets/Core.js +5 -5
- package/Widgets/Manipulators/AbstractManipulator.js +20 -14
- package/Widgets/Manipulators/CPRManipulator.js +55 -71
- package/Widgets/Manipulators/LineManipulator.js +31 -28
- package/Widgets/Manipulators/PickerManipulator.d.ts +48 -0
- package/Widgets/Manipulators/PickerManipulator.js +65 -0
- package/Widgets/Manipulators/PlaneManipulator.js +26 -23
- package/Widgets/Manipulators/TrackballManipulator.js +39 -35
- package/Widgets/Manipulators.js +4 -2
- package/Widgets/Representations/ArrowHandleRepresentation.js +148 -162
- package/Widgets/Representations/CircleContextRepresentation.js +44 -38
- package/Widgets/Representations/ContextRepresentation.js +17 -14
- package/Widgets/Representations/ConvexFaceContextRepresentation.js +50 -47
- package/Widgets/Representations/CroppingOutlineRepresentation.js +38 -27
- package/Widgets/Representations/CubeHandleRepresentation.js +21 -18
- package/Widgets/Representations/GlyphRepresentation.js +107 -152
- package/Widgets/Representations/HandleRepresentation.js +17 -14
- package/Widgets/Representations/ImplicitPlaneRepresentation.js +97 -91
- package/Widgets/Representations/LineHandleRepresentation.js +44 -41
- package/Widgets/Representations/OutlineContextRepresentation.js +42 -36
- package/Widgets/Representations/PolyLineRepresentation.js +60 -75
- package/Widgets/Representations/RectangleContextRepresentation.js +42 -37
- package/Widgets/Representations/SphereContextRepresentation.js +19 -27
- package/Widgets/Representations/SphereHandleRepresentation.js +31 -27
- package/Widgets/Representations/SplineContextRepresentation.js +46 -70
- package/Widgets/Representations/WidgetRepresentation/Constants.js +2 -2
- package/Widgets/Representations/WidgetRepresentation.js +99 -134
- package/Widgets/Representations.js +13 -13
- package/Widgets/Widgets3D/AngleWidget/behavior.js +41 -63
- package/Widgets/Widgets3D/AngleWidget.js +40 -38
- package/Widgets/Widgets3D/DistanceWidget/behavior.js +40 -61
- package/Widgets/Widgets3D/DistanceWidget.js +38 -36
- package/Widgets/Widgets3D/EllipseWidget/behavior.js +14 -19
- package/Widgets/Widgets3D/EllipseWidget/state.js +4 -2
- package/Widgets/Widgets3D/EllipseWidget.js +37 -26
- package/Widgets/Widgets3D/ImageCroppingWidget/behavior.js +26 -56
- package/Widgets/Widgets3D/ImageCroppingWidget/helpers.js +14 -17
- package/Widgets/Widgets3D/ImageCroppingWidget/state.js +20 -16
- package/Widgets/Widgets3D/ImageCroppingWidget.js +80 -98
- package/Widgets/Widgets3D/ImplicitPlaneWidget.js +55 -77
- package/Widgets/Widgets3D/InteractiveOrientationWidget/behavior.js +17 -18
- package/Widgets/Widgets3D/InteractiveOrientationWidget/state.js +15 -7
- package/Widgets/Widgets3D/InteractiveOrientationWidget.js +30 -29
- package/Widgets/Widgets3D/LabelWidget/behavior.js +37 -62
- package/Widgets/Widgets3D/LabelWidget.js +31 -25
- package/Widgets/Widgets3D/LineWidget/Constants.js +8 -8
- package/Widgets/Widgets3D/LineWidget/behavior.js +77 -114
- package/Widgets/Widgets3D/LineWidget/helpers.js +13 -20
- package/Widgets/Widgets3D/LineWidget/state.js +2 -1
- package/Widgets/Widgets3D/LineWidget.js +39 -35
- package/Widgets/Widgets3D/PaintWidget/behavior.js +24 -59
- package/Widgets/Widgets3D/PaintWidget.js +39 -37
- package/Widgets/Widgets3D/PolyLineWidget/behavior.js +44 -68
- package/Widgets/Widgets3D/PolyLineWidget.js +36 -31
- package/Widgets/Widgets3D/RectangleWidget/behavior.js +6 -11
- package/Widgets/Widgets3D/RectangleWidget/state.js +4 -2
- package/Widgets/Widgets3D/RectangleWidget.js +37 -25
- package/Widgets/Widgets3D/ResliceCursorWidget/Constants.js +35 -21
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +133 -209
- package/Widgets/Widgets3D/ResliceCursorWidget/cprBehavior.js +26 -41
- package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +89 -116
- package/Widgets/Widgets3D/ResliceCursorWidget/state.js +33 -40
- package/Widgets/Widgets3D/ResliceCursorWidget.js +186 -227
- package/Widgets/Widgets3D/SeedWidget/behavior.js +82 -0
- package/Widgets/Widgets3D/SeedWidget/state.js +18 -0
- package/Widgets/Widgets3D/SeedWidget.d.ts +44 -0
- package/Widgets/Widgets3D/SeedWidget.js +43 -0
- package/Widgets/Widgets3D/ShapeWidget/Constants.js +19 -19
- package/Widgets/Widgets3D/ShapeWidget/behavior.js +150 -252
- package/Widgets/Widgets3D/ShapeWidget.js +24 -27
- package/Widgets/Widgets3D/SphereWidget/behavior.js +35 -69
- package/Widgets/Widgets3D/SphereWidget/state.js +9 -5
- package/Widgets/Widgets3D/SphereWidget.js +34 -44
- package/Widgets/Widgets3D/SplineWidget/behavior.js +85 -120
- package/Widgets/Widgets3D/SplineWidget.js +43 -39
- package/Widgets/Widgets3D.js +15 -15
- package/Widgets/index.js +4 -4
- package/_virtual/rollup-plugin-worker-loader__module_Sources/Filters/General/PaintFilter/PaintFilter.worker.js +95 -207
- package/_virtual/rollup-plugin-worker-loader__module_Sources/Interaction/Widgets/PiecewiseGaussianWidget/ComputeHistogram.worker.js +0 -3
- package/favicon.js +5 -6
- package/index.d.ts +4 -2
- package/index.js +4 -3
- package/macros.js +4 -1931
- package/macros2.js +1684 -0
- package/package.json +6 -6
- package/vtk.js +18 -31
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import macro from '../../../macros.js';
|
|
1
|
+
import { m as macro } from '../../../macros2.js';
|
|
3
2
|
import vtkPoints from '../../../Common/Core/Points.js';
|
|
4
3
|
import { s as subtract, j as cross, d as dot, n as norm, e as distance2BetweenPoints, k as add, l as normalize } from '../../../Common/Core/Math/index.js';
|
|
5
4
|
import vtkLine from '../../../Common/DataModel/Line.js';
|
|
@@ -9,7 +8,10 @@ import { VtkDataTypes } from '../../../Common/Core/DataArray/Constants.js';
|
|
|
9
8
|
import { CCS_POLYGON_TOLERANCE } from './Constants.js';
|
|
10
9
|
import { PolygonWithPointIntersectionState } from '../../../Common/DataModel/Polygon/Constants.js';
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
const {
|
|
12
|
+
vtkErrorMacro
|
|
13
|
+
} = macro;
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* Reverse the elements between the indices firstIdx and lastIdx of the given array arr.
|
|
15
17
|
*
|
|
@@ -17,21 +19,18 @@ var vtkErrorMacro = macro.vtkErrorMacro;
|
|
|
17
19
|
* @param {Number} firstIdx
|
|
18
20
|
* @param {Number} lastIdx
|
|
19
21
|
*/
|
|
20
|
-
|
|
21
22
|
function reverseElements(arr) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var _ref = [arr[last - (i - first)], arr[i]];
|
|
30
|
-
arr[i] = _ref[0];
|
|
31
|
-
arr[last - (i - first)] = _ref[1];
|
|
23
|
+
let firstIdx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
|
|
24
|
+
let lastIdx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
|
|
25
|
+
const first = firstIdx ?? 0;
|
|
26
|
+
const last = lastIdx ?? arr.length - 1;
|
|
27
|
+
const mid = first + Math.floor((last - first) / 2);
|
|
28
|
+
for (let i = first; i <= mid; ++i) {
|
|
29
|
+
[arr[i], arr[last - (i - first)]] = [arr[last - (i - first)], arr[i]];
|
|
32
30
|
}
|
|
33
|
-
}
|
|
31
|
+
}
|
|
34
32
|
|
|
33
|
+
// ---------------------------------------------------
|
|
35
34
|
/**
|
|
36
35
|
* Compute the quality of a triangle.
|
|
37
36
|
*
|
|
@@ -41,23 +40,23 @@ function reverseElements(arr) {
|
|
|
41
40
|
* @param {Vector3} normal
|
|
42
41
|
* @returns {Number}
|
|
43
42
|
*/
|
|
44
|
-
|
|
45
43
|
function vtkCCSTriangleQuality(p0, p1, p2, normal) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
const u = [];
|
|
45
|
+
const v = [];
|
|
46
|
+
const w = [];
|
|
49
47
|
subtract(p1, p0, u);
|
|
50
48
|
subtract(p2, p1, v);
|
|
51
49
|
subtract(p0, p2, w);
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const area2 = (u[1] * v[2] - u[2] * v[1]) * normal[0] + (u[2] * v[0] - u[0] * v[2]) * normal[1] + (u[0] * v[1] - u[1] * v[0]) * normal[2];
|
|
51
|
+
let perim = Math.sqrt(u[0] * u[0] + u[1] * u[1] + u[2] * u[2]) + Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]) + Math.sqrt(w[0] * w[0] + w[1] * w[1] + w[2] * w[2]);
|
|
54
52
|
perim *= perim; // square the perimeter
|
|
53
|
+
perim = perim !== 0 ? perim : 1.0;
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
// use a normalization factor so equilateral quality is 1.0
|
|
58
56
|
return area2 / perim * 10.392304845413264;
|
|
59
|
-
}
|
|
57
|
+
}
|
|
60
58
|
|
|
59
|
+
// ---------------------------------------------------
|
|
61
60
|
/**
|
|
62
61
|
* Insert a triangle, and subdivide that triangle if one of
|
|
63
62
|
* its edges originally had more than two points before
|
|
@@ -69,91 +68,88 @@ function vtkCCSTriangleQuality(p0, p1, p2, normal) {
|
|
|
69
68
|
* @param {Array|TypedArray} polyEdges
|
|
70
69
|
* @param {Array|TypedArray} originalEdges
|
|
71
70
|
*/
|
|
72
|
-
|
|
73
71
|
function vtkCCSInsertTriangle(polys, poly, trids, polyEdges, originalEdges) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
var edgeCount = 0;
|
|
77
|
-
var edgeLocs = [-1, -1, -1]; // Check for original edge matches
|
|
72
|
+
const nextVert = [1, 2, 0];
|
|
78
73
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
// To store how many of originalEdges match
|
|
75
|
+
let edgeCount = 0;
|
|
76
|
+
const edgeLocs = [-1, -1, -1];
|
|
82
77
|
|
|
78
|
+
// Check for original edge matches
|
|
79
|
+
for (let vert = 0; vert < 3; vert++) {
|
|
80
|
+
const currId = trids[vert];
|
|
81
|
+
const edgeLoc = polyEdges[currId];
|
|
83
82
|
if (edgeLoc >= 0) {
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
let nextId = currId + 1;
|
|
86
84
|
if (nextId === poly.length) {
|
|
87
85
|
nextId = 0;
|
|
88
|
-
}
|
|
89
|
-
|
|
86
|
+
}
|
|
90
87
|
|
|
88
|
+
// Is the triangle edge a polygon edge?
|
|
91
89
|
if (nextId === trids[nextVert[vert]]) {
|
|
92
90
|
edgeLocs[vert] = edgeLoc;
|
|
93
91
|
edgeCount++;
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
|
-
|
|
98
95
|
if (edgeCount === 0) {
|
|
99
96
|
// No special edge handling, so just do one triangle
|
|
100
97
|
polys.insertNextCell([poly[trids[0]], poly[trids[1]], poly[trids[2]]]);
|
|
101
98
|
} else {
|
|
102
99
|
// Make triangle fans for edges with extra points
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
var maxPoints = 0;
|
|
106
|
-
var currSide = 0;
|
|
100
|
+
const edgePts = [[poly[trids[0]], poly[trids[1]]], [poly[trids[1]], poly[trids[2]]], [poly[trids[2]], poly[trids[0]]]];
|
|
107
101
|
|
|
108
|
-
|
|
102
|
+
// Find out which edge has the most extra points
|
|
103
|
+
let maxPoints = 0;
|
|
104
|
+
let currSide = 0;
|
|
105
|
+
for (let i = 0; i < 3; i++) {
|
|
109
106
|
if (edgeLocs[i] >= 0) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
const edgeLoc = edgeLocs[i];
|
|
108
|
+
const npts = originalEdges[edgeLoc];
|
|
109
|
+
const pts = originalEdges.slice(edgeLoc + 1, edgeLoc + 1 + npts);
|
|
114
110
|
if (!(edgePts[i][0] === pts[0] || edgePts[i][1] === pts[npts - 1])) {
|
|
115
111
|
vtkErrorMacro('assertion error in vtkCCSInsertTriangle');
|
|
116
112
|
}
|
|
117
|
-
|
|
118
113
|
if (npts > maxPoints) {
|
|
119
114
|
maxPoints = npts;
|
|
120
115
|
currSide = i;
|
|
121
116
|
}
|
|
122
|
-
|
|
123
117
|
edgePts[i] = pts;
|
|
124
118
|
}
|
|
125
|
-
}
|
|
126
|
-
|
|
119
|
+
}
|
|
127
120
|
|
|
128
|
-
|
|
129
|
-
|
|
121
|
+
// Find the edges before/after the edge with most points
|
|
122
|
+
const prevSide = (currSide + 2) % 3;
|
|
123
|
+
const nextSide = (currSide + 1) % 3;
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
|
|
125
|
+
// If other edges have only 2 points, nothing to do with them
|
|
126
|
+
const prevNeeded = edgePts[prevSide].length > 2;
|
|
127
|
+
const nextNeeded = edgePts[nextSide].length > 2;
|
|
133
128
|
|
|
134
|
-
|
|
129
|
+
// The tail is the common point in the triangle fan
|
|
130
|
+
const tailPtIds = [];
|
|
135
131
|
tailPtIds[prevSide] = edgePts[currSide][1];
|
|
136
132
|
tailPtIds[currSide] = edgePts[prevSide][0];
|
|
137
|
-
tailPtIds[nextSide] = edgePts[currSide][edgePts[currSide].length - 2];
|
|
133
|
+
tailPtIds[nextSide] = edgePts[currSide][edgePts[currSide].length - 2];
|
|
138
134
|
|
|
139
|
-
|
|
135
|
+
// Go through the sides and make the fans
|
|
136
|
+
for (let side = 0; side < 3; side++) {
|
|
140
137
|
if ((side !== prevSide || prevNeeded) && (side !== nextSide || nextNeeded)) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
let m = 0;
|
|
139
|
+
let n = edgePts[side].length - 1;
|
|
144
140
|
if (side === currSide) {
|
|
145
141
|
m += prevNeeded;
|
|
146
142
|
n -= nextNeeded;
|
|
147
143
|
}
|
|
148
|
-
|
|
149
|
-
for (var k = m; k < n; k++) {
|
|
144
|
+
for (let k = m; k < n; k++) {
|
|
150
145
|
polys.insertNextCell([edgePts[side][k], edgePts[side][k + 1], tailPtIds[side]]);
|
|
151
146
|
}
|
|
152
147
|
}
|
|
153
148
|
}
|
|
154
149
|
}
|
|
155
|
-
}
|
|
150
|
+
}
|
|
156
151
|
|
|
152
|
+
// ---------------------------------------------------
|
|
157
153
|
/**
|
|
158
154
|
* Triangulate a polygon that has been simplified by FindTrueEdges.
|
|
159
155
|
* This will re-insert the original edges. The output triangles are
|
|
@@ -170,165 +166,152 @@ function vtkCCSInsertTriangle(polys, poly, trids, polyEdges, originalEdges) {
|
|
|
170
166
|
* @param {Vector3} normal
|
|
171
167
|
* @returns {boolean}
|
|
172
168
|
*/
|
|
173
|
-
|
|
174
169
|
function vtkCCSTriangulate(poly, points, polyEdges, originalEdges, polys, normal) {
|
|
175
|
-
|
|
170
|
+
let n = poly.length;
|
|
176
171
|
|
|
172
|
+
// If the poly is a line, then skip it
|
|
177
173
|
if (n < 3) {
|
|
178
174
|
return true;
|
|
179
|
-
}
|
|
180
|
-
|
|
175
|
+
}
|
|
181
176
|
|
|
177
|
+
// If the poly is a triangle, then pass it
|
|
182
178
|
if (n === 3) {
|
|
183
|
-
|
|
179
|
+
const trids = [0, 1, 2];
|
|
184
180
|
vtkCCSInsertTriangle(polys, poly, trids, polyEdges, originalEdges);
|
|
185
181
|
return true;
|
|
186
|
-
}
|
|
187
|
-
|
|
182
|
+
}
|
|
188
183
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
184
|
+
// If the poly has 4 or more points, triangulate it
|
|
185
|
+
let triangulationFailure = false;
|
|
186
|
+
let ppoint = [];
|
|
187
|
+
let point = [];
|
|
188
|
+
let npoint = [];
|
|
189
|
+
let i = 0;
|
|
190
|
+
let j = 0;
|
|
191
|
+
let k = 0;
|
|
192
|
+
const verts = [];
|
|
197
193
|
verts.length = n;
|
|
198
|
-
|
|
199
194
|
for (i = 0; i < n; i++) {
|
|
200
195
|
verts[i] = [i, 0];
|
|
201
|
-
}
|
|
202
|
-
|
|
196
|
+
}
|
|
203
197
|
|
|
198
|
+
// compute the triangle quality for each vert
|
|
204
199
|
k = n - 2;
|
|
205
200
|
points.getPoint(poly[verts[k][0]], point);
|
|
206
201
|
i = n - 1;
|
|
207
202
|
points.getPoint(poly[verts[i][0]], npoint);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
203
|
+
let concave = 0;
|
|
204
|
+
let maxq = 0;
|
|
205
|
+
let maxi = 0;
|
|
212
206
|
for (j = 0; j < n; j++) {
|
|
213
|
-
|
|
214
|
-
ppoint = _ref2[0];
|
|
215
|
-
point = _ref2[1];
|
|
216
|
-
npoint = _ref2[2];
|
|
207
|
+
[ppoint, point, npoint] = [point, npoint, ppoint];
|
|
217
208
|
points.getPoint(poly[verts[j][0]], npoint);
|
|
218
|
-
|
|
219
|
-
|
|
209
|
+
const q = vtkCCSTriangleQuality(ppoint, point, npoint, normal);
|
|
220
210
|
if (q > maxq) {
|
|
221
211
|
maxi = i;
|
|
222
212
|
maxq = q;
|
|
223
213
|
}
|
|
224
|
-
|
|
225
214
|
concave += q < 0;
|
|
226
215
|
verts[i][1] = q;
|
|
227
216
|
i = j;
|
|
228
217
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
218
|
+
let foundEar;
|
|
219
|
+
// perform the ear-cut triangulation
|
|
232
220
|
for (;;) {
|
|
233
221
|
// if no potential ears were found, then fail
|
|
234
222
|
if (maxq <= Number.MIN_VALUE) {
|
|
235
223
|
triangulationFailure = true;
|
|
236
224
|
break;
|
|
237
225
|
}
|
|
238
|
-
|
|
239
226
|
i = maxi;
|
|
240
227
|
j = i + 1 !== n ? i + 1 : 0;
|
|
241
228
|
k = i !== 0 ? i - 1 : n - 1;
|
|
242
|
-
|
|
243
229
|
if (verts[i][1] > 0) {
|
|
244
230
|
foundEar = true;
|
|
245
231
|
points.getPoint(poly[verts[j][0]], npoint);
|
|
246
|
-
points.getPoint(poly[verts[k][0]], ppoint);
|
|
232
|
+
points.getPoint(poly[verts[k][0]], ppoint);
|
|
247
233
|
|
|
234
|
+
// only do ear check if there are concave vertices
|
|
248
235
|
if (concave) {
|
|
249
236
|
// get the normal of the split plane
|
|
250
|
-
|
|
251
|
-
|
|
237
|
+
const v = [];
|
|
238
|
+
const u = [];
|
|
252
239
|
subtract(npoint, ppoint, v);
|
|
253
240
|
cross(v, normal, u);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
241
|
+
const d = dot(ppoint, u);
|
|
242
|
+
let jj = j + 1 !== n ? j + 1 : 0;
|
|
243
|
+
let x = [];
|
|
257
244
|
points.getPoint(poly[verts[jj][0]], x);
|
|
258
|
-
|
|
259
|
-
|
|
245
|
+
let side = dot(x, u) < d;
|
|
246
|
+
let foundNegative = side;
|
|
260
247
|
|
|
248
|
+
// check for crossings of the split plane
|
|
261
249
|
jj = jj + 1 !== n ? jj + 1 : 0;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
250
|
+
let y = [];
|
|
251
|
+
const s = [];
|
|
252
|
+
const t = [];
|
|
266
253
|
for (; foundEar && jj !== k; jj = jj + 1 !== n ? jj + 1 : 0) {
|
|
267
|
-
|
|
268
|
-
x = _ref3[0];
|
|
269
|
-
y = _ref3[1];
|
|
254
|
+
[x, y] = [y, x];
|
|
270
255
|
points.getPoint(poly[verts[jj][0]], x);
|
|
271
|
-
|
|
272
|
-
|
|
256
|
+
const sside = dot(x, u) < d;
|
|
257
|
+
// XOR
|
|
273
258
|
if (side ? !sside : sside) {
|
|
274
259
|
side = !side;
|
|
275
260
|
foundNegative = true;
|
|
276
261
|
foundEar = vtkLine.intersection(ppoint, npoint, x, y, s, t) === vtkLine.IntersectionState.NO_INTERSECTION;
|
|
277
262
|
}
|
|
278
263
|
}
|
|
279
|
-
|
|
280
|
-
foundEar && (foundEar = foundNegative);
|
|
264
|
+
foundEar &&= foundNegative;
|
|
281
265
|
}
|
|
282
|
-
|
|
283
266
|
if (!foundEar) {
|
|
284
267
|
// don't try again until it is split
|
|
285
268
|
verts[i][1] = Number.MIN_VALUE;
|
|
286
269
|
} else {
|
|
287
270
|
// create a triangle from vertex and neighbors
|
|
288
|
-
|
|
289
|
-
vtkCCSInsertTriangle(polys, poly,
|
|
271
|
+
const trids = [verts[i][0], verts[j][0], verts[k][0]];
|
|
272
|
+
vtkCCSInsertTriangle(polys, poly, trids, polyEdges, originalEdges);
|
|
290
273
|
|
|
274
|
+
// remove the vertex i
|
|
291
275
|
verts.splice(i, 1);
|
|
292
276
|
k -= i === 0;
|
|
293
|
-
j -= j !== 0;
|
|
277
|
+
j -= j !== 0;
|
|
294
278
|
|
|
279
|
+
// break if this was final triangle
|
|
295
280
|
if (--n < 3) {
|
|
296
281
|
break;
|
|
297
|
-
}
|
|
298
|
-
|
|
282
|
+
}
|
|
299
283
|
|
|
300
|
-
|
|
284
|
+
// re-compute quality of previous point
|
|
285
|
+
const kk = k !== 0 ? k - 1 : n - 1;
|
|
301
286
|
points.getPoint(poly[verts[kk][0]], point);
|
|
302
|
-
|
|
287
|
+
const kq = vtkCCSTriangleQuality(point, ppoint, npoint, normal);
|
|
303
288
|
concave -= verts[k][1] < 0 && kq >= 0;
|
|
304
|
-
verts[k][1] = kq;
|
|
305
|
-
|
|
306
|
-
var _jj = j + 1 !== n ? j + 1 : 0;
|
|
289
|
+
verts[k][1] = kq;
|
|
307
290
|
|
|
308
|
-
|
|
309
|
-
|
|
291
|
+
// re-compute quality of next point
|
|
292
|
+
const jj = j + 1 !== n ? j + 1 : 0;
|
|
293
|
+
points.getPoint(poly[verts[jj][0]], point);
|
|
294
|
+
const jq = vtkCCSTriangleQuality(ppoint, npoint, point, normal);
|
|
310
295
|
concave -= verts[j][1] < 0 && jq >= 0;
|
|
311
296
|
verts[j][1] = jq;
|
|
312
297
|
}
|
|
313
|
-
}
|
|
314
|
-
|
|
298
|
+
}
|
|
315
299
|
|
|
300
|
+
// find the highest-quality ear candidate
|
|
316
301
|
maxi = 0;
|
|
317
302
|
maxq = verts[0][1];
|
|
318
|
-
|
|
319
303
|
for (i = 1; i < n; i++) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (_q > maxq) {
|
|
304
|
+
const q = verts[i][1];
|
|
305
|
+
if (q > maxq) {
|
|
323
306
|
maxi = i;
|
|
324
|
-
maxq =
|
|
307
|
+
maxq = q;
|
|
325
308
|
}
|
|
326
309
|
}
|
|
327
310
|
}
|
|
328
|
-
|
|
329
311
|
return !triangulationFailure;
|
|
330
|
-
}
|
|
312
|
+
}
|
|
331
313
|
|
|
314
|
+
// ---------------------------------------------------
|
|
332
315
|
/**
|
|
333
316
|
* Create polygons from line segments.
|
|
334
317
|
*
|
|
@@ -339,154 +322,146 @@ function vtkCCSTriangulate(poly, points, polyEdges, originalEdges, polys, normal
|
|
|
339
322
|
* @param {Array} newPolys
|
|
340
323
|
* @param {Array} incompletePolys
|
|
341
324
|
*/
|
|
342
|
-
|
|
343
325
|
function vtkCCSMakePolysFromLines(polyData, firstLine, endLine, oriented, newPolys, incompletePolys) {
|
|
344
|
-
|
|
345
|
-
|
|
326
|
+
let npts = 0;
|
|
327
|
+
let pts = [];
|
|
346
328
|
|
|
347
|
-
|
|
348
|
-
|
|
329
|
+
// Bitfield for marking lines as used
|
|
330
|
+
const usedLines = new Uint8Array(endLine - firstLine); // defaults to 0
|
|
349
331
|
|
|
332
|
+
// Require cell links to get lines from pointIds
|
|
350
333
|
polyData.buildLinks(polyData.getPoints().getNumberOfPoints());
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
334
|
+
let numNewPolys = 0;
|
|
335
|
+
let remainingLines = endLine - firstLine;
|
|
354
336
|
while (remainingLines > 0) {
|
|
355
337
|
// Create a new poly
|
|
356
|
-
|
|
357
|
-
|
|
338
|
+
const polyId = numNewPolys++;
|
|
339
|
+
const poly = [];
|
|
358
340
|
newPolys.push(poly);
|
|
359
|
-
|
|
360
|
-
|
|
341
|
+
let lineId = 0;
|
|
342
|
+
let completePoly = false;
|
|
361
343
|
|
|
344
|
+
// start the poly
|
|
362
345
|
for (lineId = firstLine; lineId < endLine; lineId++) {
|
|
363
346
|
if (!usedLines[lineId - firstLine]) {
|
|
364
347
|
pts = polyData.getCellPoints(lineId).cellPointIds;
|
|
365
348
|
npts = pts.length;
|
|
366
|
-
|
|
367
|
-
|
|
349
|
+
let n = npts;
|
|
368
350
|
if (npts > 2 && pts[0] === pts[npts - 1]) {
|
|
369
351
|
n = npts - 1;
|
|
370
352
|
completePoly = true;
|
|
371
353
|
}
|
|
372
|
-
|
|
373
354
|
poly.length = n;
|
|
374
|
-
|
|
375
|
-
for (var i = 0; i < n; i++) {
|
|
355
|
+
for (let i = 0; i < n; i++) {
|
|
376
356
|
poly[i] = pts[i];
|
|
377
357
|
}
|
|
378
|
-
|
|
379
358
|
break;
|
|
380
359
|
}
|
|
381
360
|
}
|
|
382
|
-
|
|
383
361
|
usedLines[lineId - firstLine] = 1;
|
|
384
362
|
remainingLines--;
|
|
385
|
-
|
|
386
|
-
|
|
363
|
+
let noLinesMatch = remainingLines === 0 && !completePoly;
|
|
387
364
|
while (!completePoly && !noLinesMatch && remainingLines > 0) {
|
|
388
365
|
// This is cleared if a match is found
|
|
389
|
-
noLinesMatch = true;
|
|
366
|
+
noLinesMatch = true;
|
|
390
367
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
368
|
+
// Number of points in the poly
|
|
369
|
+
const npoly = poly.length;
|
|
370
|
+
const lineEndPts = [];
|
|
371
|
+
const endPts = [poly[npoly - 1], poly[0]];
|
|
394
372
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
373
|
+
// For both open ends of the polygon
|
|
374
|
+
for (let endIdx = 0; endIdx < 2; endIdx++) {
|
|
375
|
+
const matches = [];
|
|
376
|
+
const cells = polyData.getPointCells(endPts[endIdx]);
|
|
398
377
|
|
|
399
|
-
|
|
378
|
+
// Go through all lines that contain this endpoint
|
|
379
|
+
for (let icell = 0; icell < cells.length; icell++) {
|
|
400
380
|
lineId = cells[icell];
|
|
401
|
-
|
|
402
381
|
if (lineId >= firstLine && lineId < endLine && !usedLines[lineId - firstLine]) {
|
|
403
382
|
pts = polyData.getCellPoints(lineId).cellPointIds;
|
|
404
383
|
npts = pts.length;
|
|
405
384
|
lineEndPts[0] = pts[0];
|
|
406
|
-
lineEndPts[1] = pts[npts - 1];
|
|
385
|
+
lineEndPts[1] = pts[npts - 1];
|
|
407
386
|
|
|
387
|
+
// Check that poly end matches line end
|
|
408
388
|
if (endPts[endIdx] === lineEndPts[endIdx] || !oriented && endPts[endIdx] === lineEndPts[1 - endIdx]) {
|
|
409
389
|
matches.push(lineId);
|
|
410
390
|
}
|
|
411
391
|
}
|
|
412
392
|
}
|
|
413
|
-
|
|
414
393
|
if (matches.length > 0) {
|
|
415
394
|
// Multiple matches mean we need to decide which path to take
|
|
416
395
|
if (matches.length > 1) {
|
|
417
396
|
// Remove double-backs
|
|
418
|
-
|
|
419
|
-
|
|
397
|
+
let k = matches.length;
|
|
420
398
|
do {
|
|
421
399
|
lineId = matches[--k];
|
|
422
400
|
pts = polyData.getCellPoints(lineId).cellPointIds;
|
|
423
401
|
npts = pts.length;
|
|
424
402
|
lineEndPts[0] = pts[0];
|
|
425
|
-
lineEndPts[1] = pts[npts - 1];
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
403
|
+
lineEndPts[1] = pts[npts - 1];
|
|
404
|
+
// check if line is reversed
|
|
405
|
+
const r = endPts[endIdx] !== lineEndPts[endIdx];
|
|
429
406
|
if (!r && (endIdx === 0 && poly[npoly - 2] === pts[1] || endIdx === 1 && poly[1] === pts[npts - 2]) || r && (endIdx === 0 && poly[npoly - 2] === pts[npts - 2] || endIdx === 1 && poly[1] === pts[1])) {
|
|
430
407
|
matches.splice(k, 1);
|
|
431
408
|
}
|
|
432
|
-
} while (k > 0 && matches.length > 1);
|
|
433
|
-
// they should be dealt with here.
|
|
409
|
+
} while (k > 0 && matches.length > 1);
|
|
434
410
|
|
|
411
|
+
// If there are multiple matches due to intersections,
|
|
412
|
+
// they should be dealt with here.
|
|
435
413
|
}
|
|
436
414
|
|
|
437
415
|
lineId = matches[0];
|
|
438
416
|
pts = polyData.getCellPoints(lineId).cellPointIds;
|
|
439
417
|
npts = pts.length;
|
|
440
418
|
lineEndPts[0] = pts[0];
|
|
441
|
-
lineEndPts[1] = pts[npts - 1];
|
|
419
|
+
lineEndPts[1] = pts[npts - 1];
|
|
442
420
|
|
|
421
|
+
// Do both ends match?
|
|
443
422
|
if (endPts[endIdx] === lineEndPts[endIdx]) {
|
|
444
423
|
completePoly = endPts[1 - endIdx] === lineEndPts[1 - endIdx];
|
|
445
424
|
} else {
|
|
446
425
|
completePoly = endPts[1 - endIdx] === lineEndPts[endIdx];
|
|
447
426
|
}
|
|
448
|
-
|
|
449
427
|
if (endIdx === 0) {
|
|
450
|
-
for (
|
|
451
|
-
poly.push(pts[
|
|
428
|
+
for (let i = 1; i < npts - (completePoly ? 1 : 0); i++) {
|
|
429
|
+
poly.push(pts[i]);
|
|
452
430
|
}
|
|
453
431
|
} else {
|
|
454
|
-
for (
|
|
455
|
-
poly.unshift(pts[
|
|
432
|
+
for (let i = completePoly ? 1 : 0; i < npts - 1; i++) {
|
|
433
|
+
poly.unshift(pts[i]);
|
|
456
434
|
}
|
|
457
435
|
}
|
|
458
|
-
|
|
459
436
|
if (endPts[endIdx] !== lineEndPts[endIdx]) {
|
|
460
437
|
// reverse the ids in the added line
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
438
|
+
let pit = poly.length;
|
|
439
|
+
let ptsIt = completePoly ? 1 : 0;
|
|
440
|
+
let ptsEnd = npts - 1;
|
|
465
441
|
if (endIdx === 1) {
|
|
466
442
|
pit = npts - 1 - (completePoly ? 1 : 0);
|
|
467
443
|
ptsIt = pts + 1;
|
|
468
444
|
ptsEnd = pts + npts - (completePoly ? 1 : 0);
|
|
469
445
|
}
|
|
470
|
-
|
|
471
446
|
while (ptsIt !== ptsEnd) {
|
|
472
447
|
poly[--pit] = poly[ptsIt++];
|
|
473
448
|
}
|
|
474
449
|
}
|
|
475
|
-
|
|
476
450
|
usedLines[lineId - firstLine] = 1;
|
|
477
451
|
remainingLines--;
|
|
478
452
|
noLinesMatch = false;
|
|
479
453
|
}
|
|
480
454
|
}
|
|
481
|
-
}
|
|
482
|
-
|
|
455
|
+
}
|
|
483
456
|
|
|
457
|
+
// Check for incomplete polygons
|
|
484
458
|
if (noLinesMatch) {
|
|
485
459
|
incompletePolys.push(polyId);
|
|
486
460
|
}
|
|
487
461
|
}
|
|
488
|
-
}
|
|
462
|
+
}
|
|
489
463
|
|
|
464
|
+
// ---------------------------------------------------
|
|
490
465
|
/**
|
|
491
466
|
* Join polys that have loose ends, as indicated by incompletePolys.
|
|
492
467
|
* Any polys created will have a normal opposite to the supplied normal,
|
|
@@ -498,101 +473,98 @@ function vtkCCSMakePolysFromLines(polyData, firstLine, endLine, oriented, newPol
|
|
|
498
473
|
* @param {vtkPoints} points
|
|
499
474
|
* @param {Vector3} normal
|
|
500
475
|
*/
|
|
501
|
-
|
|
502
476
|
function vtkCCSJoinLooseEnds(polys, incompletePolys, points, normal) {
|
|
503
477
|
// Relative tolerance for checking whether an edge is on the hull
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
478
|
+
const tol = CCS_POLYGON_TOLERANCE;
|
|
479
|
+
|
|
480
|
+
// A list of polys to remove when everything is done
|
|
481
|
+
const removePolys = [];
|
|
482
|
+
const p1 = [];
|
|
483
|
+
const p2 = [];
|
|
484
|
+
let poly1;
|
|
485
|
+
let poly2;
|
|
486
|
+
let pt1;
|
|
487
|
+
let pt2;
|
|
488
|
+
let dMin;
|
|
489
|
+
let iMin;
|
|
490
|
+
let v;
|
|
491
|
+
let d;
|
|
492
|
+
let n = incompletePolys.length;
|
|
519
493
|
while (n !== 0) {
|
|
520
494
|
poly1 = polys[incompletePolys[n - 1]];
|
|
521
495
|
pt1 = poly1[poly1.length - 1];
|
|
522
496
|
points.getPoint(pt1, p1);
|
|
523
497
|
dMin = Number.MAX_VALUE;
|
|
524
498
|
iMin = 0;
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
poly2 = polys[incompletePolys[_i3]];
|
|
499
|
+
for (let i = 0; i < n; i++) {
|
|
500
|
+
poly2 = polys[incompletePolys[i]];
|
|
528
501
|
pt2 = poly2[0];
|
|
529
|
-
points.getPoint(pt2, p2);
|
|
502
|
+
points.getPoint(pt2, p2);
|
|
530
503
|
|
|
504
|
+
// The next few steps verify that edge [p1, p2] is on the hull
|
|
531
505
|
v = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2]];
|
|
532
506
|
d = norm(v);
|
|
533
|
-
|
|
534
507
|
if (d !== 0) {
|
|
535
508
|
v[0] /= d;
|
|
536
509
|
v[1] /= d;
|
|
537
510
|
v[2] /= d;
|
|
538
|
-
}
|
|
539
|
-
|
|
511
|
+
}
|
|
540
512
|
|
|
541
|
-
|
|
513
|
+
// Compute the midpoint of the edge
|
|
514
|
+
const pm = [0.5 * (p1[0] + p2[0]), 0.5 * (p1[1] + p2[1]), 0.5 * (p1[2] + p2[2])];
|
|
542
515
|
|
|
543
|
-
|
|
516
|
+
// Create a plane equation
|
|
517
|
+
const pc = [];
|
|
544
518
|
cross(normal, v, pc);
|
|
545
|
-
pc[3] = -dot(pc, pm);
|
|
546
|
-
// the edge is not on the hull of the pointset.
|
|
547
|
-
|
|
548
|
-
var badPoint = false;
|
|
549
|
-
var m = polys.length;
|
|
550
|
-
var p = [];
|
|
551
|
-
|
|
552
|
-
for (var j = 0; j < m && !badPoint; j++) {
|
|
553
|
-
var poly = polys[j];
|
|
554
|
-
var npts = poly.length;
|
|
555
|
-
|
|
556
|
-
for (var k = 0; k < npts; k++) {
|
|
557
|
-
var ptId = poly[k];
|
|
519
|
+
pc[3] = -dot(pc, pm);
|
|
558
520
|
|
|
521
|
+
// Check that all points are inside the plane. If they aren't, then
|
|
522
|
+
// the edge is not on the hull of the pointset.
|
|
523
|
+
let badPoint = false;
|
|
524
|
+
const m = polys.length;
|
|
525
|
+
const p = [];
|
|
526
|
+
for (let j = 0; j < m && !badPoint; j++) {
|
|
527
|
+
const poly = polys[j];
|
|
528
|
+
const npts = poly.length;
|
|
529
|
+
for (let k = 0; k < npts; k++) {
|
|
530
|
+
const ptId = poly[k];
|
|
559
531
|
if (ptId !== pt1 && ptId !== pt2) {
|
|
560
532
|
points.getPoint(ptId, p);
|
|
561
|
-
|
|
562
|
-
|
|
533
|
+
const val = p[0] * pc[0] + p[1] * pc[1] + p[2] * pc[2] + pc[3];
|
|
534
|
+
const r2 = distance2BetweenPoints(p, pm);
|
|
563
535
|
|
|
536
|
+
// Check distance from plane against the tolerance
|
|
564
537
|
if (val < 0 && val * val > tol * tol * r2) {
|
|
565
538
|
badPoint = true;
|
|
566
539
|
break;
|
|
567
540
|
}
|
|
568
541
|
}
|
|
569
|
-
}
|
|
570
|
-
|
|
542
|
+
}
|
|
571
543
|
|
|
544
|
+
// If no bad points, then this edge is a candidate
|
|
572
545
|
if (!badPoint && d < dMin) {
|
|
573
546
|
dMin = d;
|
|
574
|
-
iMin =
|
|
547
|
+
iMin = i;
|
|
575
548
|
}
|
|
576
549
|
}
|
|
577
|
-
}
|
|
578
|
-
|
|
550
|
+
}
|
|
579
551
|
|
|
552
|
+
// If a match was found, append the polys
|
|
580
553
|
if (dMin < Number.MAX_VALUE) {
|
|
581
554
|
// Did the poly match with itself?
|
|
582
555
|
if (iMin === n - 1) {
|
|
583
556
|
// Mark the poly as closed
|
|
584
557
|
incompletePolys.pop();
|
|
585
558
|
} else {
|
|
586
|
-
|
|
559
|
+
const id2 = incompletePolys[iMin];
|
|
587
560
|
|
|
588
|
-
|
|
561
|
+
// Combine the polys
|
|
589
562
|
// for (let i = 1; i < polys[id2].length; i++) {
|
|
590
563
|
// poly1.push(polys[id2][i]);
|
|
591
564
|
// }
|
|
565
|
+
poly1.push(...polys[id2]);
|
|
592
566
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
567
|
+
// Erase the second poly
|
|
596
568
|
removePolys.push(id2);
|
|
597
569
|
incompletePolys.splice(iMin, 1);
|
|
598
570
|
}
|
|
@@ -601,25 +573,22 @@ function vtkCCSJoinLooseEnds(polys, incompletePolys, points, normal) {
|
|
|
601
573
|
removePolys.push(incompletePolys[n - 1]);
|
|
602
574
|
incompletePolys.pop();
|
|
603
575
|
}
|
|
604
|
-
|
|
605
576
|
n = incompletePolys.length;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
removePolys.sort(function (a, b) {
|
|
610
|
-
return a - b;
|
|
611
|
-
});
|
|
612
|
-
var i = removePolys.length;
|
|
577
|
+
}
|
|
613
578
|
|
|
579
|
+
// Remove polys that couldn't be completed
|
|
580
|
+
removePolys.sort((a, b) => a - b);
|
|
581
|
+
let i = removePolys.length;
|
|
614
582
|
while (i > 0) {
|
|
615
583
|
// Remove items in reverse order
|
|
616
584
|
polys.splice(removePolys[--i], 1);
|
|
617
|
-
}
|
|
618
|
-
|
|
585
|
+
}
|
|
619
586
|
|
|
587
|
+
// Clear the incompletePolys vector, it's indices are no longer valid
|
|
620
588
|
incompletePolys.length = 0;
|
|
621
|
-
}
|
|
589
|
+
}
|
|
622
590
|
|
|
591
|
+
// ---------------------------------------------------
|
|
623
592
|
/**
|
|
624
593
|
* Given three vectors p.p1, p.p2, and p.p3, this routine
|
|
625
594
|
* checks to see if progressing from p1 to p2 to p3 is a clockwise
|
|
@@ -634,44 +603,42 @@ function vtkCCSJoinLooseEnds(polys, incompletePolys, points, normal) {
|
|
|
634
603
|
* @param {Vector3} normal
|
|
635
604
|
* @returns {Number}
|
|
636
605
|
*/
|
|
637
|
-
|
|
638
606
|
function vtkCCSVectorProgression(p, p1, p2, p3, normal) {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
607
|
+
const v1 = [p1[0] - p[0], p1[1] - p[1], p1[2] - p[2]];
|
|
608
|
+
const v2 = [p2[0] - p[0], p2[1] - p[1], p2[2] - p[2]];
|
|
609
|
+
const v3 = [p3[0] - p[0], p3[1] - p[1], p3[2] - p[2]];
|
|
610
|
+
const w1 = [];
|
|
611
|
+
const w2 = [];
|
|
644
612
|
cross(v2, v1, w1);
|
|
645
613
|
cross(v2, v3, w2);
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
614
|
+
const s1 = dot(w1, normal);
|
|
615
|
+
const s2 = dot(w2, normal);
|
|
649
616
|
if (s1 !== 0 && s2 !== 0) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
// XOR
|
|
617
|
+
const sb1 = s1 < 0;
|
|
618
|
+
const sb2 = s2 < 0;
|
|
653
619
|
|
|
620
|
+
// if sines have different signs
|
|
621
|
+
// XOR
|
|
654
622
|
if (sb1 ? !sb2 : sb2) {
|
|
655
623
|
// return -1 if s2 is -ve
|
|
656
624
|
return 1 - 2 * sb2;
|
|
657
625
|
}
|
|
626
|
+
const c1 = dot(v2, v1);
|
|
627
|
+
const l1 = norm(v1);
|
|
628
|
+
const c2 = dot(v2, v3);
|
|
629
|
+
const l2 = norm(v3);
|
|
658
630
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
var c2 = dot(v2, v3);
|
|
662
|
-
var l2 = norm(v3); // ck is the difference of the cosines, flipped in sign if sines are +ve
|
|
663
|
-
|
|
664
|
-
var ck = (c2 * l2 - c1 * l1) * (1 - sb1 * 2);
|
|
665
|
-
|
|
631
|
+
// ck is the difference of the cosines, flipped in sign if sines are +ve
|
|
632
|
+
const ck = (c2 * l2 - c1 * l1) * (1 - sb1 * 2);
|
|
666
633
|
if (ck !== 0) {
|
|
667
634
|
// return the sign of ck
|
|
668
635
|
return 1 - 2 * (ck < 0);
|
|
669
636
|
}
|
|
670
637
|
}
|
|
671
|
-
|
|
672
638
|
return 0;
|
|
673
|
-
}
|
|
639
|
+
}
|
|
674
640
|
|
|
641
|
+
// ---------------------------------------------------
|
|
675
642
|
/**
|
|
676
643
|
* Check for self-intersection. Split the figure-eights.
|
|
677
644
|
* This assumes that all intersections occur at existing
|
|
@@ -685,79 +652,68 @@ function vtkCCSVectorProgression(p, p1, p2, p3, normal) {
|
|
|
685
652
|
* @param {Vector3} normal
|
|
686
653
|
* @param {Boolean} oriented
|
|
687
654
|
*/
|
|
688
|
-
|
|
689
655
|
function vtkCCSSplitAtPinchPoints(polys, points, polyGroups, polyEdges, normal, oriented) {
|
|
690
|
-
|
|
656
|
+
const tryPoints = vtkPoints.newInstance({
|
|
691
657
|
dataType: VtkDataTypes.DOUBLE,
|
|
692
658
|
empty: true
|
|
693
659
|
});
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
for (var i = 0; i < polys.length; i++) {
|
|
660
|
+
const locator = vtkIncrementalOctreePointLocator.newInstance();
|
|
661
|
+
let splitCount = 0;
|
|
662
|
+
let poly;
|
|
663
|
+
let n;
|
|
664
|
+
let bounds;
|
|
665
|
+
let tol;
|
|
666
|
+
for (let i = 0; i < polys.length; i++) {
|
|
702
667
|
poly = polys[i];
|
|
703
668
|
n = poly.length;
|
|
704
669
|
bounds = [];
|
|
705
670
|
tol = CCS_POLYGON_TOLERANCE * Math.sqrt(vtkPolygon.getBounds(poly, points, bounds));
|
|
706
|
-
|
|
707
671
|
if (tol === 0) {
|
|
708
672
|
// eslint-disable-next-line no-continue
|
|
709
673
|
continue;
|
|
710
674
|
}
|
|
711
|
-
|
|
712
675
|
tryPoints.initialize();
|
|
713
676
|
locator.setTolerance(tol);
|
|
714
677
|
locator.initPointInsertion(tryPoints, bounds);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
678
|
+
let foundMatch = false;
|
|
679
|
+
let idx1 = 0;
|
|
680
|
+
let idx2 = 0;
|
|
681
|
+
let unique = 0;
|
|
682
|
+
const point = [];
|
|
683
|
+
const p1 = [];
|
|
684
|
+
const p2 = [];
|
|
685
|
+
const p3 = [];
|
|
724
686
|
for (idx2 = 0; idx2 < n; idx2++) {
|
|
725
687
|
points.getPoint(poly[idx2], point);
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
688
|
+
const {
|
|
689
|
+
success,
|
|
690
|
+
pointIdx
|
|
691
|
+
} = locator.insertUniquePoint(point, 0);
|
|
731
692
|
if (!success) {
|
|
732
693
|
// Need vertIdx to match poly indices, so force point insertion
|
|
733
|
-
locator.insertNextPoint(point);
|
|
694
|
+
locator.insertNextPoint(point);
|
|
734
695
|
|
|
696
|
+
// Do the points have different pointIds?
|
|
735
697
|
idx1 = pointIdx;
|
|
736
698
|
unique = poly[idx2] !== poly[idx1];
|
|
737
|
-
|
|
738
699
|
if (idx2 > idx1 + 2 - unique && n + idx1 > idx2 + 2 - unique) {
|
|
739
700
|
if (oriented) {
|
|
740
701
|
// Make sure that splitting this poly won't create a hole poly
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
702
|
+
let prevIdx = n + idx1 - 1;
|
|
703
|
+
let midIdx = idx1 + 1;
|
|
704
|
+
let nextIdx = idx2 + 1;
|
|
745
705
|
if (prevIdx >= n) {
|
|
746
706
|
prevIdx -= n;
|
|
747
707
|
}
|
|
748
|
-
|
|
749
708
|
if (midIdx >= n) {
|
|
750
709
|
midIdx -= n;
|
|
751
710
|
}
|
|
752
|
-
|
|
753
711
|
if (nextIdx >= n) {
|
|
754
712
|
nextIdx -= n;
|
|
755
713
|
}
|
|
756
|
-
|
|
757
714
|
points.getPoint(poly[prevIdx], p1);
|
|
758
715
|
points.getPoint(poly[midIdx], p2);
|
|
759
716
|
points.getPoint(poly[nextIdx], p3);
|
|
760
|
-
|
|
761
717
|
if (vtkCCSVectorProgression(point, p1, p2, p3, normal) > 0) {
|
|
762
718
|
foundMatch = true;
|
|
763
719
|
break;
|
|
@@ -769,54 +725,50 @@ function vtkCCSSplitAtPinchPoints(polys, points, polyGroups, polyEdges, normal,
|
|
|
769
725
|
}
|
|
770
726
|
}
|
|
771
727
|
}
|
|
772
|
-
|
|
773
728
|
if (foundMatch) {
|
|
774
|
-
splitCount++;
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
729
|
+
splitCount++;
|
|
730
|
+
|
|
731
|
+
// Split off a new poly
|
|
732
|
+
const m = idx2 - idx1;
|
|
733
|
+
const oldPoly = polys[i];
|
|
734
|
+
const oldEdges = polyEdges[i];
|
|
735
|
+
const newPoly1 = oldPoly.slice(idx1, idx1 + m + unique);
|
|
736
|
+
const newEdges1 = oldEdges.slice(idx1, idx1 + m + unique);
|
|
737
|
+
const newPoly2 = new Array(n - m + unique);
|
|
738
|
+
const newEdges2 = new Array(n - m + unique);
|
|
784
739
|
if (unique) {
|
|
785
740
|
newEdges1[m] = -1;
|
|
786
|
-
}
|
|
787
|
-
|
|
741
|
+
}
|
|
788
742
|
|
|
789
|
-
|
|
743
|
+
// The poly that is split off, which might have more intersections
|
|
744
|
+
for (let j = 0; j < idx1 + unique; j++) {
|
|
790
745
|
newPoly2[j] = oldPoly[j];
|
|
791
746
|
newEdges2[j] = oldEdges[j];
|
|
792
747
|
}
|
|
793
|
-
|
|
794
748
|
if (unique) {
|
|
795
749
|
newEdges2[idx1] = -1;
|
|
796
750
|
}
|
|
797
|
-
|
|
798
|
-
for (var k = idx2; k < n; k++) {
|
|
751
|
+
for (let k = idx2; k < n; k++) {
|
|
799
752
|
newPoly2[k - m + unique] = oldPoly[k];
|
|
800
753
|
newEdges2[k - m + unique] = oldEdges[k];
|
|
801
754
|
}
|
|
802
|
-
|
|
803
755
|
polys[i] = newPoly1;
|
|
804
756
|
polyEdges[i] = newEdges1;
|
|
805
757
|
polys.push(newPoly2);
|
|
806
|
-
polyEdges.push(newEdges2);
|
|
807
|
-
// make a group with one entry for the new poly
|
|
758
|
+
polyEdges.push(newEdges2);
|
|
808
759
|
|
|
760
|
+
// Unless polygroup was clear (because poly was reversed),
|
|
761
|
+
// make a group with one entry for the new poly
|
|
809
762
|
polyGroups.length = polys.length;
|
|
810
|
-
|
|
811
763
|
if (polyGroups[i].length > 0) {
|
|
812
764
|
polyGroups[polys.length - 1].push(polys.length - 1);
|
|
813
765
|
}
|
|
814
766
|
}
|
|
815
767
|
}
|
|
816
|
-
|
|
817
768
|
return splitCount;
|
|
818
|
-
}
|
|
769
|
+
}
|
|
819
770
|
|
|
771
|
+
// ---------------------------------------------------
|
|
820
772
|
/**
|
|
821
773
|
* The polygons might have a lot of extra points, i.e. points
|
|
822
774
|
* in the middle of the edges. Remove those points, but keep
|
|
@@ -828,72 +780,75 @@ function vtkCCSSplitAtPinchPoints(polys, points, polyGroups, polyEdges, normal,
|
|
|
828
780
|
* @param {Array} polyEdges
|
|
829
781
|
* @param {Array} originalEdges
|
|
830
782
|
*/
|
|
831
|
-
|
|
832
783
|
function vtkCCSFindTrueEdges(polys, points, polyEdges, originalEdges) {
|
|
833
784
|
// Tolerance^2 for angle to see if line segments are parallel
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
785
|
+
const atol2 = CCS_POLYGON_TOLERANCE * CCS_POLYGON_TOLERANCE;
|
|
786
|
+
const p0 = [];
|
|
787
|
+
const p1 = [];
|
|
788
|
+
const p2 = [];
|
|
789
|
+
const v1 = [];
|
|
790
|
+
const v2 = [];
|
|
791
|
+
let l1;
|
|
792
|
+
let l2;
|
|
793
|
+
for (let polyId = 0; polyId < polys.length; polyId++) {
|
|
794
|
+
const oldPoly = polys[polyId];
|
|
795
|
+
const n = oldPoly.length;
|
|
796
|
+
const newEdges = [];
|
|
797
|
+
polyEdges.push(newEdges);
|
|
798
|
+
|
|
799
|
+
// Only useful if poly has more than three sides
|
|
849
800
|
if (n < 4) {
|
|
850
801
|
newEdges[0] = -1;
|
|
851
802
|
newEdges[1] = -1;
|
|
852
|
-
newEdges[2] = -1;
|
|
853
|
-
|
|
803
|
+
newEdges[2] = -1;
|
|
804
|
+
// eslint-disable-next-line no-continue
|
|
854
805
|
continue;
|
|
855
|
-
}
|
|
856
|
-
|
|
806
|
+
}
|
|
857
807
|
|
|
858
|
-
|
|
808
|
+
// While we remove points, m keeps track of how many points are left
|
|
809
|
+
let m = n;
|
|
859
810
|
|
|
860
|
-
|
|
861
|
-
|
|
811
|
+
// Compute bounds for tolerance
|
|
812
|
+
const bounds = [];
|
|
813
|
+
const tol2 = vtkPolygon.getBounds(oldPoly, points, bounds) * atol2;
|
|
862
814
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
815
|
+
// The new poly
|
|
816
|
+
const newPoly = [];
|
|
817
|
+
let cornerPointId = 0;
|
|
818
|
+
let oldOriginalId = -1;
|
|
866
819
|
|
|
867
|
-
|
|
868
|
-
|
|
820
|
+
// Keep the partial edge from before the first corner is found
|
|
821
|
+
const partialEdge = [];
|
|
822
|
+
let cellCount = 0;
|
|
869
823
|
points.getPoint(oldPoly[n - 1], p0);
|
|
870
824
|
points.getPoint(oldPoly[0], p1);
|
|
871
825
|
subtract(p1, p0, v1);
|
|
872
826
|
l1 = dot(v1, v1);
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
var k = j + 1;
|
|
876
|
-
|
|
827
|
+
for (let j = 0; j < n; j++) {
|
|
828
|
+
let k = j + 1;
|
|
877
829
|
if (k >= n) {
|
|
878
830
|
k -= n;
|
|
879
831
|
}
|
|
880
|
-
|
|
881
832
|
points.getPoint(oldPoly[k], p2);
|
|
882
833
|
subtract(p2, p1, v2);
|
|
883
|
-
l2 = dot(v2, v2);
|
|
834
|
+
l2 = dot(v2, v2);
|
|
884
835
|
|
|
885
|
-
|
|
836
|
+
// Dot product is |v1||v2|cos(theta)
|
|
837
|
+
const c = dot(v1, v2);
|
|
838
|
+
// sin^2(theta) = (1 - cos^2(theta))
|
|
886
839
|
// and c*c = l1*l2*cos^2(theta)
|
|
840
|
+
const s2 = l1 * l2 - c * c;
|
|
887
841
|
|
|
888
|
-
|
|
842
|
+
// In the small angle approximation, sin(theta) == theta, so
|
|
889
843
|
// s2/(l1*l2) is the angle that we want to check, but it's not
|
|
890
844
|
// a valid check if l1 or l2 is very close to zero.
|
|
891
845
|
|
|
892
|
-
|
|
846
|
+
const pointId = oldPoly[j];
|
|
847
|
+
|
|
848
|
+
// Keep the point if:
|
|
893
849
|
// 1) removing it would create a 2-point poly OR
|
|
894
850
|
// 2) it's more than "tol" distance from the prev point AND
|
|
895
851
|
// 3) the angle is greater than atol:
|
|
896
|
-
|
|
897
852
|
if (m <= 3 || l1 > tol2 && (c < 0 || l1 < tol2 || l2 < tol2 || s2 > l1 * l2 * atol2)) {
|
|
898
853
|
// Complete the previous edge only if the final point count
|
|
899
854
|
// will be greater than two
|
|
@@ -901,10 +856,9 @@ function vtkCCSFindTrueEdges(polys, points, polyEdges, originalEdges) {
|
|
|
901
856
|
if (pointId !== oldOriginalId) {
|
|
902
857
|
originalEdges.push(pointId);
|
|
903
858
|
cellCount++;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
var countLocation = originalEdges.length - cellCount - 1;
|
|
859
|
+
}
|
|
860
|
+
// Update the number of segments in the edge
|
|
861
|
+
const countLocation = originalEdges.length - cellCount - 1;
|
|
908
862
|
originalEdges[countLocation] = cellCount;
|
|
909
863
|
newEdges.push(countLocation);
|
|
910
864
|
} else if (cellCount === 0) {
|
|
@@ -912,13 +866,14 @@ function vtkCCSFindTrueEdges(polys, points, polyEdges, originalEdges) {
|
|
|
912
866
|
} else {
|
|
913
867
|
newEdges.push(-1);
|
|
914
868
|
}
|
|
869
|
+
newPoly.push(pointId);
|
|
915
870
|
|
|
916
|
-
|
|
917
|
-
|
|
871
|
+
// Start a new edge with cornerPointId as a "virtual" point
|
|
918
872
|
cornerPointId = pointId;
|
|
919
873
|
oldOriginalId = pointId;
|
|
920
|
-
cellCount = 1;
|
|
874
|
+
cellCount = 1;
|
|
921
875
|
|
|
876
|
+
// Rotate to the next point
|
|
922
877
|
p0[0] = p2[0];
|
|
923
878
|
p0[1] = p2[1];
|
|
924
879
|
p0[2] = p2[2];
|
|
@@ -934,60 +889,55 @@ function vtkCCSFindTrueEdges(polys, points, polyEdges, originalEdges) {
|
|
|
934
889
|
// First check to see if we have to add cornerPointId
|
|
935
890
|
if (cellCount === 1) {
|
|
936
891
|
originalEdges.push(1); // new edge
|
|
937
|
-
|
|
938
892
|
originalEdges.push(cornerPointId);
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
|
|
893
|
+
}
|
|
894
|
+
// Then add the new point
|
|
942
895
|
originalEdges.push(pointId);
|
|
943
896
|
oldOriginalId = pointId;
|
|
944
897
|
cellCount++;
|
|
945
898
|
} else {
|
|
946
899
|
// No corner yet, so save the point
|
|
947
900
|
partialEdge.push(pointId);
|
|
948
|
-
}
|
|
949
|
-
|
|
901
|
+
}
|
|
950
902
|
|
|
951
|
-
|
|
903
|
+
// Reduce the count
|
|
904
|
+
m--;
|
|
952
905
|
|
|
906
|
+
// Join the previous two segments, since the point was removed
|
|
953
907
|
p1[0] = p2[0];
|
|
954
908
|
p1[1] = p2[1];
|
|
955
909
|
p1[2] = p2[2];
|
|
956
910
|
subtract(p2, p0, v1);
|
|
957
911
|
l1 = dot(v1, v1);
|
|
958
912
|
}
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
for (var ii = 0; ii < partialEdge.length; ii++) {
|
|
963
|
-
var _pointId = partialEdge[ii];
|
|
913
|
+
}
|
|
964
914
|
|
|
965
|
-
|
|
915
|
+
// Add the partial edge to the end
|
|
916
|
+
for (let ii = 0; ii < partialEdge.length; ii++) {
|
|
917
|
+
const pointId = partialEdge[ii];
|
|
918
|
+
if (pointId !== oldOriginalId) {
|
|
966
919
|
if (cellCount === 1) {
|
|
967
920
|
originalEdges.push(1); // new edge
|
|
968
|
-
|
|
969
921
|
originalEdges.push(cornerPointId);
|
|
970
922
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
oldOriginalId = _pointId;
|
|
923
|
+
originalEdges.push(pointId);
|
|
924
|
+
oldOriginalId = pointId;
|
|
974
925
|
cellCount++;
|
|
975
926
|
}
|
|
976
|
-
}
|
|
977
|
-
|
|
927
|
+
}
|
|
978
928
|
|
|
929
|
+
// Finalize
|
|
979
930
|
if (cellCount > 1) {
|
|
980
931
|
// Update the number of segments in the edge
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
newEdges.push(_countLocation);
|
|
932
|
+
const countLocation = originalEdges.length - cellCount - 1;
|
|
933
|
+
originalEdges[countLocation] = cellCount;
|
|
934
|
+
newEdges.push(countLocation);
|
|
985
935
|
}
|
|
986
|
-
|
|
987
936
|
polys[polyId] = newPoly;
|
|
988
937
|
}
|
|
989
|
-
}
|
|
938
|
+
}
|
|
990
939
|
|
|
940
|
+
// ---------------------------------------------------
|
|
991
941
|
/**
|
|
992
942
|
* Reverse a cleaned-up polygon along with the info about
|
|
993
943
|
* all of its original vertices.
|
|
@@ -996,20 +946,19 @@ function vtkCCSFindTrueEdges(polys, points, polyEdges, originalEdges) {
|
|
|
996
946
|
* @param {Array} edges
|
|
997
947
|
* @param {Array} originalEdges
|
|
998
948
|
*/
|
|
999
|
-
|
|
1000
949
|
function vtkCCSReversePoly(poly, edges, originalEdges) {
|
|
1001
950
|
reverseElements(poly, 1, poly.length - 1);
|
|
1002
951
|
edges.reverse();
|
|
1003
|
-
|
|
1004
|
-
for (var i = 0; i < edges.length; i++) {
|
|
952
|
+
for (let i = 0; i < edges.length; i++) {
|
|
1005
953
|
if (edges[i] >= 0) {
|
|
1006
|
-
|
|
1007
|
-
|
|
954
|
+
const firstPtsIdx = edges[i] + 1;
|
|
955
|
+
const npts = originalEdges[edges[i]];
|
|
1008
956
|
reverseElements(originalEdges, firstPtsIdx, firstPtsIdx + npts - 1);
|
|
1009
957
|
}
|
|
1010
958
|
}
|
|
1011
|
-
}
|
|
959
|
+
}
|
|
1012
960
|
|
|
961
|
+
// ---------------------------------------------------
|
|
1013
962
|
/**
|
|
1014
963
|
* Check the sense of the polygon against the given normal. Returns
|
|
1015
964
|
* zero if the normal is zero.
|
|
@@ -1018,21 +967,19 @@ function vtkCCSReversePoly(poly, edges, originalEdges) {
|
|
|
1018
967
|
* @param {vtkPoints} points
|
|
1019
968
|
* @param {Vector3} normal
|
|
1020
969
|
*/
|
|
1021
|
-
|
|
1022
970
|
function vtkCCSCheckPolygonSense(poly, points, normal) {
|
|
1023
971
|
// Compute the normal
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
972
|
+
const pnormal = [0.0, 0.0, 0.0];
|
|
973
|
+
const p0 = [];
|
|
974
|
+
const p1 = [];
|
|
975
|
+
const p2 = [];
|
|
976
|
+
const v1 = [];
|
|
977
|
+
const v2 = [];
|
|
978
|
+
const v = [];
|
|
1031
979
|
points.getPoint(poly[0], p0);
|
|
1032
980
|
points.getPoint(poly[1], p1);
|
|
1033
981
|
subtract(p1, p0, v1);
|
|
1034
|
-
|
|
1035
|
-
for (var jj = 2; jj < poly.length; jj++) {
|
|
982
|
+
for (let jj = 2; jj < poly.length; jj++) {
|
|
1036
983
|
points.getPoint(poly[jj], p2);
|
|
1037
984
|
subtract(p2, p0, v2);
|
|
1038
985
|
cross(v1, v2, v);
|
|
@@ -1043,16 +990,17 @@ function vtkCCSCheckPolygonSense(poly, points, normal) {
|
|
|
1043
990
|
v1[0] = v2[0];
|
|
1044
991
|
v1[1] = v2[1];
|
|
1045
992
|
v1[2] = v2[2];
|
|
1046
|
-
}
|
|
1047
|
-
|
|
993
|
+
}
|
|
1048
994
|
|
|
1049
|
-
|
|
995
|
+
// Check the normal
|
|
996
|
+
const d = dot(pnormal, normal);
|
|
1050
997
|
return {
|
|
1051
998
|
isNormalNotZero: d !== 0,
|
|
1052
999
|
sense: d > 0
|
|
1053
1000
|
};
|
|
1054
|
-
}
|
|
1001
|
+
}
|
|
1055
1002
|
|
|
1003
|
+
// ---------------------------------------------------
|
|
1056
1004
|
/**
|
|
1057
1005
|
* Check whether innerPoly is inside outerPoly.
|
|
1058
1006
|
* The normal is needed to verify the polygon orientation.
|
|
@@ -1067,59 +1015,53 @@ function vtkCCSCheckPolygonSense(poly, points, normal) {
|
|
|
1067
1015
|
* @param {Bounds} bounds
|
|
1068
1016
|
* @param {Number} tol2
|
|
1069
1017
|
*/
|
|
1070
|
-
|
|
1071
1018
|
function vtkCCSPolyInPoly(outerPoly, innerPoly, points, normal, pp, bounds, tol2) {
|
|
1072
1019
|
// Find a vertex of poly "j" that isn't on the edge of poly "i".
|
|
1073
1020
|
// This is necessary or the PointInPolygon might return "true"
|
|
1074
1021
|
// based only on roundoff error.
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
for (var jj = 0; jj < m; jj++) {
|
|
1022
|
+
const n = outerPoly.length;
|
|
1023
|
+
const m = innerPoly.length;
|
|
1024
|
+
const p = [];
|
|
1025
|
+
const q1 = [];
|
|
1026
|
+
const q2 = [];
|
|
1027
|
+
for (let jj = 0; jj < m; jj++) {
|
|
1082
1028
|
// Semi-randomize the point order
|
|
1083
1029
|
// eslint-disable-next-line no-bitwise
|
|
1084
|
-
|
|
1030
|
+
const kk = (jj >> 1) + (jj & 1) * (m + 1 >> 1);
|
|
1085
1031
|
points.getPoint(innerPoly[kk], p);
|
|
1086
|
-
|
|
1087
|
-
|
|
1032
|
+
const intersectionState = vtkPolygon.pointInPolygon(p, pp, bounds, normal);
|
|
1088
1033
|
if (intersectionState === PolygonWithPointIntersectionState.FAILURE) {
|
|
1089
1034
|
vtkErrorMacro('Error finding point in polygon in vtkCCSPolyInPoly');
|
|
1090
1035
|
}
|
|
1091
|
-
|
|
1092
1036
|
if (intersectionState !== PolygonWithPointIntersectionState.OUTSIDE) {
|
|
1093
|
-
|
|
1037
|
+
let pointOnEdge = 0;
|
|
1094
1038
|
points.getPoint(outerPoly[n - 1], q1);
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1039
|
+
for (let ii = 0; ii < n; ii++) {
|
|
1040
|
+
points.getPoint(outerPoly[ii], q2);
|
|
1041
|
+
// This method returns distance squared
|
|
1042
|
+
const {
|
|
1043
|
+
distance
|
|
1044
|
+
} = vtkLine.distanceToLine(p, q1, q2);
|
|
1102
1045
|
if (distance < tol2) {
|
|
1103
1046
|
pointOnEdge = 1;
|
|
1104
1047
|
break;
|
|
1105
1048
|
}
|
|
1106
|
-
|
|
1107
1049
|
q1[0] = q2[0];
|
|
1108
1050
|
q1[1] = q2[1];
|
|
1109
1051
|
q1[2] = q2[2];
|
|
1110
1052
|
}
|
|
1111
|
-
|
|
1112
1053
|
if (!pointOnEdge) {
|
|
1113
1054
|
// Good result, point is in polygon
|
|
1114
1055
|
return true;
|
|
1115
1056
|
}
|
|
1116
1057
|
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1058
|
+
}
|
|
1119
1059
|
|
|
1060
|
+
// No matches found
|
|
1120
1061
|
return false;
|
|
1121
|
-
}
|
|
1062
|
+
}
|
|
1122
1063
|
|
|
1064
|
+
// ---------------------------------------------------
|
|
1123
1065
|
/**
|
|
1124
1066
|
* Precompute values needed for the PolyInPoly check.
|
|
1125
1067
|
* The values that are returned are as follows:
|
|
@@ -1133,29 +1075,27 @@ function vtkCCSPolyInPoly(outerPoly, innerPoly, points, normal, pp, bounds, tol2
|
|
|
1133
1075
|
* @param {Float64Array} pp
|
|
1134
1076
|
* @param {Bounds} bounds
|
|
1135
1077
|
*/
|
|
1136
|
-
|
|
1137
1078
|
function vtkCCSPrepareForPolyInPoly(outerPoly, points, pp, bounds) {
|
|
1138
|
-
|
|
1139
|
-
|
|
1079
|
+
const n = outerPoly.length;
|
|
1140
1080
|
if (n === 0) {
|
|
1141
1081
|
return 0.0; // to avoid false positive warning about uninitialized value
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
var point = [];
|
|
1146
|
-
var j = 0;
|
|
1082
|
+
}
|
|
1147
1083
|
|
|
1148
|
-
|
|
1084
|
+
// Pull out the points
|
|
1085
|
+
const point = [];
|
|
1086
|
+
let j = 0;
|
|
1087
|
+
for (let i = 0; i < n; i++) {
|
|
1149
1088
|
points.getPoint(outerPoly[i], point);
|
|
1150
1089
|
pp[j++] = point[0];
|
|
1151
1090
|
pp[j++] = point[1];
|
|
1152
1091
|
pp[j++] = point[2];
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1092
|
+
}
|
|
1155
1093
|
|
|
1094
|
+
// Find the bounding box and tolerance for the polygon
|
|
1156
1095
|
return vtkPolygon.getBounds(outerPoly, points, bounds) * (CCS_POLYGON_TOLERANCE * CCS_POLYGON_TOLERANCE);
|
|
1157
|
-
}
|
|
1096
|
+
}
|
|
1158
1097
|
|
|
1098
|
+
// ---------------------------------------------------
|
|
1159
1099
|
/**
|
|
1160
1100
|
* Check for polygons within polygons. Group the polygons
|
|
1161
1101
|
* if they are within each other. Reverse the sense of
|
|
@@ -1170,66 +1110,62 @@ function vtkCCSPrepareForPolyInPoly(outerPoly, points, pp, bounds) {
|
|
|
1170
1110
|
* @param {Vector3} normal
|
|
1171
1111
|
* @param {Boolean} oriented
|
|
1172
1112
|
*/
|
|
1173
|
-
|
|
1174
1113
|
function vtkCCSMakeHoleyPolys(newPolys, points, polyGroups, polyEdges, originalEdges, normal, oriented) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1114
|
+
const numNewPolys = newPolys.length;
|
|
1177
1115
|
if (numNewPolys <= 1) {
|
|
1178
1116
|
return;
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
var polyReversed = [];
|
|
1183
|
-
var innerPolys = []; // GroupCount is an array only needed for unoriented polys
|
|
1117
|
+
}
|
|
1184
1118
|
|
|
1185
|
-
|
|
1119
|
+
// Use bit arrays to keep track of inner polys
|
|
1120
|
+
const polyReversed = [];
|
|
1121
|
+
const innerPolys = [];
|
|
1186
1122
|
|
|
1123
|
+
// GroupCount is an array only needed for unoriented polys
|
|
1124
|
+
let groupCount;
|
|
1187
1125
|
if (!oriented) {
|
|
1188
1126
|
groupCount = new Int32Array(numNewPolys);
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
var nmax = 1;
|
|
1127
|
+
}
|
|
1193
1128
|
|
|
1194
|
-
|
|
1129
|
+
// Find the maximum poly size
|
|
1130
|
+
let nmax = 1;
|
|
1131
|
+
for (let kk = 0; kk < numNewPolys; kk++) {
|
|
1195
1132
|
nmax = Math.max(nmax, newPolys[kk].length);
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
var pp = new Float64Array(3 * nmax);
|
|
1200
|
-
var bounds = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
1201
|
-
var tol2; // Go through all polys
|
|
1133
|
+
}
|
|
1202
1134
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1135
|
+
// These are some values needed for poly-in-poly checks
|
|
1136
|
+
const pp = new Float64Array(3 * nmax);
|
|
1137
|
+
const bounds = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
1138
|
+
let tol2;
|
|
1205
1139
|
|
|
1140
|
+
// Go through all polys
|
|
1141
|
+
for (let i = 0; i < numNewPolys; i++) {
|
|
1142
|
+
const n = newPolys[i].length;
|
|
1206
1143
|
if (n < 3) {
|
|
1207
1144
|
// eslint-disable-next-line no-continue
|
|
1208
1145
|
continue;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
var _vtkCCSCheckPolygonSe = vtkCCSCheckPolygonSense(newPolys[i], points, normal),
|
|
1213
|
-
isNormalNotZero = _vtkCCSCheckPolygonSe.isNormalNotZero,
|
|
1214
|
-
sense = _vtkCCSCheckPolygonSe.sense;
|
|
1146
|
+
}
|
|
1215
1147
|
|
|
1148
|
+
// Check if poly is reversed
|
|
1149
|
+
const {
|
|
1150
|
+
isNormalNotZero,
|
|
1151
|
+
sense
|
|
1152
|
+
} = vtkCCSCheckPolygonSense(newPolys[i], points, normal);
|
|
1216
1153
|
if (isNormalNotZero) {
|
|
1217
1154
|
polyReversed[i] = !sense;
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1155
|
+
}
|
|
1220
1156
|
|
|
1221
|
-
|
|
1157
|
+
// Precompute some values needed for poly-in-poly checks
|
|
1158
|
+
tol2 = vtkCCSPrepareForPolyInPoly(newPolys[i], points, pp, bounds);
|
|
1222
1159
|
|
|
1223
|
-
|
|
1160
|
+
// Look for polygons inside of this one
|
|
1161
|
+
for (let j = 0; j < numNewPolys; j++) {
|
|
1224
1162
|
if (j !== i && newPolys[j].length >= 3) {
|
|
1225
1163
|
// Make sure polygon i is not in polygon j
|
|
1226
|
-
|
|
1227
|
-
|
|
1164
|
+
const pg = polyGroups[j];
|
|
1228
1165
|
if (!pg.includes(i)) {
|
|
1229
1166
|
if (vtkCCSPolyInPoly(newPolys[i], newPolys[j], points, normal, pp.subarray(3 * n), bounds, tol2)) {
|
|
1230
1167
|
// Add to group
|
|
1231
1168
|
polyGroups[i].push(j);
|
|
1232
|
-
|
|
1233
1169
|
if (groupCount) {
|
|
1234
1170
|
groupCount[j] += 1;
|
|
1235
1171
|
}
|
|
@@ -1238,109 +1174,97 @@ function vtkCCSMakeHoleyPolys(newPolys, points, polyGroups, polyEdges, originalE
|
|
|
1238
1174
|
}
|
|
1239
1175
|
}
|
|
1240
1176
|
}
|
|
1241
|
-
|
|
1242
1177
|
if (!oriented) {
|
|
1243
1178
|
// build a stack of polys that aren't inside other polys=
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
for (var ll = 0; ll < numNewPolys; ll++) {
|
|
1179
|
+
const outerPolyStack = [];
|
|
1180
|
+
for (let ll = 0; ll < numNewPolys; ll++) {
|
|
1247
1181
|
if (groupCount[ll] === 0) {
|
|
1248
1182
|
outerPolyStack.push(ll);
|
|
1249
1183
|
}
|
|
1250
1184
|
}
|
|
1251
|
-
|
|
1252
|
-
var _j;
|
|
1253
|
-
|
|
1185
|
+
let j;
|
|
1254
1186
|
while (outerPolyStack.length > 0) {
|
|
1255
|
-
|
|
1187
|
+
j = outerPolyStack.length - 1;
|
|
1256
1188
|
outerPolyStack.pop();
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
polyReversed[_j] = false;
|
|
1189
|
+
if (polyReversed[j]) {
|
|
1190
|
+
vtkCCSReversePoly(newPolys[j], polyEdges[j], originalEdges);
|
|
1191
|
+
polyReversed[j] = false;
|
|
1261
1192
|
}
|
|
1262
|
-
|
|
1263
|
-
if (polyGroups[_j].length > 1) {
|
|
1193
|
+
if (polyGroups[j].length > 1) {
|
|
1264
1194
|
// Convert the group into a bit array, to make manipulation easier
|
|
1265
1195
|
innerPolys.length = 0;
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
var jj = polyGroups[_j][k];
|
|
1269
|
-
|
|
1196
|
+
for (let k = 1; k < polyGroups[j].length; k++) {
|
|
1197
|
+
const jj = polyGroups[j][k];
|
|
1270
1198
|
if (groupCount[jj] > 1) {
|
|
1271
1199
|
groupCount[jj] -= 2;
|
|
1272
|
-
|
|
1273
1200
|
if (groupCount[jj] === 0) {
|
|
1274
1201
|
outerPolyStack.push(jj);
|
|
1275
1202
|
}
|
|
1276
1203
|
} else {
|
|
1277
1204
|
innerPolys[jj] = 1;
|
|
1278
1205
|
polyGroups[jj].length = 0;
|
|
1279
|
-
|
|
1280
1206
|
if (!polyReversed[jj]) {
|
|
1281
1207
|
vtkCCSReversePoly(newPolys[jj], polyEdges[jj], originalEdges);
|
|
1282
1208
|
polyReversed[jj] = false;
|
|
1283
1209
|
}
|
|
1284
1210
|
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
polyGroups[_j].length = 0;
|
|
1289
|
-
|
|
1290
|
-
polyGroups[_j].push(_j);
|
|
1211
|
+
}
|
|
1291
1212
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1213
|
+
// Use the bit array to recreate the polyGroup
|
|
1214
|
+
polyGroups[j].length = 0;
|
|
1215
|
+
polyGroups[j].push(j);
|
|
1216
|
+
for (let jj = 0; jj < numNewPolys; jj++) {
|
|
1217
|
+
if (innerPolys[jj]) {
|
|
1218
|
+
polyGroups[j].push(jj);
|
|
1295
1219
|
}
|
|
1296
1220
|
}
|
|
1297
1221
|
}
|
|
1298
1222
|
}
|
|
1299
1223
|
} else {
|
|
1300
1224
|
// oriented
|
|
1301
|
-
for (
|
|
1225
|
+
for (let j = 0; j < numNewPolys; j++) {
|
|
1302
1226
|
// Remove the groups for reversed polys
|
|
1303
|
-
if (polyReversed[
|
|
1304
|
-
polyGroups[
|
|
1305
|
-
}
|
|
1227
|
+
if (polyReversed[j]) {
|
|
1228
|
+
polyGroups[j].length = 0;
|
|
1229
|
+
}
|
|
1230
|
+
// Polys inside the interior polys have their own groups, so remove
|
|
1306
1231
|
// them from this group
|
|
1307
|
-
else if (polyGroups[
|
|
1232
|
+
else if (polyGroups[j].length > 1) {
|
|
1308
1233
|
// Convert the group into a bit array, to make manipulation easier
|
|
1309
1234
|
innerPolys.length = 0;
|
|
1235
|
+
for (let k = 1; k < polyGroups[j].length; k++) {
|
|
1236
|
+
innerPolys[polyGroups[j][k]] = true;
|
|
1237
|
+
}
|
|
1310
1238
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
} // Look for non-reversed polys inside this one
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
for (var _kk = 1; _kk < polyGroups[_j2].length; _kk++) {
|
|
1239
|
+
// Look for non-reversed polys inside this one
|
|
1240
|
+
for (let kk = 1; kk < polyGroups[j].length; kk++) {
|
|
1317
1241
|
// jj is the index of the inner poly
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
if (!polyReversed[
|
|
1242
|
+
const jj = polyGroups[j][kk];
|
|
1243
|
+
// If inner poly is not reversed then
|
|
1244
|
+
if (!polyReversed[jj]) {
|
|
1321
1245
|
// Remove that poly and all polys inside of it from the group
|
|
1322
|
-
for (
|
|
1323
|
-
innerPolys[polyGroups[
|
|
1246
|
+
for (let ii = 0; ii < polyGroups[jj].length; ii++) {
|
|
1247
|
+
innerPolys[polyGroups[jj][ii]] = false;
|
|
1324
1248
|
}
|
|
1325
1249
|
}
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
polyGroups[_j2].length = 0;
|
|
1330
|
-
|
|
1331
|
-
polyGroups[_j2].push(_j2);
|
|
1250
|
+
}
|
|
1332
1251
|
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1252
|
+
// Use the bit array to recreate the polyGroup
|
|
1253
|
+
polyGroups[j].length = 0;
|
|
1254
|
+
polyGroups[j].push(j);
|
|
1255
|
+
for (let jj = 0; jj < numNewPolys; jj++) {
|
|
1256
|
+
if (innerPolys[jj]) {
|
|
1257
|
+
polyGroups[j].push(jj);
|
|
1336
1258
|
}
|
|
1337
1259
|
}
|
|
1338
1260
|
}
|
|
1339
1261
|
}
|
|
1340
|
-
}
|
|
1262
|
+
}
|
|
1341
1263
|
|
|
1342
|
-
|
|
1264
|
+
// delete[] groupCount;
|
|
1265
|
+
}
|
|
1343
1266
|
|
|
1267
|
+
// ---------------------------------------------------
|
|
1344
1268
|
/**
|
|
1345
1269
|
* Check line segment with point Ids (i, j) to make sure that it
|
|
1346
1270
|
* doesn't cut through the edges of any polys in the group.
|
|
@@ -1356,110 +1280,99 @@ function vtkCCSMakeHoleyPolys(newPolys, points, polyGroups, polyEdges, originalE
|
|
|
1356
1280
|
* @param {Number} outerIdx
|
|
1357
1281
|
* @param {Number} innerIdx
|
|
1358
1282
|
*/
|
|
1359
|
-
|
|
1360
1283
|
function vtkCCSCheckCut(polys, points, normal, polyGroup, outerPolyId, innerPolyId, outerIdx, innerIdx) {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1284
|
+
const ptId1 = polys[outerPolyId][outerIdx];
|
|
1285
|
+
const ptId2 = polys[innerPolyId][innerIdx];
|
|
1286
|
+
const tol = CCS_POLYGON_TOLERANCE;
|
|
1287
|
+
const p1 = [];
|
|
1288
|
+
const p2 = [];
|
|
1366
1289
|
points.getPoint(ptId1, p1);
|
|
1367
1290
|
points.getPoint(ptId2, p2);
|
|
1368
|
-
|
|
1291
|
+
const w = [];
|
|
1369
1292
|
subtract(p2, p1, w);
|
|
1370
|
-
|
|
1293
|
+
const l = normalize(w);
|
|
1371
1294
|
|
|
1295
|
+
// Cuts between coincident points are good
|
|
1372
1296
|
if (l === 0) {
|
|
1373
1297
|
return true;
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
var tol2 = l * l * tol * tol; // Check the sense of the cut: it must be pointing "in" for both polys.
|
|
1378
|
-
|
|
1379
|
-
var polyId = outerPolyId;
|
|
1380
|
-
var polyIdx = outerIdx;
|
|
1381
|
-
var r = p1;
|
|
1382
|
-
var r1 = [];
|
|
1383
|
-
var r2 = p2;
|
|
1384
|
-
var r3 = [];
|
|
1385
|
-
|
|
1386
|
-
for (var ii = 0; ii < 2; ii++) {
|
|
1387
|
-
var poly = polys[polyId];
|
|
1388
|
-
var n = poly.length;
|
|
1389
|
-
var prevIdx = n - polyIdx - 1;
|
|
1390
|
-
var nextIdx = polyIdx + 1;
|
|
1298
|
+
}
|
|
1391
1299
|
|
|
1300
|
+
// Define a tolerance with units of distance squared
|
|
1301
|
+
const tol2 = l * l * tol * tol;
|
|
1302
|
+
|
|
1303
|
+
// Check the sense of the cut: it must be pointing "in" for both polys.
|
|
1304
|
+
let polyId = outerPolyId;
|
|
1305
|
+
let polyIdx = outerIdx;
|
|
1306
|
+
let r = p1;
|
|
1307
|
+
const r1 = [];
|
|
1308
|
+
let r2 = p2;
|
|
1309
|
+
const r3 = [];
|
|
1310
|
+
for (let ii = 0; ii < 2; ii++) {
|
|
1311
|
+
const poly = polys[polyId];
|
|
1312
|
+
const n = poly.length;
|
|
1313
|
+
let prevIdx = n - polyIdx - 1;
|
|
1314
|
+
let nextIdx = polyIdx + 1;
|
|
1392
1315
|
if (prevIdx >= n) {
|
|
1393
1316
|
prevIdx -= n;
|
|
1394
1317
|
}
|
|
1395
|
-
|
|
1396
1318
|
if (nextIdx >= n) {
|
|
1397
1319
|
nextIdx -= n;
|
|
1398
1320
|
}
|
|
1399
|
-
|
|
1400
1321
|
points.getPoint(poly[prevIdx], r1);
|
|
1401
1322
|
points.getPoint(poly[nextIdx], r3);
|
|
1402
|
-
|
|
1403
1323
|
if (vtkCCSVectorProgression(r, r1, r2, r3, normal) > 0) {
|
|
1404
1324
|
return false;
|
|
1405
1325
|
}
|
|
1406
|
-
|
|
1407
1326
|
polyId = innerPolyId;
|
|
1408
1327
|
polyIdx = innerIdx;
|
|
1409
1328
|
r = p2;
|
|
1410
1329
|
r2 = p1;
|
|
1411
|
-
}
|
|
1412
|
-
// First, create a cut plane that divides space at the cut line.
|
|
1413
|
-
|
|
1330
|
+
}
|
|
1414
1331
|
|
|
1415
|
-
|
|
1332
|
+
// Check for intersections of the cut with polygon edges.
|
|
1333
|
+
// First, create a cut plane that divides space at the cut line.
|
|
1334
|
+
const pc = [];
|
|
1416
1335
|
cross(normal, w, pc);
|
|
1417
1336
|
pc[3] = -dot(pc, p1);
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
var qtId1 = _poly2[_n - 1];
|
|
1337
|
+
for (let i = 0; i < polyGroup.length; i++) {
|
|
1338
|
+
const poly = polys[polyGroup[i]];
|
|
1339
|
+
const n = poly.length;
|
|
1340
|
+
const q1 = [];
|
|
1341
|
+
const q2 = [];
|
|
1342
|
+
let qtId1 = poly[n - 1];
|
|
1425
1343
|
points.getPoint(qtId1, q1);
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
var qtId2 = _poly2[j];
|
|
1344
|
+
let v1 = pc[0] * q1[0] + pc[1] * q1[1] + pc[2] * q1[2] + pc[3];
|
|
1345
|
+
let c1 = v1 > 0;
|
|
1346
|
+
for (let j = 0; j < n; j++) {
|
|
1347
|
+
const qtId2 = poly[j];
|
|
1431
1348
|
points.getPoint(qtId2, q2);
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
// so don't bother with the check.
|
|
1349
|
+
const v2 = pc[0] * q2[0] + pc[1] * q2[1] + pc[2] * q2[2] + pc[3];
|
|
1350
|
+
const c2 = v2 > 0;
|
|
1435
1351
|
|
|
1352
|
+
// If lines share an endpoint, they can't intersect,
|
|
1353
|
+
// so don't bother with the check.
|
|
1436
1354
|
if (ptId1 !== qtId1 && ptId1 !== qtId2 && ptId2 !== qtId1 && ptId2 !== qtId2) {
|
|
1437
1355
|
// Check for intersection
|
|
1438
1356
|
if ((c1 ? !c2 : c2) || v1 * v1 < tol2 || v2 * v2 < tol2) {
|
|
1439
1357
|
subtract(q2, q1, w);
|
|
1440
|
-
|
|
1441
1358
|
if (dot(w, w) > 0) {
|
|
1442
|
-
|
|
1359
|
+
const qc = [];
|
|
1443
1360
|
cross(w, normal, qc);
|
|
1444
1361
|
qc[3] = -dot(qc, q1);
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1362
|
+
const u1 = qc[0] * p1[0] + qc[1] * p1[1] + qc[2] * p1[2] + qc[3];
|
|
1363
|
+
const u2 = qc[0] * p2[0] + qc[1] * p2[1] + qc[2] * p2[2] + qc[3];
|
|
1364
|
+
const d1 = u1 > 0;
|
|
1365
|
+
const d2 = u2 > 0;
|
|
1450
1366
|
if (d1 ? !d2 : d2) {
|
|
1451
1367
|
// One final check to make sure endpoints aren't coincident
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1368
|
+
let p = p1;
|
|
1369
|
+
let q = q1;
|
|
1455
1370
|
if (v2 * v2 < v1 * v1) {
|
|
1456
1371
|
p = p2;
|
|
1457
1372
|
}
|
|
1458
|
-
|
|
1459
1373
|
if (u2 * u2 < u1 * u1) {
|
|
1460
1374
|
q = q2;
|
|
1461
1375
|
}
|
|
1462
|
-
|
|
1463
1376
|
if (distance2BetweenPoints(p, q) > tol2) {
|
|
1464
1377
|
return false;
|
|
1465
1378
|
}
|
|
@@ -1467,7 +1380,6 @@ function vtkCCSCheckCut(polys, points, normal, polyGroup, outerPolyId, innerPoly
|
|
|
1467
1380
|
}
|
|
1468
1381
|
}
|
|
1469
1382
|
}
|
|
1470
|
-
|
|
1471
1383
|
qtId1 = qtId2;
|
|
1472
1384
|
q1[0] = q2[0];
|
|
1473
1385
|
q1[1] = q2[1];
|
|
@@ -1476,10 +1388,10 @@ function vtkCCSCheckCut(polys, points, normal, polyGroup, outerPolyId, innerPoly
|
|
|
1476
1388
|
c1 = c2;
|
|
1477
1389
|
}
|
|
1478
1390
|
}
|
|
1479
|
-
|
|
1480
1391
|
return true;
|
|
1481
|
-
}
|
|
1392
|
+
}
|
|
1482
1393
|
|
|
1394
|
+
// ---------------------------------------------------
|
|
1483
1395
|
/**
|
|
1484
1396
|
* Check the quality of a cut between an outer and inner polygon.
|
|
1485
1397
|
* An ideal cut is one that forms a 90 degree angle with each
|
|
@@ -1492,85 +1404,73 @@ function vtkCCSCheckCut(polys, points, normal, polyGroup, outerPolyId, innerPoly
|
|
|
1492
1404
|
* @param {Number} j
|
|
1493
1405
|
* @param {vtkPoints} points
|
|
1494
1406
|
*/
|
|
1495
|
-
|
|
1496
1407
|
function vtkCCSCutQuality(outerPoly, innerPoly, i, j, points) {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1408
|
+
const n = outerPoly.length;
|
|
1409
|
+
const m = innerPoly.length;
|
|
1410
|
+
const a = i > 0 ? i - 1 : n - 1;
|
|
1411
|
+
const b = i < n - 1 ? i + 1 : 0;
|
|
1412
|
+
const c = j > 0 ? j - 1 : m - 1;
|
|
1413
|
+
const d = j < m - 1 ? j + 1 : 0;
|
|
1414
|
+
const p0 = [];
|
|
1415
|
+
const p1 = [];
|
|
1416
|
+
const p2 = [];
|
|
1506
1417
|
points.getPoint(outerPoly[i], p1);
|
|
1507
1418
|
points.getPoint(innerPoly[j], p2);
|
|
1508
|
-
|
|
1509
|
-
|
|
1419
|
+
const v1 = [];
|
|
1420
|
+
const v2 = [];
|
|
1510
1421
|
subtract(p2, p1, v1);
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1422
|
+
const l1 = dot(v1, v1);
|
|
1423
|
+
let l2;
|
|
1424
|
+
let qmax = 0;
|
|
1425
|
+
let q;
|
|
1515
1426
|
points.getPoint(outerPoly[a], p0);
|
|
1516
1427
|
subtract(p0, p1, v2);
|
|
1517
1428
|
l2 = dot(v2, v2);
|
|
1518
|
-
|
|
1519
1429
|
if (l2 > 0) {
|
|
1520
1430
|
q = dot(v1, v2);
|
|
1521
1431
|
q *= q / l2;
|
|
1522
|
-
|
|
1523
1432
|
if (q > qmax) {
|
|
1524
1433
|
qmax = q;
|
|
1525
1434
|
}
|
|
1526
1435
|
}
|
|
1527
|
-
|
|
1528
1436
|
points.getPoint(outerPoly[b], p0);
|
|
1529
1437
|
subtract(p0, p1, v2);
|
|
1530
1438
|
l2 = dot(v2, v2);
|
|
1531
|
-
|
|
1532
1439
|
if (l2 > 0) {
|
|
1533
1440
|
q = dot(v1, v2);
|
|
1534
1441
|
q *= q / l2;
|
|
1535
|
-
|
|
1536
1442
|
if (q > qmax) {
|
|
1537
1443
|
qmax = q;
|
|
1538
1444
|
}
|
|
1539
1445
|
}
|
|
1540
|
-
|
|
1541
1446
|
points.getPoint(innerPoly[c], p0);
|
|
1542
1447
|
subtract(p2, p0, v2);
|
|
1543
1448
|
l2 = dot(v2, v2);
|
|
1544
|
-
|
|
1545
1449
|
if (l2 > 0) {
|
|
1546
1450
|
q = dot(v1, v2);
|
|
1547
1451
|
q *= q / l2;
|
|
1548
|
-
|
|
1549
1452
|
if (q > qmax) {
|
|
1550
1453
|
qmax = q;
|
|
1551
1454
|
}
|
|
1552
1455
|
}
|
|
1553
|
-
|
|
1554
1456
|
points.getPoint(innerPoly[d], p0);
|
|
1555
1457
|
subtract(p2, p0, v2);
|
|
1556
1458
|
l2 = dot(v2, v2);
|
|
1557
|
-
|
|
1558
1459
|
if (l2 > 0) {
|
|
1559
1460
|
q = dot(v1, v2);
|
|
1560
1461
|
q *= q / l2;
|
|
1561
|
-
|
|
1562
1462
|
if (q > qmax) {
|
|
1563
1463
|
qmax = q;
|
|
1564
1464
|
}
|
|
1565
1465
|
}
|
|
1566
|
-
|
|
1567
1466
|
if (l1 > 0) {
|
|
1568
1467
|
return qmax / l1; // also l1 + qmax, incorporates distance;
|
|
1569
1468
|
}
|
|
1570
1469
|
|
|
1571
1470
|
return Number.MAX_VALUE;
|
|
1572
|
-
}
|
|
1471
|
+
}
|
|
1573
1472
|
|
|
1473
|
+
// ---------------------------------------------------
|
|
1574
1474
|
/**
|
|
1575
1475
|
* Find the two sharpest verts on an inner (i.e. inside-out) poly.
|
|
1576
1476
|
*
|
|
@@ -1579,50 +1479,44 @@ function vtkCCSCutQuality(outerPoly, innerPoly, i, j, points) {
|
|
|
1579
1479
|
* @param {Vector3} normal
|
|
1580
1480
|
* @param {[Number, Number]} verts
|
|
1581
1481
|
*/
|
|
1582
|
-
|
|
1583
1482
|
function vtkCCSFindSharpestVerts(poly, points, normal, verts) {
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1483
|
+
const p1 = [];
|
|
1484
|
+
const p2 = [];
|
|
1485
|
+
const v1 = [];
|
|
1486
|
+
const v2 = [];
|
|
1487
|
+
const v = [];
|
|
1488
|
+
let l1;
|
|
1489
|
+
let l2;
|
|
1490
|
+
const minVal = [0, 0];
|
|
1592
1491
|
verts[0] = 0;
|
|
1593
1492
|
verts[1] = 0;
|
|
1594
|
-
|
|
1493
|
+
const n = poly.length;
|
|
1595
1494
|
points.getPoint(poly[n - 1], p2);
|
|
1596
1495
|
points.getPoint(poly[0], p1);
|
|
1597
1496
|
subtract(p1, p2, v1);
|
|
1598
1497
|
l1 = Math.sqrt(dot(v1, v1));
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
var k = j + 1;
|
|
1602
|
-
|
|
1498
|
+
for (let j = 0; j < n; j++) {
|
|
1499
|
+
let k = j + 1;
|
|
1603
1500
|
if (k === n) {
|
|
1604
1501
|
k = 0;
|
|
1605
1502
|
}
|
|
1606
|
-
|
|
1607
1503
|
points.getPoint(poly[k], p2);
|
|
1608
1504
|
subtract(p2, p1, v2);
|
|
1609
1505
|
l2 = Math.sqrt(dot(v2, v2));
|
|
1610
1506
|
cross(v1, v2, v);
|
|
1611
|
-
|
|
1612
|
-
|
|
1507
|
+
const b = dot(v, normal);
|
|
1613
1508
|
if (b < 0 && l1 * l2 > 0) {
|
|
1614
1509
|
// Dot product is |v1||v2|cos(theta), range [-1, +1]
|
|
1615
|
-
|
|
1616
|
-
|
|
1510
|
+
const val = dot(v1, v2) / (l1 * l2);
|
|
1617
1511
|
if (val < minVal[0]) {
|
|
1618
1512
|
minVal[1] = minVal[0];
|
|
1619
1513
|
minVal[0] = val;
|
|
1620
1514
|
verts[1] = verts[0];
|
|
1621
1515
|
verts[0] = j;
|
|
1622
1516
|
}
|
|
1623
|
-
}
|
|
1624
|
-
|
|
1517
|
+
}
|
|
1625
1518
|
|
|
1519
|
+
// Rotate to the next point
|
|
1626
1520
|
p1[0] = p2[0];
|
|
1627
1521
|
p1[1] = p2[1];
|
|
1628
1522
|
p1[2] = p2[2];
|
|
@@ -1631,8 +1525,9 @@ function vtkCCSFindSharpestVerts(poly, points, normal, verts) {
|
|
|
1631
1525
|
v1[2] = v2[2];
|
|
1632
1526
|
l1 = l2;
|
|
1633
1527
|
}
|
|
1634
|
-
}
|
|
1528
|
+
}
|
|
1635
1529
|
|
|
1530
|
+
// ---------------------------------------------------
|
|
1636
1531
|
/**
|
|
1637
1532
|
* Find two valid cuts between outerPoly and innerPoly.
|
|
1638
1533
|
* Used by vtkCCSCutHoleyPolys.
|
|
@@ -1646,74 +1541,68 @@ function vtkCCSFindSharpestVerts(poly, points, normal, verts) {
|
|
|
1646
1541
|
* @param {Array[]} cuts
|
|
1647
1542
|
* @param {Boolean} exhaustive
|
|
1648
1543
|
*/
|
|
1649
|
-
|
|
1650
1544
|
function vtkCCSFindCuts(polys, polyGroup, outerPolyId, innerPolyId, points, normal, cuts, exhaustive) {
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
vtkCCSFindSharpestVerts(innerPoly, points, normal, verts);
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
cutlist
|
|
1660
|
-
|
|
1661
|
-
|
|
1545
|
+
const outerPoly = polys[outerPolyId];
|
|
1546
|
+
const innerPoly = polys[innerPolyId];
|
|
1547
|
+
const innerSize = innerPoly.length;
|
|
1548
|
+
// Find the two sharpest points on the inner poly
|
|
1549
|
+
const verts = [];
|
|
1550
|
+
vtkCCSFindSharpestVerts(innerPoly, points, normal, verts);
|
|
1551
|
+
|
|
1552
|
+
// A list of cut locations according to quality
|
|
1553
|
+
const cutlist = [];
|
|
1554
|
+
cutlist.length = outerPoly.length;
|
|
1555
|
+
|
|
1556
|
+
// Search for potential cuts (need to find two cuts)
|
|
1557
|
+
let cutId = 0;
|
|
1662
1558
|
cuts[0][0] = 0;
|
|
1663
1559
|
cuts[0][1] = 0;
|
|
1664
1560
|
cuts[1][0] = 0;
|
|
1665
1561
|
cuts[1][1] = 0;
|
|
1666
|
-
|
|
1667
|
-
|
|
1562
|
+
let foundCut = false;
|
|
1668
1563
|
for (cutId = 0; cutId < 2; cutId++) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
for (var i = 0; i < count && !foundCut; i++) {
|
|
1564
|
+
const count = exhaustive ? innerSize : 3;
|
|
1565
|
+
for (let i = 0; i < count && !foundCut; i++) {
|
|
1672
1566
|
// Semi-randomize the search order
|
|
1673
1567
|
// TODO: Does this do the same as in C++?
|
|
1674
1568
|
// eslint-disable-next-line no-bitwise
|
|
1675
|
-
|
|
1676
|
-
|
|
1569
|
+
let j = (i >> 1) + (i & 1) * (innerSize + 1 >> 1);
|
|
1570
|
+
// Start at the best first point
|
|
1677
1571
|
j = (j + verts[cutId]) % innerSize;
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
var q = vtkCCSCutQuality(outerPoly, innerPoly, kk, j, points);
|
|
1572
|
+
for (let kk = 0; kk < outerPoly.length; kk++) {
|
|
1573
|
+
const q = vtkCCSCutQuality(outerPoly, innerPoly, kk, j, points);
|
|
1681
1574
|
cutlist[kk] = [q, kk];
|
|
1682
1575
|
}
|
|
1576
|
+
cutlist.sort((a, b) => a[0] - b[0]);
|
|
1577
|
+
for (let lid = 0; lid < cutlist.length; lid++) {
|
|
1578
|
+
const k = cutlist[lid][1];
|
|
1683
1579
|
|
|
1684
|
-
|
|
1685
|
-
return a[0] - b[0];
|
|
1686
|
-
});
|
|
1687
|
-
|
|
1688
|
-
for (var lid = 0; lid < cutlist.length; lid++) {
|
|
1689
|
-
var k = cutlist[lid][1]; // If this is the second cut, do extra checks
|
|
1690
|
-
|
|
1580
|
+
// If this is the second cut, do extra checks
|
|
1691
1581
|
if (cutId > 0) {
|
|
1692
1582
|
// Make sure cuts don't share an endpoint
|
|
1693
1583
|
if (j === cuts[0][1] || k === cuts[0][0]) {
|
|
1694
1584
|
// eslint-disable-next-line no-continue
|
|
1695
1585
|
continue;
|
|
1696
|
-
}
|
|
1697
|
-
|
|
1586
|
+
}
|
|
1698
1587
|
|
|
1699
|
-
|
|
1700
|
-
|
|
1588
|
+
// Make sure cuts don't intersect
|
|
1589
|
+
const p1 = [];
|
|
1590
|
+
const p2 = [];
|
|
1701
1591
|
points.getPoint(outerPoly[cuts[0][0]], p1);
|
|
1702
1592
|
points.getPoint(innerPoly[cuts[0][1]], p2);
|
|
1703
|
-
|
|
1704
|
-
|
|
1593
|
+
const q1 = [];
|
|
1594
|
+
const q2 = [];
|
|
1705
1595
|
points.getPoint(outerPoly[k], q1);
|
|
1706
1596
|
points.getPoint(innerPoly[j], q2);
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1597
|
+
let u;
|
|
1598
|
+
let v;
|
|
1710
1599
|
if (vtkLine.intersection(p1, p2, q1, q2, u, v) === vtkLine.IntersectionState.YES_INTERSECTION) {
|
|
1711
1600
|
// eslint-disable-next-line no-continue
|
|
1712
1601
|
continue;
|
|
1713
1602
|
}
|
|
1714
|
-
}
|
|
1715
|
-
|
|
1603
|
+
}
|
|
1716
1604
|
|
|
1605
|
+
// This check is done for both cuts
|
|
1717
1606
|
if (vtkCCSCheckCut(polys, points, normal, polyGroup, outerPolyId, innerPolyId, k, j)) {
|
|
1718
1607
|
cuts[cutId][0] = k;
|
|
1719
1608
|
cuts[cutId][1] = j;
|
|
@@ -1722,15 +1611,14 @@ function vtkCCSFindCuts(polys, polyGroup, outerPolyId, innerPolyId, points, norm
|
|
|
1722
1611
|
}
|
|
1723
1612
|
}
|
|
1724
1613
|
}
|
|
1725
|
-
|
|
1726
1614
|
if (!foundCut) {
|
|
1727
1615
|
return false;
|
|
1728
1616
|
}
|
|
1729
1617
|
}
|
|
1730
|
-
|
|
1731
1618
|
return true;
|
|
1732
|
-
}
|
|
1619
|
+
}
|
|
1733
1620
|
|
|
1621
|
+
// ---------------------------------------------------
|
|
1734
1622
|
/**
|
|
1735
1623
|
* Helper for vtkCCSCutHoleyPolys. Change a polygon and a hole
|
|
1736
1624
|
* into two separate polygons by making two cuts between them.
|
|
@@ -1742,88 +1630,79 @@ function vtkCCSFindCuts(polys, polyGroup, outerPolyId, innerPolyId, points, norm
|
|
|
1742
1630
|
* @param {vtkPoints} points
|
|
1743
1631
|
* @param {Array[]} cuts
|
|
1744
1632
|
*/
|
|
1745
|
-
|
|
1746
1633
|
function vtkCCSMakeCuts(polys, polyEdges, outerPolyId, innerPolyId, points, cuts) {
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
var ptId2 = polys[innerPolyId][cuts[bb][1]];
|
|
1634
|
+
const q = [];
|
|
1635
|
+
const r = [];
|
|
1636
|
+
for (let bb = 0; bb < 2; bb++) {
|
|
1637
|
+
const ptId1 = polys[outerPolyId][cuts[bb][0]];
|
|
1638
|
+
const ptId2 = polys[innerPolyId][cuts[bb][1]];
|
|
1753
1639
|
points.getPoint(ptId1, q);
|
|
1754
1640
|
points.getPoint(ptId2, r);
|
|
1755
1641
|
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1642
|
+
const outerPoly = polys[outerPolyId];
|
|
1643
|
+
const innerPoly = polys[innerPolyId];
|
|
1644
|
+
const outerEdges = polyEdges[outerPolyId];
|
|
1645
|
+
const innerEdges = polyEdges[innerPolyId];
|
|
1646
|
+
|
|
1647
|
+
// Generate new polys from the cuts
|
|
1648
|
+
const n = outerPoly.length;
|
|
1649
|
+
const m = innerPoly.length;
|
|
1650
|
+
let idx;
|
|
1651
|
+
|
|
1652
|
+
// Generate poly1
|
|
1653
|
+
const n1 = n * (cuts[1][0] < cuts[0][0]) + cuts[1][0] - cuts[0][0] + 1;
|
|
1654
|
+
const n2 = n1 + m * (cuts[0][1] < cuts[1][1]) + cuts[0][1] - cuts[1][1] + 1;
|
|
1655
|
+
const poly1 = [];
|
|
1769
1656
|
poly1.length = n2;
|
|
1770
|
-
|
|
1657
|
+
const edges1 = new Array(n2);
|
|
1771
1658
|
idx = cuts[0][0];
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
var k = idx++;
|
|
1659
|
+
for (let i1 = 0; i1 < n1; i1++) {
|
|
1660
|
+
const k = idx++;
|
|
1775
1661
|
poly1[i1] = outerPoly[k];
|
|
1776
1662
|
edges1[i1] = outerEdges[k];
|
|
1777
1663
|
idx *= idx !== n;
|
|
1778
1664
|
}
|
|
1779
|
-
|
|
1780
1665
|
edges1[n1 - 1] = -1;
|
|
1781
1666
|
idx = cuts[1][1];
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
poly1[i2] = innerPoly[_k2];
|
|
1787
|
-
edges1[i2] = innerEdges[_k2];
|
|
1667
|
+
for (let i2 = n1; i2 < n2; i2++) {
|
|
1668
|
+
const k = idx++;
|
|
1669
|
+
poly1[i2] = innerPoly[k];
|
|
1670
|
+
edges1[i2] = innerEdges[k];
|
|
1788
1671
|
idx *= idx !== m;
|
|
1789
1672
|
}
|
|
1673
|
+
edges1[n2 - 1] = -1;
|
|
1790
1674
|
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
var poly2 = [];
|
|
1675
|
+
// Generate poly2
|
|
1676
|
+
const m1 = n * (cuts[0][0] < cuts[1][0]) + cuts[0][0] - cuts[1][0] + 1;
|
|
1677
|
+
const m2 = m1 + m * (cuts[1][1] < cuts[0][1]) + cuts[1][1] - cuts[0][1] + 1;
|
|
1678
|
+
const poly2 = [];
|
|
1796
1679
|
poly2.length = m2;
|
|
1797
|
-
|
|
1680
|
+
const edges2 = new Array(m2);
|
|
1798
1681
|
idx = cuts[1][0];
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
poly2[j1] = outerPoly[_k3];
|
|
1804
|
-
edges2[j1] = outerEdges[_k3];
|
|
1682
|
+
for (let j1 = 0; j1 < m1; j1++) {
|
|
1683
|
+
const k = idx++;
|
|
1684
|
+
poly2[j1] = outerPoly[k];
|
|
1685
|
+
edges2[j1] = outerEdges[k];
|
|
1805
1686
|
idx *= idx !== n;
|
|
1806
1687
|
}
|
|
1807
|
-
|
|
1808
1688
|
edges2[m1 - 1] = -1;
|
|
1809
1689
|
idx = cuts[0][1];
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
poly2[j2] = innerPoly[_k4];
|
|
1815
|
-
edges2[j2] = innerEdges[_k4];
|
|
1690
|
+
for (let j2 = m1; j2 < m2; j2++) {
|
|
1691
|
+
const k = idx++;
|
|
1692
|
+
poly2[j2] = innerPoly[k];
|
|
1693
|
+
edges2[j2] = innerEdges[k];
|
|
1816
1694
|
idx *= idx !== m;
|
|
1817
1695
|
}
|
|
1696
|
+
edges2[m2 - 1] = -1;
|
|
1818
1697
|
|
|
1819
|
-
|
|
1820
|
-
|
|
1698
|
+
// Replace outerPoly and innerPoly with these new polys
|
|
1821
1699
|
polys[outerPolyId] = poly1;
|
|
1822
1700
|
polys[innerPolyId] = poly2;
|
|
1823
1701
|
polyEdges[outerPolyId] = edges1;
|
|
1824
1702
|
polyEdges[innerPolyId] = edges2;
|
|
1825
|
-
}
|
|
1703
|
+
}
|
|
1826
1704
|
|
|
1705
|
+
// ---------------------------------------------------
|
|
1827
1706
|
/**
|
|
1828
1707
|
* After the holes have been identified, make cuts between the
|
|
1829
1708
|
* outer poly and each hole. Make two cuts per hole. The only
|
|
@@ -1838,44 +1717,41 @@ function vtkCCSMakeCuts(polys, polyEdges, outerPolyId, innerPolyId, points, cuts
|
|
|
1838
1717
|
* @param {Vector3} normal
|
|
1839
1718
|
* @returns {boolean}
|
|
1840
1719
|
*/
|
|
1841
|
-
|
|
1842
1720
|
function vtkCCSCutHoleyPolys(polys, points, polyGroups, polyEdges, normal) {
|
|
1843
|
-
|
|
1721
|
+
let cutFailure = 0;
|
|
1722
|
+
|
|
1723
|
+
// Go through all groups and cut out the first inner poly that is
|
|
1844
1724
|
// found. Every time an inner poly is cut out, the groupId counter
|
|
1845
1725
|
// is reset because cutting a poly creates a new group.
|
|
1846
|
-
|
|
1847
|
-
var groupId = 0;
|
|
1848
|
-
|
|
1726
|
+
let groupId = 0;
|
|
1849
1727
|
while (groupId < polyGroups.length) {
|
|
1850
|
-
|
|
1728
|
+
const polyGroup = polyGroups[groupId];
|
|
1851
1729
|
|
|
1730
|
+
// Only need to make a cut if the group size is greater than 1
|
|
1852
1731
|
if (polyGroup.length > 1) {
|
|
1853
1732
|
// The first member of the group is the outer poly
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
var innerPolyId = polyGroup[1]; // Sort the group by size, do largest holes first
|
|
1733
|
+
const outerPolyId = polyGroup[0];
|
|
1857
1734
|
|
|
1858
|
-
|
|
1735
|
+
// The second member of the group is the first inner poly
|
|
1736
|
+
let innerPolyId = polyGroup[1];
|
|
1859
1737
|
|
|
1860
|
-
|
|
1738
|
+
// Sort the group by size, do largest holes first
|
|
1739
|
+
let innerBySize = new Array(polyGroup.length);
|
|
1740
|
+
for (let i = 1; i < polyGroup.length; i++) {
|
|
1861
1741
|
innerBySize[i] = [polys[polyGroup[i]].length, i];
|
|
1862
1742
|
}
|
|
1743
|
+
innerBySize = [innerBySize[0], ...innerBySize.splice(1).sort((a, b) => a[0] - b[0])];
|
|
1744
|
+
reverseElements(innerBySize, 1, innerBySize.length - 1);
|
|
1863
1745
|
|
|
1864
|
-
|
|
1865
|
-
return a[0] - b[0];
|
|
1866
|
-
})));
|
|
1867
|
-
reverseElements(innerBySize, 1, innerBySize.length - 1); // Need to check all inner polys in sequence, until one succeeds.
|
|
1746
|
+
// Need to check all inner polys in sequence, until one succeeds.
|
|
1868
1747
|
// Do a quick search first, then do an exhaustive search.
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
for (var exhaustive = 0; exhaustive < 2 && !madeCut; exhaustive++) {
|
|
1874
|
-
for (var j = 1; j < polyGroup.length; j++) {
|
|
1748
|
+
let madeCut = 0;
|
|
1749
|
+
let inner = 0;
|
|
1750
|
+
for (let exhaustive = 0; exhaustive < 2 && !madeCut; exhaustive++) {
|
|
1751
|
+
for (let j = 1; j < polyGroup.length; j++) {
|
|
1875
1752
|
inner = innerBySize[j][1];
|
|
1876
1753
|
innerPolyId = polyGroup[inner];
|
|
1877
|
-
|
|
1878
|
-
|
|
1754
|
+
const cuts = [];
|
|
1879
1755
|
if (vtkCCSFindCuts(polys, polyGroup, outerPolyId, innerPolyId, points, normal, cuts, exhaustive)) {
|
|
1880
1756
|
vtkCCSMakeCuts(polys, polyEdges, outerPolyId, innerPolyId, points, cuts);
|
|
1881
1757
|
madeCut = 1;
|
|
@@ -1883,42 +1759,39 @@ function vtkCCSCutHoleyPolys(polys, points, polyGroups, polyEdges, normal) {
|
|
|
1883
1759
|
}
|
|
1884
1760
|
}
|
|
1885
1761
|
}
|
|
1886
|
-
|
|
1887
1762
|
if (madeCut) {
|
|
1888
1763
|
// Move successfully cut innerPolyId into its own group
|
|
1889
|
-
polyGroup.splice(inner, 1);
|
|
1764
|
+
polyGroup.splice(inner, 1);
|
|
1765
|
+
// Only add if innerPolyId hasn't been set already.
|
|
1890
1766
|
// Having the same poly occur as both polyGroup and
|
|
1891
1767
|
// innerPoly would cause an infinite loop.
|
|
1892
|
-
|
|
1893
1768
|
if (polyGroups[innerPolyId].length === 0) {
|
|
1894
1769
|
polyGroups[innerPolyId].push(innerPolyId);
|
|
1895
1770
|
}
|
|
1896
1771
|
} else {
|
|
1897
1772
|
// Remove all failed inner polys from the group
|
|
1898
|
-
for (
|
|
1899
|
-
innerPolyId = polyGroup[k];
|
|
1773
|
+
for (let k = 1; k < polyGroup.length; k++) {
|
|
1774
|
+
innerPolyId = polyGroup[k];
|
|
1775
|
+
// Only add if innerPolyId hasn't been set already.
|
|
1900
1776
|
// Having the same poly occur as both polyGroup and
|
|
1901
1777
|
// innerPoly would cause an infinite loop.
|
|
1902
|
-
|
|
1903
1778
|
if (polyGroups[innerPolyId].length === 0) {
|
|
1904
1779
|
polyGroups[innerPolyId].push(innerPolyId);
|
|
1905
1780
|
}
|
|
1906
1781
|
}
|
|
1907
|
-
|
|
1908
1782
|
polyGroup.length = 1;
|
|
1909
1783
|
cutFailure = 1;
|
|
1910
|
-
}
|
|
1911
|
-
// they are in poly1 or poly2
|
|
1912
|
-
|
|
1784
|
+
}
|
|
1913
1785
|
|
|
1786
|
+
// If there are other interior polys in the group, find out whether
|
|
1787
|
+
// they are in poly1 or poly2
|
|
1914
1788
|
if (polyGroup.length > 1) {
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1789
|
+
const poly1 = polys[outerPolyId];
|
|
1790
|
+
const pp = new Float64Array(3 * poly1.length);
|
|
1791
|
+
const bounds = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
|
|
1792
|
+
const tol2 = vtkCCSPrepareForPolyInPoly(poly1, points, pp, bounds);
|
|
1793
|
+
let nextGroupId = groupId;
|
|
1794
|
+
let ii = 1;
|
|
1922
1795
|
while (ii < polyGroup.length) {
|
|
1923
1796
|
if (vtkCCSPolyInPoly(poly1, polys[polyGroup[ii]], points, normal, pp, bounds, tol2)) {
|
|
1924
1797
|
// Keep this poly in polyGroup
|
|
@@ -1926,25 +1799,24 @@ function vtkCCSCutHoleyPolys(polys, points, polyGroups, polyEdges, normal) {
|
|
|
1926
1799
|
} else {
|
|
1927
1800
|
// Move this poly to poly2 group
|
|
1928
1801
|
polyGroups[innerPolyId].push(polyGroup[ii]);
|
|
1929
|
-
polyGroup.splice(ii, 1);
|
|
1802
|
+
polyGroup.splice(ii, 1);
|
|
1930
1803
|
|
|
1804
|
+
// Reduce the groupId to ensure that this new group will get cut
|
|
1931
1805
|
if (innerPolyId < nextGroupId) {
|
|
1932
1806
|
nextGroupId = innerPolyId;
|
|
1933
1807
|
}
|
|
1934
1808
|
}
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
groupId = nextGroupId; // eslint-disable-next-line no-continue
|
|
1809
|
+
}
|
|
1939
1810
|
|
|
1811
|
+
// Set the groupId for the next iteration
|
|
1812
|
+
groupId = nextGroupId;
|
|
1813
|
+
// eslint-disable-next-line no-continue
|
|
1940
1814
|
continue;
|
|
1941
1815
|
}
|
|
1942
|
-
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1816
|
+
}
|
|
1817
|
+
// Increment to the next group
|
|
1945
1818
|
groupId++;
|
|
1946
1819
|
}
|
|
1947
|
-
|
|
1948
1820
|
return !cutFailure;
|
|
1949
1821
|
}
|
|
1950
1822
|
|