@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.
Files changed (94) hide show
  1. package/package.json +1 -1
  2. package/src/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +0 -1
  3. package/src/engine/graphics/micron/MICRON_URI_FIELD.js +0 -1
  4. package/src/engine/graphics/micron/build/MICRON_PATCH_SIZE_MAX.js +0 -5
  5. package/src/engine/graphics/micron/build/PatchRepresentation.js +0 -424
  6. package/src/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +0 -311
  7. package/src/engine/graphics/micron/build/build_geometry_info.js +0 -21
  8. package/src/engine/graphics/micron/build/clustering/assignInitialPatchNeighbours.js +0 -63
  9. package/src/engine/graphics/micron/build/clustering/assign_patch_neighbours_from_topology.js +0 -46
  10. package/src/engine/graphics/micron/build/clustering/build_clustering_2.js +0 -37
  11. package/src/engine/graphics/micron/build/clustering/build_leaf_patches.js +0 -326
  12. package/src/engine/graphics/micron/build/clustering/build_leaf_patches_metis.js +0 -76
  13. package/src/engine/graphics/micron/build/clustering/computeBorderLengthChange.js +0 -59
  14. package/src/engine/graphics/micron/build/clustering/computeFaceCurvatureScore.js +0 -57
  15. package/src/engine/graphics/micron/build/clustering/computeOpenFaceFreedom.js +0 -35
  16. package/src/engine/graphics/micron/build/clustering/compute_face_connection_weight.js +0 -35
  17. package/src/engine/graphics/micron/build/clustering/populateOpenFaceNeighboursForPatch.js +0 -56
  18. package/src/engine/graphics/micron/build/clustering/validate_leaf_patch_connectivity.js +0 -44
  19. package/src/engine/graphics/micron/build/compute_micron_buffer_array_constructor.js +0 -24
  20. package/src/engine/graphics/micron/build/compute_vertex_remap_cost.js +0 -29
  21. package/src/engine/graphics/micron/build/debug/build_clustering_info.js +0 -58
  22. package/src/engine/graphics/micron/build/debug/build_graph_info.js +0 -59
  23. package/src/engine/graphics/micron/build/fill_patch_geometry_data.js +0 -270
  24. package/src/engine/graphics/micron/build/hierarchy/buildAbstractPatchHierarchy.js +0 -196
  25. package/src/engine/graphics/micron/build/hierarchy/build_intermediate_patch_topology.js +0 -162
  26. package/src/engine/graphics/micron/build/hierarchy/build_merge_graph.js +0 -89
  27. package/src/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +0 -146
  28. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertex_count.js +0 -32
  29. package/src/engine/graphics/micron/build/hierarchy/compute_patches_shared_vertices.js +0 -34
  30. package/src/engine/graphics/micron/build/hierarchy/merge_patches.js +0 -581
  31. package/src/engine/graphics/micron/build/hierarchy/metis_cluster_clusters.js +0 -53
  32. package/src/engine/graphics/micron/build/hierarchy/optimize_graph_partitioning_balance.js +0 -515
  33. package/src/engine/graphics/micron/build/hierarchy/patch_combine.js +0 -180
  34. package/src/engine/graphics/micron/build/hierarchy/patch_fill_holes_by_uncollapse.js +0 -60
  35. package/src/engine/graphics/micron/build/hierarchy/patch_stitch_parent_border.js +0 -320
  36. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_simplified_clusters.js +0 -547
  37. package/src/engine/graphics/micron/build/hierarchy/qvdr_build_tree.js +0 -140
  38. package/src/engine/graphics/micron/buildPatchwork.js +0 -68
  39. package/src/engine/graphics/micron/convert_three_object_to_micron.js +0 -179
  40. package/src/engine/graphics/micron/debug/VirtualGeometryStats.js +0 -42
  41. package/src/engine/graphics/micron/format/MICRON_GEOMETRY_PROPERTY_NAME.js +0 -1
  42. package/src/engine/graphics/micron/format/MicronGeometry.d.ts +0 -21
  43. package/src/engine/graphics/micron/format/MicronGeometry.js +0 -334
  44. package/src/engine/graphics/micron/format/MicronGeometryPatch.d.ts +0 -3
  45. package/src/engine/graphics/micron/format/MicronGeometryPatch.js +0 -205
  46. package/src/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +0 -50
  47. package/src/engine/graphics/micron/format/ThreeMicronMesh.d.ts +0 -10
  48. package/src/engine/graphics/micron/format/ThreeMicronMesh.js +0 -45
  49. package/src/engine/graphics/micron/format/VirtualGeometry.js +0 -158
  50. package/src/engine/graphics/micron/format/micron_build_proxy_geometry.js +0 -205
  51. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +0 -123
  52. package/src/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.spec.js +0 -63
  53. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +0 -83
  54. package/src/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.spec.js +0 -51
  55. package/src/engine/graphics/micron/format/serialization/deserialize_attribute_spec.js +0 -25
  56. package/src/engine/graphics/micron/format/serialization/deserialize_patch.js +0 -106
  57. package/src/engine/graphics/micron/format/serialization/serialize_attribute_spec.js +0 -18
  58. package/src/engine/graphics/micron/format/serialization/serialize_patch.js +0 -84
  59. package/src/engine/graphics/micron/format/validate_patch_bounds.js +0 -69
  60. package/src/engine/graphics/micron/plugin/GLTFAssetTransformer.js +0 -265
  61. package/src/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +0 -5
  62. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.d.ts +0 -8
  63. package/src/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -150
  64. package/src/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +0 -176
  65. package/src/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +0 -216
  66. package/src/engine/graphics/micron/prototypeMicronProxyBuild.js +0 -227
  67. package/src/engine/graphics/micron/prototypeVirtualGeometry.js +0 -911
  68. package/src/engine/graphics/micron/render/PatchCacheKey.js +0 -79
  69. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.d.ts +0 -1
  70. package/src/engine/graphics/micron/render/VIRTUAL_MESH_FLAG.js +0 -1
  71. package/src/engine/graphics/micron/render/VirtualGeometryBuilder.js +0 -207
  72. package/src/engine/graphics/micron/render/approximateTriangleArea.js +0 -25
  73. package/src/engine/graphics/micron/render/culling/PatchCullingSystem.js +0 -129
  74. package/src/engine/graphics/micron/render/instanced/PatchDataTextures.js +0 -329
  75. package/src/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -175
  76. package/src/engine/graphics/micron/render/instanced/shader/constants.js +0 -3
  77. package/src/engine/graphics/micron/render/instanced/shader/gen_micron_vertex_attribute_texture_name.js +0 -8
  78. package/src/engine/graphics/micron/render/instanced/shader/shader_rewrite_standard.js +0 -250
  79. package/src/engine/graphics/micron/render/makeThreeMeshFromVirtualGeometry.js +0 -37
  80. package/src/engine/graphics/micron/render/refinement/ActivePatchFlags.js +0 -8
  81. package/src/engine/graphics/micron/render/refinement/ActivePatchList.js +0 -241
  82. package/src/engine/graphics/micron/render/refinement/ActivePatchRecord.js +0 -154
  83. package/src/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -84
  84. package/src/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +0 -133
  85. package/src/engine/graphics/micron/render/refinement/is_patch_facing_back.js +0 -43
  86. package/src/engine/graphics/micron/render/refinement/is_patch_visible.js +0 -37
  87. package/src/engine/graphics/micron/render/v1/MaterialContext.js +0 -150
  88. package/src/engine/graphics/micron/render/v1/MaterialVertexSpec.js +0 -115
  89. package/src/engine/graphics/micron/render/v1/MicronRenderContext.js +0 -145
  90. package/src/engine/graphics/micron/render/v1/ThreeVirtualGeometryAdapter.js +0 -255
  91. package/src/engine/graphics/micron/render/v1/VGThreeRenderer.js +0 -142
  92. package/src/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +0 -54
  93. package/src/engine/graphics/micron/simplifyGeometry.js +0 -26
  94. package/src/engine/graphics/micron/util/patchToBufferGeometry.js +0 -19
@@ -1,24 +0,0 @@
1
- import { BinaryDataType } from "../../../../core/binary/type/BinaryDataType.js";
2
-
3
- /**
4
- *
5
- * @param {BinaryDataType} type
6
- * @returns {constructor}
7
- */
8
- export function compute_micron_buffer_array_constructor(type) {
9
- switch (type) {
10
- case BinaryDataType.Float32:
11
- return Float32Array;
12
- case BinaryDataType.Float16:
13
- // using uint16 to store half-float as half-float array is not implemented in browsers currently
14
- return Uint16Array;
15
- case BinaryDataType.Uint16:
16
- return Uint16Array;
17
- case BinaryDataType.Uint8:
18
- return Uint8Array;
19
- case BinaryDataType.Int8:
20
- return Int8Array;
21
- default:
22
- throw new Error(`Unsupported data type '${type}'`);
23
- }
24
- }
@@ -1,29 +0,0 @@
1
- import {
2
- compute_face_normal_change_dot_product
3
- } from "../../../../core/geom/3d/topology/simplify/compute_face_normal_change_dot_product.js";
4
-
5
- /**
6
- *
7
- * @param {TopoVertex} from
8
- * @param {TopoVertex} to
9
- *
10
- * @returns {number}
11
- */
12
- export function computeVertexRemapCost(from, to) {
13
- let result = 0;
14
-
15
- const faces = from.faces;
16
- const face_count = faces.length;
17
-
18
- for (let i = 0; i < face_count; i++) {
19
- const face = faces[i];
20
-
21
- const normal_dot = compute_face_normal_change_dot_product(face, from, to);
22
-
23
- const normal_cost = 1 - normal_dot;
24
-
25
- result += normal_cost;
26
- }
27
-
28
- return result;
29
- }
@@ -1,58 +0,0 @@
1
- import { computeStatisticalMedian } from "../../../../../core/math/statistics/computeStatisticalMedian.js";
2
- import { max2 } from "../../../../../core/math/max2.js";
3
- import { MICRON_PATCH_SIZE_MAX } from "../MICRON_PATCH_SIZE_MAX.js";
4
- import { computeStatisticalMean } from "../../../../../core/math/statistics/computeStatisticalMean.js";
5
- import { formatNumberByThousands, prettyPrint } from "../../../../../core/NumberFormat.js";
6
- import { computeStatisticalPercentile } from "../../../../../core/math/statistics/computeStatisticalPercentile.js";
7
-
8
- /**
9
- *
10
- * @param {PatchRepresentation[]} patches
11
- */
12
- export function build_clustering_info(patches) {
13
-
14
- const patch_count = patches.length;
15
-
16
- const patch_face_counts = patches.map(p => p.topology_snapshot.getFaces().size);
17
- const total_patch_faces = patch_face_counts.reduce((previousValue, x) => previousValue + x, 0);
18
-
19
- const patch_size_median = computeStatisticalMedian(patch_face_counts);
20
- const undeflow_face_count = patch_face_counts.reduce((acc, c) => {
21
- const local_underflow = max2(0, MICRON_PATCH_SIZE_MAX - c);
22
- return acc + local_underflow;
23
- }, 0);
24
- const overflow_face_count = patch_face_counts.reduce((acc, c) => {
25
- const local_overflow = max2(0, c - MICRON_PATCH_SIZE_MAX);
26
- return acc + local_overflow;
27
- }, 0);
28
-
29
- const patch_size_mean = computeStatisticalMean(patch_face_counts);
30
-
31
- const connection_count = patches.reduce((acc, p) => acc + p.neighbours.length, 0);
32
-
33
- // compute perimeter lengths
34
- const total_perimeter = patches.reduce((acc, p) => acc + p.computePerimeterLength(), 0);
35
-
36
- const underflow_patch_count = patch_face_counts.filter(p => p < MICRON_PATCH_SIZE_MAX).length;
37
-
38
- return `Leaf Stats:
39
- Total faces: ${formatNumberByThousands(total_patch_faces)}
40
- Patch count: ${formatNumberByThousands(patch_count)}
41
-
42
- patch size(median): ${patch_size_median}
43
- patch size(mean): ${patch_size_mean.toFixed(2)}
44
- patch size(10th %): ${computeStatisticalPercentile(patch_face_counts, .1, 0.1)}
45
- patch size(25th %): ${computeStatisticalPercentile(patch_face_counts, .25, 0.25)}
46
- patch size(90th %) : ${computeStatisticalPercentile(patch_face_counts, .9, 0.9)}
47
-
48
- Total undeflow patches: ${formatNumberByThousands(underflow_patch_count)} (${(underflow_patch_count * 100 / patch_count).toPrecision(3)}%)
49
- Total undeflow faces: ${formatNumberByThousands(undeflow_face_count)} (${(undeflow_face_count * 100 / total_patch_faces).toPrecision(3)}%)
50
- Total overflow faces: ${formatNumberByThousands(overflow_face_count)}
51
-
52
- Total connections: ${formatNumberByThousands(connection_count)}
53
- Average connectedness : ${(connection_count / patch_count).toPrecision(4)} neighbours/patch
54
-
55
- Total perimeter: ${prettyPrint(total_perimeter)}
56
- Average patch perimeter: ${(total_perimeter / patch_count).toPrecision(4)}
57
- `
58
- }
@@ -1,59 +0,0 @@
1
- //
2
-
3
- import { prettyPrint } from "../../../../../core/NumberFormat.js";
4
- import { MICRON_PATCH_SIZE_MAX } from "../MICRON_PATCH_SIZE_MAX.js";
5
- import { max2 } from "../../../../../core/math/max2.js";
6
-
7
- /**
8
- *
9
- * @param {PatchRepresentation} root
10
- * @returns {string}
11
- */
12
- export function build_graph_info(root) {
13
- // ingest all patches into a flat hierarchy
14
- const all_nodes = [];
15
- const leaf_nodes = [];
16
- const intermediate_nodes = [];
17
-
18
- root.traverse(n => {
19
- all_nodes.push(n);
20
-
21
- if (n.lod === 0) {
22
- leaf_nodes.push(n);
23
- } else {
24
- intermediate_nodes.push(n);
25
- }
26
- });
27
-
28
- const intermediate_face_count = intermediate_nodes.reduce((acc, p) => {
29
- return acc + p.topology_snapshot.getFaces().size;
30
- }, 0);
31
-
32
- const leaf_face_count = leaf_nodes.reduce((acc, p) => {
33
- return acc + p.topology_snapshot.getFaces().size;
34
- }, 0);
35
-
36
- const intermediate_node_count = all_nodes.length - leaf_nodes.length;
37
- const balance_quality = (leaf_nodes.length - 1) / intermediate_node_count;
38
-
39
- const intermediate_overflow_patch_count = intermediate_nodes.filter(p => p.topology_snapshot.getFaces().size > MICRON_PATCH_SIZE_MAX).length;
40
-
41
- const intermediate_overflow_face_count = intermediate_nodes
42
- .map(n => n.topology_snapshot.getFaces().size)
43
- .reduce((acc, c) => {
44
- const local_overflow = max2(0, c - MICRON_PATCH_SIZE_MAX);
45
- return acc + local_overflow;
46
- }, 0);
47
-
48
- return `Graph Stats:
49
- Total nodes: ${prettyPrint(all_nodes.length)}
50
- Total intermediate nodes: ${prettyPrint(intermediate_node_count)}
51
- Depth: ${prettyPrint(root.lod)}
52
- Balance quality: ${(balance_quality * 100).toPrecision(3)}%
53
-
54
- Intermediate face count: ${prettyPrint(intermediate_face_count)} (${(intermediate_face_count * 100 / leaf_face_count).toPrecision(3)}% of original)
55
- Intermediate overflow faces: ${prettyPrint(intermediate_overflow_face_count)} (${(intermediate_overflow_face_count * 100 / intermediate_face_count).toPrecision(3)}%)
56
-
57
- Intermediate overflow patches: ${prettyPrint(intermediate_overflow_patch_count)} (${(intermediate_overflow_patch_count * 100 / intermediate_node_count).toPrecision(3)}%)
58
- `;
59
- }
@@ -1,270 +0,0 @@
1
- import { BinaryDataType } from "../../../../core/binary/type/BinaryDataType.js";
2
- import { passThrough } from "../../../../core/function/Functions.js";
3
- import { to_half_float_uint16 } from "../../../../core/binary/to_half_float_uint16.js";
4
- import { compute_micron_buffer_array_constructor } from "./compute_micron_buffer_array_constructor.js";
5
- import { typedArrayToDataType } from "../../../../core/collection/array/typedArrayToDataType.js";
6
- import { dataTypeByteSize } from "../../../../core/binary/type/DataTypeByteSizes.js";
7
- import { UintArrayForCount } from "../../../../core/collection/array/typed/uint_array_for_count.js";
8
- import { clamp01 } from "../../../../core/math/clamp01.js";
9
-
10
- /**
11
- * @param {number} vertex_count
12
- * @param {Map<number, number>} index_map_backward
13
- * @param {number} itemSize
14
- * @param {ArrayLike<number>} attribute_array
15
- * @param {number[]} vertex_data_buffer_accessor
16
- * @param {function} transformer_method
17
- * @param {*} [transformer_context]
18
- */
19
- function transform_attribute_data(
20
- vertex_count,
21
- index_map_backward,
22
- itemSize,
23
- attribute_array,
24
- vertex_data_buffer_accessor,
25
- transformer_method,
26
- transformer_context
27
- ) {
28
- let j, k;
29
-
30
- for (j = 0; j < vertex_count; j++) {
31
- // map patch vertex index to original geometry's vertex index
32
- const source_vertex_index = index_map_backward.get(j);
33
-
34
- const source_vertex_offset = source_vertex_index * itemSize;
35
- const target_vertex_offset = j * itemSize;
36
-
37
- for (k = 0; k < itemSize; k++) {
38
-
39
- // get item value
40
- const value = attribute_array[source_vertex_offset + k];
41
-
42
- // transform
43
- const transformed_value = transformer_method.call(transformer_context, value);
44
-
45
- // write into buffer
46
- vertex_data_buffer_accessor[target_vertex_offset + k] = transformed_value;
47
- }
48
- }
49
- }
50
-
51
- /**
52
- * @param {number} vertex_count
53
- * @param {Map<number, number>} index_map_backward
54
- * @param {number} itemSize
55
- * @param {ArrayLike<number>} attribute_array
56
- * @param {number[]} vertex_data_buffer_accessor
57
- */
58
- function copy_attribute_data(vertex_count, index_map_backward, itemSize, attribute_array, vertex_data_buffer_accessor) {
59
- let j, k;
60
-
61
- for (j = 0; j < vertex_count; j++) {
62
- // map patch vertex index to original geometry's vertex index
63
- const source_vertex_index = index_map_backward.get(j);
64
-
65
- const source_vertex_offset = source_vertex_index * itemSize;
66
- const target_vertex_offset = j * itemSize;
67
-
68
- for (k = 0; k < itemSize; k++) {
69
-
70
- // get item value
71
- const value = attribute_array[source_vertex_offset + k];
72
-
73
- // write into buffer
74
- vertex_data_buffer_accessor[target_vertex_offset + k] = value;
75
- }
76
- }
77
- }
78
-
79
- /**
80
- *
81
- * @param {number} value
82
- * @returns {number}
83
- */
84
- function resample_normalized_uint16_to_uint8(value) {
85
- const normalized = clamp01(value / 65535);
86
-
87
- return Math.round(normalized * 255);
88
- }
89
-
90
- /**
91
- *
92
- * @param {number} value
93
- * @return {number}
94
- */
95
- function normalize_to_int8(value) {
96
- return Math.round(value * 127);
97
- }
98
-
99
- /**
100
- *
101
- * @param {number} value
102
- * @return {number}
103
- */
104
- function normalize_to_uint8(value) {
105
- return Math.round(value * 255);
106
- }
107
-
108
- /**
109
- * @enum {function(number):number}
110
- */
111
- const DataConverterType = {
112
- None: passThrough,
113
- Number2HalfFloat: to_half_float_uint16,
114
- Normalize2Int8: normalize_to_int8,
115
- Normalize2Uint8: normalize_to_uint8,
116
- ResampleNormalized_Uint16_to_Uint8: resample_normalized_uint16_to_uint8
117
- };
118
-
119
- /**
120
- * How to convert data from source three.js buffer attribute to what we store in the patch description based on the supplied micron spec
121
- * @param {AttributeSpec} spec
122
- * @param {THREE.BufferAttribute} source
123
- * @returns {DataConverterType}
124
- */
125
- function compute_attribute_data_converter(source, spec) {
126
- const target_type = spec.type;
127
- if (target_type === BinaryDataType.Float16) {
128
- return DataConverterType.Number2HalfFloat;
129
- } else if (spec.normalized && !source.normalized) {
130
- // source data can be normalized but isn't
131
- if (target_type === BinaryDataType.Int8) {
132
- return DataConverterType.Normalize2Int8;
133
- } else if (target_type === BinaryDataType.Uint8) {
134
- return DataConverterType.Normalize2Uint8;
135
- } else {
136
- throw new Error(`Unsupported normalized type '${target_type}'`);
137
- }
138
- } else {
139
- const source_array = source.array;
140
-
141
- const source_type = typedArrayToDataType(source_array);
142
-
143
- const target_byte_size = dataTypeByteSize(target_type);
144
- const source_byte_size = dataTypeByteSize(source_type)
145
-
146
- if (target_byte_size !== source_byte_size) {
147
- // wrong data size
148
-
149
- if (target_type === BinaryDataType.Uint8 && source_type === BinaryDataType.Uint16) {
150
- return DataConverterType.ResampleNormalized_Uint16_to_Uint8;
151
- } else {
152
- throw new Error(`Unsupported conversion ${source_type} -> ${target_type}`);
153
- }
154
-
155
- } else {
156
- return DataConverterType.None;
157
- }
158
- }
159
- }
160
-
161
- /**
162
- *
163
- * @param {MicronGeometryPatch} result
164
- * @param {THREE.BufferGeometry} buffer_geometry
165
- * @param {TopoMesh} topo
166
- * @param {VertexDataSpec} vertex_data_spec
167
- */
168
- export function fill_patch_geometry_data(result, buffer_geometry, topo, vertex_data_spec) {
169
- /**
170
- *
171
- * @type {Map<number, number>}
172
- */
173
- const index_map_forward = new Map();
174
- /**
175
- *
176
- * @type {Map<number, number>}
177
- */
178
- const index_map_backward = new Map();
179
-
180
- let vertex_count = 0;
181
-
182
- // remap vertices
183
- const faces = topo.getFaces();
184
- const face_count = faces.size;
185
- const polygon_buffer_size = face_count * 3;
186
-
187
- // pick container just large enough to point to all vertices
188
- const FaceArrayConstructor = UintArrayForCount(topo.vertices.length);
189
-
190
- result.face_indices = new FaceArrayConstructor(polygon_buffer_size);
191
- result.polygon_count = face_count;
192
-
193
- let i3 = 0;
194
- for (const topo_face of faces) {
195
-
196
- for (let j = 0; j < 3; j++) {
197
- // get vertices
198
- const topo_vertex = topo_face.vertices[j];
199
-
200
- const index = topo_vertex.index;
201
-
202
- if (!index_map_forward.has(index)) {
203
- index_map_forward.set(index, vertex_count);
204
- index_map_backward.set(vertex_count, index);
205
-
206
- vertex_count++;
207
- }
208
-
209
- // write index into patch
210
- result.face_indices[i3 + j] = index_map_forward.get(index);
211
- }
212
-
213
- i3 += 3;
214
- }
215
-
216
- // write vertices
217
- result.vertex_count = vertex_count;
218
-
219
- // collect metadata about vertices
220
-
221
-
222
- // compute byte size of each vertex
223
- const source_attributes = buffer_geometry.attributes;
224
-
225
- let vertex_buffer_attribute_address = 0;
226
-
227
- const micron_attributes = vertex_data_spec.attributes;
228
- const attribute_count = micron_attributes.length;
229
-
230
- //TODO create a single ArrayBuffer for all attributes to get better cache coherence for rendering
231
-
232
- for (let i = 0; i < attribute_count; i++) {
233
- const attribute_spec = micron_attributes[i];
234
-
235
- /**
236
- *
237
- * @type {THREE.BufferAttribute | THREE.InterleavedBufferAttribute}
238
- */
239
- const attribute = source_attributes[attribute_spec.name];
240
-
241
-
242
- if (attribute.isInterleavedBufferAttribute) {
243
- throw new Error('Interleaved buffers are not supported');
244
- }
245
-
246
- const attribute_array = attribute.array;
247
-
248
- const itemSize = attribute.itemSize;
249
-
250
- const TypedArrayConstructor = compute_micron_buffer_array_constructor(attribute_spec.type);
251
-
252
- const vertex_data_buffer_accessor = new TypedArrayConstructor(
253
- vertex_count * itemSize
254
- );
255
-
256
- const converter = compute_attribute_data_converter(attribute, attribute_spec);
257
-
258
- if (converter === DataConverterType.None) {
259
- copy_attribute_data(vertex_count, index_map_backward, itemSize, attribute_array, vertex_data_buffer_accessor);
260
-
261
- } else {
262
- transform_attribute_data(vertex_count, index_map_backward, itemSize, attribute_array, vertex_data_buffer_accessor, converter);
263
- }
264
-
265
- vertex_buffer_attribute_address += attribute_spec.getByteSize() * vertex_count;
266
-
267
- result.vertex_attribute_arrays[i] = vertex_data_buffer_accessor;
268
- }
269
-
270
- }
@@ -1,196 +0,0 @@
1
- import { merge_patches } from "./merge_patches.js";
2
- import { coarsen_graph } from "../../../../../core/graph/coarsen_graph.js";
3
- import { build_merge_graph } from "./build_merge_graph.js";
4
- import { assign_patch_neighbours_from_topology } from "../clustering/assign_patch_neighbours_from_topology.js";
5
- import { assert } from "../../../../../core/assert.js";
6
- import { graph_create_off_mesh_links } from "../../../../../core/graph/build_face_graph_from_mesh.js";
7
- import {
8
- build_vertex_quadratics
9
- } from "../../../../../core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js";
10
-
11
- /**
12
- *
13
- * @param {Graph<MultiNode<PatchRepresentation>>} graph
14
- * @param {number} n
15
- */
16
- function merge_graph_level(graph, n) {
17
- assert.isFiniteNumber(n, 'n');
18
- assert.isNonNegativeInteger(n, 'n');
19
-
20
- for (let i = 2; i <= n; i *= 2) {
21
-
22
- if (graph.getNodeCount() <= 1) {
23
- // fully merged, no further merge possible
24
- break;
25
- }
26
-
27
- coarsen_graph(graph, i);
28
- }
29
-
30
- }
31
-
32
- /**
33
- *
34
- * @type {number}
35
- */
36
- const DEFAULT_MERGE_COUNT = 4;
37
- /**
38
- * Maximum number of patches that can be merged together
39
- * @type {number}
40
- */
41
- const LIMIT_MERGE_COUNT = 64;
42
-
43
- /**
44
- *
45
- * @param {PatchRepresentation[]} nodes
46
- * @returns {PatchRepresentation}
47
- */
48
- async function assemble_graph(nodes) {
49
- /**
50
- *
51
- * @type {PatchRepresentation[]}
52
- * @private
53
- */
54
- let __nodes = nodes.slice();
55
-
56
- const initial_node_count = __nodes.length;
57
-
58
- /**
59
- *
60
- * @type {{value: number}}
61
- * @private
62
- */
63
- const __node_count = {
64
- value: initial_node_count
65
- };
66
-
67
- let level = 0;
68
- let merge_count = DEFAULT_MERGE_COUNT;
69
-
70
-
71
- /**
72
- *
73
- * @type {Map<number, Quadratic3>}
74
- */
75
- const vertex_quadratics = new Map();
76
-
77
- /*
78
- build initial quadratic errors for each vertex
79
- To keep track of error throughout simplification levels
80
- */
81
- for (let i = 0; i < __node_count.value; i++) {
82
- const patch = __nodes[i];
83
-
84
- build_vertex_quadratics({ mesh: patch.topology_snapshot, quadratics: vertex_quadratics });
85
- }
86
-
87
- while (__node_count.value > 1) {
88
-
89
- // assemble nodes into a graph
90
- const leaf_cluster_weight_graph = build_merge_graph(__nodes);
91
-
92
- if (__node_count.value <= 4 || merge_count >= 16) {
93
- // graph is quite small now, it's possible that some patches are disconnected, force connections to allow for collapse
94
- graph_create_off_mesh_links(leaf_cluster_weight_graph);
95
- }
96
-
97
- // merge graph nodes up to X nodes per cluster
98
- merge_graph_level(leaf_cluster_weight_graph, merge_count);
99
-
100
- // assemble multi-nodes
101
- const graph_nodes = leaf_cluster_weight_graph.getNodes();
102
-
103
- const old_node_count = __node_count.value;
104
-
105
- __nodes = [];
106
- __node_count.value = 0;
107
-
108
- const __promises = [];
109
-
110
- for (const multi_node of graph_nodes) {
111
- const patches_to_merge = multi_node.source_nodes;
112
-
113
- const promise = merge_patches(__nodes, __node_count, patches_to_merge, vertex_quadratics);
114
- __promises.push(promise);
115
-
116
- }
117
-
118
- await Promise.all(__promises);
119
-
120
- if (__node_count.value >= old_node_count) {
121
- // new graph has the same number of nodes as the old one
122
-
123
- if (leaf_cluster_weight_graph.getNodeCount() <= 1) {
124
- // graph is already merged to the maximum level
125
- throw new Error(`Simplification failed, graph already at maximum coarseness`);
126
- }
127
-
128
- if (merge_count >= LIMIT_MERGE_COUNT) {
129
- throw new Error(`Exceeded merge limit(=${LIMIT_MERGE_COUNT}), attempting to merge too many patches together`);
130
- }
131
-
132
- if (old_node_count <= merge_count) {
133
- throw new Error(`Already allowing to merge all of the nodes, yet merge still fails. Allowed patch count = ${merge_count}, Actual patches = ${old_node_count})`);
134
- }
135
-
136
- // failed to do any merging, increase merge scope
137
- merge_count *= 2;
138
-
139
- continue;
140
- }
141
-
142
- // clear existing neighbours for this level
143
- for (let i = 0; i < __node_count.value; i++) {
144
- const node = __nodes[i];
145
-
146
- const neighbours = node.neighbours;
147
- neighbours.splice(0, neighbours.length);
148
- }
149
-
150
- // write neighbours
151
- assign_patch_neighbours_from_topology(__nodes);
152
-
153
- level++;
154
-
155
- merge_count = DEFAULT_MERGE_COUNT;
156
- }
157
-
158
- // return root
159
- const root = __nodes[0];
160
-
161
- if (initial_node_count === 1) {
162
- // there are no children, whole hierarchy is just one node, set group bounds to equal node bounds
163
- root.group_bounding_sphere.set(root.bounding_sphere);
164
- root.group_aabb.copy(root.bounding_box);
165
- }
166
-
167
-
168
- return root;
169
- }
170
-
171
-
172
- /**
173
- * @param {TopoMesh} t
174
- */
175
- function cleanup_disconnected_edges(t) {
176
-
177
- const edges = t.getEdges();
178
-
179
- for (let edge of edges) {
180
-
181
- if (edge.faces.length === 0) {
182
- // cut
183
- edges.delete(edge);
184
- }
185
- }
186
- }
187
-
188
- /**
189
- * @param {PatchRepresentation[]} leaves
190
- * @returns {PatchRepresentation} new root
191
- */
192
- export async function buildAbstractPatchHierarchy(leaves) {
193
- const root = await assemble_graph(leaves);
194
-
195
- return root;
196
- }