@woosh/meep-engine 2.48.20 → 2.48.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +0 -1
- package/src/engine/graphics/micron/MICRON_URI_FIELD.js +0 -1
- package/src/engine/graphics/micron/build/MICRON_PATCH_SIZE_MAX.js +0 -5
- package/src/engine/graphics/micron/build/PatchRepresentation.js +0 -424
- package/src/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +0 -311
- package/src/engine/graphics/micron/build/build_geometry_info.js +0 -21
- package/src/engine/graphics/micron/build/clustering/assignInitialPatchNeighbours.js +0 -63
- package/src/engine/graphics/micron/build/clustering/assign_patch_neighbours_from_topology.js +0 -46
- package/src/engine/graphics/micron/build/clustering/build_clustering_2.js +0 -37
- package/src/engine/graphics/micron/build/clustering/build_leaf_patches.js +0 -326
- package/src/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +0 -76
- package/src/engine/graphics/micron/build/clustering/computeBorderLengthChange.js +0 -59
- package/src/engine/graphics/micron/build/clustering/computeFaceCurvatureScore.js +0 -57
- package/src/engine/graphics/micron/build/clustering/computeOpenFaceFreedom.js +0 -35
- package/src/engine/graphics/micron/build/clustering/compute_face_connection_weight.js +0 -35
- package/src/engine/graphics/micron/build/clustering/populateOpenFaceNeighboursForPatch.js +0 -56
- package/src/engine/graphics/micron/build/clustering/validate_leaf_patch_connectivity.js +0 -44
- package/src/engine/graphics/micron/build/compute_micron_buffer_array_constructor.js +0 -24
- package/src/engine/graphics/micron/build/compute_vertex_remap_cost.js +0 -29
- package/src/engine/graphics/micron/build/debug/build_clustering_info.js +0 -58
- package/src/engine/graphics/micron/build/debug/build_graph_info.js +0 -59
- package/src/engine/graphics/micron/build/fill_patch_geometry_data.js +0 -270
- package/src/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +0 -196
- package/src/engine/graphics/micron/build/hierarchy/build_intermediate_patch_topology.js +0 -162
- package/src/engine/graphics/micron/build/hierarchy/build_merge_graph.js +0 -89
- package/src/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +0 -146
- package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertex_count.js +0 -32
- package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertices.js +0 -34
- package/src/engine/graphics/micron/build/hierarchy/merge_patches.js +0 -581
- package/src/engine/graphics/micron/build/hierarchy/metis_cluster_clusters.js +0 -53
- package/src/engine/graphics/micron/build/hierarchy/optimize_graph_partitioning_balance.js +0 -515
- package/src/engine/graphics/micron/build/hierarchy/patch_combine.js +0 -180
- package/src/engine/graphics/micron/build/hierarchy/patch_fill_holes_by_uncollapse.js +0 -60
- package/src/engine/graphics/micron/build/hierarchy/patch_stitch_parent_border.js +0 -320
- package/src/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +0 -547
- package/src/engine/graphics/micron/build/hierarchy/qvdr_build_tree.js +0 -140
- package/src/engine/graphics/micron/buildPatchwork.js +0 -68
- package/src/engine/graphics/micron/convert_three_object_to_micron.js +0 -179
- package/src/engine/graphics/micron/debug/VirtualGeometryStats.js +0 -42
- package/src/engine/graphics/micron/format/MICRON_GEOMETRY_PROPERTY_NAME.js +0 -1
- package/src/engine/graphics/micron/format/MicronGeometry.d.ts +0 -21
- package/src/engine/graphics/micron/format/MicronGeometry.js +0 -334
- package/src/engine/graphics/micron/format/MicronGeometryPatch.d.ts +0 -3
- package/src/engine/graphics/micron/format/MicronGeometryPatch.js +0 -205
- package/src/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +0 -50
- package/src/engine/graphics/micron/format/ThreeMicronMesh.d.ts +0 -10
- package/src/engine/graphics/micron/format/ThreeMicronMesh.js +0 -45
- package/src/engine/graphics/micron/format/VirtualGeometry.js +0 -158
- package/src/engine/graphics/micron/format/micron_build_proxy_geometry.js +0 -205
- package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +0 -123
- package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js +0 -63
- package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +0 -83
- package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.spec.js +0 -51
- package/src/engine/graphics/micron/format/serialization/deserialize_attribute_spec.js +0 -25
- package/src/engine/graphics/micron/format/serialization/deserialize_patch.js +0 -106
- package/src/engine/graphics/micron/format/serialization/serialize_attribute_spec.js +0 -18
- package/src/engine/graphics/micron/format/serialization/serialize_patch.js +0 -84
- package/src/engine/graphics/micron/format/validate_patch_bounds.js +0 -69
- package/src/engine/graphics/micron/plugin/GLTFAssetTransformer.js +0 -265
- package/src/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +0 -5
- package/src/engine/graphics/micron/plugin/MicronRenderPlugin.d.ts +0 -8
- package/src/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -150
- package/src/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +0 -176
- package/src/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +0 -216
- package/src/engine/graphics/micron/prototypeMicronProxyBuild.js +0 -227
- package/src/engine/graphics/micron/prototypeVirtualGeometry.js +0 -911
- package/src/engine/graphics/micron/render/PatchCacheKey.js +0 -79
- package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.d.ts +0 -1
- package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.js +0 -1
- package/src/engine/graphics/micron/render/VirtualGeometryBuilder.js +0 -207
- package/src/engine/graphics/micron/render/approximateTriangleArea.js +0 -25
- package/src/engine/graphics/micron/render/culling/PatchCullingSystem.js +0 -129
- package/src/engine/graphics/micron/render/instanced/PatchDataTextures.js +0 -329
- package/src/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -175
- package/src/engine/graphics/micron/render/instanced/shader/constants.js +0 -3
- package/src/engine/graphics/micron/render/instanced/shader/gen_micron_vertex_attribute_texture_name.js +0 -8
- package/src/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +0 -250
- package/src/engine/graphics/micron/render/makeThreeMeshFromVirtualGeometry.js +0 -37
- package/src/engine/graphics/micron/render/refinement/ActivePatchFlags.js +0 -8
- package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +0 -241
- package/src/engine/graphics/micron/render/refinement/ActivePatchRecord.js +0 -154
- package/src/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -84
- package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +0 -133
- package/src/engine/graphics/micron/render/refinement/is_patch_facing_back.js +0 -43
- package/src/engine/graphics/micron/render/refinement/is_patch_visible.js +0 -37
- package/src/engine/graphics/micron/render/v1/MaterialContext.js +0 -150
- package/src/engine/graphics/micron/render/v1/MaterialVertexSpec.js +0 -115
- package/src/engine/graphics/micron/render/v1/MicronRenderContext.js +0 -145
- package/src/engine/graphics/micron/render/v1/ThreeVirtualGeometryAdapter.js +0 -255
- package/src/engine/graphics/micron/render/v1/VGThreeRenderer.js +0 -142
- package/src/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +0 -54
- package/src/engine/graphics/micron/simplifyGeometry.js +0 -26
- package/src/engine/graphics/micron/util/patchToBufferGeometry.js +0 -19
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
import { computeMeshSurfaceArea } from "../../../geometry/computeMeshSurfaceArea.js";
|
|
2
|
-
import { BitSet } from "../../../../../core/binary/BitSet.js";
|
|
3
|
-
import { computeOpenFaceFreedom } from "./computeOpenFaceFreedom.js";
|
|
4
|
-
import FastBinaryHeap from "../../../../../core/collection/heap/FastBinaryHeap.js";
|
|
5
|
-
import { PatchRepresentation } from "../PatchRepresentation.js";
|
|
6
|
-
import { MICRON_PATCH_SIZE_MAX } from "../MICRON_PATCH_SIZE_MAX.js";
|
|
7
|
-
import { populateOpenFaceNeighboursForPatch } from "./populateOpenFaceNeighboursForPatch.js";
|
|
8
|
-
import { update_topo_face_normals } from "../../../../../core/geom/3d/topology/update_topo_face_normals.js";
|
|
9
|
-
import { computeBorderLengthChange } from "./computeBorderLengthChange.js";
|
|
10
|
-
import { sign } from "../../../../../core/math/sign.js";
|
|
11
|
-
import { vec3 } from "gl-matrix";
|
|
12
|
-
import { TopoMesh } from "../../../../../core/geom/3d/topology/struct/TopoMesh.js";
|
|
13
|
-
|
|
14
|
-
const scratch_set = new Set();
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {PatchRepresentation} patch
|
|
19
|
-
* @param {TopoTriangle} face
|
|
20
|
-
* @param {Map<number, PatchRepresentation[]>} vertex_to_patch_map
|
|
21
|
-
* @returns {number}
|
|
22
|
-
*/
|
|
23
|
-
function count_additional_neighbour_patches(patch, face, vertex_to_patch_map) {
|
|
24
|
-
const neighbours = patch.neighbours;
|
|
25
|
-
|
|
26
|
-
const face_vertices = face.vertices;
|
|
27
|
-
|
|
28
|
-
scratch_set.clear();
|
|
29
|
-
const unique_additions = scratch_set;
|
|
30
|
-
|
|
31
|
-
for (let i = 0; i < 3; i++) {
|
|
32
|
-
|
|
33
|
-
const vertex = face_vertices[i];
|
|
34
|
-
|
|
35
|
-
const adjacent_patches = vertex_to_patch_map.get(vertex.index);
|
|
36
|
-
|
|
37
|
-
if (adjacent_patches === undefined) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
for (let j = 0; j < adjacent_patches.length; j++) {
|
|
42
|
-
const adjacent_patch = adjacent_patches[j];
|
|
43
|
-
|
|
44
|
-
if (adjacent_patch === patch) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!neighbours.includes(adjacent_patch)) {
|
|
49
|
-
unique_additions.add(adjacent_patch);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return unique_additions.size;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @param {TopoMesh} topoMesh
|
|
60
|
-
* @param {number[]|Uint8Array|Uint32Array} index_attribute
|
|
61
|
-
* @param {number[]|Float32Array} position_attribute
|
|
62
|
-
* @param {Map<number, PatchRepresentation>} face_to_patch_map
|
|
63
|
-
* @param {Map<number, PatchRepresentation[]>} vertex_to_patch_map
|
|
64
|
-
*/
|
|
65
|
-
export function build_leaf_patches(
|
|
66
|
-
topoMesh,
|
|
67
|
-
index_attribute,
|
|
68
|
-
position_attribute,
|
|
69
|
-
face_to_patch_map,
|
|
70
|
-
vertex_to_patch_map
|
|
71
|
-
) {
|
|
72
|
-
|
|
73
|
-
// face normals are required by various metrics and for normal-cone calculation
|
|
74
|
-
const input_topology_face_count = topoMesh.getFaces().size;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
*
|
|
78
|
-
* @type {TopoTriangle[]}
|
|
79
|
-
*/
|
|
80
|
-
const topo_mesh_faces_array = Array.from(topoMesh.getFaces());
|
|
81
|
-
|
|
82
|
-
update_topo_face_normals(topo_mesh_faces_array, input_topology_face_count);
|
|
83
|
-
|
|
84
|
-
const polygon_count = index_attribute.length / 3;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Areas of individual triangles
|
|
88
|
-
* @type {Float32Array}
|
|
89
|
-
*/
|
|
90
|
-
const face_areas = new Float32Array(polygon_count);
|
|
91
|
-
|
|
92
|
-
computeMeshSurfaceArea(face_areas, position_attribute, index_attribute, polygon_count);
|
|
93
|
-
|
|
94
|
-
// organize initial geometry into first level patches
|
|
95
|
-
|
|
96
|
-
let open_set_size = input_topology_face_count;
|
|
97
|
-
|
|
98
|
-
const open_set = BitSet.fixedSize(open_set_size);
|
|
99
|
-
|
|
100
|
-
open_set.setRange(0, open_set_size - 1);
|
|
101
|
-
let min_open_set_index = -1;
|
|
102
|
-
|
|
103
|
-
let starting_face_index;
|
|
104
|
-
let target_polygon_area = 0;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
* @type {Map<number, number>}
|
|
109
|
-
*/
|
|
110
|
-
const distances = new Map();
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
let patch;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Lower is better
|
|
117
|
-
* @param {number} face_index
|
|
118
|
-
* @returns {number}
|
|
119
|
-
*/
|
|
120
|
-
function score_function(face_index) {
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
*
|
|
124
|
-
* @type {number}
|
|
125
|
-
*/
|
|
126
|
-
const previous_face_index = came_from_map.get(face_index);
|
|
127
|
-
|
|
128
|
-
if (previous_face_index === undefined) {
|
|
129
|
-
return 0;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// distance score serves to keep topology roughly circular around the starting face
|
|
133
|
-
const distance_cost = distances.get(face_index);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// polygon score serves to keep triangles in the patch roughly same area
|
|
137
|
-
const polygon_area = face_areas[face_index];
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
*
|
|
141
|
-
* @type {TopoTriangle}
|
|
142
|
-
*/
|
|
143
|
-
const topo_face = topo_mesh_faces_array[face_index];
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
*
|
|
147
|
-
* @type {TopoTriangle}
|
|
148
|
-
*/
|
|
149
|
-
const previous_face = topo_mesh_faces_array[previous_face_index];
|
|
150
|
-
|
|
151
|
-
const normal_dot_cost = -vec3.dot(topo_face.normal, previous_face.normal);
|
|
152
|
-
|
|
153
|
-
const freedom_cost = computeOpenFaceFreedom(topo_face, open_set, topoMesh);
|
|
154
|
-
|
|
155
|
-
// Try to avoid acquiring more neighbour patches
|
|
156
|
-
const added_neighbour_cost = count_additional_neighbour_patches(patch, topo_face, vertex_to_patch_map);
|
|
157
|
-
|
|
158
|
-
// perimeter score, tries to keep the outline of the patch smooth
|
|
159
|
-
const perimeter_change = computeBorderLengthChange(topo_face, patch, face_to_patch_map);
|
|
160
|
-
|
|
161
|
-
/*
|
|
162
|
-
Compute change to perimeter/area ratio of the patch
|
|
163
|
-
Using equilateral triangle as a basis for normalization
|
|
164
|
-
A = ( (√3)/4 )*a²
|
|
165
|
-
*/
|
|
166
|
-
const area_perimeter_cost = sign(perimeter_change) * (perimeter_change * perimeter_change * 0.43301270189) / (polygon_area + 0.0001);
|
|
167
|
-
|
|
168
|
-
return distance_cost
|
|
169
|
-
+ normal_dot_cost * 0.01
|
|
170
|
-
+ area_perimeter_cost * 0.01
|
|
171
|
-
+ added_neighbour_cost
|
|
172
|
-
+ freedom_cost * 2.001
|
|
173
|
-
;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Which face did we come to this face from?
|
|
178
|
-
* @type {Map<number, number>}
|
|
179
|
-
*/
|
|
180
|
-
const came_from_map = new Map();
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
*
|
|
184
|
-
* @type {BinaryHeap<number>}
|
|
185
|
-
*/
|
|
186
|
-
const patch_face_candidates = new FastBinaryHeap(score_function);
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
*
|
|
190
|
-
* @type {PatchRepresentation[]}
|
|
191
|
-
*/
|
|
192
|
-
const patches = [];
|
|
193
|
-
|
|
194
|
-
while (open_set_size > 0) {
|
|
195
|
-
|
|
196
|
-
if (patch_face_candidates.isEmpty()) {
|
|
197
|
-
// pick any face
|
|
198
|
-
starting_face_index = open_set.nextSetBit(min_open_set_index);
|
|
199
|
-
min_open_set_index = starting_face_index + 1;
|
|
200
|
-
} else {
|
|
201
|
-
// pick next candidate
|
|
202
|
-
starting_face_index = patch_face_candidates.pop();
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// set desired area
|
|
206
|
-
target_polygon_area = face_areas[starting_face_index];
|
|
207
|
-
|
|
208
|
-
patch = new PatchRepresentation();
|
|
209
|
-
|
|
210
|
-
came_from_map.clear();
|
|
211
|
-
|
|
212
|
-
distances.clear();
|
|
213
|
-
patch_face_candidates.clear();
|
|
214
|
-
|
|
215
|
-
// record starting face
|
|
216
|
-
distances.set(starting_face_index, 0);
|
|
217
|
-
patch_face_candidates.push(starting_face_index);
|
|
218
|
-
|
|
219
|
-
const patch_topology = new TopoMesh();
|
|
220
|
-
|
|
221
|
-
for (let i = 0; i < MICRON_PATCH_SIZE_MAX && !patch_face_candidates.isEmpty(); i++) {
|
|
222
|
-
// get next
|
|
223
|
-
const next_face_index = patch_face_candidates.pop();
|
|
224
|
-
const next_face = topo_mesh_faces_array[next_face_index];
|
|
225
|
-
|
|
226
|
-
patch_topology.injectFace(next_face);
|
|
227
|
-
|
|
228
|
-
face_to_patch_map.set(next_face_index, patch);
|
|
229
|
-
|
|
230
|
-
// remove from open set
|
|
231
|
-
open_set.clear(next_face_index);
|
|
232
|
-
open_set_size--;
|
|
233
|
-
|
|
234
|
-
// re-score face neighbours
|
|
235
|
-
|
|
236
|
-
const next_face_edges = next_face.edges;
|
|
237
|
-
const next_face_edge_count = next_face_edges.length;
|
|
238
|
-
|
|
239
|
-
for (let j = 0; j < next_face_edge_count; j++) {
|
|
240
|
-
const next_face_edge = next_face_edges[j];
|
|
241
|
-
|
|
242
|
-
const faces_x = next_face_edge.faces;
|
|
243
|
-
const faces_x_count = faces_x.length;
|
|
244
|
-
|
|
245
|
-
for (let k = 0; k < faces_x_count; k++) {
|
|
246
|
-
const face_x = faces_x[k];
|
|
247
|
-
|
|
248
|
-
if (face_x === next_face) {
|
|
249
|
-
// skip self
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const neighbour_index = face_x.index;
|
|
254
|
-
|
|
255
|
-
const index_in_heap = patch_face_candidates.data.indexOf(neighbour_index);
|
|
256
|
-
if (index_in_heap !== -1) {
|
|
257
|
-
// re-score face
|
|
258
|
-
patch_face_candidates.bubbleDown(index_in_heap);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const next_face_vertices = next_face.vertices;
|
|
265
|
-
vertex_loop: for (let j = 0; j < 3; j++) {
|
|
266
|
-
const v = next_face_vertices[j];
|
|
267
|
-
|
|
268
|
-
const vertex_index = v.index;
|
|
269
|
-
|
|
270
|
-
if (patch.vertices_included.has(vertex_index)) {
|
|
271
|
-
// already included
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
patch.vertices_included.add(vertex_index);
|
|
276
|
-
|
|
277
|
-
const existing_patches = vertex_to_patch_map.get(vertex_index);
|
|
278
|
-
|
|
279
|
-
if (existing_patches === undefined) {
|
|
280
|
-
vertex_to_patch_map.set(vertex_index, [patch]);
|
|
281
|
-
} else {
|
|
282
|
-
// has neighbours
|
|
283
|
-
const existing_patch_count = existing_patches.length;
|
|
284
|
-
for (let j = 0; j < existing_patch_count; j++) {
|
|
285
|
-
const neighbour = existing_patches[j];
|
|
286
|
-
|
|
287
|
-
if (neighbour === patch) {
|
|
288
|
-
// already referenced
|
|
289
|
-
continue vertex_loop;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (patch.hasNeighbour(neighbour)) {
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
patch.addNeighbour(neighbour);
|
|
297
|
-
neighbour.addNeighbour(patch);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
existing_patches.push(patch);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// get neighbours
|
|
305
|
-
populateOpenFaceNeighboursForPatch(
|
|
306
|
-
open_set,
|
|
307
|
-
patch_face_candidates,
|
|
308
|
-
distances,
|
|
309
|
-
next_face,
|
|
310
|
-
distances.get(next_face_index),
|
|
311
|
-
came_from_map
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
patch.topology_snapshot = new TopoMesh();
|
|
316
|
-
patch.topology_snapshot.add(patch_topology);
|
|
317
|
-
|
|
318
|
-
patch.computeBounds();
|
|
319
|
-
patch.computeNormalBoundingCone();
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
patches.push(patch);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
return patches;
|
|
326
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { cluster_mesh_metis } from "../../../../../core/graph/cluster_mesh_metis.js";
|
|
2
|
-
import { MICRON_PATCH_SIZE_MAX } from "../MICRON_PATCH_SIZE_MAX.js";
|
|
3
|
-
import { PatchRepresentation } from "../PatchRepresentation.js";
|
|
4
|
-
import { TopoMesh } from "../../../../../core/geom/3d/topology/struct/TopoMesh.js";
|
|
5
|
-
import { assign_patch_neighbours_from_topology } from "./assign_patch_neighbours_from_topology.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @param {TopoMesh} topoMesh
|
|
9
|
-
* @param {number[]|Uint8Array|Uint32Array} index_attribute
|
|
10
|
-
* @param {number[]|Float32Array} position_attribute
|
|
11
|
-
* @param {Map<number, PatchRepresentation>} face_to_patch_map
|
|
12
|
-
* @param {Map<number, PatchRepresentation[]>} vertex_to_patch_map
|
|
13
|
-
*/
|
|
14
|
-
export async function build_leaf_patches_metis(
|
|
15
|
-
topoMesh,
|
|
16
|
-
index_attribute,
|
|
17
|
-
position_attribute,
|
|
18
|
-
face_to_patch_map,
|
|
19
|
-
vertex_to_patch_map
|
|
20
|
-
) {
|
|
21
|
-
|
|
22
|
-
const input_face_count = topoMesh.getFaces().size;
|
|
23
|
-
const face_array = Array.from(topoMesh.getFaces());
|
|
24
|
-
|
|
25
|
-
const partitioning = new Uint32Array(input_face_count);
|
|
26
|
-
|
|
27
|
-
const cluster_count = await cluster_mesh_metis(partitioning, topoMesh, MICRON_PATCH_SIZE_MAX);
|
|
28
|
-
|
|
29
|
-
const partition_map = [];
|
|
30
|
-
const result = [];
|
|
31
|
-
const vertex_maps = [];
|
|
32
|
-
|
|
33
|
-
function getPartitionPatch(index) {
|
|
34
|
-
const existing_patch = partition_map[index];
|
|
35
|
-
|
|
36
|
-
if (existing_patch !== undefined) {
|
|
37
|
-
return existing_patch;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const patch = new PatchRepresentation();
|
|
41
|
-
patch.topology_snapshot = new TopoMesh();
|
|
42
|
-
partition_map[index] = patch;
|
|
43
|
-
|
|
44
|
-
vertex_maps[index] = new Map();
|
|
45
|
-
|
|
46
|
-
result.push(patch);
|
|
47
|
-
|
|
48
|
-
return patch;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
for (let i = 0; i < input_face_count; i++) {
|
|
53
|
-
const cluster_index = partitioning[i];
|
|
54
|
-
|
|
55
|
-
const patch = getPartitionPatch(cluster_index);
|
|
56
|
-
const vertex_map = vertex_maps[cluster_index];
|
|
57
|
-
|
|
58
|
-
const face = face_array[i];
|
|
59
|
-
|
|
60
|
-
patch.topology_snapshot.addFaceCopy(face, vertex_map);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
for (let i = 0; i < cluster_count; i++) {
|
|
64
|
-
|
|
65
|
-
const patch = result[i];
|
|
66
|
-
|
|
67
|
-
patch.computeBounds();
|
|
68
|
-
patch.computeNormalBoundingCone();
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// compute neighbours
|
|
73
|
-
assign_patch_neighbours_from_topology(result);
|
|
74
|
-
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* If a given face is added to the patch, how beneficial would that be?
|
|
3
|
-
* @param {TopoTriangle} addition
|
|
4
|
-
* @param {PatchRepresentation} patch
|
|
5
|
-
* @param {Map<number, PatchRepresentation>} face_to_patch_map
|
|
6
|
-
* @returns {number}
|
|
7
|
-
*/
|
|
8
|
-
export function computeBorderLengthChange(addition, patch, face_to_patch_map) {
|
|
9
|
-
const candidate_edges = addition.edges;
|
|
10
|
-
const candidate_edge_count = candidate_edges.length;
|
|
11
|
-
|
|
12
|
-
let in_edge_count = 0;
|
|
13
|
-
let out_edge_count = 0;
|
|
14
|
-
let in_edge_length = 0;
|
|
15
|
-
let out_edge_length = 0;
|
|
16
|
-
|
|
17
|
-
let is_edge_in;
|
|
18
|
-
|
|
19
|
-
for (let i = 0; i < candidate_edge_count; i++) {
|
|
20
|
-
const edge = candidate_edges[i];
|
|
21
|
-
|
|
22
|
-
const neighbour_faces = edge.faces;
|
|
23
|
-
const neighbour_face_count = neighbour_faces.length;
|
|
24
|
-
|
|
25
|
-
is_edge_in = false;
|
|
26
|
-
for (let j = 0; j < neighbour_face_count; j++) {
|
|
27
|
-
const neighbour_face = neighbour_faces[j];
|
|
28
|
-
|
|
29
|
-
if (neighbour_face === addition) {
|
|
30
|
-
// skip self
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const neighbour_face_index = neighbour_face.index;
|
|
35
|
-
const patch_assignment = face_to_patch_map.get(neighbour_face_index);
|
|
36
|
-
|
|
37
|
-
if (patch_assignment === patch) {
|
|
38
|
-
// neighbour is assigned to our patch
|
|
39
|
-
is_edge_in = true;
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// take edge length
|
|
47
|
-
const edge_length = edge.length;
|
|
48
|
-
|
|
49
|
-
if (is_edge_in) {
|
|
50
|
-
in_edge_count++;
|
|
51
|
-
in_edge_length += edge_length;
|
|
52
|
-
} else {
|
|
53
|
-
out_edge_count++;
|
|
54
|
-
out_edge_length += edge_length;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return (out_edge_length - in_edge_length);
|
|
59
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { v3_dot } from "../../../../../core/geom/v3_dot.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* If a given face is added to the patch, how beneficial would that be?
|
|
5
|
-
* @param {TopoTriangle} addition
|
|
6
|
-
* @param {PatchRepresentation} patch
|
|
7
|
-
* @param {Map<number, PatchRepresentation>} face_to_patch_map
|
|
8
|
-
* @returns {number}
|
|
9
|
-
*/
|
|
10
|
-
export function computeFaceCurvatureScore(addition, patch, face_to_patch_map) {
|
|
11
|
-
const candidate_edges = addition.edges;
|
|
12
|
-
const candidate_edge_count = candidate_edges.length;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let neighbour_normal_accumulator_x = 0;
|
|
16
|
-
let neighbour_normal_accumulator_y = 0;
|
|
17
|
-
let neighbour_normal_accumulator_z = 0;
|
|
18
|
-
|
|
19
|
-
for (let i = 0; i < candidate_edge_count; i++) {
|
|
20
|
-
const edge = candidate_edges[i];
|
|
21
|
-
|
|
22
|
-
const neighbour_faces = edge.faces;
|
|
23
|
-
const neighbour_face_count = neighbour_faces.length;
|
|
24
|
-
|
|
25
|
-
for (let j = 0; j < neighbour_face_count; j++) {
|
|
26
|
-
const neighbour_face = neighbour_faces[j];
|
|
27
|
-
|
|
28
|
-
if (neighbour_face === addition) {
|
|
29
|
-
// skip self
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const neighbour_face_index = neighbour_face.index;
|
|
34
|
-
const patch_assignment = face_to_patch_map.get(neighbour_face_index);
|
|
35
|
-
|
|
36
|
-
if (patch_assignment === patch) {
|
|
37
|
-
// neighbour is assigned to our patch
|
|
38
|
-
|
|
39
|
-
const normal = neighbour_face.normal;
|
|
40
|
-
|
|
41
|
-
neighbour_normal_accumulator_x += normal[0];
|
|
42
|
-
neighbour_normal_accumulator_y += normal[1];
|
|
43
|
-
neighbour_normal_accumulator_z += normal[2];
|
|
44
|
-
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
const source_normal = addition.normal;
|
|
50
|
-
|
|
51
|
-
const curvature = v3_dot(
|
|
52
|
-
source_normal[0], source_normal[1], source_normal[2],
|
|
53
|
-
neighbour_normal_accumulator_x, neighbour_normal_accumulator_y, neighbour_normal_accumulator_z
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
return curvature;
|
|
57
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {TopoTriangle} topoFace
|
|
4
|
-
* @param {BitSet} open_set
|
|
5
|
-
* @param {TopoMesh} mesh
|
|
6
|
-
* @returns {number} number of neighbours still in the open set
|
|
7
|
-
*/
|
|
8
|
-
export function computeOpenFaceFreedom(topoFace, open_set, mesh) {
|
|
9
|
-
const edges = topoFace.edges;
|
|
10
|
-
const edge_count = edges.length;
|
|
11
|
-
|
|
12
|
-
let result = 0;
|
|
13
|
-
|
|
14
|
-
for (let i = 0; i < edge_count; i++) {
|
|
15
|
-
const topoEdge = edges[i];
|
|
16
|
-
|
|
17
|
-
const neighbours = topoEdge.faces;
|
|
18
|
-
const neighbour_count = neighbours.length;
|
|
19
|
-
|
|
20
|
-
for (let j = 0; j < neighbour_count; j++) {
|
|
21
|
-
const other_face = neighbours[j];
|
|
22
|
-
|
|
23
|
-
if (other_face === topoFace) {
|
|
24
|
-
// skip self
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (open_set.get(other_face.index)) {
|
|
29
|
-
result++;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { vec3 } from "gl-matrix";
|
|
2
|
-
import { v3_distance_sqr } from "../../../../../core/geom/v3_distance_sqr.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
*
|
|
6
|
-
* @param {TopoTriangle} f0
|
|
7
|
-
* @param {TopoTriangle} f1
|
|
8
|
-
* @returns {number}
|
|
9
|
-
*/
|
|
10
|
-
export function compute_face_connection_weight(f0, f1) {
|
|
11
|
-
const vertices_0 = f0.vertices;
|
|
12
|
-
const vertices_1 = f1.vertices;
|
|
13
|
-
|
|
14
|
-
// compute center
|
|
15
|
-
const f0_center_x = (vertices_0[0].x + vertices_0[1].x + vertices_0[2].x) * 0.333;
|
|
16
|
-
const f0_center_y = (vertices_0[0].y + vertices_0[1].y + vertices_0[2].y) * 0.333;
|
|
17
|
-
const f0_center_z = (vertices_0[0].z + vertices_0[1].z + vertices_0[2].z) * 0.333;
|
|
18
|
-
|
|
19
|
-
const f1_center_x = (vertices_1[0].x + vertices_1[1].x + vertices_1[2].x) * 0.333;
|
|
20
|
-
const f1_center_y = (vertices_1[0].y + vertices_1[1].y + vertices_1[2].y) * 0.333;
|
|
21
|
-
const f1_center_z = (vertices_1[0].z + vertices_1[1].z + vertices_1[2].z) * 0.333;
|
|
22
|
-
|
|
23
|
-
const distance_sqr = v3_distance_sqr(
|
|
24
|
-
f0_center_x, f0_center_y, f0_center_z,
|
|
25
|
-
f1_center_x, f1_center_y, f1_center_z
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
// compute normal dot
|
|
29
|
-
const dot = vec3.dot(
|
|
30
|
-
f0.normal,
|
|
31
|
-
f1.normal
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
return 2 + (1 / distance_sqr) * 0.01 + dot * 0.1;
|
|
35
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {BitSet} open_set
|
|
4
|
-
* @param {BinaryHeap<number>} result
|
|
5
|
-
* @param {Map<number,number>} distances
|
|
6
|
-
* @param {TopoTriangle} face
|
|
7
|
-
* @param {number} face_distance
|
|
8
|
-
* @param {Map<number, number>} came_from_map
|
|
9
|
-
*/
|
|
10
|
-
export function populateOpenFaceNeighboursForPatch(
|
|
11
|
-
open_set,
|
|
12
|
-
result,
|
|
13
|
-
distances,
|
|
14
|
-
face,
|
|
15
|
-
face_distance,
|
|
16
|
-
came_from_map) {
|
|
17
|
-
|
|
18
|
-
const edges = face.edges;
|
|
19
|
-
const edge_count = edges.length;
|
|
20
|
-
|
|
21
|
-
for (let i = 0; i < edge_count; i++) {
|
|
22
|
-
const edge = edges[i];
|
|
23
|
-
|
|
24
|
-
const edge_faces = edge.faces;
|
|
25
|
-
const edge_face_count = edge_faces.length;
|
|
26
|
-
|
|
27
|
-
for (let j = 0; j < edge_face_count; j++) {
|
|
28
|
-
const neighbour = edge_faces[j];
|
|
29
|
-
|
|
30
|
-
if (neighbour === face) {
|
|
31
|
-
// self
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const index = neighbour.index;
|
|
36
|
-
|
|
37
|
-
if (open_set.get(index) === false) {
|
|
38
|
-
// not in the open set
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (result.contains(index)) {
|
|
43
|
-
// already in the set
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
distances.set(index, face_distance + 1);
|
|
48
|
-
came_from_map.set(index, face.index)
|
|
49
|
-
|
|
50
|
-
result.push(index);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { noop } from "../../../../../core/function/Functions.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {PatchRepresentation[]} leaves
|
|
6
|
-
* @param {function(string)} error_consumer
|
|
7
|
-
*/
|
|
8
|
-
export function validate_leaf_patch_connectivity(leaves, error_consumer = noop) {
|
|
9
|
-
let result = true;
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* @type {Map<number, PatchRepresentation[]>}
|
|
13
|
-
*/
|
|
14
|
-
const vertex_map = new Map();
|
|
15
|
-
|
|
16
|
-
for (let i = 0; i < leaves.length; i++) {
|
|
17
|
-
const leaf = leaves[i];
|
|
18
|
-
|
|
19
|
-
for (const vertex of leaf.vertices_included) {
|
|
20
|
-
const existing_patches = vertex_map.get(vertex);
|
|
21
|
-
|
|
22
|
-
if (existing_patches === undefined) {
|
|
23
|
-
vertex_map.set(vertex, [leaf]);
|
|
24
|
-
} else {
|
|
25
|
-
// shared vertex
|
|
26
|
-
|
|
27
|
-
// check neighbours
|
|
28
|
-
const existing_patch_count = existing_patches.length;
|
|
29
|
-
for (let j = 0; j < existing_patch_count; j++) {
|
|
30
|
-
const neighbour = existing_patches[j];
|
|
31
|
-
|
|
32
|
-
if (!leaf.hasNeighbour(neighbour)) {
|
|
33
|
-
error_consumer(`No link between neighbours ${leaf.id} and ${neighbour.id} for vertex ${vertex}`);
|
|
34
|
-
result = false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
existing_patches.push(leaf);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return result;
|
|
44
|
-
}
|