@bldrs-ai/conway 1.389.1221 → 1.394.1504
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/README.md +36 -22
- package/compiled/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWebMT.js +1 -1
- package/compiled/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.js +1 -1
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts +19 -0
- package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts.map +1 -1
- package/compiled/dependencies/conway-geom/interface/conway_geometry.js +17 -0
- package/compiled/dependencies/conway-geom/interface/parameters/surface_object.d.ts +6 -0
- package/compiled/dependencies/conway-geom/interface/parameters/surface_object.d.ts.map +1 -1
- package/compiled/examples/browser-bundled.cjs +1569 -51
- package/compiled/examples/cli-bundled.cjs +2790 -436
- package/compiled/examples/cli-step-bundled.cjs +1904 -229
- package/compiled/examples/validator-bundled.cjs +1569 -51
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.d.ts +2 -2
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_curve.gen.js +2 -2
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.d.ts +3 -3
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/b_spline_surface.gen.js +3 -3
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.d.ts +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/composite_curve.gen.js +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.d.ts +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_2d.gen.js +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.d.ts +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_curve_3d.gen.js +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.d.ts +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/offset_surface.gen.js +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/presentation_style_assignment.gen.js +2 -2
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/schema_ap214.gen.js +11 -11
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.d.ts +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/AP214E3_2010_gen/shape_aspect.gen.js +1 -1
- package/compiled/src/AP214E3_2010/ap214_command_line_main.js +7 -3
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts +181 -7
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +906 -137
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.test.js +10 -2
- package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_logical_attribute.test.js +114 -0
- package/compiled/src/AP214E3_2010/ap214_model_geometry.d.ts +6 -0
- package/compiled/src/AP214E3_2010/ap214_model_geometry.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_model_geometry.js +9 -0
- package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_pcurve_basis_surfaces.test.js +233 -0
- package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_sphere_vertex_loop.test.js +147 -0
- package/compiled/src/AP214E3_2010/ap214_step_model.d.ts +2 -1
- package/compiled/src/AP214E3_2010/ap214_step_model.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_step_model.js +1 -1
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_typed_select_enum.test.js +65 -0
- package/compiled/src/AP214E3_2010/ap214_unit_scale.test.d.ts +2 -0
- package/compiled/src/AP214E3_2010/ap214_unit_scale.test.d.ts.map +1 -0
- package/compiled/src/AP214E3_2010/ap214_unit_scale.test.js +111 -0
- package/compiled/src/compat/web-ifc/ap214_streamed_open.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ap214_streamed_open.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ap214_streamed_open.test.js +190 -0
- package/compiled/src/compat/web-ifc/coordination_export_order.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/coordination_export_order.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/coordination_export_order.test.js +110 -0
- package/compiled/src/compat/web-ifc/coordination_f64.d.ts +165 -0
- package/compiled/src/compat/web-ifc/coordination_f64.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/coordination_f64.js +286 -0
- package/compiled/src/compat/web-ifc/coordination_f64.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/coordination_f64.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/coordination_f64.test.js +225 -0
- package/compiled/src/compat/web-ifc/ifc_api.d.ts +154 -0
- package/compiled/src/compat/web-ifc/ifc_api.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api.js +211 -3
- package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.js +288 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts +39 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts +30 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough_factory.js +83 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_channel.test.js +383 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.js +124 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts +132 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +488 -92
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts +268 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +996 -149
- package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ifc_api_streamed_open.test.js +129 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.d.ts +134 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.js +933 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/spatial_imposter.test.js +467 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.d.ts +187 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.js +524 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/store_preview_channel.test.js +234 -0
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts +306 -0
- package/compiled/src/compat/web-ifc/streamed_preview_channel.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/streamed_preview_channel.js +580 -0
- package/compiled/src/compat/web-ifc/web_wasm_directory.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/web_wasm_directory.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/web_wasm_directory.test.js +22 -0
- package/compiled/src/core/composed_model_skeleton.d.ts +63 -0
- package/compiled/src/core/composed_model_skeleton.d.ts.map +1 -0
- package/compiled/src/core/composed_model_skeleton.js +66 -0
- package/compiled/src/core/composed_model_skeleton.test.d.ts +2 -0
- package/compiled/src/core/composed_model_skeleton.test.d.ts.map +1 -0
- package/compiled/src/core/composed_model_skeleton.test.js +69 -0
- package/compiled/src/core/demand_geometry_queue.d.ts +147 -0
- package/compiled/src/core/demand_geometry_queue.d.ts.map +1 -0
- package/compiled/src/core/demand_geometry_queue.js +223 -0
- package/compiled/src/core/demand_geometry_queue.test.d.ts +2 -0
- package/compiled/src/core/demand_geometry_queue.test.d.ts.map +1 -0
- package/compiled/src/core/demand_geometry_queue.test.js +133 -0
- package/compiled/src/core/demand_residency_pump.d.ts +93 -0
- package/compiled/src/core/demand_residency_pump.d.ts.map +1 -0
- package/compiled/src/core/demand_residency_pump.js +120 -0
- package/compiled/src/core/demand_residency_pump.test.d.ts +2 -0
- package/compiled/src/core/demand_residency_pump.test.d.ts.map +1 -0
- package/compiled/src/core/demand_residency_pump.test.js +148 -0
- package/compiled/src/core/geometry_tile_bindings.d.ts +110 -0
- package/compiled/src/core/geometry_tile_bindings.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_bindings.js +76 -0
- package/compiled/src/core/geometry_tile_bindings.test.d.ts +2 -0
- package/compiled/src/core/geometry_tile_bindings.test.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_bindings.test.js +211 -0
- package/compiled/src/core/geometry_tile_pool.d.ts +99 -0
- package/compiled/src/core/geometry_tile_pool.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_pool.js +104 -0
- package/compiled/src/core/geometry_tile_pool.test.d.ts +2 -0
- package/compiled/src/core/geometry_tile_pool.test.d.ts.map +1 -0
- package/compiled/src/core/geometry_tile_pool.test.js +180 -0
- package/compiled/src/core/mem/chunked_pool.d.ts +116 -0
- package/compiled/src/core/mem/chunked_pool.d.ts.map +1 -0
- package/compiled/src/core/mem/chunked_pool.js +149 -0
- package/compiled/src/core/mem/chunked_pool.test.d.ts +2 -0
- package/compiled/src/core/mem/chunked_pool.test.d.ts.map +1 -0
- package/compiled/src/core/mem/chunked_pool.test.js +63 -0
- package/compiled/src/core/mem/shared_asset_pool.d.ts +82 -0
- package/compiled/src/core/mem/shared_asset_pool.d.ts.map +1 -0
- package/compiled/src/core/mem/shared_asset_pool.js +113 -0
- package/compiled/src/core/mem/shared_asset_pool.test.d.ts +2 -0
- package/compiled/src/core/mem/shared_asset_pool.test.d.ts.map +1 -0
- package/compiled/src/core/mem/shared_asset_pool.test.js +49 -0
- package/compiled/src/core/model_registry.d.ts +87 -0
- package/compiled/src/core/model_registry.d.ts.map +1 -0
- package/compiled/src/core/model_registry.js +101 -0
- package/compiled/src/core/model_registry.test.d.ts +2 -0
- package/compiled/src/core/model_registry.test.d.ts.map +1 -0
- package/compiled/src/core/model_registry.test.js +60 -0
- package/compiled/src/core/model_uri.d.ts +57 -0
- package/compiled/src/core/model_uri.d.ts.map +1 -0
- package/compiled/src/core/model_uri.js +101 -0
- package/compiled/src/core/model_uri.test.d.ts +2 -0
- package/compiled/src/core/model_uri.test.d.ts.map +1 -0
- package/compiled/src/core/model_uri.test.js +49 -0
- package/compiled/src/core/progress.d.ts +16 -2
- package/compiled/src/core/progress.d.ts.map +1 -1
- package/compiled/src/core/progress.js +31 -5
- package/compiled/src/core/progress.test.js +11 -2
- package/compiled/src/core/progress_log.d.ts +1 -0
- package/compiled/src/core/progress_log.d.ts.map +1 -1
- package/compiled/src/core/progress_log.js +7 -2
- package/compiled/src/core/progress_log.test.js +21 -0
- package/compiled/src/core/shared_byte_budget.d.ts +60 -0
- package/compiled/src/core/shared_byte_budget.d.ts.map +1 -0
- package/compiled/src/core/shared_byte_budget.js +85 -0
- package/compiled/src/core/shared_byte_budget.test.d.ts +2 -0
- package/compiled/src/core/shared_byte_budget.test.d.ts.map +1 -0
- package/compiled/src/core/shared_byte_budget.test.js +55 -0
- package/compiled/src/core/wasm_heap.d.ts +208 -0
- package/compiled/src/core/wasm_heap.d.ts.map +1 -0
- package/compiled/src/core/wasm_heap.js +417 -0
- package/compiled/src/core/wasm_heap.test.d.ts +2 -0
- package/compiled/src/core/wasm_heap.test.d.ts.map +1 -0
- package/compiled/src/core/wasm_heap.test.js +546 -0
- package/compiled/src/demand/index.d.ts +23 -0
- package/compiled/src/demand/index.d.ts.map +1 -0
- package/compiled/src/demand/index.js +22 -0
- package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.d.ts +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.d.ts.map +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcLogical.gen.js +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.d.ts.map +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcPresentationStyleAssignment.gen.js +2 -2
- package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.d.ts +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.d.ts.map +1 -1
- package/compiled/src/ifc/ifc4_gen/IfcRelInterferesElements.gen.js +1 -1
- package/compiled/src/ifc/ifc4_gen/schema_ifc.gen.js +2 -2
- package/compiled/src/ifc/ifc_demand_extraction.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_demand_extraction.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_demand_extraction.test.js +251 -0
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts +367 -6
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_geometry_extraction.js +1322 -389
- package/compiled/src/ifc/ifc_grid_placement.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_grid_placement.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_grid_placement.test.js +261 -0
- package/compiled/src/ifc/ifc_model_geometry.d.ts +12 -0
- package/compiled/src/ifc/ifc_model_geometry.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_model_geometry.js +15 -0
- package/compiled/src/ifc/ifc_regression_batch_main.js +210 -12
- package/compiled/src/ifc/ifc_spatial_skeleton.d.ts +145 -0
- package/compiled/src/ifc/ifc_spatial_skeleton.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_spatial_skeleton.js +266 -0
- package/compiled/src/ifc/ifc_spatial_skeleton.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_spatial_skeleton.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_spatial_skeleton.test.js +199 -0
- package/compiled/src/ifc/ifc_step_model.d.ts +6 -2
- package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_model.js +6 -4
- package/compiled/src/ifc/ifc_step_parser.d.ts +58 -0
- package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_step_parser.js +64 -0
- package/compiled/src/ifc/ifc_stream_model.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_stream_model.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_stream_model.test.js +70 -0
- package/compiled/src/ifc/ifc_stream_open.d.ts +131 -0
- package/compiled/src/ifc/ifc_stream_open.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_stream_open.js +116 -0
- package/compiled/src/ifc/ifc_stream_open.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_stream_open.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_stream_open.test.js +230 -0
- package/compiled/src/ifc/ifc_tile_extractor.d.ts +84 -0
- package/compiled/src/ifc/ifc_tile_extractor.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_tile_extractor.js +134 -0
- package/compiled/src/ifc/ifc_tile_extractor.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_tile_extractor.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_tile_extractor.test.js +118 -0
- package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts +2 -0
- package/compiled/src/ifc/ifc_typed_select_enum.test.d.ts.map +1 -0
- package/compiled/src/ifc/ifc_typed_select_enum.test.js +60 -0
- package/compiled/src/index.d.ts +21 -1
- package/compiled/src/index.d.ts.map +1 -1
- package/compiled/src/index.js +28 -1
- package/compiled/src/logging/logger.d.ts +16 -2
- package/compiled/src/logging/logger.d.ts.map +1 -1
- package/compiled/src/logging/logger.js +34 -7
- package/compiled/src/logging/logger.test.js +30 -0
- package/compiled/src/mem/index.d.ts +17 -0
- package/compiled/src/mem/index.d.ts.map +1 -0
- package/compiled/src/mem/index.js +16 -0
- package/compiled/src/namespace_surface.test.d.ts +2 -0
- package/compiled/src/namespace_surface.test.d.ts.map +1 -0
- package/compiled/src/namespace_surface.test.js +43 -0
- package/compiled/src/parsing/parsing_buffer.d.ts +23 -0
- package/compiled/src/parsing/parsing_buffer.d.ts.map +1 -1
- package/compiled/src/parsing/parsing_buffer.js +31 -0
- package/compiled/src/scripts/model_report_displacement.test.d.ts +2 -0
- package/compiled/src/scripts/model_report_displacement.test.d.ts.map +1 -0
- package/compiled/src/scripts/model_report_displacement.test.js +104 -0
- package/compiled/src/scripts/render_glb_paths.test.d.ts +2 -0
- package/compiled/src/scripts/render_glb_paths.test.d.ts.map +1 -0
- package/compiled/src/scripts/render_glb_paths.test.js +115 -0
- package/compiled/src/step/indexing/step_type_indexer.d.ts +20 -0
- package/compiled/src/step/indexing/step_type_indexer.d.ts.map +1 -1
- package/compiled/src/step/indexing/step_type_indexer.js +67 -0
- package/compiled/src/step/parsing/byte_source.d.ts +153 -0
- package/compiled/src/step/parsing/byte_source.d.ts.map +1 -0
- package/compiled/src/step/parsing/byte_source.js +106 -0
- package/compiled/src/step/parsing/byte_source.test.d.ts +2 -0
- package/compiled/src/step/parsing/byte_source.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/byte_source.test.js +47 -0
- package/compiled/src/step/parsing/byte_source_node.d.ts +41 -0
- package/compiled/src/step/parsing/byte_source_node.d.ts.map +1 -0
- package/compiled/src/step/parsing/byte_source_node.js +54 -0
- package/compiled/src/step/parsing/columnar_index.d.ts +103 -0
- package/compiled/src/step/parsing/columnar_index.d.ts.map +1 -0
- package/compiled/src/step/parsing/columnar_index.js +224 -0
- package/compiled/src/step/parsing/columnar_index.test.d.ts +2 -0
- package/compiled/src/step/parsing/columnar_index.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/columnar_index.test.js +155 -0
- package/compiled/src/step/parsing/cross_reference_registry.d.ts +95 -0
- package/compiled/src/step/parsing/cross_reference_registry.d.ts.map +1 -0
- package/compiled/src/step/parsing/cross_reference_registry.js +91 -0
- package/compiled/src/step/parsing/cross_reference_registry.test.d.ts +2 -0
- package/compiled/src/step/parsing/cross_reference_registry.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/cross_reference_registry.test.js +66 -0
- package/compiled/src/step/parsing/decode_utf8.d.ts +15 -0
- package/compiled/src/step/parsing/decode_utf8.d.ts.map +1 -1
- package/compiled/src/step/parsing/decode_utf8.js +28 -0
- package/compiled/src/step/parsing/express_ref_scan.d.ts +20 -0
- package/compiled/src/step/parsing/express_ref_scan.d.ts.map +1 -0
- package/compiled/src/step/parsing/express_ref_scan.js +91 -0
- package/compiled/src/step/parsing/express_ref_scan.test.d.ts +2 -0
- package/compiled/src/step/parsing/express_ref_scan.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/express_ref_scan.test.js +28 -0
- package/compiled/src/step/parsing/index_sidecar.d.ts +81 -0
- package/compiled/src/step/parsing/index_sidecar.d.ts.map +1 -0
- package/compiled/src/step/parsing/index_sidecar.js +283 -0
- package/compiled/src/step/parsing/index_sidecar.test.d.ts +2 -0
- package/compiled/src/step/parsing/index_sidecar.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/index_sidecar.test.js +122 -0
- package/compiled/src/step/parsing/inf_recovery_index.test.d.ts +2 -0
- package/compiled/src/step/parsing/inf_recovery_index.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/inf_recovery_index.test.js +108 -0
- package/compiled/src/step/parsing/prefix_type_index.d.ts +124 -0
- package/compiled/src/step/parsing/prefix_type_index.d.ts.map +1 -0
- package/compiled/src/step/parsing/prefix_type_index.js +207 -0
- package/compiled/src/step/parsing/prefix_type_index.test.d.ts +2 -0
- package/compiled/src/step/parsing/prefix_type_index.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/prefix_type_index.test.js +298 -0
- package/compiled/src/step/parsing/range_byte_source.d.ts +69 -0
- package/compiled/src/step/parsing/range_byte_source.d.ts.map +1 -0
- package/compiled/src/step/parsing/range_byte_source.js +78 -0
- package/compiled/src/step/parsing/range_byte_source.test.d.ts +2 -0
- package/compiled/src/step/parsing/range_byte_source.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/range_byte_source.test.js +70 -0
- package/compiled/src/step/parsing/record_event.d.ts +23 -0
- package/compiled/src/step/parsing/record_event.d.ts.map +1 -0
- package/compiled/src/step/parsing/record_event.js +1 -0
- package/compiled/src/step/parsing/record_field_cursor.d.ts +94 -0
- package/compiled/src/step/parsing/record_field_cursor.d.ts.map +1 -0
- package/compiled/src/step/parsing/record_field_cursor.js +189 -0
- package/compiled/src/step/parsing/step_deserialization_functions.d.ts +29 -0
- package/compiled/src/step/parsing/step_deserialization_functions.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_deserialization_functions.js +45 -0
- package/compiled/src/step/parsing/step_deserialization_functions.test.js +59 -1
- package/compiled/src/step/parsing/step_parser.d.ts +66 -1
- package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
- package/compiled/src/step/parsing/step_parser.js +164 -10
- package/compiled/src/step/parsing/step_string_parser.js +8 -8
- package/compiled/src/step/parsing/streaming_index_builder.d.ts +141 -0
- package/compiled/src/step/parsing/streaming_index_builder.d.ts.map +1 -0
- package/compiled/src/step/parsing/streaming_index_builder.js +280 -0
- package/compiled/src/step/parsing/streaming_index_builder.test.d.ts +2 -0
- package/compiled/src/step/parsing/streaming_index_builder.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/streaming_index_builder.test.js +107 -0
- package/compiled/src/step/parsing/streaming_index_builder_async.test.d.ts +2 -0
- package/compiled/src/step/parsing/streaming_index_builder_async.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/streaming_index_builder_async.test.js +109 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.d.ts +71 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.d.ts.map +1 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.js +88 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.test.d.ts +2 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/streaming_record_dispatcher.test.js +66 -0
- package/compiled/src/step/parsing/uint32_sink.d.ts +72 -0
- package/compiled/src/step/parsing/uint32_sink.d.ts.map +1 -0
- package/compiled/src/step/parsing/uint32_sink.js +180 -0
- package/compiled/src/step/parsing/uint32_sink.test.d.ts +2 -0
- package/compiled/src/step/parsing/uint32_sink.test.d.ts.map +1 -0
- package/compiled/src/step/parsing/uint32_sink.test.js +199 -0
- package/compiled/src/step/step_buffer_provider.d.ts +48 -3
- package/compiled/src/step/step_buffer_provider.d.ts.map +1 -1
- package/compiled/src/step/step_buffer_provider.js +60 -11
- package/compiled/src/step/step_buffer_provider.test.js +14 -0
- package/compiled/src/step/step_entity_base.d.ts +65 -3
- package/compiled/src/step/step_entity_base.d.ts.map +1 -1
- package/compiled/src/step/step_entity_base.js +135 -3
- package/compiled/src/step/step_model_base.d.ts +221 -8
- package/compiled/src/step/step_model_base.d.ts.map +1 -1
- package/compiled/src/step/step_model_base.js +542 -7
- package/compiled/src/stream/index.d.ts +34 -0
- package/compiled/src/stream/index.d.ts.map +1 -0
- package/compiled/src/stream/index.js +32 -0
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -1
|
@@ -4,10 +4,110 @@ import { ObjectPool } from "../core/native_pool.js";
|
|
|
4
4
|
import { MemoizationCapture, RegressionCaptureState } from "../core/regression_capture_state.js";
|
|
5
5
|
import { ExtractResult } from "../core/shared_constants.js";
|
|
6
6
|
import Logger from "../logging/logger.js";
|
|
7
|
-
import {
|
|
7
|
+
import { arrayToWasmHeap, wasmHeapView } from "../core/wasm_heap.js";
|
|
8
|
+
import { advanced_brep_shape_representation, advanced_face, annotation_occurrence, axis2_placement_2d, axis2_placement_3d, b_spline_curve, b_spline_curve_with_knots, b_spline_surface, b_spline_surface_with_knots, boolean_result, cartesian_point, cartesian_transformation_operator_3d, circle, colour_rgb, composite_curve, composite_curve_segment, conical_surface, context_dependent_shape_representation, conversion_based_unit, curve, cylindrical_surface, draughting_model, edge_curve, edge_loop, ellipse, extruded_area_solid, face, face_based_surface_model, faceted_brep, fill_area_style_colour, geometric_curve_set, geometrically_bounded_2d_wireframe_representation, geometrically_bounded_wireframe_shape_representation, global_unit_assigned_context, half_space_solid, item_defined_transformation, length_unit, line, manifold_solid_brep, mapped_item, next_assembly_usage_occurrence, over_riding_styled_item, parameter_value, pcurve, placement, plane, poly_loop, polyline, pre_defined_colour, presentation_layer_assignment, product, product_definition, product_definition_shape, property_definition, rational_b_spline_curve, rational_b_spline_surface, representation_item, representation_relationship_with_transformation, shape_definition_representation, shape_representation, shape_representation_relationship, shell_based_surface_model, si_prefix, si_unit, spherical_surface, styled_item, surface_curve, surface_of_linear_extrusion, surface_of_revolution, surface_side, surface_style_fill_area, surface_style_rendering, surface_style_usage, toroidal_surface, trimmed_curve, trimming_preference, vertex_loop, vertex_point, view_volume, } from "./AP214E3_2010_gen/index.js";
|
|
8
9
|
import EntityTypesAP214 from "./AP214E3_2010_gen/entity_types_ap214.gen.js";
|
|
9
10
|
import { AP214ProductShapeMap } from "./ap214_product_shape_map.js";
|
|
10
11
|
import { AP214SceneBuilder } from "./ap214_scene_builder.js";
|
|
12
|
+
// Fewest points a bound can have and still span a plane, which is what
|
|
13
|
+
// GetBasisFromCoplanarPoints needs downstream.
|
|
14
|
+
const MINIMUM_BOUND_POINTS = 3;
|
|
15
|
+
// Ceiling on how finely one span of a pcurve's parameter curve is sampled
|
|
16
|
+
// when it is pushed through an angular surface parameterization. Nothing in
|
|
17
|
+
// STEP bounds how far a parameter curve may run in u or v - a helix wound a
|
|
18
|
+
// thousand times is a legal (if unusual) parameter-space line - and without a
|
|
19
|
+
// cap the sample count is a function of file content rather than of the
|
|
20
|
+
// extractor. At circleSegments density this is over twenty full turns of a
|
|
21
|
+
// single span - well past the point where the polyline is the limiting
|
|
22
|
+
// factor on any face it bounds.
|
|
23
|
+
const MAXIMUM_PCURVE_SPAN_SAMPLES = 256;
|
|
24
|
+
/**
|
|
25
|
+
* Whether an edge's vertices are the basis curve's own endpoints, making its
|
|
26
|
+
* trim a no-op that spans the whole curve.
|
|
27
|
+
*
|
|
28
|
+
* Only B-splines are considered. A LINE or CIRCLE has no endpoint entities to
|
|
29
|
+
* compare against — a circle is unbounded parametrically, and a line's trim is
|
|
30
|
+
* what gives it extent at all — so "whole curve" does not apply to them and
|
|
31
|
+
* their trims must be resolved.
|
|
32
|
+
*
|
|
33
|
+
* Compared by entity localID, not by coordinates: the file references the
|
|
34
|
+
* same CARTESIAN_POINT from both the control point list and the VERTEX_POINT,
|
|
35
|
+
* so this is exact and needs no tolerance.
|
|
36
|
+
*
|
|
37
|
+
* localID rather than object identity, deliberately. `===` looks equivalent
|
|
38
|
+
* and is not: getTypedElementByLocalID caches instances only while
|
|
39
|
+
* model.elementMemoization holds, and extraction turns it off for
|
|
40
|
+
* lowMemoryMode or a buffer over MEMOIZATION_THRESHOLD. StepModelBase says so
|
|
41
|
+
* outright — "it's not guaranteed element objects returned from this have
|
|
42
|
+
* referential equality even if they have ID equality". With `===` this guard
|
|
43
|
+
* would quietly stop firing on exactly the large models where a dropped face
|
|
44
|
+
* costs most.
|
|
45
|
+
*
|
|
46
|
+
* @param basisCurve The edge's underlying geometry.
|
|
47
|
+
* @param edgeStart The edge's start vertex.
|
|
48
|
+
* @param edgeEnd The edge's end vertex.
|
|
49
|
+
* @return {boolean} True when the edge covers the entire basis curve.
|
|
50
|
+
*/
|
|
51
|
+
function isWholeCurveEdge(basisCurve, edgeStart, edgeEnd) {
|
|
52
|
+
if (!(edgeStart instanceof vertex_point) ||
|
|
53
|
+
!(edgeEnd instanceof vertex_point)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
// An edge from a vertex back to ITSELF spans the whole of its basis curve:
|
|
57
|
+
// that is how STEP writes a closed edge, and trimming a circle by one point
|
|
58
|
+
// taken twice is how a torus's equator circles were resolving to a single
|
|
59
|
+
// point - which starved the revolution face of every angular sample it had
|
|
60
|
+
// and collapsed the swept surface flat (conway#461). The caller's gates make
|
|
61
|
+
// this safe for an open basis curve too: recovery only replaces the trimmed
|
|
62
|
+
// result when it was already degenerate AND the untrimmed extraction yields
|
|
63
|
+
// more points, and an identical-vertex edge over an open curve is degenerate
|
|
64
|
+
// whichever way it is read.
|
|
65
|
+
if (edgeStart.vertex_geometry.localID === edgeEnd.vertex_geometry.localID) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
if (!(basisCurve instanceof b_spline_curve)) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const controlPoints = basisCurve.control_points_list;
|
|
72
|
+
if (controlPoints.length < 2) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const first = controlPoints[0].localID;
|
|
76
|
+
const last = controlPoints[controlPoints.length - 1].localID;
|
|
77
|
+
const from = edgeStart.vertex_geometry.localID;
|
|
78
|
+
const to = edgeEnd.vertex_geometry.localID;
|
|
79
|
+
// Either orientation: same_sense is normalised separately, and an edge
|
|
80
|
+
// running end -> start still spans the whole curve. A closed curve whose
|
|
81
|
+
// first and last control points coincide also lands here, which is correct
|
|
82
|
+
// — that edge is the whole curve too.
|
|
83
|
+
return (from === first && to === last) || (from === last && to === first);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Render something thrown that is not an Error, for a log message.
|
|
87
|
+
*
|
|
88
|
+
* Interpolating a thrown value straight into a template string is how the
|
|
89
|
+
* public baseline ended up with 8 rows reading `[object Object]` — a message
|
|
90
|
+
* that names the face type and then says nothing about the failure. JSON
|
|
91
|
+
* first so a plain thrown object shows its fields; String() as the fallback
|
|
92
|
+
* for what JSON cannot take (cycles, BigInt, symbols).
|
|
93
|
+
*
|
|
94
|
+
* @param thrown The caught value, known not to be an Error.
|
|
95
|
+
* @return {string} A description with at least as much information as String().
|
|
96
|
+
*/
|
|
97
|
+
function describeThrown(thrown) {
|
|
98
|
+
try {
|
|
99
|
+
const asJson = JSON.stringify(thrown);
|
|
100
|
+
// undefined for a symbol or a bare undefined; "{}" for an object whose
|
|
101
|
+
// own properties are all non-enumerable, which is no better than String().
|
|
102
|
+
if (asJson !== void 0 && asJson !== "{}") {
|
|
103
|
+
return asJson;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Cyclic, BigInt, or a throwing toJSON - fall through.
|
|
108
|
+
}
|
|
109
|
+
return String(thrown);
|
|
110
|
+
}
|
|
11
111
|
/**
|
|
12
112
|
* Extract an AP214 Colour into our RGBA color, using premultiplied alpha.
|
|
13
113
|
*
|
|
@@ -21,6 +121,19 @@ import { AP214SceneBuilder } from "./ap214_scene_builder.js";
|
|
|
21
121
|
export function extractColorRGBPremultiplied(from, alpha = 1) {
|
|
22
122
|
return [from.red * alpha, from.green * alpha, from.blue * alpha, alpha];
|
|
23
123
|
}
|
|
124
|
+
// RGB values for the ISO 10303-46 pre-defined draughting colour names
|
|
125
|
+
// (draughting_pre_defined_colour / pre_defined_colour), which carry a name
|
|
126
|
+
// instead of components.
|
|
127
|
+
const PRE_DEFINED_COLOUR_RGB = {
|
|
128
|
+
"red": [1, 0, 0],
|
|
129
|
+
"green": [0, 1, 0],
|
|
130
|
+
"blue": [0, 0, 1],
|
|
131
|
+
"yellow": [1, 1, 0],
|
|
132
|
+
"magenta": [1, 0, 1],
|
|
133
|
+
"cyan": [0, 1, 1],
|
|
134
|
+
"black": [0, 0, 0],
|
|
135
|
+
"white": [1, 1, 1],
|
|
136
|
+
};
|
|
24
137
|
/**
|
|
25
138
|
* Extract an AP214 Colour into our RGBA color.
|
|
26
139
|
*
|
|
@@ -59,16 +172,6 @@ export function extractColorOrFactor(from, surfaceColor, alpha = 1) {
|
|
|
59
172
|
* Can export to OBJ, GLTF (Draco), GLB (Draco)
|
|
60
173
|
*/
|
|
61
174
|
export class AP214GeometryExtraction {
|
|
62
|
-
/**
|
|
63
|
-
* Construct a geometry extraction from an AP214 step model and conway model
|
|
64
|
-
*
|
|
65
|
-
* @param conwayModel
|
|
66
|
-
* @param model
|
|
67
|
-
* @param limitCSGDepth Whether to limit the depth of CSG operations.
|
|
68
|
-
* @param csgDepthLimit The maximum depth for CSG operations when limit CSG depth is used,
|
|
69
|
-
* or the maximum level for CSG memoization if it is not.
|
|
70
|
-
* @param lowMemoryMode Whether to enable low memory mode for geometry extraction.
|
|
71
|
-
*/
|
|
72
175
|
constructor(conwayModel, model, limitCSGDepth = true, csgDepthLimit = 20, lowMemoryMode = false) {
|
|
73
176
|
this.conwayModel = conwayModel;
|
|
74
177
|
this.model = model;
|
|
@@ -88,7 +191,9 @@ export class AP214GeometryExtraction {
|
|
|
88
191
|
* Statistics by the loader/proxies after extraction.
|
|
89
192
|
*/
|
|
90
193
|
this.geometryTypeCounts = new Map();
|
|
194
|
+
this.demandCursor_ = 0;
|
|
91
195
|
this.csgMemoization = !this.lowMemoryMode;
|
|
196
|
+
this.quietRecoverableLogging = false;
|
|
92
197
|
this.materials = model.materials;
|
|
93
198
|
this.scene = new AP214SceneBuilder(model, conwayModel, this.materials);
|
|
94
199
|
this.productShapeMap = new AP214ProductShapeMap();
|
|
@@ -508,14 +613,7 @@ export class AP214GeometryExtraction {
|
|
|
508
613
|
* @return {number} Pointer/memory address
|
|
509
614
|
*/
|
|
510
615
|
arrayToWasmHeap(array) {
|
|
511
|
-
|
|
512
|
-
const bytesPerElement = array.BYTES_PER_ELEMENT;
|
|
513
|
-
const numBytes = array.length * bytesPerElement;
|
|
514
|
-
const arrayPtr = this.wasmModule._malloc(numBytes);
|
|
515
|
-
// Create a new Uint8Array view on the Wasm memory buffer, then set the array to it
|
|
516
|
-
const arrayWasm = new Uint8Array(this.wasmModule.HEAPU8.buffer, arrayPtr, numBytes);
|
|
517
|
-
arrayWasm.set(new Uint8Array(array.buffer));
|
|
518
|
-
return arrayPtr;
|
|
616
|
+
return arrayToWasmHeap(this.wasmModule, array);
|
|
519
617
|
}
|
|
520
618
|
/**
|
|
521
619
|
* @param array
|
|
@@ -791,18 +889,39 @@ export class AP214GeometryExtraction {
|
|
|
791
889
|
const fillAreaColor = fillAreaStyles.find((value => value instanceof fill_area_style_colour));
|
|
792
890
|
if (fillAreaColor !== void 0) {
|
|
793
891
|
try {
|
|
794
|
-
|
|
795
|
-
|
|
892
|
+
// `fill_colour` is the schema's colour select, but AP214
|
|
893
|
+
// gives pre_defined_colour TWO supertypes (colour AND
|
|
894
|
+
// pre_defined_item) and the single-inheritance generator
|
|
895
|
+
// kept only pre_defined_item — so the typed getter throws
|
|
896
|
+
// "incorrectly typed" for e.g.
|
|
897
|
+
// DRAUGHTING_PRE_DEFINED_COLOUR('white') (Onshape exports).
|
|
898
|
+
// Re-extract the same field (offset 1) under the type the
|
|
899
|
+
// generator did keep, and map the name to RGB.
|
|
900
|
+
let surfaceColor;
|
|
901
|
+
let fillColor;
|
|
902
|
+
try {
|
|
903
|
+
fillColor = fillAreaColor.fill_colour;
|
|
904
|
+
}
|
|
905
|
+
catch {
|
|
906
|
+
const preDefined = fillAreaColor.extractElement(1, 0, 0, true, pre_defined_colour);
|
|
907
|
+
const rgb = PRE_DEFINED_COLOUR_RGB[preDefined?.name?.toLowerCase() ?? ""];
|
|
908
|
+
if (rgb !== void 0) {
|
|
909
|
+
surfaceColor = [rgb[0], rgb[1], rgb[2], 1];
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
if (fillColor instanceof colour_rgb) {
|
|
913
|
+
surfaceColor = extractColorRGBPremultiplied(fillColor, 1);
|
|
914
|
+
}
|
|
915
|
+
if (surfaceColor === void 0) {
|
|
796
916
|
continue;
|
|
797
917
|
}
|
|
798
|
-
const surfaceColor = extractColorRGBPremultiplied(fillColor, 1);
|
|
799
918
|
newMaterial.baseColor = surfaceColor;
|
|
800
919
|
newMaterial.legacyColor = surfaceColor;
|
|
801
920
|
newMaterial.roughness = 1;
|
|
802
921
|
}
|
|
803
922
|
catch (error) {
|
|
804
|
-
Logger.warning(`Error extracting fill area style color for expressID:
|
|
805
|
-
#${from.expressID} - type:
|
|
923
|
+
Logger.warning(`Error extracting fill area style color for expressID:
|
|
924
|
+
#${from.expressID} - type:
|
|
806
925
|
${EntityTypesAP214[style.type]} - error: ${error}`);
|
|
807
926
|
}
|
|
808
927
|
}
|
|
@@ -994,9 +1113,18 @@ export class AP214GeometryExtraction {
|
|
|
994
1113
|
*/
|
|
995
1114
|
extractCurve(from, parentSense = true, isEdge = false, trimmingArguments = void 0) {
|
|
996
1115
|
let stepCurve;
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1116
|
+
// Edge-supplied trims are specific to one EDGE_CURVE, but `from` is the
|
|
1117
|
+
// shared basis curve — memoising a trimmed extraction under the basis
|
|
1118
|
+
// curve's localID would hand the first edge's arc to every other edge
|
|
1119
|
+
// sharing that curve. Trimmed extractions are memoised by the caller
|
|
1120
|
+
// under the EDGE_CURVE's localID instead (see extractAdvancedFace);
|
|
1121
|
+
// untrimmed extractions stay memoised here.
|
|
1122
|
+
const hasEdgeTrims = trimmingArguments?.exist === true;
|
|
1123
|
+
if (!hasEdgeTrims) {
|
|
1124
|
+
stepCurve = this.curves.get(from.localID);
|
|
1125
|
+
if (stepCurve !== void 0) {
|
|
1126
|
+
return stepCurve;
|
|
1127
|
+
}
|
|
1000
1128
|
}
|
|
1001
1129
|
// console.log("[extractCurve]: curve express ID: "
|
|
1002
1130
|
// + from.expressID + " type: " + EntityTypesAP214[from.type])
|
|
@@ -1090,9 +1218,16 @@ export class AP214GeometryExtraction {
|
|
|
1090
1218
|
stepCurve = this.extractCurve(parentCurve, sameSense, isEdge);
|
|
1091
1219
|
}
|
|
1092
1220
|
else if (from instanceof pcurve) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1221
|
+
// An explicit 3D representation beats the parameter-space mapping where
|
|
1222
|
+
// one is carried, as it already does for surface_curve and seam_curve
|
|
1223
|
+
// reached in their own right. surface_curve rather than seam_curve:
|
|
1224
|
+
// seam_curve and intersection_curve are both its subtypes and all three
|
|
1225
|
+
// carry curve_3d, so this is the same preference over the whole family
|
|
1226
|
+
// (bldrs-ai/conway#505).
|
|
1227
|
+
const surfaceCurve = from.findVariant(surface_curve);
|
|
1228
|
+
if (surfaceCurve !== void 0) {
|
|
1229
|
+
stepCurve =
|
|
1230
|
+
this.extractCurve(surfaceCurve.curve_3d, parentSense, isEdge, trimmingArguments);
|
|
1096
1231
|
}
|
|
1097
1232
|
else {
|
|
1098
1233
|
stepCurve = this.extractPScurve1(from);
|
|
@@ -1102,7 +1237,9 @@ export class AP214GeometryExtraction {
|
|
|
1102
1237
|
Logger.warning(`Unsupported Curve! Type: ${EntityTypesAP214[from.type]}`);
|
|
1103
1238
|
return;
|
|
1104
1239
|
}
|
|
1105
|
-
|
|
1240
|
+
if (!hasEdgeTrims) {
|
|
1241
|
+
this.curves.add(from.localID, stepCurve);
|
|
1242
|
+
}
|
|
1106
1243
|
return stepCurve;
|
|
1107
1244
|
}
|
|
1108
1245
|
/**
|
|
@@ -1150,36 +1287,232 @@ export class AP214GeometryExtraction {
|
|
|
1150
1287
|
return compositeCurve;
|
|
1151
1288
|
}
|
|
1152
1289
|
/**
|
|
1290
|
+
* The ISO 10303-42 parameterization of an elementary basis surface,
|
|
1291
|
+
* expressed in that surface's placement-local frame. Writing C for the
|
|
1292
|
+
* placement's origin, x/y/z for its axes, R (and r) for the radii and a for
|
|
1293
|
+
* conical_surface.semi_angle, the standard's forms are
|
|
1294
|
+
*
|
|
1295
|
+
* plane s(u,v) = C + u x + v y
|
|
1296
|
+
* cylindrical s(u,v) = C + R((cos u) x + (sin u) y) + v z
|
|
1297
|
+
* conical s(u,v) = C + (R + v tan a)((cos u) x + (sin u) y) + v z
|
|
1298
|
+
* spherical s(u,v) = C + R cos v ((cos u) x + (sin u) y) + R sin v z
|
|
1299
|
+
* toroidal s(u,v) = C + (R + r cos v)((cos u) x + (sin u) y)
|
|
1300
|
+
* + r sin v z
|
|
1301
|
+
*
|
|
1302
|
+
* Note v on a sphere is a LATITUDE in [-90, 90] degrees, not a polar angle,
|
|
1303
|
+
* and v on a torus runs around the tube. Those four are quoted here from the
|
|
1304
|
+
* entities IFC adopted verbatim from this part - IfcPlane,
|
|
1305
|
+
* IfcCylindricalSurface, IfcSphericalSurface and IfcToroidalSurface, each
|
|
1306
|
+
* carrying its equation under "Definition according to ISO/CD 10303-42" plus
|
|
1307
|
+
* "Entity adapted from <name> defined in ISO 10303-42".
|
|
1308
|
+
*
|
|
1309
|
+
* The cone is the one worth stating explicitly, because it is the arm a
|
|
1310
|
+
* review of this code read the other way (bldrs-ai/conway#520): its v is
|
|
1311
|
+
* distance along the AXIS, so the radius grows by tan a per unit v - not
|
|
1312
|
+
* distance along the generator, which would grow it by sin a. Two STEP readers
|
|
1313
|
+
* settle it the same way. Open CASCADE parameterizes its own
|
|
1314
|
+
* Geom_ConicalSurface along the generator, P(u,v) = O + (R + v sin a)(...)
|
|
1315
|
+
* + v cos a z, and therefore rescales v by 1/cos(a) coming in from STEP and
|
|
1316
|
+
* by cos(a) going back out - GeomConvert_Units::DegreeToRadian and
|
|
1317
|
+
* ::RadianToDegree, which is exactly the path its STEP reader pushes pcurves
|
|
1318
|
+
* through (StepToTopoDS_TranslateEdge::MakePCurve). truck's STEP reader
|
|
1319
|
+
* builds the cone by revolving the line (R,0,0) + t (tan a, 0, 1), which is
|
|
1320
|
+
* the form above with t = v.
|
|
1321
|
+
*
|
|
1322
|
+
* conway-geom tessellates the same surfaces by inverting these formulae:
|
|
1323
|
+
* TriangulateCylindricalSurface, TriangulateSphericalSurface,
|
|
1324
|
+
* TriangulateConicalSurface and TriangulateToroidalSurface (conway-geom
|
|
1325
|
+
* `conway_geometry/operations/mesh_utils.h`) recover (theta, height) or
|
|
1326
|
+
* (theta, latitude) from world points, so a pcurve mapped here lands on the
|
|
1327
|
+
* same surface the face it bounds is triangulated on. It differs in one
|
|
1328
|
+
* deliberate way, on the cone's sign - see that arm.
|
|
1329
|
+
*
|
|
1330
|
+
* Angular parameters are radians taken straight from the file. Conway
|
|
1331
|
+
* applies no plane-angle unit conversion anywhere on the STEP path -
|
|
1332
|
+
* conical_surface.semi_angle reaches conway-geom raw in
|
|
1333
|
+
* extractConicalSurface - so a degree-unit export is wrong here in exactly
|
|
1334
|
+
* the same way, and consistently so.
|
|
1335
|
+
*
|
|
1336
|
+
* @param from The basis surface.
|
|
1337
|
+
* @return {SurfaceParameterization | undefined} The parameterization, or
|
|
1338
|
+
* undefined for a surface that has none here (b-spline and swept surfaces).
|
|
1339
|
+
*/
|
|
1340
|
+
surfaceParameterization(from) {
|
|
1341
|
+
if (from instanceof plane) {
|
|
1342
|
+
// The one non-angular case: (u, v) are distances along the placement's
|
|
1343
|
+
// x and y axes.
|
|
1344
|
+
return {
|
|
1345
|
+
position: from.position,
|
|
1346
|
+
evaluate: (u, v) => ({ x: u, y: v, z: 0 }),
|
|
1347
|
+
angularU: false,
|
|
1348
|
+
angularV: false,
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
if (from instanceof cylindrical_surface) {
|
|
1352
|
+
const radius = from.radius;
|
|
1353
|
+
return {
|
|
1354
|
+
position: from.position,
|
|
1355
|
+
evaluate: (u, v) => ({ x: radius * Math.cos(u), y: radius * Math.sin(u), z: v }),
|
|
1356
|
+
angularU: true,
|
|
1357
|
+
angularV: false,
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
if (from instanceof conical_surface) {
|
|
1361
|
+
const radius = from.radius;
|
|
1362
|
+
// tan, not sin, because v is axial distance rather than distance along
|
|
1363
|
+
// the generator - see the equations in this method's doc comment.
|
|
1364
|
+
//
|
|
1365
|
+
// Signed, unlike the native tesselator's tan(fabs(semi_angle)): that
|
|
1366
|
+
// one fits its generator line from boundary samples and only needs the
|
|
1367
|
+
// taper's magnitude, whereas the 2D curve here was authored against the
|
|
1368
|
+
// spec's parameterization, where the radius grows with v by the SIGNED
|
|
1369
|
+
// taper and a narrowing cone runs the other way.
|
|
1370
|
+
const taper = Math.tan(from.semi_angle);
|
|
1371
|
+
return {
|
|
1372
|
+
position: from.position,
|
|
1373
|
+
evaluate: (u, v) => {
|
|
1374
|
+
const ring = radius + (v * taper);
|
|
1375
|
+
return { x: ring * Math.cos(u), y: ring * Math.sin(u), z: v };
|
|
1376
|
+
},
|
|
1377
|
+
angularU: true,
|
|
1378
|
+
angularV: false,
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
if (from instanceof spherical_surface) {
|
|
1382
|
+
const radius = from.radius;
|
|
1383
|
+
return {
|
|
1384
|
+
position: from.position,
|
|
1385
|
+
evaluate: (u, v) => {
|
|
1386
|
+
const ring = radius * Math.cos(v);
|
|
1387
|
+
return {
|
|
1388
|
+
x: ring * Math.cos(u),
|
|
1389
|
+
y: ring * Math.sin(u),
|
|
1390
|
+
z: radius * Math.sin(v),
|
|
1391
|
+
};
|
|
1392
|
+
},
|
|
1393
|
+
angularU: true,
|
|
1394
|
+
angularV: true,
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
// Covers degenerate_toroidal_surface, which is a subtype and shares the
|
|
1398
|
+
// parameterization (it only restricts the range v is meaningful over).
|
|
1399
|
+
if (from instanceof toroidal_surface) {
|
|
1400
|
+
const majorRadius = from.major_radius;
|
|
1401
|
+
const minorRadius = from.minor_radius;
|
|
1402
|
+
return {
|
|
1403
|
+
position: from.position,
|
|
1404
|
+
evaluate: (u, v) => {
|
|
1405
|
+
const ring = majorRadius + (minorRadius * Math.cos(v));
|
|
1406
|
+
return {
|
|
1407
|
+
x: ring * Math.cos(u),
|
|
1408
|
+
y: ring * Math.sin(u),
|
|
1409
|
+
z: minorRadius * Math.sin(v),
|
|
1410
|
+
};
|
|
1411
|
+
},
|
|
1412
|
+
angularU: true,
|
|
1413
|
+
angularV: true,
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
return void 0;
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Extract a pcurve: a curve given in the parameter space of a basis surface
|
|
1420
|
+
* (ISO 10303-42). The parameter curve is extracted through the ordinary
|
|
1421
|
+
* curve path and its (u, v) samples are pushed through the basis surface's
|
|
1422
|
+
* parameterization, giving the 3D polyline every other arm of extractCurve
|
|
1423
|
+
* hands back.
|
|
1153
1424
|
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1425
|
+
* Extent comes from the parameter curve itself: a bounded one (polyline,
|
|
1426
|
+
* b-spline, trimmed or composite curve) carries its own, and an unbounded
|
|
1427
|
+
* 2D LINE or CIRCLE gets whatever the ordinary line/circle extraction gives
|
|
1428
|
+
* it. An EDGE_CURVE's vertex trims are 3D and are deliberately NOT inverted
|
|
1429
|
+
* back into parameter space here, so an edge whose parameter curve is an
|
|
1430
|
+
* unbounded LINE comes out at that line's own extent rather than the edge's
|
|
1431
|
+
* - see https://github.com/bldrs-ai/conway/issues/505.
|
|
1432
|
+
*
|
|
1433
|
+
* @param from The pcurve to extract.
|
|
1434
|
+
* @return {CurveObject | undefined} The mapped 3D curve, or undefined where
|
|
1435
|
+
* the basis surface has no parameterization here or the parameter curve
|
|
1436
|
+
* yields no points. Both are warned about naming the type responsible, so
|
|
1437
|
+
* the residue is measurable per surface family rather than as one row.
|
|
1156
1438
|
*/
|
|
1157
1439
|
extractPScurve1(from) {
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1160
|
-
|
|
1440
|
+
const basisSurface = from.basis_surface;
|
|
1441
|
+
const parameterization = this.surfaceParameterization(basisSurface);
|
|
1442
|
+
if (parameterization === void 0) {
|
|
1443
|
+
Logger.warning("Unsupported PCURVE basis surface, type: " +
|
|
1444
|
+
`${EntityTypesAP214[basisSurface.type]}`, from.expressID);
|
|
1161
1445
|
return;
|
|
1162
1446
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
// pointsFlattened[ 3 ] = point[ 0 ] + ( dir[ 0 ] * mag )
|
|
1171
|
-
// pointsFlattened[ 4 ] = point[ 1 ] + ( dir[ 1 ] * mag )
|
|
1172
|
-
// pointsFlattened[ 5 ] = point[ 2 ] + ( dir[ 2 ] * mag )
|
|
1447
|
+
// ISO 10303-42 constrains reference_to_curve to a single curve item in a
|
|
1448
|
+
// 2D parametric context, but the field is a general representation, so
|
|
1449
|
+
// the curve is searched for rather than indexed blindly.
|
|
1450
|
+
const parameterCurveItem = from.reference_to_curve.items.find((item) => item instanceof curve);
|
|
1451
|
+
if (parameterCurveItem === void 0) {
|
|
1452
|
+
Logger.warning("PCURVE reference_to_curve carries no curve item", from.expressID);
|
|
1453
|
+
return;
|
|
1173
1454
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1455
|
+
const parameterCurve = this.extractCurve(parameterCurveItem);
|
|
1456
|
+
const parameterCount = parameterCurve?.getPointsSize() ?? 0;
|
|
1457
|
+
if (parameterCurve === void 0 || parameterCount === 0) {
|
|
1458
|
+
// extractCurve has already warned under the parameter curve's own type.
|
|
1459
|
+
return;
|
|
1177
1460
|
}
|
|
1461
|
+
// The frame is built by the same native call the surface side uses
|
|
1462
|
+
// (extractCylindricalSurface and friends), so the pcurve is orthonormalised
|
|
1463
|
+
// identically to the surface it lies on rather than by a second, subtly
|
|
1464
|
+
// different implementation here.
|
|
1465
|
+
const placement = this.conwayModel.getAxis2Placement3D(this.extractAxis2Placement3D(parameterization.position, basisSurface.localID, true));
|
|
1466
|
+
const transform = placement.getValues();
|
|
1467
|
+
// Sample density for angular parameters: the same knob the ellipse path
|
|
1468
|
+
// uses, so a mapped arc is tessellated like every other arc conway emits.
|
|
1469
|
+
const angularStep = (2 * Math.PI) / this.circleSegments;
|
|
1470
|
+
const localPoints = [];
|
|
1471
|
+
let previous = parameterCurve.get2d(0);
|
|
1472
|
+
localPoints.push(parameterization.evaluate(previous.x, previous.y));
|
|
1473
|
+
for (let index = 1; index < parameterCount; ++index) {
|
|
1474
|
+
const current = parameterCurve.get2d(index);
|
|
1475
|
+
const deltaU = current.x - previous.x;
|
|
1476
|
+
const deltaV = current.y - previous.y;
|
|
1477
|
+
// A straight run in an angular parameter is an arc in space, so a span
|
|
1478
|
+
// that covers real angle is subdivided rather than chorded across.
|
|
1479
|
+
let samples = 1;
|
|
1480
|
+
if (parameterization.angularU) {
|
|
1481
|
+
samples = Math.max(samples, Math.ceil(Math.abs(deltaU) / angularStep));
|
|
1482
|
+
}
|
|
1483
|
+
if (parameterization.angularV) {
|
|
1484
|
+
samples = Math.max(samples, Math.ceil(Math.abs(deltaV) / angularStep));
|
|
1485
|
+
}
|
|
1486
|
+
samples = Math.min(samples, MAXIMUM_PCURVE_SPAN_SAMPLES);
|
|
1487
|
+
for (let sample = 1; sample <= samples; ++sample) {
|
|
1488
|
+
const ratio = sample / samples;
|
|
1489
|
+
localPoints.push(parameterization.evaluate(previous.x + (deltaU * ratio), previous.y + (deltaV * ratio)));
|
|
1490
|
+
}
|
|
1491
|
+
previous = current;
|
|
1492
|
+
}
|
|
1493
|
+
// Column-major Glmdmat4: basis columns at 0, 4, 8, translation at 12.
|
|
1494
|
+
const pointsFlattened = new Float64Array(localPoints.length * this.THREE_DIMENSIONS);
|
|
1495
|
+
let offset = 0;
|
|
1496
|
+
for (const localPoint of localPoints) {
|
|
1497
|
+
pointsFlattened[offset] =
|
|
1498
|
+
(transform[0] * localPoint.x) + (transform[4] * localPoint.y) +
|
|
1499
|
+
(transform[8] * localPoint.z) + transform[12];
|
|
1500
|
+
pointsFlattened[offset + 1] =
|
|
1501
|
+
(transform[1] * localPoint.x) + (transform[5] * localPoint.y) +
|
|
1502
|
+
(transform[9] * localPoint.z) + transform[13];
|
|
1503
|
+
pointsFlattened[offset + 2] =
|
|
1504
|
+
(transform[2] * localPoint.x) + (transform[6] * localPoint.y) +
|
|
1505
|
+
(transform[10] * localPoint.z) + transform[14];
|
|
1506
|
+
offset += this.THREE_DIMENSIONS;
|
|
1507
|
+
}
|
|
1508
|
+
placement.delete();
|
|
1178
1509
|
const pointsPtr = this.arrayToWasmHeap(pointsFlattened);
|
|
1179
1510
|
const parameters = this.paramsGetPolyCurvePool.acquire();
|
|
1180
1511
|
parameters.points = pointsPtr;
|
|
1181
|
-
parameters.pointsLength =
|
|
1182
|
-
parameters.dimensions =
|
|
1512
|
+
parameters.pointsLength = localPoints.length;
|
|
1513
|
+
parameters.dimensions = this.THREE_DIMENSIONS;
|
|
1514
|
+
parameters.senseAgreement = true;
|
|
1515
|
+
parameters.isEdge = false;
|
|
1183
1516
|
const curve_ = this.conwayModel.getPolyCurve(parameters);
|
|
1184
1517
|
this.paramsGetPolyCurvePool.release(parameters);
|
|
1185
1518
|
this.wasmModule._free(pointsPtr);
|
|
@@ -1576,15 +1909,20 @@ export class AP214GeometryExtraction {
|
|
|
1576
1909
|
return void 0;
|
|
1577
1910
|
}
|
|
1578
1911
|
/**
|
|
1579
|
-
* Efficiently flatten the points into a
|
|
1912
|
+
* Efficiently flatten the points into a Float64Array.
|
|
1913
|
+
*
|
|
1914
|
+
* Float64 because getPolyCurve, the only consumer, reinterprets the buffer
|
|
1915
|
+
* as `const double *`: Float32 elements decode there as unrelated numbers
|
|
1916
|
+
* (and read twice as many bytes as were written). Matches the IFC side's
|
|
1917
|
+
* helper of the same name.
|
|
1580
1918
|
*
|
|
1581
1919
|
* @param points - Array of AP214CartesianPoint
|
|
1582
1920
|
* @param dimensions - dimensions of points
|
|
1583
|
-
* @return {
|
|
1921
|
+
* @return {Float64Array}
|
|
1584
1922
|
*/
|
|
1585
|
-
|
|
1923
|
+
flattenPointsToFloat64Array(points, dimensions) {
|
|
1586
1924
|
const totalCoordinates = points.length * dimensions;
|
|
1587
|
-
const flatCoordinates = new
|
|
1925
|
+
const flatCoordinates = new Float64Array(totalCoordinates);
|
|
1588
1926
|
let offset = 0;
|
|
1589
1927
|
points.forEach((point) => {
|
|
1590
1928
|
flatCoordinates.set(point.coordinates, offset);
|
|
@@ -1604,7 +1942,7 @@ export class AP214GeometryExtraction {
|
|
|
1604
1942
|
const pointsLength = points.length;
|
|
1605
1943
|
const dim = pointsLength > 0 ? points[0].coordinates.length : this.THREE_DIMENSIONS;
|
|
1606
1944
|
if (pointsLength > 0) {
|
|
1607
|
-
const pointsFlattened = this.
|
|
1945
|
+
const pointsFlattened = this.flattenPointsToFloat64Array(points, dim);
|
|
1608
1946
|
const pointsPtr = this.arrayToWasmHeap(pointsFlattened);
|
|
1609
1947
|
const parameters = this.paramsGetPolyCurvePool.acquire();
|
|
1610
1948
|
parameters.points = pointsPtr;
|
|
@@ -1925,7 +2263,12 @@ export class AP214GeometryExtraction {
|
|
|
1925
2263
|
Logger.error(`Error extracting face ${EntityTypesAP214[face_.type]} - ${error.message}\t\n${error.stack} - expressID: #${face_.expressID}`);
|
|
1926
2264
|
}
|
|
1927
2265
|
else {
|
|
1928
|
-
|
|
2266
|
+
// A non-Error throw interpolates as "[object Object]" in a template
|
|
2267
|
+
// string, which is what 8 occurrences in the public baseline
|
|
2268
|
+
// actually say - the message names the face type and nothing else.
|
|
2269
|
+
// JSON first so a plain thrown object shows its fields; String() as
|
|
2270
|
+
// the fallback for what JSON cannot take (cycles, BigInt, symbols).
|
|
2271
|
+
Logger.error(`Error extracting face ${EntityTypesAP214[face_.type]} - ${describeThrown(error)} - expressID: #${face_.expressID}`);
|
|
1929
2272
|
}
|
|
1930
2273
|
}
|
|
1931
2274
|
}
|
|
@@ -2085,6 +2428,11 @@ export class AP214GeometryExtraction {
|
|
|
2085
2428
|
}
|
|
2086
2429
|
const conwayModel = this.conwayModel;
|
|
2087
2430
|
const bound3DVector = this.nativeBound3DVector();
|
|
2431
|
+
// Loop curves are collected before bound creation so the outer-bound
|
|
2432
|
+
// heuristic below can compare their extents across the whole face.
|
|
2433
|
+
const loopCurves = [];
|
|
2434
|
+
const loopIsOuter = [];
|
|
2435
|
+
const loopOrientations = [];
|
|
2088
2436
|
for (const bound of bounds) {
|
|
2089
2437
|
let vec3Array;
|
|
2090
2438
|
const innerBound = bound.bound;
|
|
@@ -2160,14 +2508,97 @@ export class AP214GeometryExtraction {
|
|
|
2160
2508
|
};
|
|
2161
2509
|
}
|
|
2162
2510
|
}
|
|
2511
|
+
// EDGE_CURVE.same_sense: does the edge's start→end direction agree
|
|
2512
|
+
// with the basis curve's parametrisation? For same_sense=false the
|
|
2513
|
+
// edge sweeps from edge_start to edge_end AGAINST the curve
|
|
2514
|
+
// parameter. The native circle/ellipse trim (getAP214Circle) always
|
|
2515
|
+
// sweeps the positive parametric arc from trim1 to trim2 (its
|
|
2516
|
+
// senseAgreement=false path mis-negates the sweep), so ignoring
|
|
2517
|
+
// same_sense selects the COMPLEMENT arc — e.g. Onshape AP242
|
|
2518
|
+
// exports write near-straight edges as shallow arcs of large
|
|
2519
|
+
// circles, and the complement is a ~340° loop that explodes the
|
|
2520
|
+
// face boundary (Right_Hand.step spikes; the CDT "Intersecting
|
|
2521
|
+
// constraint edges" cascade). Normalise instead of forwarding the
|
|
2522
|
+
// flag: swap the trim ends so the positive sweep is the correct
|
|
2523
|
+
// arc, leaving the extracted (memoised) curve running edge_end →
|
|
2524
|
+
// edge_start; the orientation check below compensates.
|
|
2525
|
+
const sameSense = edgeElement.same_sense;
|
|
2163
2526
|
const trimmingArguments = {
|
|
2164
2527
|
exist: !!((trimmingStart !== void 0 && trimmingEnd !== void 0)),
|
|
2165
|
-
start: trimmingStart,
|
|
2166
|
-
end: trimmingEnd,
|
|
2528
|
+
start: sameSense ? trimmingStart : trimmingEnd,
|
|
2529
|
+
end: sameSense ? trimmingEnd : trimmingStart,
|
|
2167
2530
|
};
|
|
2168
|
-
|
|
2531
|
+
// Trimmed extractions are memoised under THIS edge's localID —
|
|
2532
|
+
// not the basis curve's — so edges sharing one basis curve with
|
|
2533
|
+
// different trims each get their own arc, while the second
|
|
2534
|
+
// ORIENTED_EDGE user of this edge (the adjacent face) still
|
|
2535
|
+
// reuses the extraction. extractCurve skips its basis-curve
|
|
2536
|
+
// memo whenever edge trims exist (see hasEdgeTrims there); the
|
|
2537
|
+
// shared this.curves container keeps ownership either way.
|
|
2538
|
+
let curve = this.curves.get(edgeElement.localID);
|
|
2539
|
+
if (curve === void 0) {
|
|
2540
|
+
curve = this.extractCurve(edgeCurve, true, true, trimmingArguments);
|
|
2541
|
+
// An edge whose vertices ARE the basis curve's own endpoints
|
|
2542
|
+
// spans the whole curve, so its trim carries no information —
|
|
2543
|
+
// and on some B-splines resolving it anyway comes back as just
|
|
2544
|
+
// the two endpoints. When such edges form a face's outer loop
|
|
2545
|
+
// the loop is collinear by construction, GetBasisFromCoplanarPoints
|
|
2546
|
+
// finds no basis, and TriangulateBounds discards the ENTIRE face,
|
|
2547
|
+
// eleven good 47-point inner bounds along with it (two edges on
|
|
2548
|
+
// nist_ctc_02_asme1_rc.stp, bldrs-ai/conway#492).
|
|
2549
|
+
//
|
|
2550
|
+
// Deliberately gated on the result being degenerate rather than
|
|
2551
|
+
// on the trim being a no-op. Most whole-curve trims resolve
|
|
2552
|
+
// correctly — 33 of 35 on that model — and bypassing those too
|
|
2553
|
+
// would re-route working edges onto a different extraction and
|
|
2554
|
+
// memoisation path for no reason, which is churn masquerading as
|
|
2555
|
+
// a fix. This only fires where the current path has already
|
|
2556
|
+
// failed, so an edge that works keeps its exact output.
|
|
2557
|
+
if (curve !== void 0 &&
|
|
2558
|
+
curve.getPointsSize() < MINIMUM_BOUND_POINTS &&
|
|
2559
|
+
isWholeCurveEdge(edgeCurve, edgeStart, edgeEnd)) {
|
|
2560
|
+
// extractCurve memoises an untrimmed extraction under the
|
|
2561
|
+
// BASIS curve's localID and owns it there.
|
|
2562
|
+
const untrimmed = this.extractCurve(edgeCurve, true, true, { exist: false, start: void 0, end: void 0 });
|
|
2563
|
+
const recovered = untrimmed !== void 0 &&
|
|
2564
|
+
untrimmed.getPointsSize() > curve.getPointsSize();
|
|
2565
|
+
if (recovered) {
|
|
2566
|
+
// Only now is the trimmed result known to be a defect rather
|
|
2567
|
+
// than the curve's honest shape - a degree-1 B-spline over
|
|
2568
|
+
// two control points really is two points, trimmed or not,
|
|
2569
|
+
// and warning about those would be the false-row noise the
|
|
2570
|
+
// comment further down argues against.
|
|
2571
|
+
Logger.warning(`Whole-curve trim on edge #${edgeElement.expressID} ` +
|
|
2572
|
+
`(${EntityTypesAP214[edgeCurve.type]}) resolved to ` +
|
|
2573
|
+
`${curve.getPointsSize()} point(s); recovered ` +
|
|
2574
|
+
`${untrimmed.getPointsSize()} untrimmed.`);
|
|
2575
|
+
// The trimmed CurveObject is being dropped, and nothing else
|
|
2576
|
+
// holds it: it was never added to this.curves, so without
|
|
2577
|
+
// this its native allocation is unreachable.
|
|
2578
|
+
curve.delete();
|
|
2579
|
+
curve = untrimmed;
|
|
2580
|
+
}
|
|
2581
|
+
// Memoise under the edge either way. The adjacent face's
|
|
2582
|
+
// ORIENTED_EDGE shares this edge, and without the entry it
|
|
2583
|
+
// re-runs the whole native trim extraction, re-warns, and
|
|
2584
|
+
// leaks a second trimmed curve.
|
|
2585
|
+
if (curve !== void 0 && trimmingArguments.exist) {
|
|
2586
|
+
this.curves.add(edgeElement.localID, curve);
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
else if (curve !== void 0 && trimmingArguments.exist) {
|
|
2590
|
+
this.curves.add(edgeElement.localID, curve);
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2169
2593
|
if (curve !== void 0) {
|
|
2170
|
-
|
|
2594
|
+
// The memoised curve runs edge_start→edge_end when same_sense
|
|
2595
|
+
// held, edge_end→edge_start when the trims were swapped above
|
|
2596
|
+
// (and, for untrimmed basis curves like full B-splines, native
|
|
2597
|
+
// point order is parametric order — reversed relative to the
|
|
2598
|
+
// edge exactly when same_sense is false). Traversal for this
|
|
2599
|
+
// ORIENTED_EDGE must run with `orientation`, so invert on the
|
|
2600
|
+
// XOR of the two flags rather than orientation alone.
|
|
2601
|
+
if (edge.orientation !== sameSense) {
|
|
2171
2602
|
// reverse curve
|
|
2172
2603
|
// Logger.info("edge orientation == true, inverting curve")
|
|
2173
2604
|
const invertedCurve = curve.clone();
|
|
@@ -2224,9 +2655,13 @@ export class AP214GeometryExtraction {
|
|
|
2224
2655
|
}
|
|
2225
2656
|
else {
|
|
2226
2657
|
Logger.warning(`Unsupported bound ${bound.bound}`);
|
|
2227
|
-
// Free this iteration's edge-curve vector
|
|
2228
|
-
//
|
|
2658
|
+
// Free this iteration's edge-curve vector, previously collected
|
|
2659
|
+
// loop curves and the face's partial bound vector before bailing
|
|
2660
|
+
// out, or they leak per bad face.
|
|
2229
2661
|
nativeEdgeCurves.delete();
|
|
2662
|
+
for (const loopCurve of loopCurves) {
|
|
2663
|
+
loopCurve.delete();
|
|
2664
|
+
}
|
|
2230
2665
|
bound3DVector.delete();
|
|
2231
2666
|
return;
|
|
2232
2667
|
}
|
|
@@ -2236,11 +2671,67 @@ export class AP214GeometryExtraction {
|
|
|
2236
2671
|
};
|
|
2237
2672
|
// Logger.info("isEdgeLoop: " + (isEdgeLoop) ? "TRUE" : "FALSE")
|
|
2238
2673
|
const curve = this.conwayModel.getLoop(parameters);
|
|
2239
|
-
//
|
|
2674
|
+
// No general "bound has fewer than 3 points" check here, deliberately.
|
|
2675
|
+
// It looks like the obvious backstop for the #479 family and it is not:
|
|
2676
|
+
// a VERTEX_LOOP is one point and zero edges BY DESIGN - the degenerate
|
|
2677
|
+
// loop at a sphere pole or cone apex - and it is legitimate input that
|
|
2678
|
+
// conway is expected to handle (bldrs-ai/conway#461). Measured on the
|
|
2679
|
+
// smoke subset, such a check fires 50 times across Right_Hand.step and
|
|
2680
|
+
// nist_ctc_01_asme1_rd.stp, and every one of those is a valid
|
|
2681
|
+
// VERTEX_LOOP or single-edge closed loop. Reporting them would put 50
|
|
2682
|
+
// false "the face will be dropped" rows into the blessed baseline, which
|
|
2683
|
+
// is the noise problem in #478 rather than a fix for it.
|
|
2684
|
+
//
|
|
2685
|
+
// The known real cause is handled above, where it IS distinguishable
|
|
2686
|
+
// from legitimate input.
|
|
2687
|
+
loopCurves.push(curve);
|
|
2688
|
+
loopIsOuter.push(bound.type === EntityTypesAP214.FACE_OUTER_BOUND);
|
|
2689
|
+
loopOrientations.push(bound.orientation);
|
|
2690
|
+
vec3Array.delete();
|
|
2691
|
+
nativeEdgeCurves.delete();
|
|
2692
|
+
}
|
|
2693
|
+
// STEP allows a face's loops to all be plain FACE_BOUNDs; without a
|
|
2694
|
+
// FACE_OUTER_BOUND the native triangulators would warn ("Expected outer
|
|
2695
|
+
// bound, using fallback tesselation") and treat loops[0] as outer, which
|
|
2696
|
+
// is only right by luck (Onshape AP242 exports order hole loops first on
|
|
2697
|
+
// some faces). A face's outer loop strictly contains its holes, so tag
|
|
2698
|
+
// the loop with the largest bounding-box diagonal as the outer one.
|
|
2699
|
+
if (loopCurves.length > 1 && !loopIsOuter.includes(true)) {
|
|
2700
|
+
let largestIndex = 0;
|
|
2701
|
+
let largestDiagonal2 = -1;
|
|
2702
|
+
for (let loopIndex = 0; loopIndex < loopCurves.length; ++loopIndex) {
|
|
2703
|
+
const loopCurve = loopCurves[loopIndex];
|
|
2704
|
+
const pointCount = loopCurve.getPointsSize();
|
|
2705
|
+
let minX = Infinity;
|
|
2706
|
+
let minY = Infinity;
|
|
2707
|
+
let minZ = Infinity;
|
|
2708
|
+
let maxX = -Infinity;
|
|
2709
|
+
let maxY = -Infinity;
|
|
2710
|
+
let maxZ = -Infinity;
|
|
2711
|
+
for (let where = 0; where < pointCount; ++where) {
|
|
2712
|
+
const point = loopCurve.get3d(where);
|
|
2713
|
+
minX = Math.min(minX, point.x);
|
|
2714
|
+
minY = Math.min(minY, point.y);
|
|
2715
|
+
minZ = Math.min(minZ, point.z);
|
|
2716
|
+
maxX = Math.max(maxX, point.x);
|
|
2717
|
+
maxY = Math.max(maxY, point.y);
|
|
2718
|
+
maxZ = Math.max(maxZ, point.z);
|
|
2719
|
+
}
|
|
2720
|
+
const diagonal2 = ((maxX - minX) * (maxX - minX)) +
|
|
2721
|
+
((maxY - minY) * (maxY - minY)) +
|
|
2722
|
+
((maxZ - minZ) * (maxZ - minZ));
|
|
2723
|
+
if (pointCount > 0 && diagonal2 > largestDiagonal2) {
|
|
2724
|
+
largestDiagonal2 = diagonal2;
|
|
2725
|
+
largestIndex = loopIndex;
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
loopIsOuter[largestIndex] = true;
|
|
2729
|
+
}
|
|
2730
|
+
for (let loopIndex = 0; loopIndex < loopCurves.length; ++loopIndex) {
|
|
2240
2731
|
const parametersCreateBounds3D = {
|
|
2241
|
-
curve:
|
|
2242
|
-
orientation:
|
|
2243
|
-
type:
|
|
2732
|
+
curve: loopCurves[loopIndex],
|
|
2733
|
+
orientation: loopOrientations[loopIndex],
|
|
2734
|
+
type: loopIsOuter[loopIndex] ? 0 : 1,
|
|
2244
2735
|
};
|
|
2245
2736
|
const bound3D = this.conwayModel.createBound3D(parametersCreateBounds3D);
|
|
2246
2737
|
bound3DVector.push_back(bound3D);
|
|
@@ -2248,15 +2739,19 @@ export class AP214GeometryExtraction {
|
|
|
2248
2739
|
// bound wrapper are temporaries that must be freed to avoid leaking
|
|
2249
2740
|
// native memory on every face bound.
|
|
2250
2741
|
bound3D.delete();
|
|
2251
|
-
|
|
2252
|
-
vec3Array.delete();
|
|
2253
|
-
nativeEdgeCurves.delete();
|
|
2742
|
+
loopCurves[loopIndex].delete();
|
|
2254
2743
|
}
|
|
2255
2744
|
const surface = from.face_geometry;
|
|
2256
2745
|
// add face to geometry
|
|
2257
2746
|
const nativeSurface = (new (this.wasmModule.IfcSurface));
|
|
2258
2747
|
this.extractSurface(surface, nativeSurface);
|
|
2259
2748
|
nativeSurface.sameSense = from.same_sense;
|
|
2749
|
+
// Declares the flag above as real, so the tessellator may orient the
|
|
2750
|
+
// face against the surface normal. Extractors that leave this false
|
|
2751
|
+
// (the IFC path today) keep the older projection-based orientation
|
|
2752
|
+
// rather than having a default-constructed sense read as an answer.
|
|
2753
|
+
// See https://github.com/bldrs-ai/conway/issues/459.
|
|
2754
|
+
nativeSurface.sameSenseKnown = true;
|
|
2260
2755
|
const parameters = {
|
|
2261
2756
|
boundsArray: bound3DVector,
|
|
2262
2757
|
advancedBrep: true,
|
|
@@ -2346,11 +2841,24 @@ export class AP214GeometryExtraction {
|
|
|
2346
2841
|
* @param nativeSurface
|
|
2347
2842
|
*/
|
|
2348
2843
|
extractSurfaceOfLinearExtrusion(from, nativeSurface) {
|
|
2349
|
-
|
|
2350
|
-
|
|
2844
|
+
// AP214's swept_curve is a bare curve, not a profile_def, so it goes
|
|
2845
|
+
// through extractCurve + createNativeIfcProfile like the revolution
|
|
2846
|
+
// path does. extractProfile() never fills nativeProfile for bare
|
|
2847
|
+
// curves, which silently dropped every linear-extrusion face (1,370
|
|
2848
|
+
// faces on the Jetenginestep compressor shaft alone).
|
|
2849
|
+
const nativeCurve = this.extractCurve(from.swept_curve);
|
|
2850
|
+
if (nativeCurve === void 0) {
|
|
2351
2851
|
Logger.warning("Couldn't get curve profile for linear extrusion surface");
|
|
2352
2852
|
return;
|
|
2353
2853
|
}
|
|
2854
|
+
const parameters = {
|
|
2855
|
+
curve: nativeCurve,
|
|
2856
|
+
holes: this.nativeVectorCurve(),
|
|
2857
|
+
isConvex: false,
|
|
2858
|
+
isComposite: false,
|
|
2859
|
+
profiles: this.nativeVectorProfile(),
|
|
2860
|
+
};
|
|
2861
|
+
const nativeProfile = this.conwayModel.createNativeIfcProfile(parameters);
|
|
2354
2862
|
const extrusionAxis = from.extrusion_axis;
|
|
2355
2863
|
const depth = extrusionAxis.magnitude;
|
|
2356
2864
|
const directionCoords = extrusionAxis.orientation.direction_ratios;
|
|
@@ -2362,7 +2870,7 @@ export class AP214GeometryExtraction {
|
|
|
2362
2870
|
y: directionCoords[1],
|
|
2363
2871
|
z: directionCoords[2],
|
|
2364
2872
|
},
|
|
2365
|
-
profile:
|
|
2873
|
+
profile: nativeProfile,
|
|
2366
2874
|
};
|
|
2367
2875
|
}
|
|
2368
2876
|
/**
|
|
@@ -2473,9 +2981,13 @@ export class AP214GeometryExtraction {
|
|
|
2473
2981
|
pointer = this.wasmModule._malloc(numBytes);
|
|
2474
2982
|
capacity = maxPossibleFloats;
|
|
2475
2983
|
}
|
|
2476
|
-
// 2) Create a Float64Array view into WASM memory
|
|
2477
|
-
//
|
|
2478
|
-
|
|
2984
|
+
// 2) Create a Float64Array view into WASM memory, over the heap as it is
|
|
2985
|
+
// after the _malloc above rather than over whatever view the module had
|
|
2986
|
+
// cached before it - see wasm_heap.ts for why those can differ. Built
|
|
2987
|
+
// rather than subarray'd off HEAPF64 for the same reason: subarray clamps
|
|
2988
|
+
// an out-of-range window into a short one, and the set() loop below would
|
|
2989
|
+
// then quietly write somewhere other than the allocation (#485).
|
|
2990
|
+
const wasmFloat64View = wasmHeapView(this.wasmModule, Float64Array, pointer, capacity);
|
|
2479
2991
|
// 3) Single pass to skip consecutive duplicates, fill up the wasm array
|
|
2480
2992
|
let offset = 0;
|
|
2481
2993
|
let prevLocalID = -1;
|
|
@@ -2792,6 +3304,38 @@ export class AP214GeometryExtraction {
|
|
|
2792
3304
|
result.setValues(v);
|
|
2793
3305
|
return result;
|
|
2794
3306
|
}
|
|
3307
|
+
/**
|
|
3308
|
+
* The root transform taking a shape representation's own length unit
|
|
3309
|
+
* into conway's world space.
|
|
3310
|
+
*
|
|
3311
|
+
* World space is METRES. That convention is set by the IFC path, which
|
|
3312
|
+
* folds `linearScalingFactor` — metres per file unit — into its
|
|
3313
|
+
* coordination matrix (`compat/web-ifc/coordination_f64.ts`). STEP
|
|
3314
|
+
* geometry is emitted in raw file coordinates instead, so the
|
|
3315
|
+
* whole-model unit conversion has to ride on this root transform.
|
|
3316
|
+
*
|
|
3317
|
+
* The factor is therefore metres-per-file-unit itself: a millimetre
|
|
3318
|
+
* file scales by 1e-3. It is NOT the reciprocal — using `1 / unitInM`
|
|
3319
|
+
* put every millimetre STEP model into world space 1e6x too large,
|
|
3320
|
+
* and 1e6x out of step with any IFC model federated beside it. That
|
|
3321
|
+
* went unseen because Share frames the camera from the model's own
|
|
3322
|
+
* bounds, which absorbs a uniform scale error, and because the
|
|
3323
|
+
* regression digests hash geometry in file coordinates, which this
|
|
3324
|
+
* transform never touches.
|
|
3325
|
+
* See https://github.com/bldrs-ai/conway/issues/458.
|
|
3326
|
+
*
|
|
3327
|
+
* @param shapeRepresentation The representation whose unit context to read.
|
|
3328
|
+
* @return The scale transform, or undefined if no length unit is declared.
|
|
3329
|
+
*/
|
|
3330
|
+
rootUnitScaleTransform(shapeRepresentation) {
|
|
3331
|
+
const sourceShapeContext = shapeRepresentation.context_of_items.findVariant(global_unit_assigned_context)?.units?.
|
|
3332
|
+
find((unit) => unit.findVariant(length_unit))?.findVariant(length_unit);
|
|
3333
|
+
if (sourceShapeContext === void 0) {
|
|
3334
|
+
return void 0;
|
|
3335
|
+
}
|
|
3336
|
+
const sourceUnitInM = this.convertToMetres(sourceShapeContext) ?? 1;
|
|
3337
|
+
return this.uniformScaleAffine(this.identity3DNativeMatrix, sourceUnitInM);
|
|
3338
|
+
}
|
|
2795
3339
|
/**
|
|
2796
3340
|
*
|
|
2797
3341
|
*/
|
|
@@ -2809,7 +3353,14 @@ export class AP214GeometryExtraction {
|
|
|
2809
3353
|
}
|
|
2810
3354
|
}
|
|
2811
3355
|
catch (error) {
|
|
2812
|
-
|
|
3356
|
+
if (!this.quietRecoverableLogging) {
|
|
3357
|
+
// toString(), not localID: localID is the dense internal index and
|
|
3358
|
+
// means nothing against the source file, and these land in the
|
|
3359
|
+
// regression run's `expressids` column where the whole point is to
|
|
3360
|
+
// be able to go look at the record. It also spells the inline case
|
|
3361
|
+
// honestly rather than passing off an index as a reference.
|
|
3362
|
+
Logger.error(`Error populating styled item map: ${error}`, styledItem.toString());
|
|
3363
|
+
}
|
|
2813
3364
|
}
|
|
2814
3365
|
}
|
|
2815
3366
|
for (const overridingStyledItem of overridingStyledItems) {
|
|
@@ -2819,7 +3370,9 @@ export class AP214GeometryExtraction {
|
|
|
2819
3370
|
}
|
|
2820
3371
|
}
|
|
2821
3372
|
catch (error) {
|
|
2822
|
-
|
|
3373
|
+
if (!this.quietRecoverableLogging) {
|
|
3374
|
+
Logger.error(`Error populating overriding styled item map: ${error}`, overridingStyledItem.toString());
|
|
3375
|
+
}
|
|
2823
3376
|
}
|
|
2824
3377
|
}
|
|
2825
3378
|
}
|
|
@@ -2902,16 +3455,27 @@ export class AP214GeometryExtraction {
|
|
|
2902
3455
|
* @return {[ExtractResult, AP214SceneBuilder]} - Enum indicating extraction result
|
|
2903
3456
|
* + Geometry array
|
|
2904
3457
|
*/
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
3458
|
+
/**
|
|
3459
|
+
* Prepare per-unit demand extraction (STEP demand parity phase 2)
|
|
3460
|
+
* without executing any geometry work: builds the assembly tree and
|
|
3461
|
+
* thunks exactly like the whole-model walk, but the root executions
|
|
3462
|
+
* are captured as an ordered list of UNITS — a childless root is one
|
|
3463
|
+
* unit; a root with children is flattened one level (one unit per
|
|
3464
|
+
* immediate child, in order, then one for the root's own items), so
|
|
3465
|
+
* single-root assemblies still pump progressively per part. Executing
|
|
3466
|
+
* every unit in order then calling {@link finishDemandExtraction}
|
|
3467
|
+
* reproduces the whole-model walk exactly — the classic
|
|
3468
|
+
* {@link extractAP214GeometryData} runs through this same path.
|
|
3469
|
+
* Idempotent.
|
|
3470
|
+
*/
|
|
3471
|
+
// eslint-disable-next-line max-lines-per-function
|
|
3472
|
+
prepareDemandExtraction() {
|
|
3473
|
+
if (this.demandUnits_ !== void 0) {
|
|
3474
|
+
return;
|
|
3475
|
+
}
|
|
2912
3476
|
const model = this.model;
|
|
2913
3477
|
const treeMap = new Map();
|
|
2914
|
-
const makeThunk = (representation, owningElementLocalID, mappedTreeNode) => {
|
|
3478
|
+
const makeThunk = (representation, owningElementLocalID, mappedTreeNode, slice) => {
|
|
2915
3479
|
return (owningLocalID, parentTransform) => {
|
|
2916
3480
|
owningLocalID ??= owningElementLocalID;
|
|
2917
3481
|
const mappedItem = mappedTreeNode !== void 0 || parentTransform !== void 0;
|
|
@@ -2920,8 +3484,12 @@ export class AP214GeometryExtraction {
|
|
|
2920
3484
|
if (parentTransform !== void 0) {
|
|
2921
3485
|
this.scene.addTransform(representation.localID, parentTransform.getValues(), parentTransform, true);
|
|
2922
3486
|
}
|
|
2923
|
-
if (mappedTreeNode?.children !== void 0
|
|
2924
|
-
|
|
3487
|
+
if (mappedTreeNode?.children !== void 0 &&
|
|
3488
|
+
(slice === void 0 || slice.childStart !== slice.childEnd)) {
|
|
3489
|
+
const sliceChildren = slice !== void 0 ?
|
|
3490
|
+
mappedTreeNode.children.slice(slice.childStart, slice.childEnd) :
|
|
3491
|
+
mappedTreeNode.children;
|
|
3492
|
+
for (const [childLocalID, childOwningLocalID, childTransform] of sliceChildren) {
|
|
2925
3493
|
const mappedChild = treeMap.get(childLocalID);
|
|
2926
3494
|
const enterChildStackDepth = this.scene.stackLength;
|
|
2927
3495
|
const enterChildParent = this.scene.currentParent;
|
|
@@ -2955,7 +3523,10 @@ export class AP214GeometryExtraction {
|
|
|
2955
3523
|
mappedChild.thunk(childOwningLocalID, childTransform);
|
|
2956
3524
|
}
|
|
2957
3525
|
catch (ex) {
|
|
2958
|
-
if (
|
|
3526
|
+
if (this.quietRecoverableLogging) {
|
|
3527
|
+
// Preview prefix: dangling children are expected — skip quietly.
|
|
3528
|
+
}
|
|
3529
|
+
else if (ex instanceof Error) {
|
|
2959
3530
|
Logger.error(`Error processing child shape_representation: \n\t${ex.name}\n\t${ex.message}\n\texpressID: #${this.model.getExpressIDByLocalID(childLocalID)}`);
|
|
2960
3531
|
}
|
|
2961
3532
|
else {
|
|
@@ -2966,12 +3537,14 @@ export class AP214GeometryExtraction {
|
|
|
2966
3537
|
while (this.scene.stackLength > enterChildStackDepth) {
|
|
2967
3538
|
this.scene.popTransform();
|
|
2968
3539
|
}
|
|
2969
|
-
if (this.scene.stackLength !== enterChildStackDepth ||
|
|
3540
|
+
if ((this.scene.stackLength !== enterChildStackDepth ||
|
|
3541
|
+
this.scene.currentParent !== enterChildParent) && !this.quietRecoverableLogging) {
|
|
2970
3542
|
Logger.error(`Stack length mismatch after processing child shape_representation ${this.scene.currentParent} ${enterChildParent} expressID: #${representation.expressID}`);
|
|
2971
3543
|
}
|
|
2972
3544
|
}
|
|
2973
3545
|
}
|
|
2974
|
-
|
|
3546
|
+
const includeItems = slice?.includeItems ?? true;
|
|
3547
|
+
for (const item of includeItems ? representation.items : []) {
|
|
2975
3548
|
try {
|
|
2976
3549
|
if (item instanceof placement) {
|
|
2977
3550
|
this.extractPlacement(item, mappedItem);
|
|
@@ -2995,7 +3568,12 @@ export class AP214GeometryExtraction {
|
|
|
2995
3568
|
}
|
|
2996
3569
|
catch (ex) {
|
|
2997
3570
|
if (ex instanceof Error) {
|
|
2998
|
-
|
|
3571
|
+
// Stack included for the same reason extractFaces includes it:
|
|
3572
|
+
// this family's message is the same string for every occurrence
|
|
3573
|
+
// ("Value in select must be populated" accounts for all 274 in
|
|
3574
|
+
// the NIST AP242 set), so without a stack there is nothing to
|
|
3575
|
+
// tell one occurrence from another or say WHICH select failed.
|
|
3576
|
+
Logger.error(`Error processing representation item: \n\t${ex.name}\n\t${ex.message}\n\t${ex.stack}\n\texpressID: #${item.expressID}`);
|
|
2999
3577
|
}
|
|
3000
3578
|
else {
|
|
3001
3579
|
Logger.error(`Unknown exception processing representation item (${ex}) expressID: #${item.expressID}`);
|
|
@@ -3005,16 +3583,25 @@ export class AP214GeometryExtraction {
|
|
|
3005
3583
|
while (this.scene.stackLength > entryTransformDepth) {
|
|
3006
3584
|
this.scene.popTransform();
|
|
3007
3585
|
}
|
|
3008
|
-
if (this.scene.stackLength !== entryTransformDepth ||
|
|
3586
|
+
if ((this.scene.stackLength !== entryTransformDepth ||
|
|
3587
|
+
this.scene.currentParent !== currentParent) && !this.quietRecoverableLogging) {
|
|
3009
3588
|
Logger.error(`Stack length mismatch after processing shape_representation ${this.scene.currentParent} ${currentParent} expressID: #${representation.expressID}`);
|
|
3010
3589
|
}
|
|
3011
3590
|
};
|
|
3012
3591
|
};
|
|
3013
|
-
|
|
3592
|
+
// Roots the whole-model walk would execute, in execution order —
|
|
3593
|
+
// expanded into units at the end of preparation (children arrays
|
|
3594
|
+
// are final only once every edge loop has run).
|
|
3595
|
+
const pendingRoots = [];
|
|
3596
|
+
{
|
|
3014
3597
|
this.scene.clearParentStack();
|
|
3015
3598
|
// 256 meg limit for memoization - smaller models get a big
|
|
3016
3599
|
// win from memoization, but much larger models it uses far too much heap.
|
|
3017
3600
|
const MEMOIZATION_THRESHOLD = 256 * 1024 * 1024;
|
|
3601
|
+
// Remembered for finishDemandExtraction / the classic wrapper's
|
|
3602
|
+
// finally — the pump spans many calls, so restoration cannot live
|
|
3603
|
+
// in a single method's finally anymore.
|
|
3604
|
+
this.demandMemoizationRestore_ = this.model.elementMemoization;
|
|
3018
3605
|
if (this.lowMemoryMode || model.bufferBytesize > MEMOIZATION_THRESHOLD) {
|
|
3019
3606
|
this.model.elementMemoization = false;
|
|
3020
3607
|
}
|
|
@@ -3040,9 +3627,21 @@ export class AP214GeometryExtraction {
|
|
|
3040
3627
|
}
|
|
3041
3628
|
}
|
|
3042
3629
|
for (const contextDependentShapeRepresentation of contextDependentShapeRepresentations) {
|
|
3043
|
-
|
|
3630
|
+
// Per-record containment: reference getters throw on
|
|
3631
|
+
// malformed/dangling records (a mid-parse PREFIX model — the
|
|
3632
|
+
// preview channel's snapshots — always has a truncated tail).
|
|
3633
|
+
// One bad edge record skips, it must not abort the whole
|
|
3634
|
+
// preparation.
|
|
3635
|
+
let assembly;
|
|
3636
|
+
let shapeRelationship;
|
|
3637
|
+
try {
|
|
3638
|
+
assembly = contextDependentShapeRepresentation.represented_product_relation;
|
|
3639
|
+
shapeRelationship = contextDependentShapeRepresentation.representation_relation;
|
|
3640
|
+
}
|
|
3641
|
+
catch {
|
|
3642
|
+
continue;
|
|
3643
|
+
}
|
|
3044
3644
|
const owningLocalID = assembly.localID;
|
|
3045
|
-
const shapeRelationship = contextDependentShapeRepresentation.representation_relation;
|
|
3046
3645
|
shapeRepresentationRelationshipsSeen.add(shapeRelationship.localID);
|
|
3047
3646
|
/* Exporters disagree on the rep_1/rep_2 order of an assembly
|
|
3048
3647
|
* placement relationship: as1-style files write (child, parent),
|
|
@@ -3056,8 +3655,15 @@ export class AP214GeometryExtraction {
|
|
|
3056
3655
|
* SDR-bound product definition against them, and keep the legacy
|
|
3057
3656
|
* (child, parent) reading when the match is ambiguous/unresolvable.
|
|
3058
3657
|
*/
|
|
3059
|
-
let sourceShape
|
|
3060
|
-
let targetShape
|
|
3658
|
+
let sourceShape;
|
|
3659
|
+
let targetShape;
|
|
3660
|
+
try {
|
|
3661
|
+
sourceShape = shapeRelationship.rep_1;
|
|
3662
|
+
targetShape = shapeRelationship.rep_2;
|
|
3663
|
+
}
|
|
3664
|
+
catch {
|
|
3665
|
+
continue;
|
|
3666
|
+
}
|
|
3061
3667
|
let orientationFlipped = false;
|
|
3062
3668
|
try {
|
|
3063
3669
|
const nauo = assembly.definition;
|
|
@@ -3078,7 +3684,15 @@ export class AP214GeometryExtraction {
|
|
|
3078
3684
|
catch {
|
|
3079
3685
|
// Malformed NAUO/PDS reference — keep the legacy orientation.
|
|
3080
3686
|
}
|
|
3081
|
-
|
|
3687
|
+
let transform;
|
|
3688
|
+
let isContinue;
|
|
3689
|
+
try {
|
|
3690
|
+
[transform, isContinue] = this.doTransforms(shapeRelationship, sourceShape, targetShape, owningLocalID, orientationFlipped);
|
|
3691
|
+
}
|
|
3692
|
+
catch {
|
|
3693
|
+
// Malformed transform record (prefix truncation) — skip the edge.
|
|
3694
|
+
continue;
|
|
3695
|
+
}
|
|
3082
3696
|
if (isContinue) {
|
|
3083
3697
|
continue;
|
|
3084
3698
|
}
|
|
@@ -3089,6 +3703,8 @@ export class AP214GeometryExtraction {
|
|
|
3089
3703
|
sourceNode = { parents: 1 };
|
|
3090
3704
|
treeMap.set(sourceID, sourceNode);
|
|
3091
3705
|
sourceNode.thunk = makeThunk(sourceShape, owningLocalID, sourceNode);
|
|
3706
|
+
sourceNode.rep = sourceShape;
|
|
3707
|
+
sourceNode.owningLocalID = owningLocalID;
|
|
3092
3708
|
}
|
|
3093
3709
|
else {
|
|
3094
3710
|
sourceNode.parents ??= 0;
|
|
@@ -3117,9 +3733,21 @@ export class AP214GeometryExtraction {
|
|
|
3117
3733
|
* source and rep_2 is the target, whereas in
|
|
3118
3734
|
* context_dependent_shape_representation, the relationship is inverted.
|
|
3119
3735
|
*/
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3736
|
+
let sourceShape;
|
|
3737
|
+
let targetShape;
|
|
3738
|
+
let transform;
|
|
3739
|
+
let isContinue;
|
|
3740
|
+
try {
|
|
3741
|
+
sourceShape = shapeRelationship.rep_2;
|
|
3742
|
+
targetShape = shapeRelationship.rep_1;
|
|
3743
|
+
[transform, isContinue] =
|
|
3744
|
+
this.doTransforms(shapeRelationship, sourceShape, targetShape, owningLocalID);
|
|
3745
|
+
}
|
|
3746
|
+
catch {
|
|
3747
|
+
// Malformed relationship/transform record (prefix truncation)
|
|
3748
|
+
// — skip the edge.
|
|
3749
|
+
continue;
|
|
3750
|
+
}
|
|
3123
3751
|
if (isContinue) {
|
|
3124
3752
|
continue;
|
|
3125
3753
|
}
|
|
@@ -3135,6 +3763,8 @@ export class AP214GeometryExtraction {
|
|
|
3135
3763
|
++sourceNode.parents;
|
|
3136
3764
|
}
|
|
3137
3765
|
sourceNode.thunk = makeThunk(sourceShape, owningLocalID, sourceNode);
|
|
3766
|
+
sourceNode.rep = sourceShape;
|
|
3767
|
+
sourceNode.owningLocalID = owningLocalID;
|
|
3138
3768
|
let targetNode = treeMap.get(targetID);
|
|
3139
3769
|
if (targetNode === void 0) {
|
|
3140
3770
|
targetNode = { parents: 0, children: [[sourceID, owningLocalID, transform]] };
|
|
@@ -3147,12 +3777,20 @@ export class AP214GeometryExtraction {
|
|
|
3147
3777
|
}
|
|
3148
3778
|
const shapeDefinitions = model.types(shape_definition_representation);
|
|
3149
3779
|
for (const shapeDefinitionRepresentation of shapeDefinitions) {
|
|
3150
|
-
|
|
3151
|
-
|
|
3780
|
+
let shapeRepresentation;
|
|
3781
|
+
let definition;
|
|
3782
|
+
try {
|
|
3783
|
+
shapeRepresentation = shapeDefinitionRepresentation.used_representation;
|
|
3784
|
+
if (!(shapeRepresentation instanceof shape_representation)) {
|
|
3785
|
+
continue;
|
|
3786
|
+
}
|
|
3787
|
+
definition = shapeDefinitionRepresentation.definition;
|
|
3788
|
+
}
|
|
3789
|
+
catch {
|
|
3790
|
+
// Malformed SDR record (prefix truncation) — skip it.
|
|
3152
3791
|
continue;
|
|
3153
3792
|
}
|
|
3154
3793
|
//this.scene.clearParentStack()
|
|
3155
|
-
const definition = shapeDefinitionRepresentation.definition;
|
|
3156
3794
|
const owningElementLocalID = definition.localID;
|
|
3157
3795
|
let treeNode = treeMap.get(shapeRepresentation.localID);
|
|
3158
3796
|
const hasMappedNode = treeNode !== void 0;
|
|
@@ -3166,18 +3804,26 @@ export class AP214GeometryExtraction {
|
|
|
3166
3804
|
const mappedTreeNode = treeNode;
|
|
3167
3805
|
const thunk = makeThunk(shapeRepresentation, owningElementLocalID, mappedTreeNode);
|
|
3168
3806
|
mappedTreeNode.thunk = thunk;
|
|
3807
|
+
mappedTreeNode.rep = shapeRepresentation;
|
|
3808
|
+
mappedTreeNode.owningLocalID = owningElementLocalID;
|
|
3169
3809
|
if (!hasMappedNode) {
|
|
3170
3810
|
mappedTreeNode.processed = true;
|
|
3171
|
-
const sourceShapeContext = shapeRepresentation.context_of_items.findVariant(global_unit_assigned_context)?.units?.
|
|
3172
|
-
find(unit => unit.findVariant(length_unit))?.findVariant(length_unit);
|
|
3173
3811
|
let scaleTransform = void 0;
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3812
|
+
try {
|
|
3813
|
+
scaleTransform = this.rootUnitScaleTransform(shapeRepresentation);
|
|
3814
|
+
}
|
|
3815
|
+
catch {
|
|
3816
|
+
// Malformed unit context (prefix truncation) — no unit scale.
|
|
3817
|
+
scaleTransform = void 0;
|
|
3178
3818
|
}
|
|
3179
|
-
// not an assembly mapped item
|
|
3180
|
-
|
|
3819
|
+
// not an assembly mapped item — capture as a pending root
|
|
3820
|
+
// instead of executing inline (these nodes are childless by
|
|
3821
|
+
// construction: they were absent from the tree before this
|
|
3822
|
+
// loop, and all edges were added by the earlier loops).
|
|
3823
|
+
pendingRoots.push({
|
|
3824
|
+
node: mappedTreeNode,
|
|
3825
|
+
scaleTransform,
|
|
3826
|
+
});
|
|
3181
3827
|
continue;
|
|
3182
3828
|
}
|
|
3183
3829
|
}
|
|
@@ -3195,45 +3841,168 @@ export class AP214GeometryExtraction {
|
|
|
3195
3841
|
const mappedTreeNode = treeNode;
|
|
3196
3842
|
const owningElementLocalID = shapeRepresentation.localID;
|
|
3197
3843
|
mappedTreeNode.thunk = makeThunk(shapeRepresentation, owningElementLocalID, mappedTreeNode);
|
|
3844
|
+
mappedTreeNode.rep = shapeRepresentation;
|
|
3845
|
+
mappedTreeNode.owningLocalID = owningElementLocalID;
|
|
3198
3846
|
}
|
|
3199
|
-
// All thunks are set
|
|
3200
|
-
//
|
|
3847
|
+
// All thunks are set — capture remaining assembly-tree roots as
|
|
3848
|
+
// pending roots in the exact order the whole-model walk executed
|
|
3849
|
+
// them.
|
|
3201
3850
|
for (const [sourceID, mappedNode] of treeMap.entries()) {
|
|
3202
3851
|
if ((mappedNode.parents ?? 0) === 0 && mappedNode.thunk !== void 0 && mappedNode.processed !== true) {
|
|
3203
|
-
//this.scene.clearParentStack()
|
|
3204
|
-
const shapeRepresentation = this.model.getTypedElementByLocalID(sourceID, shape_representation);
|
|
3205
|
-
const sourceShapeContext = shapeRepresentation.context_of_items.findVariant(global_unit_assigned_context)?.units?.
|
|
3206
|
-
find(unit => unit.findVariant(length_unit))?.findVariant(length_unit);
|
|
3207
3852
|
let scaleTransform = void 0;
|
|
3208
|
-
|
|
3209
|
-
const
|
|
3210
|
-
scaleTransform =
|
|
3211
|
-
|
|
3853
|
+
try {
|
|
3854
|
+
const shapeRepresentation = this.model.getTypedElementByLocalID(sourceID, shape_representation);
|
|
3855
|
+
scaleTransform = this.rootUnitScaleTransform(shapeRepresentation);
|
|
3856
|
+
}
|
|
3857
|
+
catch {
|
|
3858
|
+
// Malformed unit context (prefix truncation) — no unit scale.
|
|
3859
|
+
scaleTransform = void 0;
|
|
3212
3860
|
}
|
|
3213
|
-
|
|
3214
|
-
mappedNode.thunk(void 0, scaleTransform);
|
|
3861
|
+
pendingRoots.push({ node: mappedNode, scaleTransform });
|
|
3215
3862
|
}
|
|
3216
3863
|
}
|
|
3217
|
-
//
|
|
3218
|
-
//
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3864
|
+
// Expand pending roots into ordered execution units: childless
|
|
3865
|
+
// roots run their original thunk whole; roots with children are
|
|
3866
|
+
// flattened one level — one unit per immediate child (in order),
|
|
3867
|
+
// then one for the root's own representation items, matching the
|
|
3868
|
+
// thunk body's children-then-items order exactly.
|
|
3869
|
+
const units = [];
|
|
3870
|
+
for (const root of pendingRoots) {
|
|
3871
|
+
const node = root.node;
|
|
3872
|
+
const scaleTransform = root.scaleTransform;
|
|
3873
|
+
const childCount = node.children?.length ?? 0;
|
|
3874
|
+
if (childCount === 0 || node.rep === void 0) {
|
|
3875
|
+
units.push(() => node.thunk(void 0, scaleTransform));
|
|
3876
|
+
continue;
|
|
3877
|
+
}
|
|
3878
|
+
for (let child = 0; child < childCount; ++child) {
|
|
3879
|
+
const sliced = makeThunk(node.rep, node.owningLocalID, node, { childStart: child, childEnd: child + 1, includeItems: false });
|
|
3880
|
+
units.push(() => sliced(void 0, scaleTransform));
|
|
3881
|
+
}
|
|
3882
|
+
const itemsOnly = makeThunk(node.rep, node.owningLocalID, node, { childStart: 0, childEnd: 0, includeItems: true });
|
|
3883
|
+
units.push(() => itemsOnly(void 0, scaleTransform));
|
|
3884
|
+
}
|
|
3885
|
+
this.demandUnits_ = units;
|
|
3886
|
+
}
|
|
3887
|
+
}
|
|
3888
|
+
/**
|
|
3889
|
+
* Total demand units (see prepareDemandExtraction).
|
|
3890
|
+
*
|
|
3891
|
+
* @return {number} The unit count (0 before preparation).
|
|
3892
|
+
*/
|
|
3893
|
+
get demandUnitCount() {
|
|
3894
|
+
return this.demandUnits_?.length ?? 0;
|
|
3895
|
+
}
|
|
3896
|
+
/**
|
|
3897
|
+
* Units already executed by extractDemandUnitBatch.
|
|
3898
|
+
*
|
|
3899
|
+
* @return {number} The cursor.
|
|
3900
|
+
*/
|
|
3901
|
+
get demandUnitCursor() {
|
|
3902
|
+
return this.demandCursor_;
|
|
3903
|
+
}
|
|
3904
|
+
/**
|
|
3905
|
+
* Advance the unit cursor WITHOUT executing (parse-time preview
|
|
3906
|
+
* generations resume a global ordinal on a fresh prefix extraction —
|
|
3907
|
+
* earlier units were already emitted from earlier generations).
|
|
3908
|
+
*
|
|
3909
|
+
* @param count Units to skip.
|
|
3910
|
+
*/
|
|
3911
|
+
skipDemandUnits(count) {
|
|
3912
|
+
const units = this.demandUnits_;
|
|
3913
|
+
if (units === void 0) {
|
|
3914
|
+
return;
|
|
3915
|
+
}
|
|
3916
|
+
this.demandCursor_ = Math.min(this.demandCursor_ + Math.max(count, 0), units.length);
|
|
3917
|
+
}
|
|
3918
|
+
/**
|
|
3919
|
+
* Execute the next `count` demand units (STEP demand parity phase 2)
|
|
3920
|
+
* — the per-unit pump behind the shim's ExtractGeometryBatch for
|
|
3921
|
+
* AP214 models. Staged face tessellation is finalized after every
|
|
3922
|
+
* batch so captured geometry is complete and readable.
|
|
3923
|
+
*
|
|
3924
|
+
* @param count Max units to execute this call (min 1).
|
|
3925
|
+
* @return {number} Units actually executed.
|
|
3926
|
+
*/
|
|
3927
|
+
extractDemandUnitBatch(count) {
|
|
3928
|
+
const units = this.demandUnits_;
|
|
3929
|
+
if (units === void 0) {
|
|
3930
|
+
return 0;
|
|
3931
|
+
}
|
|
3932
|
+
const end = Math.min(this.demandCursor_ + Math.max(count, 1), units.length);
|
|
3933
|
+
let executed = 0;
|
|
3934
|
+
for (; this.demandCursor_ < end; ++this.demandCursor_) {
|
|
3935
|
+
try {
|
|
3936
|
+
units[this.demandCursor_]();
|
|
3937
|
+
++executed;
|
|
3222
3938
|
}
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3939
|
+
catch (ex) {
|
|
3940
|
+
if (this.quietRecoverableLogging) {
|
|
3941
|
+
// Preview prefix: failing units are expected — retried on a
|
|
3942
|
+
// richer generation, and the durable extraction re-runs all.
|
|
3943
|
+
}
|
|
3944
|
+
else if (ex instanceof Error) {
|
|
3945
|
+
Logger.error(`Error processing demand unit: \n\t${ex.name}\n\t${ex.message}`);
|
|
3946
|
+
}
|
|
3947
|
+
else {
|
|
3948
|
+
Logger.error(`Unknown exception processing demand unit (${ex})`);
|
|
3949
|
+
}
|
|
3228
3950
|
}
|
|
3229
|
-
|
|
3951
|
+
}
|
|
3952
|
+
// Deferred face tessellation must land before geometry is read.
|
|
3953
|
+
this.finalizeStagedFaces();
|
|
3954
|
+
return executed;
|
|
3955
|
+
}
|
|
3956
|
+
/**
|
|
3957
|
+
* Complete a demand extraction after every unit has run: final staged
|
|
3958
|
+
* tessellation, temporaries cleanup, point-buffer release and
|
|
3959
|
+
* memoization restore — the tail the whole-model walk runs.
|
|
3960
|
+
*
|
|
3961
|
+
* @return {[ExtractResult, AP214SceneBuilder, AP214ProductShapeMap]}
|
|
3962
|
+
* The completed extraction result.
|
|
3963
|
+
*/
|
|
3964
|
+
finishDemandExtraction() {
|
|
3965
|
+
this.finalizeStagedFaces();
|
|
3966
|
+
if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
|
|
3967
|
+
this.model.geometry.deleteTemporaries();
|
|
3968
|
+
}
|
|
3969
|
+
if (this.pointBuffer?.pointer) {
|
|
3970
|
+
this.wasmModule._free(this.pointBuffer.pointer);
|
|
3971
|
+
this.pointBuffer = null;
|
|
3972
|
+
}
|
|
3973
|
+
if (this.demandMemoizationRestore_ !== void 0) {
|
|
3974
|
+
this.model.elementMemoization = this.demandMemoizationRestore_;
|
|
3975
|
+
this.demandMemoizationRestore_ = void 0;
|
|
3976
|
+
}
|
|
3977
|
+
return [ExtractResult.COMPLETE, this.scene, this.productShapeMap];
|
|
3978
|
+
}
|
|
3979
|
+
/**
|
|
3980
|
+
* Whole-model extraction: prepare + run every demand unit + finish —
|
|
3981
|
+
* a single code path with the per-unit pump, so pumped and classic
|
|
3982
|
+
* extractions are identical by construction.
|
|
3983
|
+
*
|
|
3984
|
+
* @param logTime Unused (kept for call compatibility).
|
|
3985
|
+
* @return {[ExtractResult, AP214SceneBuilder, AP214ProductShapeMap]}
|
|
3986
|
+
* The completed extraction result.
|
|
3987
|
+
*/
|
|
3988
|
+
// eslint-disable-next-line no-unused-vars
|
|
3989
|
+
extractAP214GeometryData(logTime = false) {
|
|
3990
|
+
try {
|
|
3991
|
+
this.prepareDemandExtraction();
|
|
3992
|
+
while (this.demandCursor_ < this.demandUnitCount) {
|
|
3993
|
+
this.extractDemandUnitBatch(this.demandUnitCount);
|
|
3994
|
+
}
|
|
3995
|
+
return this.finishDemandExtraction();
|
|
3230
3996
|
}
|
|
3231
3997
|
finally {
|
|
3232
3998
|
// Ensure no staged face jobs outlive extraction (their target
|
|
3233
3999
|
// geometry may be freed once the model is invalidated), even if
|
|
3234
4000
|
// extraction exits through an exception.
|
|
3235
4001
|
this.finalizeStagedFaces();
|
|
3236
|
-
this.
|
|
4002
|
+
if (this.demandMemoizationRestore_ !== void 0) {
|
|
4003
|
+
this.model.elementMemoization = this.demandMemoizationRestore_;
|
|
4004
|
+
this.demandMemoizationRestore_ = void 0;
|
|
4005
|
+
}
|
|
3237
4006
|
}
|
|
3238
4007
|
}
|
|
3239
4008
|
/**
|