@woosh/meep-engine 2.164.0 → 2.165.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/build/bundle-worker-terrain.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BitImage2.d.ts +91 -0
- package/src/core/binary/BitImage2.d.ts.map +1 -0
- package/src/core/binary/BitImage2.js +242 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts +22 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts.map +1 -0
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -0
- package/src/core/geom/2d/packing/skyline.d.ts +116 -0
- package/src/core/geom/2d/packing/skyline.d.ts.map +1 -0
- package/src/core/geom/2d/packing/skyline.js +258 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts +18 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts.map +1 -0
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +86 -0
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -0
- package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -0
- package/src/core/geom/3d/atlas/Chart.d.ts +58 -0
- package/src/core/geom/3d/atlas/Chart.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/Chart.js +77 -0
- package/src/core/geom/3d/atlas/REVIEW_02.md +392 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts +73 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.d.ts +17 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts +25 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts +17 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -0
- package/src/core/geom/3d/atlas/atlas_generate.d.ts +39 -0
- package/src/core/geom/3d/atlas/atlas_generate.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_generate.js +43 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +84 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts +25 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts +22 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts +9 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts +9 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts +27 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts +22 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/io/bt_loop_uv.js +57 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts +36 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts +62 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +551 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts +22 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.js +73 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts +37 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +270 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts +23 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +224 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts +14 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts +22 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts +20 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts +27 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts +31 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts +23 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts +24 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts +27 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +113 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts +44 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +275 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts +22 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts.map +1 -0
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +199 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts +32 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts.map +1 -0
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts +20 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts.map +1 -0
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +66 -0
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +13 -11
- package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.d.ts.map +1 -1
- package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js +4 -3
- package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +4 -3
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.js +4 -3
- package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.d.ts.map +1 -1
- package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.js +10 -6
- package/src/core/geom/3d/topology/struct/TopoMesh.js +2 -2
- package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts +0 -2
- package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/TopoTriangle.js +2 -2
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +8 -27
- package/src/core/geom/vec3/v3_cotangent.d.ts +20 -0
- package/src/core/geom/vec3/v3_cotangent.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_cotangent.js +29 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.d.ts +19 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -0
- package/src/core/geom/vec3/v3_multiply.d.ts +16 -0
- package/src/core/geom/vec3/v3_multiply.d.ts.map +1 -0
- package/src/core/geom/vec3/v3_multiply.js +19 -0
- package/src/core/math/linalg/cg/cg_solve.d.ts +24 -0
- package/src/core/math/linalg/cg/cg_solve.d.ts.map +1 -0
- package/src/core/math/linalg/cg/cg_solve.js +106 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts +21 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts.map +1 -0
- package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +19 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts +50 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -0
- package/src/core/math/linalg/sparse/spm_matvec.d.ts +9 -0
- package/src/core/math/linalg/sparse/spm_matvec.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/spm_matvec.js +22 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts +12 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts.map +1 -0
- package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -0
- package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.d.ts +39 -0
- package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.js +22 -1
- package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.d.ts.map +1 -1
- package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.js +32 -9
- package/src/core/math/physics/mie/compute_mie_phase.d.ts +2 -3
- package/src/core/math/physics/mie/compute_mie_phase.d.ts.map +1 -1
- package/src/core/math/physics/mie/compute_mie_phase.js +1 -3
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +0 -1
- package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
- package/src/core/math/physics/mie/lorenz_mie_coefs.js +0 -7
- package/src/engine/ecs/attachment/TransformAttachmentBinding.js +3 -3
- package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -2
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +4 -3
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +2 -2
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +9 -8
- package/src/engine/graphics/GraphicsEngine.d.ts.map +1 -1
- package/src/engine/graphics/GraphicsEngine.js +2 -1
- package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +2 -2
- package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +2 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +2 -2
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +0 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +8 -7
- package/src/engine/graphics/geometry/MikkT/AvgTSpace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/AvgTSpace.js +11 -6
- package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +2 -3
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/CalcTexArea.js +3 -4
- package/src/engine/graphics/geometry/MikkT/DegenEpilogue.js +4 -4
- package/src/engine/graphics/geometry/MikkT/EvalTspace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/EvalTspace.js +11 -8
- package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +7 -8
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +8 -8
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/InitTriInfo.js +30 -25
- package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +7 -7
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts +0 -1
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/NormalizeSafe.js +6 -4
- package/src/engine/graphics/geometry/MikkT/STSpace.d.ts +0 -2
- package/src/engine/graphics/geometry/MikkT/STSpace.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/STSpace.js +3 -3
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts +0 -2
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts.map +1 -1
- package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.js +0 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts +0 -2
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.js +4 -3
- package/src/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +2 -2
- package/src/engine/graphics/impostors/octahedral/grid/UvEncoder.d.ts +17 -7
- package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.js +2 -2
- package/src/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +3 -3
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +4 -3
- package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
- package/src/engine/graphics/render/forward_plus/model/Decal.d.ts +0 -2
- package/src/engine/graphics/render/forward_plus/model/Decal.d.ts.map +1 -1
- package/src/engine/graphics/render/forward_plus/model/Decal.js +3 -3
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +4 -3
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +6 -4
- package/src/engine/graphics/sh3/lightmap/ARTIFACTS_PLAN.md +146 -0
- package/src/engine/graphics/sh3/lightmap/CODE_REVIEW.md +121 -0
- package/src/engine/graphics/sh3/lightmap/LIGHTMAPPER_REVIEW.md +183 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts +90 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.js +678 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts +32 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.js +155 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts +49 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_denoise.js +136 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts +19 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_dilate.js +89 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts +54 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_gather.js +168 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts +30 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.js +145 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts +38 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.js +152 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts +2 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts.map +1 -0
- package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.js +186 -0
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.js +6 -4
- package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +3 -3
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.d.ts.map +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +5 -4
- package/src/engine/graphics/sh3/sky/hosek/prototype_hosek.js +2 -2
- package/src/engine/input/devices/KeyboardDevice.d.ts +61 -14
- package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
- package/src/engine/input/devices/KeyboardDevice.js +41 -15
- package/src/engine/input/devices/isHTMLElementFocusable.d.ts.map +1 -1
- package/src/engine/input/devices/isHTMLElementFocusable.js +2 -9
- package/src/engine/sound/simulation/prototypeAcousticSolver.js +261 -143
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
# Atlas Review 02 — meep vs xatlas (quality) + recent-literature survey
|
|
2
|
+
|
|
3
|
+
Status: **research & planning only** (2026-06-25). No code changes proposed for now.
|
|
4
|
+
Scope: chart (segmentation + parameterization) quality and packing quality of the meep
|
|
5
|
+
UV-atlas port versus [jpcy/xatlas](https://github.com/jpcy/xatlas), plus a survey of recent
|
|
6
|
+
(≈2017–2026) literature on charting, parameterization, and packing.
|
|
7
|
+
|
|
8
|
+
Companion to [ATLAS_PORT_PLAN.md](ATLAS_PORT_PLAN.md) (the build contract + bench findings).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. Executive summary
|
|
13
|
+
|
|
14
|
+
meep is a faithful, deterministic, robustness-hardened port of xatlas's **core** algorithms —
|
|
15
|
+
the same chart cost model, the same ortho→LSCM→piecewise parameterization cascade with the same
|
|
16
|
+
acceptance thresholds, the same planar-region-atomic growth, and the same silhouette bitmap packer
|
|
17
|
+
for small atlases. Where it differs, it has **deliberately omitted xatlas's quality-refinement
|
|
18
|
+
passes** (chart merging, Lloyd seed relocation, a per-growth validity gate, best-fit packing, and
|
|
19
|
+
silhouette packing at production scale) in favour of determinism, simplicity, and — above all —
|
|
20
|
+
**speed at scale**.
|
|
21
|
+
|
|
22
|
+
| Axis | Verdict vs xatlas | Magnitude (estimated) |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| **Parameterization** | **On par** | Algorithmically equivalent. xatlas marginally more robust LSCM assembly (ABF-angle rows); both share the same "no area control" limitation. |
|
|
25
|
+
| **Chart segmentation** | **Modestly behind** on complex/curved meshes; **near parity** on flat/CAD content | ≈ **10–30 % more charts**, longer/raggier seams on organic meshes (missing `mergeCharts`, per-add validity gate, straightness term, largest-area seeding). Identical on planar-dominant content. |
|
|
26
|
+
| **Packing** | **Behind at production scale** (deliberate speed trade); **near parity** on flat/rectangular charts and small atlases | ≈ **10–25 % lower utilization** on irregular/curved charts at ≥2048², in exchange for **~100–1000× faster** packing (3–43 ms vs xatlas's ~2 s random / ~43 s brute). |
|
|
27
|
+
|
|
28
|
+
**Bottom line.** On clean, flat/CAD-like content meep is essentially at parity with xatlas. On
|
|
29
|
+
complex curved/organic meshes it produces somewhat more charts and looser packing, while running
|
|
30
|
+
dramatically faster. The two highest-value, lowest-risk quality wins, both classical and
|
|
31
|
+
deterministic, are: (1) a **chart-merge + best-fit-packing** pass to close most of the structural
|
|
32
|
+
gap, and (2) an **ARAP/SLIM-style isometric relaxation** (reusing the existing sparse-CG core) to
|
|
33
|
+
kill the documented max-stretch outliers (133–359) that conformal LSCM cannot fix.
|
|
34
|
+
|
|
35
|
+
> **Confidence / caveat.** The *direction* of every verdict is high-confidence (grounded in a
|
|
36
|
+
> line-by-line read of both codebases — xatlas web-verified against `xatlas.cpp`/`xatlas.h` at
|
|
37
|
+
> `master`). The *magnitudes* are **estimates**: there is **no head-to-head benchmark on identical
|
|
38
|
+
> inputs** yet. In particular the chart-count (~10–30 %) and utilization (~10–25 %) percentages are
|
|
39
|
+
> **extrapolated from the nature of the missing features**, not measured — they are the softest
|
|
40
|
+
> numbers here. The single most useful follow-up is a same-mesh A/B harness (§5, item P0) to turn
|
|
41
|
+
> these ranges into measured numbers.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 1. Method
|
|
46
|
+
|
|
47
|
+
- **meep side** — line-by-line read of `atlas_compute_charts.js`, `segment/*`, `param/*`,
|
|
48
|
+
`pack/*`, the `core/math/linalg/{cg,sparse}` solvers, and the 2D packing primitives
|
|
49
|
+
(`skyline.js`, `BitImage2.js`, `tri2_rasterize_conservative.js`, `min_area_rect_2d.js`), plus the
|
|
50
|
+
bench (`atlas_generate.bench.spec.js`) and ATLAS_PORT_PLAN findings.
|
|
51
|
+
- **xatlas side** — web-verified extraction from `source/xatlas/xatlas.cpp` + `xatlas.h` (`master`):
|
|
52
|
+
`ChartOptions`/`PackOptions` defaults, `ClusteredCharts`/`PlanarCharts`, `computeCost`,
|
|
53
|
+
`computeLeastSquaresConformalMap`, `Chart::parameterize`, `PiecewiseParam`, `pack::Atlas::addCharts`,
|
|
54
|
+
`findChartLocation_{bruteForce,random}`. Corroborated against Castaño's "Lightmap Parameterization"
|
|
55
|
+
lineage and the TABI (2026) benchmark numbers for xatlas.
|
|
56
|
+
- **Literature** — web searches across charting/cutting, parameterization/flattening, and packing;
|
|
57
|
+
each entry below is web-verified with a URL.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 2. Chart segmentation (charting)
|
|
62
|
+
|
|
63
|
+
### 2.1 What is identical
|
|
64
|
+
|
|
65
|
+
meep's region-grow charter is a faithful port of xatlas's `ClusteredCharts` **cost core and growth
|
|
66
|
+
substrate**:
|
|
67
|
+
|
|
68
|
+
| Parameter / mechanism | meep | xatlas | Match |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `maxCost` | 2 | 2.0 | ✅ |
|
|
71
|
+
| `normalDeviationWeight` | 2 | 2.0 | ✅ |
|
|
72
|
+
| `normalSeamWeight` | 4 | 4.0 | ✅ |
|
|
73
|
+
| `roundnessWeight` | 0.01 | 0.01 | ✅ |
|
|
74
|
+
| Hard normal reject | `1−dot ≥ 0.707` (~73°) | `≥ 0.707f` | ✅ |
|
|
75
|
+
| Coplanar-region epsilon | `dot ≥ 1−1e-4` | `1e-4` | ✅ |
|
|
76
|
+
| Planar-region **atomic** growth | default (regions are growth atoms) | yes (chart swallows whole coplanar region) | ✅ |
|
|
77
|
+
| Greedy global-min candidate w/ lazy re-eval | yes (`IndexedFloatMinHeap`, stale-requeue) | yes (`CostQueue`, lazy pop) | ✅ |
|
|
78
|
+
| Determinism + total coverage | yes (ascending seed, fixed reductions) | yes (deterministic tie-breaks) | ✅ |
|
|
79
|
+
|
|
80
|
+
The three implemented cost terms — normal deviation `N = min(1−dot, 1)`, length-weighted normal
|
|
81
|
+
seam `NS = Σ len·(1−dot)/Σ len`, and relative-isoperimetric roundness
|
|
82
|
+
`R = 1 − (B²/A)_old/(B²/A)_new` — are the **exact xatlas formulas**, with identical weights.
|
|
83
|
+
|
|
84
|
+
### 2.2 Where meep is behind
|
|
85
|
+
|
|
86
|
+
| Feature xatlas has | meep status | Quality impact |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| **`straightnessWeight = 6.0`** (clamped ≤0; pulls boundaries onto concave creases / closes gaps) | **Absent** (only 3 of 5 terms implemented) | Raggier, slightly longer chart boundaries; this is xatlas's *highest-weighted* term. |
|
|
89
|
+
| **`mergeCharts`** (merges slivers, embedded quads, contained charts; proxy-dot ≥ 0.5) | **Absent** | More, less-balanced charts; over-segmentation never cleaned up. **The single biggest gap.** |
|
|
90
|
+
| **Per-add validity gate** (each candidate face is ortho-projected and rejected if it flips/overlaps; failed regions blacklisted) | **Absent** — validity is deferred to the parameterization stage | meep can grow a non-developable chart that only gets split *downstream* by an LSCM-failure → `atlas_piecewise_resegment`. xatlas keeps charts developable *at growth time*. |
|
|
91
|
+
| **Lloyd seed relocation** (`relocateSeeds`→`resetCharts`, then re-grow) | **Absent** | Charts depend on seed order, not iterated centroid/best-fit relocation. (Modest: xatlas's default `maxIterations = 1` runs just one relocate pass.) |
|
|
92
|
+
| **Largest-area-region seeding** | meep seeds by **ascending id** | Less well-centred initial charts. |
|
|
93
|
+
| `textureSeamWeight = 0.5` | **Intentionally dropped** (no authored UVs in scope) | N/A — correct per locked scope. |
|
|
94
|
+
|
|
95
|
+
### 2.3 Verdict — segmentation: **modestly behind**
|
|
96
|
+
|
|
97
|
+
On **planar-dominant / CAD / architectural** meshes the planar-region fast path dominates and the
|
|
98
|
+
two are effectively identical (a flat surface of any tessellation → one chart in both). On
|
|
99
|
+
**curved / organic / decimated** meshes meep produces **~10–30 % more charts** with longer, less
|
|
100
|
+
regular seams, and is more prone to the documented **max-stretch outliers (133–359)** because
|
|
101
|
+
nothing splits a chart on a stretch criterion until parameterization fails. The dominant missing
|
|
102
|
+
pieces, in order of impact: `mergeCharts` > per-add validity gate > straightness term >
|
|
103
|
+
largest-area seeding ≈ Lloyd relocation.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 3. Parameterization
|
|
108
|
+
|
|
109
|
+
### 3.1 What is identical
|
|
110
|
+
|
|
111
|
+
| Mechanism | meep | xatlas | Match |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| Cascade | Ortho → LSCM → Piecewise | Planar → Ortho → LSCM → Piecewise | ✅ (meep folds Planar into Ortho) |
|
|
114
|
+
| Ortho-accept mean (L2) stretch | ≤ 1.1 | ≤ 1.1 | ✅ |
|
|
115
|
+
| Ortho-accept max (L∞) stretch | ≤ 1.25 | ≤ 1.25 | ✅ |
|
|
116
|
+
| Ortho-accept flips / zero-area / boundary self-intersect | all required clean | all required clean | ✅ |
|
|
117
|
+
| Ortho plane fit | PCA smallest-eigenvector | least-squares fit (+eigen fallback) | ✅ (equivalent) |
|
|
118
|
+
| LSCM | least-squares conformal, **2 diameter pins** | least-squares conformal, **2 diameter pins** | ✅ |
|
|
119
|
+
| LSCM accept gate | **bijectivity only (not stretch)** | **bijectivity only (not stretch)** | ✅ (shared limitation) |
|
|
120
|
+
| Piecewise fallback | greedy ortho region-grow into valid sub-charts | greedy ortho region-grow (`PiecewiseParam`) | ✅ |
|
|
121
|
+
| Stretch metric | Sander/Hoppe L2+L∞, scale-normalized (similarity = 1.0) | same family | ✅ |
|
|
122
|
+
|
|
123
|
+
### 3.2 The only real differences (both minor)
|
|
124
|
+
|
|
125
|
+
- **LSCM row assembly.** meep uses the classic Lévy complex-edge formulation (`1/√area` weights)
|
|
126
|
+
for *every* triangle. xatlas uses an **ABF-angle formulation** (`setup_abf_relations`, interior
|
|
127
|
+
angles with a largest-angle swap for stability) and falls back to the complex-edge form only for
|
|
128
|
+
degenerate triangles. xatlas's is marginally more numerically robust; results are otherwise the
|
|
129
|
+
same conformal map.
|
|
130
|
+
- **Solver.** meep: matrix-free **normal-equations** CG, cap `max(200, 10·free_cols)`. xatlas:
|
|
131
|
+
OpenNL CG, cap `5·V`. meep allows more iterations but the normal equations square the condition
|
|
132
|
+
number; xatlas's is slightly better conditioned. Both are CG-based least-squares; no practical
|
|
133
|
+
quality difference on the well-conditioned per-chart systems.
|
|
134
|
+
|
|
135
|
+
### 3.3 Verdict — parameterization: **on par**
|
|
136
|
+
|
|
137
|
+
meep is algorithmically equivalent to xatlas here. Same cascade, same thresholds, same 2-pin
|
|
138
|
+
conformal LSCM, same bijectivity-only acceptance, same guaranteed-terminating piecewise fallback.
|
|
139
|
+
xatlas's only edge is the ABF-angle LSCM rows (a hair more robust). **Both share the same ceiling:**
|
|
140
|
+
conformal LSCM preserves angles but not area, and neither minimizes stretch after the solve — so the
|
|
141
|
+
133–359 max-stretch outliers exist by design in *both*. This is the axis where literature (§4.2)
|
|
142
|
+
offers the clearest upgrade for *both*.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 4-prelude. Packing
|
|
147
|
+
|
|
148
|
+
### Packing — what is identical
|
|
149
|
+
|
|
150
|
+
| Mechanism | meep | xatlas | Match |
|
|
151
|
+
|---|---|---|---|
|
|
152
|
+
| Utilization sizing target | 0.75 | 0.75 | ✅ |
|
|
153
|
+
| Per-chart scale `√(surf/param)·density` | yes | yes | ✅ |
|
|
154
|
+
| Rotate-to-min-area-OBB | yes (`rotateChartsToAxis`) | yes | ✅ |
|
|
155
|
+
| 90° placement rotation | yes (`rotateCharts`, mask+transpose) | yes (0°/90° only — *not* 4-way) | ✅ |
|
|
156
|
+
| Sort order | perimeter descending | perimeter descending | ✅ |
|
|
157
|
+
| Small-atlas packer | bitmap **silhouette** canBlit (shifted-OR + or_blit) | bitmap silhouette | ✅ |
|
|
158
|
+
| Conservative raster + padding dilation | yes | yes (+ optional `bilinear` expand) | ✅ |
|
|
159
|
+
| Multi-page spill / pow-2 growing page | yes | yes | ✅ |
|
|
160
|
+
|
|
161
|
+
### Packing — where meep is behind
|
|
162
|
+
|
|
163
|
+
| Feature | meep | xatlas | Impact |
|
|
164
|
+
|---|---|---|---|
|
|
165
|
+
| **Placement selection** | **first-fit** (lowest-then-leftmost, no scoring) | **best-fit** — scores candidates by `max(extent)² + area` (square-biasing), via stepped brute-force or 4096 random attempts | Looser, less-square atlases. Best-fit vs first-fit is a well-known density gap. |
|
|
166
|
+
| **Packer at production scale (>256²)** | switches to **skyline rectangle** packer (bounding boxes, simple skyline overhang waste) | keeps the **bitmap silhouette** packer at *all* sizes | meep packs rectangles where xatlas interlocks silhouettes → notably lower utilization on irregular charts at scale — but **100–1000× faster** (3–43 ms vs xatlas ~2 s/~43 s). A deliberate trade (meep measured the bitmap path at 13–22 s/2048²). |
|
|
167
|
+
| **`blockAlign` 4×4** (BC/DXT block safety) | **Absent** (backlog) | optional (default off) | Charts can straddle compression-block edges → bleed under BC/ETC/ASTC. |
|
|
168
|
+
| **bilinear-tap expansion** | `dilate(padding)` only | `bilinearExpand` + dilate | Cosmetic; meep's conservative raster + dilate covers most of it. |
|
|
169
|
+
| Density search | **elastic**: re-pack up to 40× at 0.8× density | scale solved ~once | meep-specific robustness, but up to 40× redundant packing work in the worst case. |
|
|
170
|
+
|
|
171
|
+
### Packing — verdict: **behind at production scale, near parity small/flat**
|
|
172
|
+
|
|
173
|
+
- **≤256² atlases:** same silhouette-interlocking class, but first-fit vs best-fit → meep slightly
|
|
174
|
+
looser.
|
|
175
|
+
- **Flat / rectangular charts:** skyline does fine (bench high end ~95 %) → near parity.
|
|
176
|
+
- **Irregular / curved charts at ≥2048²:** meep's rectangle skyline leaves more waste than xatlas's
|
|
177
|
+
silhouette best-fit → **~10–25 % lower utilization (estimated)**, bought with a **~100–1000×
|
|
178
|
+
speedup**. xatlas is the offline quality reference (TABI 2026: xatlas-random ≈ 1.89 avg L2
|
|
179
|
+
stretch, the best of the compared methods, at ~2 s/model; brute ~43 s).
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 4. Literature survey (≈2017–2026)
|
|
184
|
+
|
|
185
|
+
Web-verified; URLs included. Grouped by axis. The recurring meta-finding: the field has moved past
|
|
186
|
+
the 2002-LSCM / 2005-D-Charts lineage that xatlas (and thus meep) implements, but **the best ideas
|
|
187
|
+
for a deterministic, dependency-free, real-time library are the classical-compatible ones** — the
|
|
188
|
+
neural/RL methods contribute *objectives* (distortion-driven cuts, fewer charts) far more than
|
|
189
|
+
*portable algorithms*.
|
|
190
|
+
|
|
191
|
+
### 4.1 Charting / cutting / seam placement
|
|
192
|
+
|
|
193
|
+
| Work | Year | One-line | Relevance to meep |
|
|
194
|
+
|---|---|---|---|
|
|
195
|
+
| [D-Charts: Quasi-Developable Mesh Segmentation](https://www.cs.ubc.ca/~sheffa/papers/EG05.pdf) | 2005 | Region-grow with a **cone-fit** developability metric, bounding distortion *during* segmentation | meep's direct ancestor; the **cone-fit proxy** (vs pure normal-deviation) would let cylinders/cones grow into single charts → kills the curved-mesh over-fragmentation + stretch outliers. **Lowest-risk, highest-fit.** |
|
|
196
|
+
| [Variational Surface Cutting](https://www.cs.cmu.edu/~kmcrane/Projects/VariationalCuts/) | 2018 | Global PDE flow evolves the cut graph to minimize distortion + seam length | The "global, length-regularized cuts" counter-philosophy to greedy grow. Too heavy to port; motivates a boundary-length term + boundary-straightening post-pass. |
|
|
197
|
+
| [OptCuts: Joint Cuts + Parameterization](https://www.cs.ubc.ca/labs/imager/tr/2018/OptCuts/) | 2018 | A single **distortion bound** drives the cuts; alternates cut-update ↔ symmetric-Dirichlet flatten; globally bijective, minimal seam length | The strongest argument to make a **distortion threshold the primary segmentation knob** (meep's `stretch` metric already exists). Replace the LSCM-fail→explode fallback with a distortion-bounded re-cut. |
|
|
198
|
+
| [AutoCuts](https://dl.acm.org/doi/abs/10.1145/3130800.3130845) | 2017 | One differentiable distortion+seam-length energy; cuts emerge from it | Portable cheap heuristic: add an explicit **boundary-length penalty** to the grow/merge cost (data already in `atlas_build_edge_lengths.js`). |
|
|
199
|
+
| [Developability-Driven Piecewise Approximations](https://dl.acm.org/doi/10.1145/3528223.3530117) | 2022 | Deform-then-partition into near-developable patches with regular seams | "Light developability-aware normal smoothing *before* segmentation" lets the existing grower form larger, cleaner charts. |
|
|
200
|
+
| [Evolutionary Piecewise Developable Approximations](https://dl.acm.org/doi/10.1145/3592140) | 2023 | Global/evolutionary search for fewer patches | Evidence that iterate-and-merge (the `mergeCharts`/Lloyd backlog) is the right direction; full search is diminishing returns for a real-time lib. |
|
|
201
|
+
| [PartUV: Part-Based UV Unwrapping](https://arxiv.org/abs/2511.16659) | 2025 | Top-down recursive split under a distortion bound + learned part priors; ~1/31 Blender's chart count | **Most directly relevant modern paper.** The **recursive-split-only-when-distortion-exceeds-the-bound** skeleton is deterministic and portable even without the learned part decomposition → fewer, larger charts. |
|
|
202
|
+
| [SeamGPT / Auto-Regressive Surface Cutting](https://arxiv.org/abs/2506.18017) · [MeshTailor](https://arxiv.org/abs/2603.27309) · [SeamCrafter](https://arxiv.org/abs/2509.20725) | 2025–26 | GPT-style learned seam generation mimicking artist cuts | Not portable (datasets + transformers). Transferable: seams follow **high-dihedral feature edges** (meep has `edge_dihedral`) and want **long coherent chains** → a boundary-chain straightening post-pass. SeamCrafter's **seam-evaluation score** (= f(seam length, fragmentation, distortion)) is a portable objective. |
|
|
203
|
+
| [Unsupervised Param w/ Semantic + Visibility](https://arxiv.org/abs/2509.25094) | 2025 | AO-weighted seam term hides cuts in occluded regions | Portable: a cheap per-edge AO/visibility proxy (reuse engine BVH) biasing the cost to **hide seams** — a dimension meep's purely-geometric cost ignores. |
|
|
204
|
+
| [Nuvo: Neural UV Mapping](https://pratulsrinivasan.github.io/nuvo/) | ECCV 2024 | Per-asset neural field for *unruly* (NeRF/soup) geometry | Out of scope (meep requires clean welded manifolds). A scope marker for if meep ever ingests scanned/AI soup. |
|
|
205
|
+
|
|
206
|
+
### 4.2 Parameterization / flattening / injectivity
|
|
207
|
+
|
|
208
|
+
| Work | Year | One-line | Relevance to meep |
|
|
209
|
+
|---|---|---|---|
|
|
210
|
+
| [LSCM](https://dl.acm.org/doi/10.1145/566654.566590) | 2002 | The conformal-LS + region-grow pipeline meep/xatlas implement | Validates meep's core as the well-understood baseline; improvement budget is better spent on cuts + isometric relaxation than on this solver. |
|
|
211
|
+
| [ARAP/ASAP local–global](https://www.eecs.harvard.edu/~sjg/papers/arap.pdf) | 2008 | Per-triangle rotation fit + one sparse SPD stitch solve, iterated | **Cheapest meaningful upgrade over LSCM.** Each global step is the *same* CG solve meep already runs; minimizes *isometric* (shape) distortion → directly attacks high-stretch charts. No injectivity guarantee (flip gate stays). |
|
|
212
|
+
| [SLIM: Scalable Locally Injective Maps](https://igl.ethz.ch/projects/slim/) | 2017 | Local/global for flip-preventing barrier energies (symmetric Dirichlet); reused-Hessian sparse solves | **Strongest candidate to replace the whole cascade.** Guarantees no flips (vs meep's post-hoc reject), minimizes isometric distortion, scales to millions of faces. Needs an injective init + line search; ~20–40 solves/chart, only on charts failing the ortho gate. |
|
|
213
|
+
| [Boundary First Flattening (BFF)](https://arxiv.org/abs/1704.06873) | 2017 | Linear conformal flattening with **explicit boundary control**; one Laplacian factorization | Natural drop-in over free-boundary LSCM; reuses the (present-but-unused) `v3_cotangent`. Automatic minimal-area boundary → fewer cuts, fewer self-intersection rejects. Caveat: cot-Laplacian indefinite on obtuse triangles (clamp / intrinsic Delaunay). |
|
|
214
|
+
| [Foldover-free maps in 50 lines](https://arxiv.org/abs/2102.03069) + [Practical Lowest Distortion](https://arxiv.org/abs/2201.12112) | 2021–22 | Untangle from an **arbitrary (even folded)** start, then minimize mean then **max** distortion; tiny, deterministic, Newton/L-BFGS | **Most meep-aligned modern optimizer.** Can subsume *both* the flip-reject path *and* the piecewise-explode fallback: feed it the ortho/LSCM output, get a foldover-free low-distortion chart. Optimizes **max distortion last** — exactly meep's accept/reject quantity. |
|
|
215
|
+
| [Progressive Parameterizations](https://dl.acm.org/doi/10.1145/3197517.3201331) | 2018 | Foldover-free, low-distortion via a progressive reference; 20k-mesh reliability study | Robustness-engineered alternative/complement to SLIM; composes with meep's CG + an ARAP step. |
|
|
216
|
+
| [Isometric Energies (IsoSEA/IsoTLC)](https://duxingyi-charles.github.io/publication/isometric-energies-for-recovering-injectivity-in-constrained-mapping/) | 2022 | Recover injectivity *and* minimize isometric distortion in one energy | A strong default barrier energy if meep builds the optimizer; same solver shape as SLIM/foldover-free. |
|
|
217
|
+
| [Progressive Embedding](https://github.com/hankstag/progressive_embedding) | 2019 | Float-robust replacement for Tutte; collapse→re-insert keeping a valid embedding | The robust **injective initializer** any barrier solver needs; overlaps meep's existing half-edge collapse simplifier (`bt_mesh_simplify_by_error`). |
|
|
218
|
+
| [Scaffold (2017)](https://cims.nyu.edu/gcl/papers/Scaffold-2017.pdf) + [Efficient Bijective (2020)](https://dl.acm.org/doi/10.1145/3386569.3392435) | 2017–20 | Turn *global* bijectivity into *local* injectivity via a (boundary-band) scaffold | If meep ever wants one guaranteed-overlap-free chart for a whole object; the 2020 boundary-band version scales with boundary length (matches meep's perf culture) and removes the O(b²) self-intersection test. |
|
|
219
|
+
| [CETM](https://dl.acm.org/doi/10.1145/1360612.1360676) | 2008 | Discrete conformal via convex log-scale energy (cot-Laplacian Hessian); auto cone singularities | Theoretical anchor for BFF; cone-singularity idea = fewer cuts on high-curvature closed charts. Reference, not a port target. |
|
|
220
|
+
| [TinyAD](https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.14607) | 2022 | Per-element AD → free Newton solver; the prototyping pattern | The **design blueprint**: per-triangle local energy + small analytic 2×2/3×3 Hessian → assemble into `SparseMatrixCSR` → `cg_solve`, behind one energy interface, so meep can swap conformal/ARAP/symmetric-Dirichlet/IsoSEA without re-deriving. |
|
|
221
|
+
|
|
222
|
+
### 4.3 Packing
|
|
223
|
+
|
|
224
|
+
| Work | Year | One-line | Relevance to meep |
|
|
225
|
+
|---|---|---|---|
|
|
226
|
+
| [A Thousand Ways to Pack the Bin (Jylänki)](https://github.com/juj/RectangleBinPack) | 2010 | Canonical 2D rect-packing survey: MaxRects > Guillotine > Skyline-BL > Shelf on density; reverse on speed | Locates meep's skyline packer; **best-short-side-fit / min-waste** skyline variants beat plain bottom-left; MaxRects is the density upgrade path meep lacks. Validates the {0°,90°} rotation set. |
|
|
227
|
+
| [TABI: Tight & Balanced Interactive Atlas Packing](https://arxiv.org/abs/2602.07782) | 2026 | **Per-axis "local AABB" + OBB proxies**, row-folding, horizontal+vertical compaction; closes ~48 % of the gap to offline xatlas at **~5 ms (~464× faster)** | **Most actionable modern reference.** The local-AABB proxy gives most of the interlocking benefit of meep's bitmap mask at O(slices) cost → lets meep pack tightly **above** its 256² bitmap ceiling, bridging its exact-but-small and loose-but-scalable packers. |
|
|
228
|
+
| [FastAtlas: Real-Time Compact Atlases](https://arxiv.org/abs/2502.17712) | 2025 | GPU parallel: bucket by height, parallel scale-search, row-fold, advancing-front push-up; <1.5 ms on 9M-tri | The **"compute the right scale ~once, allow overflow then rescale"** idea is a serial-friendly alternative to meep's 40× elastic-shrink retry loop. |
|
|
229
|
+
| [Two-dimensional irregular packing: a review](https://www.frontiersin.org/journals/mechanical-engineering/articles/10.3389/fmech.2022.966691/full) | 2022 | NFP vs raster/pixel vs envelope; metaheuristic sequence optimization | Locates meep's bitmap canBlit precisely as the **raster/pixel** method — cheap overlap test, **poor at *searching* for the best position** (exactly meep's first-fit weakness). NFP = tighter but fragile on concave/holed shapes. |
|
|
230
|
+
| [stb_rect_pack / Skyline-BL practitioner study](https://www.david-colson.com/2020/03/10/exploring-rect-packing.html) | 2020 | Skyline-BL + first-fit-decreasing is simple, fast, "good enough" | Validates meep's skyline-as-scalable-default; highest leverage is in **ordering + best-fit metric**, not the data structure. |
|
|
231
|
+
| [WebRender atlas allocation](https://mozillagfx.wordpress.com/2021/02/04/improving-texture-atlas-allocation-in-webrender/) | 2021 | Dynamic (online) atlases prefer shelf/slab over guillotine (fragmentation) | Boundary marker: meep's pack is **offline/one-shot**, so high-density guillotine/MaxRects methods are fair game; the fragmentation caveat only applies if meep grows a *streaming* atlas. |
|
|
232
|
+
| [Learning Gradient Fields for Irregular Packing](https://arxiv.org/abs/2310.19814) · [Attend2Pack](https://arxiv.org/abs/2107.04333) · [RCQL](https://arxiv.org/abs/2111.06726) | 2021–23 | Learned/RL packing; scales to 1000s of pieces | Gains over strong heuristics are **single-digit %**, and the real lever is **ordering policy**. Watch-items, not adopt-items; the takeaway is "try several deterministic orderings, keep the best." |
|
|
233
|
+
| [Ptex / UDIM / Htex](https://www.fxguide.com/fxfeatured/ptex_the_other_side/) | 2008/2002/2022 | Sidestep packing entirely (per-face/per-halfedge) or relax to integer tiles | Bounds the ambition: chasing the last few % of density only matters because meep is atlas-committed. UDIM maps naturally onto meep's existing multi-page support — a possible future output mode. |
|
|
234
|
+
| [Robust NFP generation](https://www.mdpi.com/2227-7390/10/16/2941) | 2019–22 | No-fit-polygon = the tight-irregular-nesting primitive | The max-density frontier for meep's concave charts, but expensive/fragile on non-convex+holed shapes — why the port chose bitmap. Held as a documented "if we ever need maximum density" option. |
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 5. Prioritized opportunities (planning backlog — deterministic, dependency-free only)
|
|
239
|
+
|
|
240
|
+
Ranked by estimated value ÷ effort. **All are classical/deterministic** — the neural/RL methods are
|
|
241
|
+
explicitly *not* adopt-items (non-deterministic, heavy deps, only approximately bijective, against
|
|
242
|
+
meep's exact/black-box-tested library semantics); we harvest their *objectives*, not their models.
|
|
243
|
+
|
|
244
|
+
### 5.0 MEASURED OUTCOMES (2026-06-26) — the gating already ran
|
|
245
|
+
|
|
246
|
+
The P0 metrics harness was built ([atlas_bench_lib.js](atlas_bench_lib.js) +
|
|
247
|
+
[atlas_metrics.bench.spec.js](atlas_metrics.bench.spec.js): chart count + chart-type histogram,
|
|
248
|
+
stretch mean/max/p50/p90/p99 + high-distortion tail, seam length, utilization, A/B runner) and used to
|
|
249
|
+
gate the three Tier-1 items below. **All three were measured to *not* be free wins on our actual
|
|
250
|
+
pipeline** — and the harness surfaced the real lever instead. This is the payoff of measuring first.
|
|
251
|
+
|
|
252
|
+
| Tier-1 item | Measured verdict | Evidence |
|
|
253
|
+
|---|---|---|
|
|
254
|
+
| **mergeCharts** | **Trade-off, not a win** — kept as an off-by-default opt-in (`segment.merge`, `mergeMinDot`). Implemented + 6 unit tests. | Safe threshold (0.9) → −1 % charts (greedy already joins coplanar regions). Effective (0.5) → −20 % charts / −7 % seam but **p99 stretch 4.27→15.21** and piecewise 127→192. No threshold gives fewer-charts-AND-no-stretch-regression. |
|
|
255
|
+
| **best-fit packing** | **Rejected** (implemented, measured, reverted). | Δutil **0.00pp** on every fixture in both elastic and growing-page modes — min-waste's few-% gain is masked by pow2 pages + 0.8× elastic-density quantization. |
|
|
256
|
+
| **ARAP-for-curvature** | **Premise invalidated** (not built). | Clean curved/developable surfaces (sphere, hemisphere, cylinder, cone, torus) already flatten with **max stretch ≤ 1.5**. LSCM is essentially isometric there. |
|
|
257
|
+
|
|
258
|
+
**The real lever the harness found: LSCM boundary self-intersection.** The dominant quality problem is
|
|
259
|
+
*not* any of the three above. On the decimated terrain (970 charts, **127 piecewise-explosion
|
|
260
|
+
sub-charts**), failure-reason instrumentation of the parameterize cascade showed the explosion comes
|
|
261
|
+
from **31 LSCM charts that fail bijectivity, ALL 31 on boundary self-intersection** (zero on
|
|
262
|
+
zero-area / degenerate-input / mixed-winding). Free-boundary conformal LSCM has no injectivity
|
|
263
|
+
guarantee, so on complex/curved boundaries the UV outline overlaps itself; the piecewise fallback then
|
|
264
|
+
(correctly) cuts each into ~4 ortho pieces. *(A sliver/degenerate-input hypothesis was tested first and
|
|
265
|
+
disproven — a degenerate-input-tolerant validity tweak was provably inert and reverted. The max-stretch
|
|
266
|
+
~5877 outlier is real but area-negligible: the area-weighted mean stays ~2.5.)*
|
|
267
|
+
|
|
268
|
+
**Attempt 1 — Tutte/convex-boundary rescue (built, measured, then REMOVED).** The natural first try is a
|
|
269
|
+
guaranteed-injective embedding: pin each self-intersecting disk chart to a circle and solve the interior
|
|
270
|
+
(Tutte's theorem ⇒ no flips, no self-intersection). It **works structurally** — on the decimated
|
|
271
|
+
terrain it eliminated the explosion (127 piecewise → 0, replaced by 31 whole charts, **−96 charts**,
|
|
272
|
+
utilization **71.9 % → 86.3 %**, all guaranteed bijective) — but the **distortion is catastrophic**:
|
|
273
|
+
mean stretch **2.55 → 70.9**, p99 **4.27 → 2467**. The self-intersecting charts are *thin/curled* (that
|
|
274
|
+
is why LSCM curled them), so forcing them onto a circle ruins them. **Confirmed boundary-dominated:**
|
|
275
|
+
upgrading the interior weights uniform → Floater mean-value changed nothing (70.82 → 70.88). So a
|
|
276
|
+
convex-boundary embedding is the wrong tool here, and the piecewise explosion (compact low-distortion
|
|
277
|
+
pieces) is the *better* quality outcome.
|
|
278
|
+
|
|
279
|
+
**Attempt 2 — shape-aware convex boundary (built, measured, reverted).** Map the boundary to an
|
|
280
|
+
aspect-matched ellipse instead of a circle (still convex ⇒ still injective). **No improvement** (71.67 vs
|
|
281
|
+
70.9): a curled chart's LSCM layout curls into a roughly *round* blob, so its aspect can't be estimated
|
|
282
|
+
without already flattening — a catch-22 that rules out the whole convex-boundary family.
|
|
283
|
+
|
|
284
|
+
**Attempt 3 — BFF, intrinsic boundary-first (built, measured, now ALWAYS-ON; the right approach).**
|
|
285
|
+
`CHART_TYPE.BFF`: build the flat boundary from the chart's own edge lengths + curvature
|
|
286
|
+
(Gauss-Bonnet closure), then a **conformal** pinned-boundary interior (harmonic was tried first and
|
|
287
|
+
flipped 26/31; conformal is far less flip-prone). **It clears the gate the convex family failed** —
|
|
288
|
+
decimated terrain −4 charts, mean stretch **2.55 → 2.51 (better, not worse)**, every BFF chart bijective,
|
|
289
|
+
no clean-fixture regression: a Pareto-safe win, not Tutte's 70×. **But tiny magnitude — only 1 of 31**
|
|
290
|
+
self-intersecting charts is rescued; the other 30 fail (diagnosed: 25 flip, 5 self-intersect) because the
|
|
291
|
+
v1 **uniform** curvature redistribution leaves the boundary too contorted.
|
|
292
|
+
|
|
293
|
+
**Attempt 4 — BFF's optimal Dirichlet-to-Neumann boundary (built, measured; the definitive answer).**
|
|
294
|
+
Replaced the uniform curvature with the DtN-optimal distribution (fix boundary scale 0, interior Poisson
|
|
295
|
+
`L_II u = Ω_I`, `k̃_b = (π−θ_b) − (L u)_b`). The **DtN boundary fixed the interior** — conformal-interior
|
|
296
|
+
flips **25 → 2** — and stayed Pareto-safe (−6 charts, mean 2.55 → 2.51, p99 4.27 → 3.99). **But still only
|
|
297
|
+
~2 of 31 rescued: the flattened *boundary* now self-intersects on ~27/31, and that is FUNDAMENTAL** — true
|
|
298
|
+
unclamped cotangents made it *worse* (1 rescue, 30 self-intersections). These high-curvature decimated
|
|
299
|
+
charts **cannot be developed to a simple boundary** while preserving edge lengths, so cutting (piecewise)
|
|
300
|
+
is the correct injective answer; BFF rescues only the ~2 low-curvature ones.
|
|
301
|
+
|
|
302
|
+
**Conclusion (the metrics settle it): the piecewise explosion is largely correct behavior** for
|
|
303
|
+
decimated/high-curvature charts — they are intrinsically un-flattenable-whole, and BFF (the right,
|
|
304
|
+
fully-built tool) confirms it. BFF is **folded into the single always-on cascade** (ortho → LSCM → BFF →
|
|
305
|
+
piecewise, no flags): it is free (compute delta ~−0.3 %, since it runs only on charts that already failed
|
|
306
|
+
LSCM) and strictly Pareto-safe (accepts only bijective + near-isometric whole charts). The failed Tutte
|
|
307
|
+
convex-boundary path was **removed** (strictly dominated). The only way to
|
|
308
|
+
keep these charts whole would be to let the *boundary be cut* during optimization (OptCuts-style joint
|
|
309
|
+
cut+flatten) or a scaffolded injective nonlinear map (SLIM) — large, separate builds whose payoff (~29
|
|
310
|
+
hard charts, decimated assets only) the metrics say is modest. So: **no further parameterization work is
|
|
311
|
+
warranted on the current asset mix; the validated atlas pipeline is in good shape, and the residual
|
|
312
|
+
over-segmentation on decimated content is the right answer, not a defect.**
|
|
313
|
+
|
|
314
|
+
### 5.1 Original ranked backlog (pre-measurement — kept for context)
|
|
315
|
+
|
|
316
|
+
**P0 — Head-to-head A/B bench.** ✅ **DONE** (the metrics harness above). The remaining gap is an
|
|
317
|
+
*xatlas* side-by-side on identical meshes (we have meep-side metrics + xatlas's published numbers).
|
|
318
|
+
|
|
319
|
+
**Tier 1 — biggest quality-per-effort, reuse existing infra**
|
|
320
|
+
|
|
321
|
+
1. **`mergeCharts` pass** (xatlas parity + Evolutionary-Developability evidence). Post-segmentation
|
|
322
|
+
greedy merge of adjacent charts whose proxy normals agree (dot ≥ ~0.5) and whose merged ortho
|
|
323
|
+
projection stays valid. Closes most of the segmentation chart-count gap. *Effort: moderate;
|
|
324
|
+
reuses the cost/validity machinery.* → **MEASURED (§5.0): trade-off, shipped off-by-default.**
|
|
325
|
+
2. **Best-fit placement metric in the bitmap packer** (xatlas + Jylänki). Replace `find_first_fit`'s
|
|
326
|
+
first-feasible return with a scored scan (`max(extent)² + area`, or contact-perimeter / wasted-gutter).
|
|
327
|
+
Highest-leverage single packing-density win. *Effort: low.* → **MEASURED (§5.0): 0.00pp, rejected**
|
|
328
|
+
(note: measured for the skyline path; the bitmap-path best-fit is untested but the same pow2/elastic
|
|
329
|
+
quantization applies, so it is deprioritized).
|
|
330
|
+
3. **ARAP local/global as the LSCM successor** (Liu 2008 → SLIM). One per-triangle rotation fit +
|
|
331
|
+
the *same* sparse-CG global solve, iterated — invoked only on charts that fail the ortho gate.
|
|
332
|
+
Directly attacks the 133–359 max-stretch outliers conformal LSCM cannot fix. *Effort: low–moderate;
|
|
333
|
+
reuses `cg_solve`.* → **MEASURED (§5.0): premise invalidated for curvature** (clean curved meshes
|
|
334
|
+
already flatten ≤1.5; the outliers are sliver-driven). ARAP would only help *if* paired with sliver
|
|
335
|
+
cleanup — re-evaluate after the sliver work, not before.
|
|
336
|
+
|
|
337
|
+
**Tier 2 — strong, moderate effort**
|
|
338
|
+
|
|
339
|
+
4. **D-Charts cone-fit developability proxy** in the segmentation cost (Julius 2005). Augment the
|
|
340
|
+
per-face normal-deviation with a cone-fit angle so curved-but-developable regions (cylinders,
|
|
341
|
+
cones, fillets) grow into single charts. Targets the curved-mesh over-fragmentation at its root.
|
|
342
|
+
5. **TABI local-AABB proxy packer above 256²** (TABI 2026). Per-axis interval-AABBs give most of the
|
|
343
|
+
silhouette-interlocking benefit at O(slices) cost → tight packing at production sizes without the
|
|
344
|
+
bitmap's O(area·mask) blowup. Bridges meep's exact-small / loose-large packer split.
|
|
345
|
+
6. **Distortion-bounded re-cut instead of piecewise explode** (OptCuts/PartUV). When a chart's
|
|
346
|
+
stretch exceeds the bound, open the seam along the highest-distortion edge ring (top-down,
|
|
347
|
+
recursive) rather than exploding into many ortho sub-charts → fewer, larger charts, shorter seams.
|
|
348
|
+
7. **Multi-ordering best-of-N packing** (RL "sequence" lesson, xatlas "attempts"). Try a few
|
|
349
|
+
deterministic orderings (area-desc, max-side-desc, height-desc, perimeter-desc) and keep the
|
|
350
|
+
tightest. *Effort: low.*
|
|
351
|
+
|
|
352
|
+
**Tier 3 — targeted / opportunistic**
|
|
353
|
+
|
|
354
|
+
8. **Straightness cost term** + **boundary-chain straightening post-pass** (xatlas parity +
|
|
355
|
+
AutoCuts/Variational + MeshTailor ChainingSeams). Add the missing 5th cost term and walk each
|
|
356
|
+
chart boundary to snap it onto connected high-dihedral chains → boundary regularity.
|
|
357
|
+
9. **`blockAlign` 4×4** (xatlas) — if atlas pages ever feed BC/ETC/ASTC compression.
|
|
358
|
+
10. **Foldover-free / Practical-Lowest-Distortion untangler** (2021–22) — the heavier but
|
|
359
|
+
most-meep-aligned option to *replace both* the flip-reject and piecewise-explode paths with one
|
|
360
|
+
deterministic untangling solve that minimizes max distortion last. Build behind a TinyAD-style
|
|
361
|
+
one-energy-interface so conformal/ARAP/symmetric-Dirichlet/IsoSEA are swappable.
|
|
362
|
+
11. **BFF parameterization backend** behind a `CHART_TYPE` flag — linear, boundary-controlled, fewer
|
|
363
|
+
self-intersection rejects; reuses the unused `v3_cotangent`.
|
|
364
|
+
12. **Visibility/AO-weighted seam term** (ICLR-2026) — bias seams into occluded edges using the
|
|
365
|
+
engine BVH; for atlases that feed final rendering.
|
|
366
|
+
13. **Largest-area seeding + ≥1 Lloyd relocation** (xatlas parity) — small, completes the
|
|
367
|
+
segmentation-parity story.
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 6. Appendix — parameter cross-reference (verified)
|
|
372
|
+
|
|
373
|
+
**Segmentation** (meep `ATLAS_SEGMENT_DEFAULTS` vs xatlas `ChartOptions`):
|
|
374
|
+
`maxCost 2 / 2.0` ✅ · `normalDeviationWeight 2 / 2.0` ✅ · `normalSeamWeight 4 / 4.0` ✅ ·
|
|
375
|
+
`roundnessWeight 0.01 / 0.01` ✅ · `straightnessWeight —/6.0` ❌ · `textureSeamWeight —/0.5`
|
|
376
|
+
(dropped, intentional) · hard reject `0.707 / 0.707` ✅ · coplanar eps `1e-4 / 1e-4` ✅ ·
|
|
377
|
+
`maxIterations` 1-pass-no-relocate / 1-pass-with-relocate+merge+fill ❌ · seed `ascending-id /
|
|
378
|
+
largest-area-region` ❌.
|
|
379
|
+
|
|
380
|
+
**Parameterization:** ortho-accept `mean≤1.1, max≤1.25` ✅✅ · LSCM `2 diameter pins` ✅ · LSCM rows
|
|
381
|
+
`complex-edge(Lévy) / ABF-angle(+fallback)` ~ · solver `normal-eq CG / OpenNL CG` ~ · LSCM accept
|
|
382
|
+
`bijectivity-only` ✅ (shared limitation) · piecewise `greedy ortho grow` ✅.
|
|
383
|
+
|
|
384
|
+
**Packing:** util target `0.75 / 0.75` ✅ · `rotateChartsToAxis true/true` ✅ · `rotateCharts(90°)
|
|
385
|
+
true/true` ✅ · sort `perimeter-desc / perimeter-desc` ✅ · placement `first-fit / best-fit` ❌ ·
|
|
386
|
+
scale packer `skyline-rect(>256²) / bitmap-silhouette(all sizes)` ❌ (deliberate) · small packer
|
|
387
|
+
`bitmap-silhouette / bitmap-silhouette` ✅ · `blockAlign —/optional` ❌ · density `elastic-40× /
|
|
388
|
+
solved-once` (meep-specific).
|
|
389
|
+
|
|
390
|
+
**Source of record:** xatlas web-verified at `source/xatlas/xatlas.{cpp,h}` `master`; meep at
|
|
391
|
+
`src/core/geom/3d/atlas/**` (see ATLAS_PORT_PLAN.md for file map). All literature URLs above are
|
|
392
|
+
web-verified.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** Flat n×n plane in z=0. Single planar region => one chart, zero stretch. */
|
|
2
|
+
export function soup_plane(n: any): any[];
|
|
3
|
+
/** Deterministic gently-bumpy terrain (curved, smooth, no RNG). */
|
|
4
|
+
export function soup_terrain(n: any, amplitude: any): any[];
|
|
5
|
+
/** Dense bumpy terrain decimated by the production simplifier -> irregular, over-segmenting asset. */
|
|
6
|
+
export function soup_decimated_terrain(n: any, amplitude: any, error: any): number[];
|
|
7
|
+
/** UV sphere (fanned poles, no degenerate tris). Smooth closed surface. */
|
|
8
|
+
export function soup_uv_sphere(rings: any, sectors: any): any[];
|
|
9
|
+
/** Upper hemisphere cap (intrinsic positive curvature -> MUST distort under any flattening). */
|
|
10
|
+
export function soup_hemisphere(rings: any, sectors: any): any[];
|
|
11
|
+
/** Open cylinder side (no caps): a DEVELOPABLE surface — should flatten to a flat strip with ~zero stretch. */
|
|
12
|
+
export function soup_cylinder_open(radial: any, rings: any, height: any, radius: any): any[];
|
|
13
|
+
/** Open cone side (no base): DEVELOPABLE — flattens to a circular sector with ~zero stretch. */
|
|
14
|
+
export function soup_cone_open(radial: any, rings: any, height: any, radius: any): any[];
|
|
15
|
+
/** Torus: irregular, curved charts (a packing stress fixture). */
|
|
16
|
+
export function soup_torus(rings: any, sides: any, R: any, rr: any): any[];
|
|
17
|
+
/** Grid of unit cubes (each cube => 6 charts at 90°; a chart-count fixture). */
|
|
18
|
+
export function soup_cube_field(count: any): any[];
|
|
19
|
+
export function build_mesh(soup: any): BinaryTopology;
|
|
20
|
+
/**
|
|
21
|
+
* Per-run chart-quality metrics. `charts` are finalized charts (each with
|
|
22
|
+
* `surface_area`, `parametric_area`, `type`, and solved `uv`).
|
|
23
|
+
*
|
|
24
|
+
* @param {Chart[]} charts
|
|
25
|
+
* @returns {object} chart_count, ortho/lscm/piecewise counts, area-weighted
|
|
26
|
+
* mean_stretch, max_stretch, p50/p90/p99 of per-chart worst stretch,
|
|
27
|
+
* tail_count + tail_area_frac (charts above TAIL_STRETCH), degenerate count.
|
|
28
|
+
*/
|
|
29
|
+
export function chart_metrics(charts: Chart[]): object;
|
|
30
|
+
/** Total 3D length of edges cut between different charts (texture seams) + fraction of interior length. */
|
|
31
|
+
export function seam_metrics(mesh: any, charts: any): {
|
|
32
|
+
seam_len: number;
|
|
33
|
+
seam_pct: number;
|
|
34
|
+
interior_len: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Run the full pipeline once and return the metric panel. Always rebuilds the
|
|
38
|
+
* mesh from the soup so packing-only A/Bs are independent (pack mutates uv).
|
|
39
|
+
*
|
|
40
|
+
* @param {number[]} soup triangle soup
|
|
41
|
+
* @param {object} [computeOpts] atlas_compute_charts options
|
|
42
|
+
* @param {object} [packOpts] atlas_pack_charts options
|
|
43
|
+
* @returns {object} flattened metric panel
|
|
44
|
+
*/
|
|
45
|
+
export function measure(soup: number[], computeOpts?: object, packOpts?: object): object;
|
|
46
|
+
/** Median wall-clock of `fn` over a time budget, with warmup. */
|
|
47
|
+
export function time_median(fn: any, budget_ms?: number, warmup?: number): any;
|
|
48
|
+
/**
|
|
49
|
+
* A/B: measure baseline vs candidate on the same fixture and return both panels
|
|
50
|
+
* plus per-key deltas. The caller asserts the expected direction (the gate).
|
|
51
|
+
*
|
|
52
|
+
* @param {number[]} soup
|
|
53
|
+
* @param {{compute?:object, pack?:object}} a baseline options
|
|
54
|
+
* @param {{compute?:object, pack?:object}} b candidate options
|
|
55
|
+
* @returns {{base:object, cand:object, delta:object}}
|
|
56
|
+
*/
|
|
57
|
+
export function ab(soup: number[], a: {
|
|
58
|
+
compute?: object;
|
|
59
|
+
pack?: object;
|
|
60
|
+
}, b: {
|
|
61
|
+
compute?: object;
|
|
62
|
+
pack?: object;
|
|
63
|
+
}): {
|
|
64
|
+
base: object;
|
|
65
|
+
cand: object;
|
|
66
|
+
delta: object;
|
|
67
|
+
};
|
|
68
|
+
/** Compact one-line metric panel for console output. */
|
|
69
|
+
export function fmt(m: any): string;
|
|
70
|
+
/** Charts whose worst (L∞) per-triangle stretch exceeds this count as the "high-distortion tail". */
|
|
71
|
+
export const TAIL_STRETCH: 2;
|
|
72
|
+
import { BinaryTopology } from "../topology/struct/binary/BinaryTopology.js";
|
|
73
|
+
//# sourceMappingURL=atlas_bench_lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atlas_bench_lib.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/atlas/atlas_bench_lib.js"],"names":[],"mappings":"AAoCA,8EAA8E;AAC9E,0CAKC;AAED,mEAAmE;AACnE,4DAMC;AAED,sGAAsG;AACtG,qFAIC;AAED,2EAA2E;AAC3E,gEAYC;AAED,gGAAgG;AAChG,iEAYC;AAED,+GAA+G;AAC/G,6FAQC;AAED,gGAAgG;AAChG,yFAUC;AAED,kEAAkE;AAClE,2EASC;AAED,gFAAgF;AAChF,mDAWC;AAED,sDAIC;AA8BD;;;;;;;;GAQG;AACH,sCALW,OAAO,GACL,MAAM,CA0ClB;AAED,2GAA2G;AAC3G;;;;EAsBC;AAGD;;;;;;;;GAQG;AACH,8BALW,MAAM,EAAE,gBACR,MAAM,aACN,MAAM,GACJ,MAAM,CAgBlB;AAED,iEAAiE;AACjE,+EAWC;AAED;;;;;;;;GAQG;AACH,yBALW,MAAM,EAAE,KACR;IAAC,OAAO,CAAC,EAAC,MAAM,CAAC;IAAC,IAAI,CAAC,EAAC,MAAM,CAAA;CAAC,KAC/B;IAAC,OAAO,CAAC,EAAC,MAAM,CAAC;IAAC,IAAI,CAAC,EAAC,MAAM,CAAA;CAAC;UACvB,MAAM;UAAO,MAAM;WAAQ,MAAM;EAUnD;AAED,wDAAwD;AACxD,oCAMC;AApJD,qGAAqG;AACrG,6BAAgC;+BAvKa,6CAA6C"}
|