@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.
- package/core/assert.js +1 -1
- package/core/binary/float2uint8.js +8 -0
- package/core/binary/uint82float.js +8 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +6 -4
- package/core/collection/array/array_get_index_in_range.js +16 -0
- package/core/collection/array/typed/isTypedArray.js +20 -0
- package/core/collection/array/typedArrayToDataType.js +1 -0
- package/{engine/navigation/grid → core/collection/heap}/BinaryHeap.js +6 -1
- package/{engine/navigation/grid → core/collection/heap}/FastBinaryHeap.js +3 -2
- package/{engine/navigation/grid → core/collection/heap}/FastBinaryHeap.spec.js +3 -3
- package/core/collection/heap/Uin32Heap.spec.js +59 -0
- package/core/collection/heap/Uint32Heap.js +385 -0
- package/core/collection/list/List.d.ts +1 -1
- package/core/collection/table/RowFirstTable.js +34 -0
- package/core/collection/table/RowFirstTable.spec.js +59 -1
- package/core/color/Color.js +83 -1
- package/core/color/YCbCr_to_rgb_uint24.js +3 -4
- package/core/color/hsv2rgb.js +4 -3
- package/core/color/linear_to_sRGB.js +4 -5
- package/core/color/rgb2hex.js +1 -1
- package/core/color/rgb2uint24.js +6 -4
- package/core/color/rgb_to_YCbCr_uint24.js +11 -13
- package/core/events/signal/Signal.d.ts +11 -9
- package/core/events/signal/Signal.spec.js +16 -0
- package/core/geom/2d/quad-tree/qt_collect_by_circle.js +67 -0
- package/core/geom/3d/topology/computeTopoMeshVertexDuplicates.js +9 -6
- package/core/geom/3d/topology/expandConnectivityByLocality.js +5 -5
- package/core/geom/3d/topology/query/query_edge_is_boundary.js +7 -0
- package/core/geom/3d/topology/query/query_edge_is_manifold.js +13 -0
- package/core/geom/3d/topology/query/query_edge_is_manifold_or_boundary.js +11 -0
- package/core/geom/3d/topology/query/query_edge_is_wire.js +13 -0
- package/core/geom/3d/topology/query/query_edge_other_vertex.js +20 -0
- package/core/geom/3d/topology/query/query_edge_share_vert.js +9 -0
- package/core/geom/3d/topology/query/query_face_get_other_edges.js +39 -0
- package/core/geom/3d/topology/query/query_face_next_vertex.js +19 -0
- package/core/geom/3d/topology/query/query_face_prev_vertex.js +18 -0
- package/core/geom/3d/topology/query/query_vertex_in_edge.js +14 -0
- package/core/geom/3d/topology/query/query_vertex_pair_share_face.js +24 -0
- package/core/geom/3d/topology/query/query_vertices_in_edge.js +19 -0
- package/core/geom/3d/topology/simplify/collapseEdge.spec.js +3 -5
- package/core/geom/3d/topology/simplify/collapse_all_degenerate_edges.js +8 -10
- package/core/geom/3d/topology/simplify/compute_face_normal_change_dot_product.js +12 -2
- package/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +277 -0
- package/core/geom/3d/topology/simplify/edge_collapse_quadratic.js +126 -0
- package/core/geom/3d/topology/simplify/prototypeMeshSimplification.js +502 -0
- package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +37 -5
- package/core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js +86 -1
- package/core/geom/3d/topology/simplify/simplifyTopoMesh.js +4 -4
- package/core/geom/3d/topology/simplify/simplifyTopoMesh2.js +119 -0
- package/core/geom/3d/topology/simplify/tm_edge_collapse_is_degenerate_flip.js +81 -0
- package/core/geom/3d/topology/{TopoEdge.js → struct/TopoEdge.js} +47 -20
- package/core/geom/3d/topology/{TopoEdge.spec.js → struct/TopoEdge.spec.js} +0 -0
- package/core/geom/3d/topology/{TopoMesh.js → struct/TopoMesh.js} +20 -41
- package/core/geom/3d/topology/{TopoTriangle.js → struct/TopoTriangle.js} +15 -25
- package/core/geom/3d/topology/{TopoVertex.js → struct/TopoVertex.js} +21 -4
- package/core/geom/3d/topology/{TopoVertex.spec.js → struct/TopoVertex.spec.js} +0 -0
- package/core/geom/3d/topology/tm_edge_kill.js +24 -0
- package/core/geom/3d/topology/tm_edge_splice.js +42 -0
- package/core/geom/3d/topology/tm_face_area.js +18 -0
- package/core/geom/3d/topology/tm_face_kill.js +12 -0
- package/core/geom/3d/topology/tm_face_normal.js +14 -0
- package/core/geom/3d/topology/tm_kill_only_edge.js +35 -0
- package/core/geom/3d/topology/tm_kill_only_face.js +12 -0
- package/core/geom/3d/topology/tm_kill_only_vert.js +14 -0
- package/core/geom/3d/topology/tm_vert_kill.js +19 -0
- package/core/geom/3d/topology/tm_vert_splice.js +64 -0
- package/core/geom/3d/topology/tm_vertex_compute_normal.js +42 -0
- package/core/geom/3d/topology/topoMeshToBufferGeometry.js +18 -4
- package/core/geom/3d/topology/weld_duplicate_vertices.js +63 -0
- package/core/geom/Quaternion.d.ts +21 -1
- package/core/geom/Quaternion.js +279 -200
- package/core/geom/Quaternion.spec.js +71 -2
- package/core/geom/Vector2.js +3 -3
- package/core/geom/Vector3.d.ts +2 -0
- package/core/geom/Vector3.js +31 -7
- package/core/geom/Vector3.schema.json +16 -0
- package/core/geom/Vector4.js +16 -0
- package/core/geom/packing/MaxRectangles.js +1 -1
- package/core/graph/cluster_mesh_metis.js +16 -0
- package/core/graph/coarsen_graph.js +1 -1
- package/core/graph/graph_k_means_cluster.js +1 -1
- package/core/json/JsonUtils.js +2 -20
- package/core/math/bell_membership_function.js +19 -0
- package/core/math/exp2.js +8 -0
- package/core/math/interval/NumericInterval.js +17 -0
- package/core/math/physics/brdf/brdf_burley.js +25 -0
- package/core/math/physics/bsdf/bsdf_schlick.js +22 -0
- package/core/math/physics/irradiance/interpolate_irradiance_linear.js +18 -0
- package/{engine/sound/ecs/emitter/attenuate/attenuateSoundLogarithmic.js → core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js} +2 -2
- package/{engine/sound/ecs/emitter/attenuate/attenuateSoundSmith.js → core/math/physics/irradiance/interpolate_irradiance_smith.js} +1 -1
- package/core/math/random/seededRandom.js +2 -31
- package/core/math/random/seededRandom_Mulberry32.js +31 -0
- package/core/math/random/seededRandom_sine.js +33 -0
- package/core/model/ObservedEnum.js +8 -0
- package/editor/Editor.js +97 -1
- package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
- package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.js +13 -105
- package/editor/ecs/component/FieldDescriptor.js +34 -0
- package/editor/ecs/component/FieldValueAdapter.js +20 -0
- package/editor/ecs/component/TypeEditor.js +33 -0
- package/editor/ecs/component/TypeSchema.d.ts +38 -0
- package/editor/ecs/component/createFieldEditor.js +90 -0
- package/editor/ecs/component/createObjectEditor.js +266 -60
- package/editor/ecs/component/editors/ColorEditor.js +39 -0
- package/editor/ecs/component/editors/HTMLElementEditor.js +17 -0
- package/editor/ecs/component/editors/ImagePathEditor.js +50 -0
- package/editor/ecs/component/editors/NumericIntervalEditor.js +86 -0
- package/editor/ecs/component/editors/ObservedBooleanEditor.js +13 -0
- package/editor/ecs/component/editors/ObservedEnumEditor.js +32 -0
- package/editor/ecs/component/editors/ObservedIntegerEditor.js +43 -0
- package/editor/ecs/component/editors/ObservedStringEditor.js +51 -0
- package/editor/ecs/component/editors/Sampler2DEditor.js +107 -0
- package/editor/ecs/component/editors/collection/ListEditor.js +83 -0
- package/editor/ecs/component/editors/common/BitFlagsEditor.js +80 -0
- package/editor/ecs/component/editors/common/EnumEditor.js +41 -0
- package/editor/ecs/component/editors/common/makeV3_editor.js +85 -0
- package/editor/ecs/component/editors/common/noEditor.js +9 -0
- package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +17 -0
- package/editor/ecs/component/editors/ecs/MinimapMarkerEditor.js +16 -0
- package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +44 -0
- package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -0
- package/editor/ecs/component/editors/ecs/ParticleEmitterEditor.js +58 -0
- package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +54 -0
- package/editor/ecs/component/editors/ecs/SimulationStepDefinitionEditor.js +21 -0
- package/editor/ecs/component/editors/ecs/Trail2DEditor.js +33 -0
- package/editor/ecs/component/editors/ecs/TransformEditor.js +23 -0
- package/editor/ecs/component/editors/ecs/terrain/SplatMappingEditor.js +21 -0
- package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +89 -0
- package/editor/ecs/component/editors/ecs/terrain/TerrainLayerEditor.js +18 -0
- package/editor/ecs/component/editors/ecs/terrain/TerrainLayersEditor.js +22 -0
- package/editor/ecs/component/editors/ecs/terrain/TerrainOverlayEditor.js +20 -0
- package/editor/ecs/component/editors/geom/QuaternionEditor.js +56 -0
- package/editor/ecs/component/editors/geom/Vector1Editor.js +57 -0
- package/editor/ecs/component/editors/geom/Vector2Editor.js +11 -0
- package/editor/ecs/component/editors/geom/Vector3Editor.js +13 -0
- package/editor/ecs/component/editors/geom/Vector4Editor.js +12 -0
- package/editor/ecs/component/editors/primitive/ArrayEditor.js +46 -0
- package/editor/ecs/component/editors/primitive/BooleanEditor.js +27 -0
- package/editor/ecs/component/editors/primitive/FunctionEditor.js +29 -0
- package/editor/ecs/component/editors/primitive/NumberEditor.js +60 -0
- package/editor/ecs/component/editors/primitive/ObjectEditor.js +12 -0
- package/editor/ecs/component/editors/primitive/StringEditor.js +31 -0
- package/editor/ecs/component/editors/three/BufferGeometryEditor.js +28 -0
- package/editor/ecs/component/editors/three/MaterialEditor.js +27 -0
- package/editor/ecs/component/editors/three/MeshEditor.js +35 -0
- package/editor/ecs/component/editors/three/TextureEditor.js +32 -0
- package/editor/ecs/component/findNearestRegisteredType.js +59 -0
- package/editor/ecs/component/prototypeObjectEditor.js +379 -0
- package/editor/tools/SelectionTool.js +1 -1
- package/editor/tools/paint/TerrainHeightPaintTool.js +88 -68
- package/editor/tools/paint/TerrainPaintTool.js +2 -1
- package/editor/tools/paint/TerrainTexturePaintTool.js +8 -73
- package/editor/view/EditorView.js +1 -1
- package/editor/view/ecs/ComponentControlView.js +2 -30
- package/editor/view/ecs/EntityEditor.js +61 -139
- package/editor/view/ecs/components/GridObstacleController.js +4 -4
- package/editor/view/ecs/components/TerrainController.js +1 -1
- package/editor/view/ecs/components/common/NumberController.js +19 -7
- package/editor/view/node-graph/NodeGraphView.js +2 -2
- package/editor/view/node-graph/NodeView.js +7 -9
- package/engine/animation/keyed2/AnimationTrack.js +1 -1
- package/engine/asset/AssetManager.d.ts +1 -1
- package/engine/asset/AssetManager.js +390 -388
- package/engine/asset/loaders/gltf/extensions/MSFT_texture_dds.js +14 -2
- package/engine/ecs/components/TagEditor.js +15 -0
- package/engine/ecs/fow/FogOfWarEditor.js +13 -0
- package/engine/ecs/parent/ParentEntitySystem.js +57 -0
- package/engine/ecs/terrain/ecs/OffsetScaleTransform2D.d.ts +6 -0
- package/engine/ecs/terrain/ecs/Terrain.js +44 -43
- package/engine/ecs/terrain/ecs/TerrainSystem.js +2 -2
- package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +1 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +26 -28
- package/engine/ecs/terrain/overlay/TerrainOverlay.js +71 -66
- package/engine/ecs/terrain/tiles/TerrainTileManager.js +23 -0
- package/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +1 -1
- package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +13 -7
- package/engine/ecs/terrain/util/tensionOptimizeUV.js +1 -1
- package/engine/ecs/transform/Transform.d.ts +2 -0
- package/engine/ecs/transform/Transform.editor.schema.json +16 -0
- package/engine/ecs/transform/Transform.js +3 -0
- package/engine/graphics/ecs/highlight/HighlightEditor.js +17 -0
- package/engine/graphics/ecs/light/Light.js +0 -47
- package/engine/graphics/ecs/light/LightSerializationAdapter.js +50 -0
- package/engine/graphics/ecs/mesh/MeshEditor.js +28 -0
- package/engine/graphics/ecs/mesh-v2/DrawMode.js +2 -1
- package/engine/graphics/ecs/mesh-v2/aggregate/prototypeSGMesh.js +3 -3
- package/engine/graphics/ecs/mesh-v2/build_three_object.js +3 -1
- package/engine/graphics/ecs/mesh-v2/sg_compute_hierarchy_bounding_box_by_parent_entity.js +31 -0
- package/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.d.ts +4 -0
- package/engine/graphics/ecs/sprite/Sprite.js +11 -0
- package/engine/graphics/ecs/sprite/SpriteSystemPE.js +133 -0
- package/engine/graphics/ecs/sprite/prototypeSpriteSystem.js +1570 -0
- package/engine/graphics/micron/build/PatchRepresentation.js +7 -3
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +18 -8
- package/engine/graphics/micron/build/clustering/build_clustering_2.js +1 -1
- package/engine/graphics/micron/build/clustering/build_leaf_patches.js +2 -2
- package/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +1 -1
- package/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +21 -3
- package/engine/graphics/micron/build/hierarchy/merge_patches.js +96 -43
- package/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +11 -5
- package/engine/graphics/micron/format/VirtualGeometry.js +46 -3
- package/engine/graphics/micron/format/micron_build_proxy_geometry.js +4 -2
- package/engine/graphics/micron/prototypeVirtualGeometry.js +47 -10
- package/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +17 -17
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +15 -3
- package/engine/graphics/micron/simplifyGeometry.js +1 -1
- package/engine/graphics/particles/particular/engine/ParticularEngine.js +5 -0
- package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -9
- package/engine/graphics/particles/particular/engine/renderers/ParticleRenderer.js +12 -10
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +7 -2
- package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticlePool.js +27 -0
- package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticleRenderer.js +80 -0
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +16 -4
- package/engine/graphics/shaders/TerrainShader.js +8 -8
- package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +2 -1
- package/engine/graphics/texture/sampler/Sampler2D.js +206 -201
- package/engine/graphics/texture/sampler/Sampler2D.spec.js +34 -35
- package/engine/graphics/texture/sampler/bicubic.js +59 -0
- package/engine/graphics/texture/sampler/downsampleSample2D.spec.js +2 -2
- package/engine/graphics/texture/sampler/genericResampleSampler2D.js +0 -2
- package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +146 -0
- package/engine/graphics/texture/sampler/{downsampleSampler2D.js → sampler2D_scale_down_linear.js} +8 -4
- package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +140 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -3
- package/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +1 -1
- package/engine/graphics/util/ScaleObject3ToBox.js +14 -1
- package/engine/graphics/util/makeMeshPreviewScene.js +2 -1
- package/engine/grid/components/GridObstacle.js +0 -44
- package/engine/grid/components/GridObstacleSerializationAdapter.js +46 -0
- package/engine/input/devices/PointerDevice.d.ts +1 -1
- package/engine/input/devices/PointerDevice.js +17 -2
- package/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
- package/engine/navigation/ecs/components/Path.d.ts +2 -0
- package/engine/navigation/ecs/components/Path.js +6 -1
- package/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +117 -0
- package/engine/navigation/grid/AStar.js +1 -1
- package/engine/navigation/grid/GridField.js +3 -2
- package/engine/platform/GetURLHash.js +27 -0
- package/engine/platform/WebEnginePlatform.js +1 -22
- package/engine/sound/ecs/emitter/SoundEmitter.js +10 -6
- package/engine/ui/DraggableAspect.js +2 -2
- package/generation/GridGenerator.js +7 -6
- package/generation/example/SampleGenerator0.js +39 -35
- package/generation/example/filters/SampleGroundMoistureFilter.js +58 -17
- package/generation/example/generators/interactive/mir_generator_place_buff_objects.js +7 -6
- package/generation/example/generators/mir_generator_place_bases.js +7 -3
- package/generation/example/generators/mir_generator_place_road_decorators.js +3 -3
- package/generation/example/generators/mir_generator_place_starting_point.js +3 -2
- package/generation/example/themes/SampleTheme0.js +11 -7
- package/generation/filtering/numeric/CellFilterLiteralFloat.js +5 -0
- package/generation/filtering/numeric/complex/CellFilterDilate.js +36 -0
- package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +15 -5
- package/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +53 -1
- package/generation/filtering/numeric/math/CellFilterMax2.js +3 -0
- package/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +55 -0
- package/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +42 -0
- package/generation/filtering/numeric/sampling/CellFilterSampleLayerCubic.js +36 -0
- package/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +41 -0
- package/generation/grid/GridData.d.ts +5 -1
- package/generation/grid/GridData.js +35 -36
- package/generation/grid/MarkerMatchCounter.js +5 -3
- package/generation/grid/generation/discrete/GridTaskConnectRooms.js +1 -1
- package/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +1 -1
- package/generation/grid/generation/discrete/layer/GridTaskDistanceToMarkers.js +1 -1
- package/generation/grid/generation/road/GridTaskGenerateRoads.js +1 -1
- package/generation/markers/GridActionRuleSet.js +15 -32
- package/generation/markers/GridCellActionPlaceMarker.js +12 -8
- package/generation/markers/debug/visualizeMarkers.js +56 -36
- package/generation/markers/emitter/MarkerNodeEmitterFromAction.js +8 -8
- package/generation/markers/prototypeGridCellActionPlaceMarker.js +209 -0
- package/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -5
- package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +2 -2
- package/generation/placement/GridCellPlacementRule.js +31 -25
- package/generation/theme/ThemeEngine.js +1 -1
- package/package.json +1 -1
- package/samples/terrain/from_image.js +7 -3
- package/samples/terrain/main.js +1 -1
- package/view/View.js +23 -1
- package/view/common/LabelView.js +1 -1
- package/view/compose3x3transform.js +32 -8
- package/view/controller/dat/DatGuiUtils.js +1 -1
- package/view/elements/DropDownSelectionView.js +11 -3
- package/view/elements/image/ImageView.js +3 -1
- package/core/model/ObservedReal.js +0 -55
- package/editor/ecs/component/ObjectEditor.js +0 -0
- package/engine/graphics/particles/particular/engine/renderers/SoftBillboardParticleRenderer.js +0 -7
- package/engine/sound/ecs/emitter/attenuate/attenuateSoundLinear.js +0 -11
- 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 "
|
|
2
|
-
import { array_remove_first } from "
|
|
3
|
-
import { array_push_if_unique } from "
|
|
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
|
|
104
|
-
this.v1
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
/**
|
|
File without changes
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { assert } from "
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 "
|
|
2
|
-
import { array_push_if_unique } from "
|
|
3
|
-
import { assert } from "
|
|
4
|
-
import { array_remove_first } from "
|
|
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 {
|
|
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
|
|
43
|
+
const l_sqr = v3_length_sqr(crossX, crossY, crossZ);
|
|
44
44
|
|
|
45
|
-
if (
|
|
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
|
|
52
|
-
|
|
53
|
-
const
|
|
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 =
|
|
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 "
|
|
2
|
-
import { array_push_if_unique } from "
|
|
3
|
-
import { array_remove_first } from "
|
|
4
|
-
import { v3_distance } from "
|
|
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
|
*/
|
|
File without changes
|
|
@@ -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
|
+
}
|