@woosh/meep-engine 2.37.18 → 2.38.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.
Files changed (289) hide show
  1. package/core/assert.js +1 -1
  2. package/core/binary/float2uint8.js +8 -0
  3. package/core/binary/uint82float.js +8 -0
  4. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +6 -4
  5. package/core/collection/array/array_get_index_in_range.js +16 -0
  6. package/core/collection/array/typed/isTypedArray.js +20 -0
  7. package/core/collection/array/typedArrayToDataType.js +1 -0
  8. package/{engine/navigation/grid → core/collection/heap}/BinaryHeap.js +6 -1
  9. package/{engine/navigation/grid → core/collection/heap}/FastBinaryHeap.js +3 -2
  10. package/{engine/navigation/grid → core/collection/heap}/FastBinaryHeap.spec.js +3 -3
  11. package/core/collection/heap/Uin32Heap.spec.js +59 -0
  12. package/core/collection/heap/Uint32Heap.js +385 -0
  13. package/core/collection/list/List.d.ts +1 -1
  14. package/core/collection/table/RowFirstTable.js +34 -0
  15. package/core/collection/table/RowFirstTable.spec.js +59 -1
  16. package/core/color/Color.js +83 -1
  17. package/core/color/YCbCr_to_rgb_uint24.js +3 -4
  18. package/core/color/hsv2rgb.js +4 -3
  19. package/core/color/linear_to_sRGB.js +4 -5
  20. package/core/color/rgb2hex.js +1 -1
  21. package/core/color/rgb2uint24.js +6 -4
  22. package/core/color/rgb_to_YCbCr_uint24.js +11 -13
  23. package/core/events/signal/Signal.d.ts +11 -9
  24. package/core/events/signal/Signal.spec.js +16 -0
  25. package/core/geom/2d/quad-tree/qt_collect_by_circle.js +67 -0
  26. package/core/geom/3d/topology/computeTopoMeshVertexDuplicates.js +9 -6
  27. package/core/geom/3d/topology/expandConnectivityByLocality.js +5 -5
  28. package/core/geom/3d/topology/query/query_edge_is_boundary.js +7 -0
  29. package/core/geom/3d/topology/query/query_edge_is_manifold.js +13 -0
  30. package/core/geom/3d/topology/query/query_edge_is_manifold_or_boundary.js +11 -0
  31. package/core/geom/3d/topology/query/query_edge_is_wire.js +13 -0
  32. package/core/geom/3d/topology/query/query_edge_other_vertex.js +20 -0
  33. package/core/geom/3d/topology/query/query_edge_share_vert.js +9 -0
  34. package/core/geom/3d/topology/query/query_face_get_other_edges.js +39 -0
  35. package/core/geom/3d/topology/query/query_face_next_vertex.js +19 -0
  36. package/core/geom/3d/topology/query/query_face_prev_vertex.js +18 -0
  37. package/core/geom/3d/topology/query/query_vertex_in_edge.js +14 -0
  38. package/core/geom/3d/topology/query/query_vertex_pair_share_face.js +24 -0
  39. package/core/geom/3d/topology/query/query_vertices_in_edge.js +19 -0
  40. package/core/geom/3d/topology/simplify/collapseEdge.spec.js +3 -5
  41. package/core/geom/3d/topology/simplify/collapse_all_degenerate_edges.js +8 -10
  42. package/core/geom/3d/topology/simplify/compute_face_normal_change_dot_product.js +12 -2
  43. package/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +277 -0
  44. package/core/geom/3d/topology/simplify/edge_collapse_quadratic.js +126 -0
  45. package/core/geom/3d/topology/simplify/prototypeMeshSimplification.js +502 -0
  46. package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +37 -5
  47. package/core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js +86 -1
  48. package/core/geom/3d/topology/simplify/simplifyTopoMesh.js +4 -4
  49. package/core/geom/3d/topology/simplify/simplifyTopoMesh2.js +119 -0
  50. package/core/geom/3d/topology/simplify/tm_edge_collapse_is_degenerate_flip.js +81 -0
  51. package/core/geom/3d/topology/{TopoEdge.js → struct/TopoEdge.js} +47 -20
  52. package/core/geom/3d/topology/{TopoEdge.spec.js → struct/TopoEdge.spec.js} +0 -0
  53. package/core/geom/3d/topology/{TopoMesh.js → struct/TopoMesh.js} +20 -41
  54. package/core/geom/3d/topology/{TopoTriangle.js → struct/TopoTriangle.js} +15 -25
  55. package/core/geom/3d/topology/{TopoVertex.js → struct/TopoVertex.js} +21 -4
  56. package/core/geom/3d/topology/{TopoVertex.spec.js → struct/TopoVertex.spec.js} +0 -0
  57. package/core/geom/3d/topology/tm_edge_kill.js +24 -0
  58. package/core/geom/3d/topology/tm_edge_splice.js +42 -0
  59. package/core/geom/3d/topology/tm_face_area.js +18 -0
  60. package/core/geom/3d/topology/tm_face_kill.js +12 -0
  61. package/core/geom/3d/topology/tm_face_normal.js +14 -0
  62. package/core/geom/3d/topology/tm_kill_only_edge.js +35 -0
  63. package/core/geom/3d/topology/tm_kill_only_face.js +12 -0
  64. package/core/geom/3d/topology/tm_kill_only_vert.js +14 -0
  65. package/core/geom/3d/topology/tm_vert_kill.js +19 -0
  66. package/core/geom/3d/topology/tm_vert_splice.js +64 -0
  67. package/core/geom/3d/topology/tm_vertex_compute_normal.js +42 -0
  68. package/core/geom/3d/topology/topoMeshToBufferGeometry.js +18 -4
  69. package/core/geom/3d/topology/weld_duplicate_vertices.js +63 -0
  70. package/core/geom/Quaternion.d.ts +21 -1
  71. package/core/geom/Quaternion.js +279 -200
  72. package/core/geom/Quaternion.spec.js +71 -2
  73. package/core/geom/Vector2.js +3 -3
  74. package/core/geom/Vector3.d.ts +2 -0
  75. package/core/geom/Vector3.js +31 -7
  76. package/core/geom/Vector3.schema.json +16 -0
  77. package/core/geom/Vector4.js +16 -0
  78. package/core/geom/packing/MaxRectangles.js +1 -1
  79. package/core/graph/cluster_mesh_metis.js +16 -0
  80. package/core/graph/coarsen_graph.js +1 -1
  81. package/core/graph/graph_k_means_cluster.js +1 -1
  82. package/core/json/JsonUtils.js +2 -20
  83. package/core/math/bell_membership_function.js +19 -0
  84. package/core/math/exp2.js +8 -0
  85. package/core/math/interval/NumericInterval.js +17 -0
  86. package/core/math/physics/brdf/brdf_burley.js +25 -0
  87. package/core/math/physics/bsdf/bsdf_schlick.js +22 -0
  88. package/core/math/physics/irradiance/interpolate_irradiance_linear.js +18 -0
  89. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundLogarithmic.js → core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js} +2 -2
  90. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundSmith.js → core/math/physics/irradiance/interpolate_irradiance_smith.js} +1 -1
  91. package/core/math/random/seededRandom.js +2 -31
  92. package/core/math/random/seededRandom_Mulberry32.js +31 -0
  93. package/core/math/random/seededRandom_sine.js +33 -0
  94. package/core/model/ObservedEnum.js +8 -0
  95. package/editor/Editor.js +97 -1
  96. package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
  97. package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
  98. package/editor/actions/concrete/PatchTerrainHeightAction.js +13 -105
  99. package/editor/ecs/component/FieldDescriptor.js +34 -0
  100. package/editor/ecs/component/FieldValueAdapter.js +20 -0
  101. package/editor/ecs/component/TypeEditor.js +33 -0
  102. package/editor/ecs/component/TypeSchema.d.ts +38 -0
  103. package/editor/ecs/component/createFieldEditor.js +90 -0
  104. package/editor/ecs/component/createObjectEditor.js +266 -60
  105. package/editor/ecs/component/editors/ColorEditor.js +39 -0
  106. package/editor/ecs/component/editors/HTMLElementEditor.js +17 -0
  107. package/editor/ecs/component/editors/ImagePathEditor.js +50 -0
  108. package/editor/ecs/component/editors/NumericIntervalEditor.js +86 -0
  109. package/editor/ecs/component/editors/ObservedBooleanEditor.js +13 -0
  110. package/editor/ecs/component/editors/ObservedEnumEditor.js +32 -0
  111. package/editor/ecs/component/editors/ObservedIntegerEditor.js +43 -0
  112. package/editor/ecs/component/editors/ObservedStringEditor.js +51 -0
  113. package/editor/ecs/component/editors/Sampler2DEditor.js +107 -0
  114. package/editor/ecs/component/editors/collection/ListEditor.js +83 -0
  115. package/editor/ecs/component/editors/common/BitFlagsEditor.js +80 -0
  116. package/editor/ecs/component/editors/common/EnumEditor.js +41 -0
  117. package/editor/ecs/component/editors/common/makeV3_editor.js +85 -0
  118. package/editor/ecs/component/editors/common/noEditor.js +9 -0
  119. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +17 -0
  120. package/editor/ecs/component/editors/ecs/MinimapMarkerEditor.js +16 -0
  121. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +44 -0
  122. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -0
  123. package/editor/ecs/component/editors/ecs/ParticleEmitterEditor.js +58 -0
  124. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +54 -0
  125. package/editor/ecs/component/editors/ecs/SimulationStepDefinitionEditor.js +21 -0
  126. package/editor/ecs/component/editors/ecs/Trail2DEditor.js +33 -0
  127. package/editor/ecs/component/editors/ecs/TransformEditor.js +23 -0
  128. package/editor/ecs/component/editors/ecs/terrain/SplatMappingEditor.js +21 -0
  129. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +89 -0
  130. package/editor/ecs/component/editors/ecs/terrain/TerrainLayerEditor.js +18 -0
  131. package/editor/ecs/component/editors/ecs/terrain/TerrainLayersEditor.js +22 -0
  132. package/editor/ecs/component/editors/ecs/terrain/TerrainOverlayEditor.js +20 -0
  133. package/editor/ecs/component/editors/geom/QuaternionEditor.js +56 -0
  134. package/editor/ecs/component/editors/geom/Vector1Editor.js +57 -0
  135. package/editor/ecs/component/editors/geom/Vector2Editor.js +11 -0
  136. package/editor/ecs/component/editors/geom/Vector3Editor.js +13 -0
  137. package/editor/ecs/component/editors/geom/Vector4Editor.js +12 -0
  138. package/editor/ecs/component/editors/primitive/ArrayEditor.js +46 -0
  139. package/editor/ecs/component/editors/primitive/BooleanEditor.js +27 -0
  140. package/editor/ecs/component/editors/primitive/FunctionEditor.js +29 -0
  141. package/editor/ecs/component/editors/primitive/NumberEditor.js +60 -0
  142. package/editor/ecs/component/editors/primitive/ObjectEditor.js +12 -0
  143. package/editor/ecs/component/editors/primitive/StringEditor.js +31 -0
  144. package/editor/ecs/component/editors/three/BufferGeometryEditor.js +28 -0
  145. package/editor/ecs/component/editors/three/MaterialEditor.js +27 -0
  146. package/editor/ecs/component/editors/three/MeshEditor.js +35 -0
  147. package/editor/ecs/component/editors/three/TextureEditor.js +32 -0
  148. package/editor/ecs/component/findNearestRegisteredType.js +59 -0
  149. package/editor/ecs/component/prototypeObjectEditor.js +379 -0
  150. package/editor/tools/SelectionTool.js +1 -1
  151. package/editor/tools/paint/TerrainHeightPaintTool.js +88 -68
  152. package/editor/tools/paint/TerrainPaintTool.js +2 -1
  153. package/editor/tools/paint/TerrainTexturePaintTool.js +8 -73
  154. package/editor/view/EditorView.js +1 -1
  155. package/editor/view/ecs/ComponentControlView.js +2 -30
  156. package/editor/view/ecs/EntityEditor.js +61 -139
  157. package/editor/view/ecs/components/GridObstacleController.js +4 -4
  158. package/editor/view/ecs/components/TerrainController.js +1 -1
  159. package/editor/view/ecs/components/common/NumberController.js +19 -7
  160. package/editor/view/node-graph/NodeGraphView.js +2 -2
  161. package/editor/view/node-graph/NodeView.js +7 -9
  162. package/engine/animation/keyed2/AnimationTrack.js +1 -1
  163. package/engine/asset/AssetManager.d.ts +1 -1
  164. package/engine/asset/AssetManager.js +390 -388
  165. package/engine/asset/loaders/gltf/extensions/MSFT_texture_dds.js +14 -2
  166. package/engine/ecs/components/TagEditor.js +15 -0
  167. package/engine/ecs/fow/FogOfWarEditor.js +13 -0
  168. package/engine/ecs/parent/ParentEntitySystem.js +57 -0
  169. package/engine/ecs/terrain/ecs/OffsetScaleTransform2D.d.ts +6 -0
  170. package/engine/ecs/terrain/ecs/Terrain.js +44 -43
  171. package/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
  172. package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +1 -1
  173. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +26 -28
  174. package/engine/ecs/terrain/overlay/TerrainOverlay.js +71 -66
  175. package/engine/ecs/terrain/tiles/TerrainTileManager.js +23 -0
  176. package/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +1 -1
  177. package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +13 -7
  178. package/engine/ecs/terrain/util/tensionOptimizeUV.js +1 -1
  179. package/engine/ecs/transform/Transform.d.ts +2 -0
  180. package/engine/ecs/transform/Transform.editor.schema.json +16 -0
  181. package/engine/ecs/transform/Transform.js +3 -0
  182. package/engine/graphics/ecs/highlight/HighlightEditor.js +17 -0
  183. package/engine/graphics/ecs/light/Light.js +0 -47
  184. package/engine/graphics/ecs/light/LightSerializationAdapter.js +50 -0
  185. package/engine/graphics/ecs/mesh/MeshEditor.js +28 -0
  186. package/engine/graphics/ecs/mesh-v2/DrawMode.js +2 -1
  187. package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +3 -3
  188. package/engine/graphics/ecs/mesh-v2/build_three_object.js +3 -1
  189. package/engine/graphics/ecs/mesh-v2/sg_compute_hierarchy_bounding_box_by_parent_entity.js +31 -0
  190. package/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.d.ts +4 -0
  191. package/engine/graphics/ecs/sprite/Sprite.js +11 -0
  192. package/engine/graphics/ecs/sprite/SpriteSystemPE.js +133 -0
  193. package/engine/graphics/ecs/sprite/prototypeSpriteSystem.js +1570 -0
  194. package/engine/graphics/micron/build/PatchRepresentation.js +7 -3
  195. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +18 -8
  196. package/engine/graphics/micron/build/clustering/build_clustering_2.js +1 -1
  197. package/engine/graphics/micron/build/clustering/build_leaf_patches.js +2 -2
  198. package/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +1 -1
  199. package/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +21 -3
  200. package/engine/graphics/micron/build/hierarchy/merge_patches.js +96 -43
  201. package/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +11 -5
  202. package/engine/graphics/micron/format/VirtualGeometry.js +46 -3
  203. package/engine/graphics/micron/format/micron_build_proxy_geometry.js +4 -2
  204. package/engine/graphics/micron/prototypeVirtualGeometry.js +47 -10
  205. package/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +17 -17
  206. package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +15 -3
  207. package/engine/graphics/micron/simplifyGeometry.js +1 -1
  208. package/engine/graphics/particles/particular/engine/ParticularEngine.js +5 -0
  209. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -9
  210. package/engine/graphics/particles/particular/engine/renderers/ParticleRenderer.js +12 -10
  211. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +7 -2
  212. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticlePool.js +27 -0
  213. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticleRenderer.js +80 -0
  214. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +16 -4
  215. package/engine/graphics/shaders/TerrainShader.js +8 -8
  216. package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +2 -1
  217. package/engine/graphics/texture/sampler/Sampler2D.js +206 -201
  218. package/engine/graphics/texture/sampler/Sampler2D.spec.js +34 -35
  219. package/engine/graphics/texture/sampler/bicubic.js +59 -0
  220. package/engine/graphics/texture/sampler/downsampleSample2D.spec.js +2 -2
  221. package/engine/graphics/texture/sampler/genericResampleSampler2D.js +0 -2
  222. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +146 -0
  223. package/engine/graphics/texture/sampler/{downsampleSampler2D.js → sampler2D_scale_down_linear.js} +8 -4
  224. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +140 -0
  225. package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -3
  226. package/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +1 -1
  227. package/engine/graphics/util/ScaleObject3ToBox.js +14 -1
  228. package/engine/graphics/util/makeMeshPreviewScene.js +2 -1
  229. package/engine/grid/components/GridObstacle.js +0 -44
  230. package/engine/grid/components/GridObstacleSerializationAdapter.js +46 -0
  231. package/engine/input/devices/PointerDevice.d.ts +1 -1
  232. package/engine/input/devices/PointerDevice.js +17 -2
  233. package/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
  234. package/engine/navigation/ecs/components/Path.d.ts +2 -0
  235. package/engine/navigation/ecs/components/Path.js +6 -1
  236. package/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +117 -0
  237. package/engine/navigation/grid/AStar.js +1 -1
  238. package/engine/navigation/grid/GridField.js +3 -2
  239. package/engine/platform/GetURLHash.js +27 -0
  240. package/engine/platform/WebEnginePlatform.js +1 -22
  241. package/engine/sound/ecs/emitter/SoundEmitter.js +10 -6
  242. package/engine/ui/DraggableAspect.js +2 -2
  243. package/generation/GridGenerator.js +7 -6
  244. package/generation/example/SampleGenerator0.js +39 -35
  245. package/generation/example/filters/SampleGroundMoistureFilter.js +58 -17
  246. package/generation/example/generators/interactive/mir_generator_place_buff_objects.js +7 -6
  247. package/generation/example/generators/mir_generator_place_bases.js +7 -3
  248. package/generation/example/generators/mir_generator_place_road_decorators.js +3 -3
  249. package/generation/example/generators/mir_generator_place_starting_point.js +3 -2
  250. package/generation/example/themes/SampleTheme0.js +11 -7
  251. package/generation/filtering/numeric/CellFilterLiteralFloat.js +5 -0
  252. package/generation/filtering/numeric/complex/CellFilterDilate.js +36 -0
  253. package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +15 -5
  254. package/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +53 -1
  255. package/generation/filtering/numeric/math/CellFilterMax2.js +3 -0
  256. package/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +55 -0
  257. package/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +42 -0
  258. package/generation/filtering/numeric/sampling/CellFilterSampleLayerCubic.js +36 -0
  259. package/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +41 -0
  260. package/generation/grid/GridData.d.ts +5 -1
  261. package/generation/grid/GridData.js +35 -36
  262. package/generation/grid/MarkerMatchCounter.js +5 -3
  263. package/generation/grid/generation/discrete/GridTaskConnectRooms.js +1 -1
  264. package/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +1 -1
  265. package/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.js +1 -1
  266. package/generation/grid/generation/road/GridTaskGenerateRoads.js +1 -1
  267. package/generation/markers/GridActionRuleSet.js +15 -32
  268. package/generation/markers/GridCellActionPlaceMarker.js +12 -8
  269. package/generation/markers/debug/visualizeMarkers.js +56 -36
  270. package/generation/markers/emitter/MarkerNodeEmitterFromAction.js +8 -8
  271. package/generation/markers/prototypeGridCellActionPlaceMarker.js +209 -0
  272. package/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -5
  273. package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +2 -2
  274. package/generation/placement/GridCellPlacementRule.js +31 -25
  275. package/generation/theme/ThemeEngine.js +1 -1
  276. package/package.json +1 -1
  277. package/samples/terrain/from_image.js +7 -3
  278. package/samples/terrain/main.js +1 -1
  279. package/view/View.js +23 -1
  280. package/view/common/LabelView.js +1 -1
  281. package/view/compose3x3transform.js +32 -8
  282. package/view/controller/dat/DatGuiUtils.js +1 -1
  283. package/view/elements/DropDownSelectionView.js +11 -3
  284. package/view/elements/image/ImageView.js +3 -1
  285. package/core/model/ObservedReal.js +0 -55
  286. package/editor/ecs/component/ObjectEditor.js +0 -0
  287. package/engine/graphics/particles/particular/engine/renderers/SoftBillboardParticleRenderer.js +0 -7
  288. package/engine/sound/ecs/emitter/attenuate/attenuateSoundLinear.js +0 -11
  289. package/generation/filtering/numeric/CellFilterReadGridLayer.js +0 -73
@@ -0,0 +1,119 @@
1
+ import { Uint32Heap } from "../../../../collection/heap/Uint32Heap.js";
2
+ import { build_vertex_quadratics } from "./quadratic/build_vertex_quadratics.js";
3
+ import {
4
+ compute_edge_collapse_cost,
5
+ decimate_edge_collapse_snap,
6
+ edge_collapse_pick_target_vertex
7
+ } from "./decimate_edge_collapse_snap.js";
8
+ import { max2 } from "../../../../math/max2.js";
9
+
10
+ /**
11
+ *
12
+ * @param {Iterable<TopoEdge>} edges
13
+ * @param {Set<number>} restricted_vertices
14
+ * @param {Uint32Heap} heap
15
+ * @param {Map<number, Quadratic3>} vertex_quadratics
16
+ * @param {Map<number,TopoEdge>} edge_lookup
17
+ */
18
+ export function edge_collapse_populate_heap(edges, restricted_vertices, heap, vertex_quadratics, edge_lookup) {
19
+
20
+ const edge_array = Array.from(edges);
21
+ const total_edge_count = edge_array.length;
22
+
23
+ for (let i = 0; i < total_edge_count; i++) {
24
+ const edge = edge_array[i];
25
+
26
+ if (
27
+ restricted_vertices.has(edge.v0.index)
28
+ && restricted_vertices.has(edge.v1.index)
29
+ ) {
30
+ // both vertices are fixed, can't simplify the edge
31
+ continue;
32
+ }
33
+
34
+ heap.insert(edge.index, compute_edge_collapse_cost(edge, vertex_quadratics, restricted_vertices));
35
+
36
+ edge_lookup.set(edge.index, edge);
37
+ }
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @param {TopoMesh} mesh
43
+ * @param {number} num_faces_to_remove
44
+ * @param {Uint32Heap} heap
45
+ * @param {Map<number,TopoEdge>} edge_lookup
46
+ * @param {Set<number>} restricted_vertices
47
+ * @param {Map<number, Quadratic3>} vertex_quadratics
48
+ */
49
+ export function edge_collapse_reduce_face_count(mesh, num_faces_to_remove, heap, edge_lookup, restricted_vertices, vertex_quadratics) {
50
+ const mesh_faces = mesh.getFaces();
51
+
52
+ const target_face_count = max2(0, mesh_faces.size - num_faces_to_remove);
53
+
54
+ let cycle_count = 0;
55
+ let cycle_limit = max2(heap.size, num_faces_to_remove * 4);
56
+
57
+ while (
58
+ !heap.is_empty()
59
+ && mesh_faces.size > target_face_count
60
+ && cycle_count < cycle_limit
61
+ ) {
62
+ const edge_index = heap.pop_min();
63
+
64
+ const edge = edge_lookup.get(edge_index);
65
+
66
+ let target;
67
+
68
+ target = edge_collapse_pick_target_vertex(edge, restricted_vertices);
69
+
70
+ if (target === undefined) {
71
+ // invalid collapse
72
+ continue;
73
+ }
74
+
75
+ decimate_edge_collapse_snap(mesh, edge, target, vertex_quadratics, heap, restricted_vertices);
76
+
77
+ cycle_count++;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Simplifies a given topology mesh by reducing number of faces. Preserves original vertices
83
+ * NOTE: preserves outline of the mesh, that is the open edge
84
+ * NOTE: assumes that face normals are set
85
+ * @param {TopoMesh} mesh
86
+ * @param {number} num_faces_to_remove desired number of faces to remove
87
+ * @param {Set<number>} [restricted_vertices] vertices that are not allowed to be removed
88
+ */
89
+ export function simplifyTopoMesh2(mesh, num_faces_to_remove, restricted_vertices = new Set()) {
90
+
91
+ const mesh_faces = mesh.getFaces();
92
+ const face_count = mesh_faces.size;
93
+
94
+ if (num_faces_to_remove <= 0 || face_count <= 0) {
95
+ // we're already at the target
96
+ return;
97
+ }
98
+
99
+ const heap = new Uint32Heap(mesh.getEdges().size);
100
+ /**
101
+ *
102
+ * @type {Map<number, Quadratic3>}
103
+ */
104
+ const vertex_quadratics = new Map();
105
+
106
+ build_vertex_quadratics({ mesh: mesh, quadratics: vertex_quadratics });
107
+
108
+ const edge_lookup = new Map();
109
+ edge_collapse_populate_heap(mesh.getEdges(), restricted_vertices, heap, vertex_quadratics, edge_lookup);
110
+ edge_collapse_reduce_face_count(mesh, num_faces_to_remove, heap, edge_lookup, restricted_vertices, vertex_quadratics);
111
+
112
+
113
+ // debugValidateMesh(mesh);
114
+
115
+ // get rid of degenerate edges
116
+ // collapse_all_degenerate_edges(mesh.getEdges(), mesh);
117
+
118
+ // debugValidateMesh(mesh);
119
+ }
@@ -0,0 +1,81 @@
1
+ import { query_edge_other_vertex } from "../query/query_edge_other_vertex.js";
2
+ import { query_face_next_vertex } from "../query/query_face_next_vertex.js";
3
+ import { query_face_prev_vertex } from "../query/query_face_prev_vertex.js";
4
+ import { v3_length_sqr } from "../../../v3_length_sqr.js";
5
+ import { v3_dot } from "../../../v3_dot.js";
6
+
7
+ /**
8
+ * @see https://github.com/blender/blender/blob/594f47ecd2d5367ca936cf6fc6ec8168c2b360d0/source/blender/bmesh/tools/bmesh_decimate_collapse.c#L164
9
+ * @param {TopoEdge} edge
10
+ * @param {TopoVertex} target
11
+ * @returns {boolean}
12
+ */
13
+ export function tm_edge_collapse_is_degenerate_flip(edge, target) {
14
+ const victim = query_edge_other_vertex(edge, target);
15
+
16
+ const victim_faces = victim.faces;
17
+ const victim_face_count = victim_faces.length;
18
+
19
+ for (let i = 0; i < victim_face_count; i++) {
20
+ const face = victim_faces[i];
21
+
22
+ // get a vertex that's next after victim vertex in order
23
+ const next_vertex = query_face_next_vertex(face, victim);
24
+ const prev_vertex = query_face_prev_vertex(face, victim);
25
+
26
+ if (next_vertex === target || prev_vertex === target) {
27
+ // face attached to collapsing edge, ignore
28
+ continue;
29
+ }
30
+
31
+ const vo_x = prev_vertex.x - next_vertex.x;
32
+ const vo_y = prev_vertex.y - next_vertex.y;
33
+ const vo_z = prev_vertex.z - next_vertex.z;
34
+
35
+ const vv_x = prev_vertex.x - victim.x;
36
+ const vv_y = prev_vertex.y - victim.y;
37
+ const vv_z = prev_vertex.z - victim.z;
38
+
39
+ const vt_x = prev_vertex.x - target.x;
40
+ const vt_y = prev_vertex.y - target.y;
41
+ const vt_z = prev_vertex.z - target.z;
42
+
43
+ // cross( other, victim )
44
+ const vx_ov_x = vo_y * vv_z - vo_z * vv_y;
45
+ const vx_ov_y = vo_z * vv_x - vo_x * vv_z;
46
+ const vx_ov_z = vo_x * vv_y - vo_y * vv_x;
47
+
48
+ // cross( other, target )
49
+ const vx_ot_x = vo_y * vt_z - vo_z * vt_y;
50
+ const vx_ot_y = vo_z * vt_x - vo_x * vt_z;
51
+ const vx_ot_z = vo_x * vt_y - vo_y * vt_x;
52
+
53
+ const dot = v3_dot(vx_ov_x, vx_ov_y, vx_ov_z, vx_ot_x, vx_ot_y, vx_ot_z);
54
+
55
+ const squared_distance_sum = v3_length_sqr(vx_ov_x, vx_ov_y, vx_ov_z)
56
+ + v3_length_sqr(vx_ot_x, vx_ot_y, vx_ot_z);
57
+
58
+ /*
59
+
60
+ vec3.sub(vec_other, prev_vertex, next_vertex);
61
+ vec3.sub(vec_exist, prev_vertex, victim);
62
+ vec3.sub(vec_optim, prev_vertex, target);
63
+
64
+ vec3.cross(vec_exist, vec_other, vec_exist);
65
+ vec3.cross(vec_optim, vec_other, vec_optim);
66
+
67
+
68
+ // avoid normalization
69
+ const dot = vec3.dot(vec_exist, vec_optim);
70
+ const squared_distance_sum = vec3.squaredLength(vec_exist) + vec3.squaredLength(vec_other);
71
+ */
72
+
73
+ // if (dot <= squared_distance_sum * 0.000001) {
74
+ if (dot <= squared_distance_sum * 0.000001) {
75
+ return true;
76
+ }
77
+
78
+ }
79
+
80
+ return false;
81
+ }
@@ -1,9 +1,21 @@
1
- import { assert } from "../../../assert.js";
2
- import { array_remove_first } from "../../../collection/array/array_remove_first.js";
3
- import { array_push_if_unique } from "../../../collection/array/array_push_if_unique.js";
1
+ import { assert } from "../../../../assert.js";
2
+ import { array_remove_first } from "../../../../collection/array/array_remove_first.js";
3
+ import { array_push_if_unique } from "../../../../collection/array/array_push_if_unique.js";
4
+ import { query_vertex_in_edge } from "../query/query_vertex_in_edge.js";
5
+ import { query_edge_other_vertex } from "../query/query_edge_other_vertex.js";
6
+ import { query_vertices_in_edge } from "../query/query_vertices_in_edge.js";
7
+ import { query_edge_is_boundary } from "../query/query_edge_is_boundary.js";
8
+
9
+ let index_counter = 0;
4
10
 
5
11
  export class TopoEdge {
6
12
  constructor() {
13
+ /**
14
+ * Unique ID
15
+ * @type {number}
16
+ */
17
+ this.index = index_counter++;
18
+
7
19
  /**
8
20
  *
9
21
  * @type {TopoVertex}
@@ -29,6 +41,21 @@ export class TopoEdge {
29
41
  this.lengthSqr = -1;
30
42
  }
31
43
 
44
+ /**
45
+ *
46
+ * @param {number} i
47
+ * @returns {TopoVertex}
48
+ */
49
+ getVertexByIndex(i) {
50
+ if (i === 0) {
51
+ return this.v0;
52
+ } else if (i === 1) {
53
+ return this.v1;
54
+ } else {
55
+ throw new Error('Index out of bounds');
56
+ }
57
+ }
58
+
32
59
  /**
33
60
  *
34
61
  * @param {TopoEdge} other
@@ -100,8 +127,15 @@ export class TopoEdge {
100
127
  * Remove self from the topology graph
101
128
  */
102
129
  unlink() {
103
- this.v0.removeEdge(this);
104
- this.v1.removeEdge(this);
130
+ const v0 = this.v0;
131
+ const v1 = this.v1;
132
+
133
+ v0.removeEdge(this);
134
+
135
+ if (v0 !== v1) {
136
+ // special check for degenerate edges where both vertices are the same
137
+ v1.removeEdge(this);
138
+ }
105
139
 
106
140
  const faces = this.faces;
107
141
  const face_count = faces.length;
@@ -120,14 +154,14 @@ export class TopoEdge {
120
154
  return this.v0 === this.v1;
121
155
  }
122
156
 
123
-
124
157
  /**
158
+ * @deprecated use {@link query_edge_is_boundary} instead
125
159
  * Is this a an edge of topology as a whole?
126
160
  * @return {boolean}
127
161
  */
128
162
  isTopologyBorder() {
129
163
  //attached to exactly one face
130
- return this.faces.length === 1;
164
+ return query_edge_is_boundary(this);
131
165
  }
132
166
 
133
167
  /**
@@ -265,38 +299,31 @@ export class TopoEdge {
265
299
  }
266
300
 
267
301
  /**
268
- *
302
+ * @deprecated use {@link query_edge_other_vertex} instead
269
303
  * @param {TopoVertex} v
270
304
  * @return {TopoVertex}
271
305
  */
272
306
  getOtherVertex(v) {
273
- if (v === this.v0) {
274
- return this.v1;
275
- } else {
276
- return this.v0;
277
- }
307
+ return query_edge_other_vertex(this, v);
278
308
  }
279
309
 
280
310
  /**
281
- *
311
+ * @deprecated use {@link @query_vertex_in_edge} instead
282
312
  * @param {TopoVertex} v
283
313
  * @return {boolean}
284
314
  */
285
315
  containsVertex(v) {
286
- return v === this.v0 || v === this.v1;
316
+ return query_vertex_in_edge(this, v);
287
317
  }
288
318
 
289
319
  /**
290
- *
320
+ @deprecated use {@link query_vertices_in_edge} instead
291
321
  * @param {TopoVertex} a
292
322
  * @param {TopoVertex} b
293
323
  * @return {boolean}
294
324
  */
295
325
  containsBothVertices(a, b) {
296
- const v0 = this.v0;
297
- const v1 = this.v1;
298
-
299
- return (a === v0 || a === v1) && (b === v0 || b === v1);
326
+ return query_vertices_in_edge(this, a, b);
300
327
  }
301
328
 
302
329
  /**
@@ -1,10 +1,14 @@
1
- import { assert } from "../../../assert.js";
1
+ import { assert } from "../../../../assert.js";
2
2
  import { TopoEdge } from "./TopoEdge.js";
3
3
  import { TopoTriangle } from "./TopoTriangle.js";
4
4
  import { TopoVertex } from "./TopoVertex.js";
5
- import { array_remove_first } from "../../../collection/array/array_remove_first.js";
6
- import { array_push_if_unique } from "../../../collection/array/array_push_if_unique.js";
5
+ import { array_push_if_unique } from "../../../../collection/array/array_push_if_unique.js";
7
6
  import { vec3 } from "gl-matrix";
7
+ import { tm_kill_only_vert } from "../tm_kill_only_vert.js";
8
+ import { tm_kill_only_edge } from "../tm_kill_only_edge.js";
9
+ import { tm_kill_only_face } from "../tm_kill_only_face.js";
10
+ import { query_edge_other_vertex } from "../query/query_edge_other_vertex.js";
11
+ import { formatNumberByThousands } from "../../../../NumberFormat.js";
8
12
 
9
13
  export class TopoMesh {
10
14
  constructor() {
@@ -305,14 +309,11 @@ export class TopoMesh {
305
309
  }
306
310
 
307
311
  /**
308
- *
312
+ * @deprecated use {@link tm_kill_only_vert}
309
313
  * @param {TopoVertex} v
310
314
  */
311
315
  removeVertex(v) {
312
- assert.equal(v.isTopoVertex, true, "v.isTopoVertex !== true");
313
- assert.arrayHas(this.vertices, v, 'element not found');
314
-
315
- array_remove_first(this.vertices, v);
316
+ tm_kill_only_vert(this, v);
316
317
  }
317
318
 
318
319
  /**
@@ -346,36 +347,11 @@ export class TopoMesh {
346
347
  }
347
348
 
348
349
  /**
349
- *
350
+ * @deprecated use {@link tm_kill_only_edge}
350
351
  * @param {TopoEdge} e
351
352
  */
352
353
  removeEdge(e) {
353
- assert.equal(e.isTopoEdge, true, "e.isTopoEdge !== true");
354
-
355
- // validate that the edge does not have any live back links
356
- // const vertices = this.vertices;
357
- // const vertex_count = vertices.length;
358
- // for (let i = 0; i < vertex_count; i++) {
359
- // const v = vertices[i];
360
- //
361
- // if (v.containsEdge(e)) {
362
- // // live link to edge
363
- // debugger;
364
- // }
365
- // }
366
- //
367
- // const faces = this.faces;
368
- // const face_count = faces.length;
369
- // for (let i = 0; i < face_count; i++) {
370
- // const face = faces[i];
371
- //
372
- // if (face.containsEdge(e)) {
373
- // // live link to face
374
- // debugger;
375
- // }
376
- // }
377
-
378
- this.__edges.delete(e);
354
+ tm_kill_only_edge(this, e);
379
355
  }
380
356
 
381
357
  /**
@@ -441,13 +417,11 @@ export class TopoMesh {
441
417
  }
442
418
 
443
419
  /**
444
- *
420
+ * @deprecated use {@link tm_kill_only_face} instead
445
421
  * @param {TopoTriangle} f
446
422
  */
447
423
  removeFace(f) {
448
- assert.equal(f.isTopoFace, true, "f.isTopoFace !== true");
449
-
450
- this.__faces.delete(f);
424
+ tm_kill_only_face(this, f);
451
425
  }
452
426
 
453
427
  /**
@@ -474,7 +448,8 @@ export class TopoMesh {
474
448
  assert.equal(a.isTopoVertex, true, 'a.isTopoVertex !== true');
475
449
  assert.equal(b.isTopoVertex, true, 'b.isTopoVertex !== true');
476
450
 
477
- assert.notEqual(a, b, 'a === b, attempting to create an edge from vertex to itself');
451
+ // DEBUG degenerate edge check
452
+ // assert.notEqual(a, b, 'a === b, attempting to create an edge from vertex to itself');
478
453
 
479
454
  const aEdges = a.edges;
480
455
  const n = aEdges.length;
@@ -482,7 +457,7 @@ export class TopoMesh {
482
457
  for (let i = 0; i < n; i++) {
483
458
  const edge = aEdges[i];
484
459
 
485
- if (edge.getOtherVertex(a) === b) {
460
+ if (query_edge_other_vertex(edge, a) === b) {
486
461
  // found existing edge between A and B
487
462
  return edge;
488
463
  }
@@ -618,6 +593,10 @@ export class TopoMesh {
618
593
  topoFaces.add(f);
619
594
  }
620
595
  }
596
+
597
+ toString() {
598
+ return `TopoMesh{ vertices: ${formatNumberByThousands(this.vertices.length)}, edges: ${formatNumberByThousands(this.getEdges().size)}, faces: ${formatNumberByThousands(this.getFaces().size)} }`;
599
+ }
621
600
  }
622
601
 
623
602
 
@@ -1,9 +1,9 @@
1
- import { array_replace_all } from "../../../collection/array/array_replace_all.js";
2
- import { array_push_if_unique } from "../../../collection/array/array_push_if_unique.js";
3
- import { assert } from "../../../assert.js";
4
- import { array_remove_first } from "../../../collection/array/array_remove_first.js";
1
+ import { array_replace_all } from "../../../../collection/array/array_replace_all.js";
2
+ import { array_push_if_unique } from "../../../../collection/array/array_push_if_unique.js";
3
+ import { assert } from "../../../../assert.js";
4
+ import { array_remove_first } from "../../../../collection/array/array_remove_first.js";
5
5
  import { vec3 } from "gl-matrix";
6
- import { v3_length } from "../../v3_length.js";
6
+ import { v3_length_sqr } from "../../../v3_length_sqr.js";
7
7
 
8
8
  /**
9
9
  *
@@ -40,17 +40,19 @@ export function compute_triangle_normal(result, vA, vB, vC) {
40
40
  const crossY = vCBz * vABx - vCBx * vABz;
41
41
  const crossZ = vCBx * vABy - vCBy * vABx;
42
42
 
43
- const l = v3_length(crossX, crossY, crossZ);
43
+ const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
44
44
 
45
- if (l === 0) {
45
+ if (l_sqr === 0) {
46
46
  // degenerate triangle, provide arbitrary invalid result
47
47
  vec3.set(result, 0, 0, 0);
48
48
  return;
49
49
  }
50
50
 
51
- const x = crossX / l;
52
- const y = crossY / l;
53
- const z = crossZ / l;
51
+ const l_inv = 1 / Math.sqrt(l_sqr);
52
+
53
+ const x = crossX * l_inv;
54
+ const y = crossY * l_inv;
55
+ const z = crossZ * l_inv;
54
56
 
55
57
 
56
58
  vec3.set(
@@ -59,13 +61,15 @@ export function compute_triangle_normal(result, vA, vB, vC) {
59
61
  );
60
62
  }
61
63
 
64
+ let index_counter = 0;
65
+
62
66
  export class TopoTriangle {
63
67
  constructor() {
64
68
  /**
65
69
  * Identifying index, can be used to link back to buffer-geometry face by index or any other useful ID purposes
66
70
  * @type {number}
67
71
  */
68
- this.index = 0;
72
+ this.index = index_counter++;
69
73
  /**
70
74
  *
71
75
  * @type {TopoVertex[]}
@@ -82,20 +86,6 @@ export class TopoTriangle {
82
86
  * @type {number[]|vec3}
83
87
  */
84
88
  this.normal = [0, 0, 0];
85
-
86
- /**
87
- * Doubly-linked list pointer
88
- * @type {TopoTriangle|null}
89
- * @private
90
- */
91
- this.__link_previous = null;
92
-
93
- /**
94
- * Doubly-linked list pointer
95
- * @type {TopoTriangle|null}
96
- * @private
97
- */
98
- this.__link_next = null;
99
89
  }
100
90
 
101
91
  /**
@@ -1,7 +1,7 @@
1
- import { assert } from "../../../assert.js";
2
- import { array_push_if_unique } from "../../../collection/array/array_push_if_unique.js";
3
- import { array_remove_first } from "../../../collection/array/array_remove_first.js";
4
- import { v3_distance } from "../../v3_distance.js";
1
+ import { assert } from "../../../../assert.js";
2
+ import { array_push_if_unique } from "../../../../collection/array/array_push_if_unique.js";
3
+ import { array_remove_first } from "../../../../collection/array/array_remove_first.js";
4
+ import { v3_distance } from "../../../v3_distance.js";
5
5
 
6
6
  export class TopoVertex {
7
7
  constructor() {
@@ -40,6 +40,18 @@ export class TopoVertex {
40
40
  this.z = 0;
41
41
  }
42
42
 
43
+ get 0() {
44
+ return this.x;
45
+ }
46
+
47
+ get 1() {
48
+ return this.y;
49
+ }
50
+
51
+ get 2() {
52
+ return this.z;
53
+ }
54
+
43
55
  /**
44
56
  *
45
57
  * @param {TopoVertex} other
@@ -166,6 +178,7 @@ export class TopoVertex {
166
178
  * @param {TopoEdge} e
167
179
  */
168
180
  addEdge(e) {
181
+ assert.defined(e, 'e');
169
182
  assert.equal(e.isTopoEdge, true, "e.isTopoEdge !== true");
170
183
  assert.arrayHasNo(this.edges, e, 'already contains edge');
171
184
 
@@ -178,7 +191,9 @@ export class TopoVertex {
178
191
  * @return {boolean}
179
192
  */
180
193
  addUniqueEdge(e) {
194
+ assert.defined(e, 'e');
181
195
  assert.equal(e.isTopoEdge, true, "e.isTopoEdge !== true");
196
+
182
197
  return array_push_if_unique(this.edges, e);
183
198
  }
184
199
 
@@ -224,11 +239,13 @@ export class TopoVertex {
224
239
  const r = array_remove_first(this.edges, e);
225
240
 
226
241
  assert.arrayHasNo(this.edges, e, 'found an instance of removed edge');
242
+ assert.arrayHasNo(this.edges, undefined, 'found an instance of undefined');
227
243
 
228
244
  return r;
229
245
  }
230
246
 
231
247
  /**
248
+ * @deprecated use {@link tm_vert_splice} instead
232
249
  * Replaces another vertex with self, updates faces and edges of replaced victim
233
250
  * @param {TopoVertex} victim
234
251
  */
@@ -0,0 +1,24 @@
1
+ import { tm_face_kill } from "./tm_face_kill.js";
2
+ import { tm_kill_only_edge } from "./tm_kill_only_edge.js";
3
+
4
+ /**
5
+ * Remove edge and all faces that use it
6
+ * NOTE: Loosely based on blender's code: https://github.com/blender/blender/blob/594f47ecd2d5367ca936cf6fc6ec8168c2b360d0/source/blender/bmesh/intern/bmesh_core.c#L987
7
+ * @param {TopoMesh} mesh
8
+ * @param {TopoEdge} edge
9
+ */
10
+ export function tm_edge_kill(mesh, edge) {
11
+
12
+ const faces = edge.faces;
13
+ const face_count = faces.length;
14
+
15
+ for (let i = face_count - 1; i >= 0; i--) {
16
+ tm_face_kill(mesh, faces[i]);
17
+ }
18
+
19
+ edge.unlink();
20
+
21
+ tm_kill_only_edge(mesh, edge);
22
+ }
23
+
24
+
@@ -0,0 +1,42 @@
1
+ import { query_vertex_in_edge } from "./query/query_vertex_in_edge.js";
2
+ import { assert } from "../../../assert.js";
3
+ import { tm_edge_kill } from "./tm_edge_kill.js";
4
+
5
+ /**
6
+ * Splice Edge
7
+ * Splice two unique edges which share the same two vertices into one edge
8
+ * source onto destination, removing source
9
+ *
10
+ * PRECONDITION: Edges must share vertices
11
+ * @param {TopoMesh} mesh
12
+ * @param {TopoEdge} destination
13
+ * @param {TopoEdge} source
14
+ * @returns {boolean}
15
+ */
16
+ export function tm_edge_splice(mesh, destination, source) {
17
+ if (!query_vertex_in_edge(source, destination.v0) || !query_vertex_in_edge(source, destination.v1)) {
18
+ // do not share vertices, can't splice
19
+
20
+ // the caller must make sure that this never happens
21
+ assert.ok(false);
22
+
23
+ return false;
24
+ }
25
+
26
+ // move faces
27
+ const source_faces = source.faces;
28
+ const source_face_count = source_faces.length;
29
+ for (let i = 0; i < source_face_count; i++) {
30
+ const a = source_faces.pop();
31
+
32
+ a.removeEdge(source);
33
+
34
+ a.addUniqueEdge(destination);
35
+ destination.addUniqueFace(a);
36
+ }
37
+
38
+
39
+ tm_edge_kill(mesh, source);
40
+
41
+ return true;
42
+ }
@@ -0,0 +1,18 @@
1
+ import { computeTriangleSurfaceArea } from "../../../../engine/graphics/geometry/computeMeshSurfaceArea.js";
2
+
3
+ /**
4
+ *
5
+ * @param {TopoTriangle} face
6
+ * @returns {number}
7
+ */
8
+ export function tm_face_area(face) {
9
+ const v0 = face.vertices[0];
10
+ const v1 = face.vertices[1];
11
+ const v2 = face.vertices[2];
12
+
13
+ return computeTriangleSurfaceArea(
14
+ v0.x, v0.y, v0.z,
15
+ v1.x, v1.y, v1.z,
16
+ v2.x, v2.y, v2.z
17
+ );
18
+ }
@@ -0,0 +1,12 @@
1
+ import { tm_kill_only_face } from "./tm_kill_only_face.js";
2
+
3
+ /**
4
+ *
5
+ * @param {TopoMesh} mesh
6
+ * @param {TopoTriangle} face
7
+ */
8
+ export function tm_face_kill(mesh, face) {
9
+ face.unlink();
10
+
11
+ tm_kill_only_face(mesh, face);
12
+ }