@bldrs-ai/conway 0.7.766 → 0.8.782

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +30 -31
  2. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +1 -1
  3. package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +1 -1
  4. package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts +19 -0
  5. package/compiled/dependencies/conway-geom/interface/conway_geometry.d.ts.map +1 -1
  6. package/compiled/dependencies/conway-geom/interface/conway_geometry.js +31 -0
  7. package/compiled/dependencies/conway-geom/interface/geometry_object.d.ts +4 -0
  8. package/compiled/dependencies/conway-geom/interface/geometry_object.d.ts.map +1 -1
  9. package/compiled/dependencies/conway-geom/interface/parameters/params_get_boolean_result.d.ts +1 -0
  10. package/compiled/dependencies/conway-geom/interface/parameters/params_get_boolean_result.d.ts.map +1 -1
  11. package/compiled/dependencies/conway-geom/interface/parse_buffer.d.ts +11 -0
  12. package/compiled/dependencies/conway-geom/interface/parse_buffer.d.ts.map +1 -0
  13. package/compiled/dependencies/conway-geom/interface/parse_buffer.js +1 -0
  14. package/compiled/src/AP214E3_2010/ap214_command_line_main.js +11 -13
  15. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +0 -1
  16. package/compiled/src/AP214E3_2010/ap214_geometry_extraction.test.js +15 -13
  17. package/compiled/src/AP214E3_2010/ap214_step_model.d.ts.map +1 -1
  18. package/compiled/src/AP214E3_2010/ap214_step_model.test.js +12 -1
  19. package/compiled/src/AP214E3_2010/ap214_step_parser.d.ts.map +1 -1
  20. package/compiled/src/core/canonical_mesh.d.ts +1 -1
  21. package/compiled/src/core/canonical_mesh.d.ts.map +1 -1
  22. package/compiled/src/core/geometry_aggregator.test.js +7 -7
  23. package/compiled/src/core/packed_mesh.test.js +4 -4
  24. package/compiled/src/ifc/ifc_command_line_main.js +17 -16
  25. package/compiled/src/ifc/ifc_geometry_extraction.d.ts +6 -4
  26. package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
  27. package/compiled/src/ifc/ifc_geometry_extraction.js +107 -102
  28. package/compiled/src/ifc/ifc_geometry_extraction.test.js +4 -4
  29. package/compiled/src/ifc/ifc_model_geometry.d.ts +4 -0
  30. package/compiled/src/ifc/ifc_model_geometry.d.ts.map +1 -1
  31. package/compiled/src/ifc/ifc_model_geometry.js +13 -0
  32. package/compiled/src/ifc/ifc_property_extraction.test.js +12 -1
  33. package/compiled/src/ifc/ifc_regression_main.js +5 -3
  34. package/compiled/src/ifc/ifc_scene_builder.test.js +11 -8
  35. package/compiled/src/ifc/ifc_step_model.d.ts +1 -0
  36. package/compiled/src/ifc/ifc_step_model.d.ts.map +1 -1
  37. package/compiled/src/ifc/ifc_step_model.js +1 -0
  38. package/compiled/src/ifc/ifc_step_model.test.js +12 -1
  39. package/compiled/src/ifc/ifc_step_parser.d.ts +1 -0
  40. package/compiled/src/ifc/ifc_step_parser.d.ts.map +1 -1
  41. package/compiled/src/ifc/ifc_step_parser.js +1 -0
  42. package/compiled/src/step/parsing/step_deserialization_functions.d.ts +1 -1
  43. package/compiled/src/step/parsing/step_deserialization_functions.d.ts.map +1 -1
  44. package/compiled/src/step/parsing/step_deserialization_functions.js +1 -1
  45. package/compiled/src/step/parsing/step_parser.d.ts +1 -1
  46. package/compiled/src/step/parsing/step_parser.d.ts.map +1 -1
  47. package/compiled/src/step/parsing/step_parser.js +3 -3
  48. package/compiled/src/step/parsing/step_vtable_builder.d.ts +4 -3
  49. package/compiled/src/step/parsing/step_vtable_builder.d.ts.map +1 -1
  50. package/compiled/src/step/parsing/step_vtable_builder.js +5 -4
  51. package/compiled/src/step/step_entity_base.d.ts +27 -2
  52. package/compiled/src/step/step_entity_base.d.ts.map +1 -1
  53. package/compiled/src/step/step_entity_base.js +77 -15
  54. package/compiled/src/step/step_entity_internal_reference.d.ts +1 -0
  55. package/compiled/src/step/step_entity_internal_reference.d.ts.map +1 -1
  56. package/compiled/src/step/step_external_mapping.test.js +12 -1
  57. package/compiled/src/step/step_model_base.d.ts.map +1 -1
  58. package/compiled/src/step/step_model_base.js +1 -0
  59. package/compiled/src/version/version.js +1 -1
  60. package/compiled/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +6 -1
  62. package/compiled/src/examples/browser.d.ts +0 -3
  63. package/compiled/src/examples/browser.d.ts.map +0 -1
  64. package/compiled/src/examples/browser.js +0 -388
  65. package/compiled/src/examples/validator.d.ts +0 -8
  66. package/compiled/src/examples/validator.d.ts.map +0 -1
  67. package/compiled/src/examples/validator.js +0 -378
@@ -113,14 +113,17 @@ export class IfcGeometryExtraction {
113
113
  * @param conwayModel
114
114
  * @param model
115
115
  */
116
- constructor(conwayModel, model) {
116
+ constructor(conwayModel, model, lowMemoryMode = false) {
117
117
  this.conwayModel = conwayModel;
118
118
  this.model = model;
119
+ this.lowMemoryMode = lowMemoryMode;
119
120
  /* eslint-disable no-magic-numbers */
120
121
  this.TWO_DIMENSIONS = 2;
121
122
  this.THREE_DIMENSIONS = 3;
122
123
  this.circleSegments = 12;
124
+ this.csgMemoization = true;
123
125
  this.freeVectorPolygonalFaces_ = [];
126
+ this.csgMemoization = !this.lowMemoryMode;
124
127
  this.materials = model.materials;
125
128
  this.scene = new IfcSceneBuilder(model, conwayModel, this.materials);
126
129
  this.voidMaterials = model.voidMaterials;
@@ -490,20 +493,19 @@ export class IfcGeometryExtraction {
490
493
  * @param isRelVoid - is this geometry a relvoid?
491
494
  */
492
495
  extractTriangulatedFaceSet(entity, temporary = false, isRelVoid = false) {
493
- // Flatten points / indices into a single array
494
- const points = new Float64Array(entity.Coordinates.CoordList.flat());
495
- const indices = new Uint32Array(entity.CoordIndex.flat());
496
- const pointsArrayPtr = this.arrayToWasmHeap(points);
497
- const indicesArrayPtr = this.arrayToWasmHeap(indices);
498
- const parameters = this.paramsGetTriangulatedFaceSetPool.acquire();
499
- parameters.indices = indicesArrayPtr;
500
- parameters.indicesArrayLength = indices.length;
501
- parameters.points = pointsArrayPtr;
502
- parameters.pointsArrayLength = points.length;
503
- const geometry = this.conwayModel.getTriangulatedFaceSetGeometry(parameters);
504
- this.paramsGetTriangulatedFaceSetPool?.release(parameters);
505
- this.wasmModule._free(pointsArrayPtr);
506
- this.wasmModule._free(indicesArrayPtr);
496
+ const conwayModel = this.conwayModel;
497
+ const geometry = conwayModel.nativeGeometry();
498
+ const coordParseBuffer = conwayModel.nativeParseBuffer();
499
+ const faceParseBuffer = conwayModel.nativeParseBuffer();
500
+ if (!entity.Coordinates.extractParseBuffer(0, coordParseBuffer, this.wasmModule.HEAPU8, true)) {
501
+ coordParseBuffer.resize(0);
502
+ }
503
+ if (!entity.extractParseBuffer(3, faceParseBuffer, this.wasmModule.HEAPU8, true)) {
504
+ faceParseBuffer.resize(0);
505
+ }
506
+ geometry.extractVerticesAndTriangles(coordParseBuffer, faceParseBuffer);
507
+ conwayModel.freeParseBuffer(coordParseBuffer);
508
+ conwayModel.freeParseBuffer(faceParseBuffer);
507
509
  const canonicalMesh = {
508
510
  type: CanonicalMeshType.BUFFER_GEOMETRY,
509
511
  geometry: geometry,
@@ -524,8 +526,6 @@ export class IfcGeometryExtraction {
524
526
  */
525
527
  extractPolygonalFaceSet(entity, temporary = false, isRelVoid = false) {
526
528
  const result = ExtractResult.COMPLETE;
527
- // Flatten points into a single Float32Array
528
- const points = new Float64Array(entity.Coordinates.CoordList.flat());
529
529
  // Temporary storage for indices and start indices
530
530
  const allIndices = [];
531
531
  const allStartIndices = [];
@@ -568,9 +568,13 @@ export class IfcGeometryExtraction {
568
568
  const polygonalFaceBufferOffsetsArrayPtr = this.arrayToWasmHeap(polygonalFaceBufferOffsetsArray);
569
569
  const startIndicesBufferOffsetsArray = new Uint32Array(startIndicesBufferOffsets);
570
570
  const startIndicesBufferOffsetsArrayPtr = this.arrayToWasmHeap(startIndicesBufferOffsetsArray);
571
- const pointsArrayPtr = this.arrayToWasmHeap(points);
572
571
  const polygonalFaceVector = this.wasmModule.buildIndexedPolygonalFaceVector(indicesArrayPtr, indicesArray.length, startIndicesArrayPtr, polygonalFaceBufferOffsetsArrayPtr, polygonalFaceBufferOffsets.length, startIndicesBufferOffsetsArrayPtr, startIndicesBufferOffsets.length);
573
- const pointsArrayNative = this.wasmModule.createVertexVector(pointsArrayPtr, points.length);
572
+ const pointsParseBuffer = this.conwayModel.nativeParseBuffer();
573
+ if (!entity.Coordinates.extractParseBuffer(0, pointsParseBuffer, this.wasmModule.HEAPU8, true)) {
574
+ pointsParseBuffer.resize(0);
575
+ }
576
+ const pointsArrayNative = this.wasmModule.parseVertexVector(pointsParseBuffer);
577
+ this.conwayModel.freeParseBuffer(pointsParseBuffer);
574
578
  const parameters = {
575
579
  indicesPerFace: indicesPerFace,
576
580
  points: pointsArrayNative,
@@ -583,7 +587,6 @@ export class IfcGeometryExtraction {
583
587
  this.wasmModule._free(startIndicesArrayPtr);
584
588
  this.wasmModule._free(polygonalFaceBufferOffsetsArrayPtr);
585
589
  this.wasmModule._free(startIndicesBufferOffsetsArrayPtr);
586
- this.wasmModule._free(pointsArrayPtr);
587
590
  polygonalFaceVector.delete();
588
591
  const canonicalMesh = {
589
592
  type: CanonicalMeshType.BUFFER_GEOMETRY,
@@ -707,6 +710,12 @@ export class IfcGeometryExtraction {
707
710
  * @param from
708
711
  */
709
712
  extractBooleanResult(from, isRelVoid = false) {
713
+ if (this.csgMemoization) {
714
+ const geometry = (isRelVoid ? this.model.voidGeometry : this.model.geometry).getByLocalID(from.localID);
715
+ if (geometry !== void 0) {
716
+ return;
717
+ }
718
+ }
710
719
  this.csgOperations.add(from.localID, {
711
720
  type: CsgOperationType.DIFFERENCE,
712
721
  operand1ID: from.FirstOperand.localID,
@@ -719,7 +728,7 @@ export class IfcGeometryExtraction {
719
728
  from.FirstOperand instanceof IfcPolygonalBoundedHalfSpace ||
720
729
  from.FirstOperand instanceof IfcHalfSpaceSolid ||
721
730
  from.FirstOperand instanceof IfcFacetedBrep) {
722
- this.extractBooleanOperand(from.FirstOperand, isRelVoid, from);
731
+ this.extractBooleanOperand(from.FirstOperand, isRelVoid, from, isRelVoid);
723
732
  }
724
733
  if (from.SecondOperand instanceof IfcExtrudedAreaSolid ||
725
734
  from.SecondOperand instanceof IfcPolygonalFaceSet ||
@@ -728,7 +737,7 @@ export class IfcGeometryExtraction {
728
737
  from.SecondOperand instanceof IfcPolygonalBoundedHalfSpace ||
729
738
  from.SecondOperand instanceof IfcHalfSpaceSolid ||
730
739
  from.SecondOperand instanceof IfcFacetedBrep) {
731
- this.extractBooleanOperand(from.SecondOperand, isRelVoid);
740
+ this.extractBooleanOperand(from.SecondOperand, isRelVoid, undefined, true);
732
741
  }
733
742
  // get geometry TODO(nickcastel50): eventually support flattening meshes
734
743
  let flatFirstMeshVector; // = this.nativeVectorGeometry()
@@ -775,18 +784,8 @@ export class IfcGeometryExtraction {
775
784
  secondMesh = this.model.geometry.getByLocalID(from.SecondOperand.localID);
776
785
  }
777
786
  if (secondMesh !== void 0 && secondMesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
778
- /* const _testEntity2 = this.model.getElementByLocalID(secondMesh.localID)!
779
- const outputFilePath_ =
780
- `${_testEntity2.expressID}_${EntityTypesIfc[_testEntity2.type]}_SECOND_MESH.obj`
781
- this.dumpGeometry(outputFilePath_, secondMesh.geometry) */
782
- // const geometryParts = secondMesh.geometry.getParts()
783
- // if (false) {// geometryParts.size() > 0) {
784
- // flatSecondMeshVector = geometryParts
785
- // flatSecondMeshVectorFromParts = true
786
- // } else {
787
787
  flatSecondMeshVector = this.nativeVectorGeometry();
788
788
  flatSecondMeshVector.push_back(secondMesh.geometry);
789
- // }
790
789
  }
791
790
  else {
792
791
  Logger.error(`Error extracting secondOperand geometry for expressID:
@@ -798,6 +797,7 @@ export class IfcGeometryExtraction {
798
797
  parameters.flatFirstMesh = flatFirstMeshVector;
799
798
  parameters.flatSecondMesh = flatSecondMeshVector;
800
799
  parameters.operatorType = from.Operator.valueOf();
800
+ parameters.isSubtractOperand = isRelVoid;
801
801
  const booleanGeometryObject = this.conwayModel.getBooleanResult(parameters);
802
802
  // const outputFilePath =
803
803
  // `${from.expressID}_${EntityTypesIfc[from.type]}_post_subtract_test.obj`
@@ -826,14 +826,16 @@ export class IfcGeometryExtraction {
826
826
  }
827
827
  // add mesh to the list of mesh objects
828
828
  if (!isRelVoid) {
829
- if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
829
+ if (!this.csgMemoization &&
830
+ RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
830
831
  this.dropNonSceneGeometry(firstMesh.localID);
831
832
  this.dropNonSceneGeometry(secondMesh.localID);
832
833
  }
833
834
  this.model.geometry.add(canonicalMesh);
834
835
  }
835
836
  else {
836
- if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
837
+ if (!this.csgMemoization &&
838
+ RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
837
839
  this.model.voidGeometry.delete(firstMesh.localID);
838
840
  this.model.voidGeometry.delete(secondMesh.localID);
839
841
  }
@@ -855,7 +857,13 @@ export class IfcGeometryExtraction {
855
857
  * @param from The operand to extract.
856
858
  * @return {void}
857
859
  */
858
- extractBooleanOperand(from, isRelVoid = false, representationItem) {
860
+ extractBooleanOperand(from, isRelVoid = false, representationItem, isSecondOperand = false) {
861
+ if (this.csgMemoization) {
862
+ const geometry = (isRelVoid ? this.model.voidGeometry : this.model.geometry).getByLocalID(from.localID);
863
+ if (geometry !== void 0) {
864
+ return;
865
+ }
866
+ }
859
867
  if (from instanceof IfcExtrudedAreaSolid) {
860
868
  // mark as temporary
861
869
  this.extractExtrudedAreaSolid(from, true, isRelVoid);
@@ -887,7 +895,7 @@ export class IfcGeometryExtraction {
887
895
  from.FirstOperand instanceof IfcPolygonalBoundedHalfSpace ||
888
896
  from.FirstOperand instanceof IfcHalfSpaceSolid ||
889
897
  from.FirstOperand instanceof IfcFacetedBrep) {
890
- this.extractBooleanOperand(from.FirstOperand, isRelVoid, representationItem);
898
+ this.extractBooleanOperand(from.FirstOperand, isRelVoid, representationItem, isSecondOperand);
891
899
  }
892
900
  if (from.SecondOperand instanceof IfcExtrudedAreaSolid ||
893
901
  from.SecondOperand instanceof IfcPolygonalFaceSet ||
@@ -896,7 +904,7 @@ export class IfcGeometryExtraction {
896
904
  from.SecondOperand instanceof IfcPolygonalBoundedHalfSpace ||
897
905
  from.SecondOperand instanceof IfcHalfSpaceSolid ||
898
906
  from.SecondOperand instanceof IfcFacetedBrep) {
899
- this.extractBooleanOperand(from.SecondOperand, isRelVoid);
907
+ this.extractBooleanOperand(from.SecondOperand, isRelVoid, void 0, true);
900
908
  }
901
909
  // get geometry TODO(nickcastel50): eventually support flattening meshes
902
910
  let flatFirstMeshVector; // = this.nativeVectorGeometry()
@@ -909,22 +917,8 @@ export class IfcGeometryExtraction {
909
917
  firstMesh = this.model.geometry.getByLocalID(from.FirstOperand.localID);
910
918
  }
911
919
  if (firstMesh !== void 0 && firstMesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
912
- /* const _testEntity = this.model.getElementByLocalID(firstMesh.localID)!
913
- const outputFilePath_ =
914
- `${_testEntity.expressID}_${EntityTypesIfc[_testEntity.type]}FIRST_MESH.obj`
915
-
916
- this.dumpGeometry(outputFilePath_, firstMesh.geometry) */
917
- // const geometryParts = firstMesh.geometry.getParts()
918
- // if (geometryParts.size() > 0) {
919
- // /* for (let geometryPartIndex = 0;
920
- // geometryPartIndex < geometryParts.size(); ++geometryPartIndex) {
921
- // flatFirstMeshVector.push_back(geometryParts.get(geometryPartIndex))
922
- // }*/
923
- // flatFirstMeshVector = geometryParts
924
- // } else {
925
920
  flatFirstMeshVector = this.nativeVectorGeometry();
926
921
  flatFirstMeshVector.push_back(firstMesh.geometry);
927
- // }
928
922
  }
929
923
  else {
930
924
  Logger.error(`(Operand) Error extracting firstOperand geometry for expressID:
@@ -942,22 +936,8 @@ export class IfcGeometryExtraction {
942
936
  secondMesh = this.model.geometry.getByLocalID(from.SecondOperand.localID);
943
937
  }
944
938
  if (secondMesh !== void 0 && secondMesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
945
- /* const _testEntity2 = this.model.getElementByLocalID(secondMesh.localID)!
946
- const outputFilePath_ =
947
- `${_testEntity2.expressID}_${EntityTypesIfc[_testEntity2.type]}_SECOND_MESH.obj`
948
-
949
- this.dumpGeometry(outputFilePath_, secondMesh.geometry) */
950
- // const geometryParts = secondMesh.geometry.getParts()
951
- // if (geometryParts.size() > 0) {
952
- // /* for (let geometryPartIndex = 0;
953
- // geometryPartIndex < geometryParts.size(); ++geometryPartIndex) {
954
- // flatSecondMeshVector.push_back(geometryParts.get(geometryPartIndex))
955
- // }*/
956
- // flatSecondMeshVector = geometryParts
957
- // } else {
958
939
  flatSecondMeshVector = this.nativeVectorGeometry();
959
940
  flatSecondMeshVector.push_back(secondMesh.geometry);
960
- // }
961
941
  }
962
942
  else {
963
943
  Logger.error(`(Operand) Error extracting secondOperand geometry for expressID:
@@ -969,10 +949,8 @@ export class IfcGeometryExtraction {
969
949
  parameters.flatFirstMesh = flatFirstMeshVector;
970
950
  parameters.flatSecondMesh = flatSecondMeshVector;
971
951
  parameters.operatorType = from.Operator.valueOf();
952
+ parameters.isSubtractOperand = isSecondOperand;
972
953
  const booleanGeometryObject = this.conwayModel.getBooleanResult(parameters);
973
- // const outputFilePath =
974
- // `${from.expressID}_${EntityTypesIfc[from.type]}_post_subtract_operand.obj`
975
- // this.dumpGeometry(outputFilePath, booleanGeometryObject)
976
954
  const canonicalMesh = {
977
955
  type: CanonicalMeshType.BUFFER_GEOMETRY,
978
956
  geometry: booleanGeometryObject,
@@ -995,14 +973,16 @@ export class IfcGeometryExtraction {
995
973
  }
996
974
  // add mesh to the list of mesh objects
997
975
  if (!isRelVoid) {
998
- if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
976
+ if (!this.csgMemoization &&
977
+ RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
999
978
  this.dropNonSceneGeometry(firstMesh.localID);
1000
979
  this.dropNonSceneGeometry(secondMesh.localID);
1001
980
  }
1002
981
  this.model.geometry.add(canonicalMesh);
1003
982
  }
1004
983
  else {
1005
- if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
984
+ if (!this.csgMemoization &&
985
+ RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
1006
986
  this.model.voidGeometry.delete(firstMesh.localID);
1007
987
  this.model.voidGeometry.delete(secondMesh.localID);
1008
988
  }
@@ -1195,9 +1175,9 @@ export class IfcGeometryExtraction {
1195
1175
  return;
1196
1176
  }
1197
1177
  const radius = from.Radius;
1198
- const innerRadius = from.InnerRadius || -1;
1199
- const startParam = from.StartParam || -1;
1200
- const endParam = from.EndParam || -1;
1178
+ const innerRadius = from.InnerRadius ?? -1;
1179
+ const startParam = from.StartParam ?? -1;
1180
+ const endParam = from.EndParam ?? -1;
1201
1181
  const closed = false;
1202
1182
  const parameters = {
1203
1183
  directrix,
@@ -2427,9 +2407,9 @@ export class IfcGeometryExtraction {
2427
2407
  * @param dimensions - dimensions of points
2428
2408
  * @return {Float32Array}
2429
2409
  */
2430
- flattenPointsToFloat32Array(points, dimensions) {
2410
+ flattenPointsToFloat64Array(points, dimensions) {
2431
2411
  const totalCoordinates = points.length * dimensions;
2432
- const flatCoordinates = new Float32Array(totalCoordinates);
2412
+ const flatCoordinates = new Float64Array(totalCoordinates);
2433
2413
  let offset = 0;
2434
2414
  points.forEach((point) => {
2435
2415
  flatCoordinates.set(point.Coordinates, offset);
@@ -2447,7 +2427,7 @@ export class IfcGeometryExtraction {
2447
2427
  const pointsLength = from.Points.length;
2448
2428
  const dim = from.Dim;
2449
2429
  if (pointsLength > 0) {
2450
- const pointsFlattened = this.flattenPointsToFloat32Array(points, dim);
2430
+ const pointsFlattened = this.flattenPointsToFloat64Array(points, dim);
2451
2431
  const pointsPtr = this.arrayToWasmHeap(pointsFlattened);
2452
2432
  const parameters = this.paramsGetPolyCurvePool.acquire();
2453
2433
  parameters.points = pointsPtr;
@@ -2631,9 +2611,20 @@ export class IfcGeometryExtraction {
2631
2611
  const segmentVector = this.nativeSegmentVector();
2632
2612
  if (from.Segments !== null) {
2633
2613
  for (let i = 0; i < from.Segments.length; i++) {
2634
- const indexArray = this.createAndPopulateNativeIndices(from.Segments[i].Value);
2614
+ const localSegment = from.Segments[i];
2615
+ const parseBuffer = this.conwayModel.nativeParseBuffer();
2616
+ let indexArray;
2617
+ try {
2618
+ if (!localSegment.extractParseBuffer(0, parseBuffer, this.wasmModule.HEAPU8, true)) {
2619
+ parseBuffer.resize(0);
2620
+ }
2621
+ indexArray = this.wasmModule.parseUint32Vector(parseBuffer);
2622
+ }
2623
+ finally {
2624
+ this.conwayModel.freeParseBuffer(parseBuffer);
2625
+ }
2635
2626
  const segment = {
2636
- isArcType: (from.Segments[i].type === EntityTypesIfc.IFCARCINDEX),
2627
+ isArcType: (localSegment.type === EntityTypesIfc.IFCARCINDEX),
2637
2628
  indices: indexArray,
2638
2629
  };
2639
2630
  segmentVector.push_back(segment);
@@ -2644,16 +2635,29 @@ export class IfcGeometryExtraction {
2644
2635
  return;
2645
2636
  }
2646
2637
  // initialize new native glm::vec3 array object (free memory with delete())
2647
- const pointsArray = this.nativeVectorGlmVec2(fromPoints.CoordList.length);
2648
- if (fromPoints instanceof IfcCartesianPointList2D ||
2649
- fromPoints instanceof IfcCartesianPointList3D) {
2650
- const coords = fromPoints.CoordList;
2651
- // populate points array
2652
- for (let i = 0; i < coords.length; i++) {
2653
- const coord = coords[i];
2654
- pointsArray.set(i, { x: coord[0], y: coord[1] });
2638
+ let pointsArray;
2639
+ // = this.nativeVectorGlmdVec2((fromPoints as any).CoordList.length)
2640
+ const parseBuffer = this.conwayModel.nativeParseBuffer();
2641
+ try {
2642
+ if (!fromPoints.extractParseBuffer(0, parseBuffer, this.wasmModule.HEAPU8, true)) {
2643
+ parseBuffer.resize(0);
2644
+ }
2645
+ if (fromPoints instanceof IfcCartesianPointList2D) { // ||
2646
+ // fromPoints instanceof IfcCartesianPointList3D ) {
2647
+ pointsArray = this.wasmModule.parsePoint2DVector(parseBuffer);
2648
+ // populate points array
2649
+ // for (let i = 0; i < coords.length; i++) {
2650
+ // const coord = coords[ i ]
2651
+ // pointsArray.set(i, { x: coord[ 0 ], y: coord[ 1 ] })
2652
+ // }
2653
+ }
2654
+ else {
2655
+ pointsArray = this.wasmModule.parsePoint3Dto2DVector(parseBuffer);
2655
2656
  }
2656
2657
  }
2658
+ finally {
2659
+ this.conwayModel.freeParseBuffer(parseBuffer);
2660
+ }
2657
2661
  const paramsGetIndexedPolyCurve = {
2658
2662
  dimensions: 2,
2659
2663
  segments: segmentVector,
@@ -2748,6 +2752,9 @@ export class IfcGeometryExtraction {
2748
2752
  foundGeometry = this.model.voidGeometry.getByLocalID(from.localID);
2749
2753
  }
2750
2754
  if (foundGeometry !== void 0) {
2755
+ if (foundGeometry.temporary) {
2756
+ foundGeometry.temporary = false;
2757
+ }
2751
2758
  if (addGeometry) {
2752
2759
  this.scene.addGeometry(from.localID, owningElementLocalID, isSpace);
2753
2760
  }
@@ -3065,27 +3072,22 @@ export class IfcGeometryExtraction {
3065
3072
  extractAdvancedFace(from, geometry) {
3066
3073
  if (from.Bounds.length > 0) {
3067
3074
  const bound3DVector = this.nativeBound3DVector();
3075
+ const conwayModel = this.conwayModel;
3068
3076
  for (const bound of from.Bounds) {
3069
- const vec3Array = this.nativeVectorGlmdVec3();
3077
+ let vec3Array;
3070
3078
  const innerBound = bound.Bound;
3071
3079
  const nativeEdgeCurves = this.nativeVectorCurve();
3072
3080
  if (innerBound instanceof IfcPolyLoop) {
3073
- let prevLocalID = -1;
3074
- for (const point of innerBound.Polygon) {
3075
- const coords = point.Coordinates;
3076
- const vec3 = {
3077
- x: coords[0],
3078
- y: coords[1],
3079
- z: coords[2],
3080
- };
3081
- const currentLocalID = point.localID;
3082
- if (currentLocalID !== prevLocalID) {
3083
- vec3Array.push_back(vec3);
3084
- prevLocalID = currentLocalID;
3085
- }
3081
+ // let prevLocalID: number = -1
3082
+ const coordParseBuffer = conwayModel.nativeParseBuffer();
3083
+ if (!innerBound.extractParseBuffer(0, coordParseBuffer, this.wasmModule.HEAPU8, true)) {
3084
+ coordParseBuffer.resize(0);
3086
3085
  }
3086
+ vec3Array = this.wasmModule.parseVertexVector(coordParseBuffer);
3087
+ this.wasmModule.freeParseBuffer(coordParseBuffer);
3087
3088
  }
3088
3089
  else if (innerBound instanceof IfcEdgeLoop) {
3090
+ vec3Array = this.nativeVectorGlmdVec3();
3089
3091
  // Logger.info("innerBound Ne: " + innerBound.Ne)
3090
3092
  for (const edge of innerBound.EdgeList) {
3091
3093
  // // Logger.info("IfcOrientedEdge expressID: " + edge.expressID)
@@ -4061,7 +4063,6 @@ export class IfcGeometryExtraction {
4061
4063
  default:
4062
4064
  return null;
4063
4065
  }
4064
- /* eslint-enable no-case-declarations */
4065
4066
  }
4066
4067
  /**
4067
4068
  *
@@ -4094,7 +4095,7 @@ export class IfcGeometryExtraction {
4094
4095
  // 256 meg limit for memoization - smaller models get a big
4095
4096
  // win from memoization, but much larger models it uses far too much heap.
4096
4097
  const MEMOIZATION_THRESHOLD = 256 * 1024 * 1024;
4097
- if (this.model.bufferBytesize > MEMOIZATION_THRESHOLD) {
4098
+ if (this.lowMemoryMode || this.model.bufferBytesize > MEMOIZATION_THRESHOLD) {
4098
4099
  this.model.elementMemoization = false;
4099
4100
  }
4100
4101
  for (const relAssociateMaterial of relAssociatesMaterials) {
@@ -4361,6 +4362,10 @@ export class IfcGeometryExtraction {
4361
4362
  }
4362
4363
  }
4363
4364
  }
4365
+ if (RegressionCaptureState.memoization !== MemoizationCapture.FULL) {
4366
+ this.model.geometry.deleteTemporaries();
4367
+ this.model.voidGeometry.deleteTemporaries();
4368
+ }
4364
4369
  result = ExtractResult.COMPLETE;
4365
4370
  return [result, this.scene];
4366
4371
  }
@@ -18,15 +18,15 @@ async function initializeGeometryExtractor() {
18
18
  if (result0 !== ParseResult.COMPLETE) {
19
19
  return ExtractResult.INCOMPLETE;
20
20
  }
21
- const [, model] = parser.parseDataToModel(bufferInput);
22
- if (model === void 0) {
23
- return ExtractResult.INCOMPLETE;
24
- }
25
21
  const conwayGeometry = new ConwayGeometry();
26
22
  const initializationStatus = await conwayGeometry.initialize();
27
23
  if (!initializationStatus) {
28
24
  return;
29
25
  }
26
+ const [, model] = parser.parseDataToModel(bufferInput);
27
+ if (model === void 0) {
28
+ return ExtractResult.INCOMPLETE;
29
+ }
30
30
  conwayModel = new IfcGeometryExtraction(conwayGeometry, model);
31
31
  return conwayModel.isInitialized();
32
32
  }
@@ -20,6 +20,10 @@ export declare class IfcModelGeometry implements ModelGeometry {
20
20
  * @return {number}
21
21
  */
22
22
  get length(): number;
23
+ /**
24
+ * Delete the temporaries from this.
25
+ */
26
+ deleteTemporaries(): void;
23
27
  /**
24
28
  *
25
29
  * @param mesh
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_model_geometry.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_model_geometry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAoB,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAmB,MAAM,4BAA4B,CAAA;AAG/E;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;aASvB,KAAK,EAAE,YAAY;aAAkB,MAAM,EAAE,OAAO;IAPjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D;;;;OAIG;gBAC0B,KAAK,EAAE,YAAY,EAAkB,MAAM,GAAE,OAAe;IAEzF;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACI,GAAG,CAAC,IAAI,EAAE,aAAa;IAK9B;;;;OAIG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM;IAe7B;;;;OAIG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D;;;OAGG;IACI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAI3D;;;OAGG;IACI,qBAAqB,IAAI,MAAM;IAqBtC;;;;OAIG;IACK,IAAI,IAAK,gBAAgB,CAAE;QACjC,8BAA8B;QAC9B,MAAM;QACN,iBAAiB;QACjB,MAAM;KAAC,GAAG;QACV,8BAA8B;QAC9B,MAAM;QACN,SAAS;QACT,SAAS;KAAC,CAAC;CAqDd"}
1
+ {"version":3,"file":"ifc_model_geometry.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_model_geometry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAoB,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAmB,MAAM,4BAA4B,CAAA;AAG/E;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;aASvB,KAAK,EAAE,YAAY;aAAkB,MAAM,EAAE,OAAO;IAPjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D;;;;OAIG;gBAC0B,KAAK,EAAE,YAAY,EAAkB,MAAM,GAAE,OAAe;IAEzF;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAgBhC;;;OAGG;IACI,GAAG,CAAC,IAAI,EAAE,aAAa;IAK9B;;;;OAIG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM;IAe7B;;;;OAIG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D;;;OAGG;IACI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAI3D;;;OAGG;IACI,qBAAqB,IAAI,MAAM;IAqBtC;;;;OAIG;IACK,IAAI,IAAK,gBAAgB,CAAE;QACjC,8BAA8B;QAC9B,MAAM;QACN,iBAAiB;QACjB,MAAM;KAAC,GAAG;QACV,8BAA8B;QAC9B,MAAM;QACN,SAAS;QACT,SAAS;KAAC,CAAC;CAqDd"}
@@ -22,6 +22,19 @@ export class IfcModelGeometry {
22
22
  get length() {
23
23
  return this.meshes_.size;
24
24
  }
25
+ /**
26
+ * Delete the temporaries from this.
27
+ */
28
+ deleteTemporaries() {
29
+ for (const [key, value] of this.meshes_) {
30
+ if (value.temporary) {
31
+ this.meshes_.delete(key);
32
+ if (value.type === CanonicalMeshType.BUFFER_GEOMETRY) {
33
+ value.geometry.delete();
34
+ }
35
+ }
36
+ }
37
+ }
25
38
  /**
26
39
  *
27
40
  * @param mesh
@@ -1,9 +1,17 @@
1
1
  import fs from 'fs';
2
- import { describe, expect, test } from '@jest/globals';
2
+ import { beforeAll, describe, expect, test } from '@jest/globals';
3
3
  import { IfcPropertyExtraction, PropertyExtractResult } from './ifc_property_extraction';
4
4
  import { ParseResult } from '../step/parsing/step_parser';
5
5
  import IfcStepParser from './ifc_step_parser';
6
6
  import ParsingBuffer from '../parsing/parsing_buffer';
7
+ import { ConwayGeometry } from '../../dependencies/conway-geom';
8
+ const conwayGeometry = new ConwayGeometry();
9
+ /**
10
+ * Intialize conway geom.
11
+ */
12
+ async function initializeConwayGeom() {
13
+ await conwayGeometry.initialize();
14
+ }
7
15
  /**
8
16
  * @return {PropertyExtractResult} indicating whether the IFC properties extraction was successful.
9
17
  */
@@ -22,6 +30,9 @@ function parseProperties() {
22
30
  return IfcPropertyExtraction.extractIFCProperties(model, true);
23
31
  }
24
32
  describe('Ifc Properties Extraction', () => {
33
+ beforeAll(async () => {
34
+ await initializeConwayGeom();
35
+ });
25
36
  test('parseProperties()', () => {
26
37
  expect(parseProperties()).toBe(PropertyExtractResult.COMPLETE);
27
38
  });
@@ -19,6 +19,7 @@ import { dumpGeometryOBJs, geometryHashes } from './ifc_model_geometry_node';
19
19
  import { curveHashes, dumpCurveOBJs } from './ifc_model_curves_node';
20
20
  import { dumpProfileOBJs, profileHashes } from './ifc_model_profile_node';
21
21
  import { Console } from 'console';
22
+ const conwayGeom = new ConwayGeometry();
22
23
  main();
23
24
  /**
24
25
  * Encapsultes a string in a CSV safe way.
@@ -56,10 +57,11 @@ function displayErrors(filePath) {
56
57
  /**
57
58
  * Generalised error handling wrapper
58
59
  */
59
- function main() {
60
- Environment.checkEnvironment();
61
- Logger.initializeWasmCallbacks();
60
+ async function main() {
62
61
  try {
62
+ await conwayGeom.initialize();
63
+ Environment.checkEnvironment();
64
+ Logger.initializeWasmCallbacks();
63
65
  doWork();
64
66
  }
65
67
  catch (error) {
@@ -7,10 +7,18 @@ import ParsingBuffer from '../parsing/parsing_buffer';
7
7
  import { ConwayGeometry } from '../../dependencies/conway-geom';
8
8
  import { ExtractResult } from '../core/shared_constants';
9
9
  let conwayModel;
10
+ const conwayGeometry = new ConwayGeometry();
11
+ /**
12
+ * Intialize conway geom.
13
+ */
14
+ async function initializeConwayGeom() {
15
+ await conwayGeometry.initialize();
16
+ }
10
17
  /**
11
18
  * Initialize the geometry extractor with index IFC.
12
19
  */
13
20
  async function initializeGeometryExtractor() {
21
+ await initializeConwayGeom();
14
22
  const parser = IfcStepParser.Instance;
15
23
  const indexIfcBuffer = fs.readFileSync('data/index.ifc');
16
24
  const bufferInput = new ParsingBuffer(indexIfcBuffer);
@@ -22,11 +30,6 @@ async function initializeGeometryExtractor() {
22
30
  if (model === void 0) {
23
31
  return ExtractResult.INCOMPLETE;
24
32
  }
25
- const conwayGeometry = new ConwayGeometry();
26
- const initializationStatus = await conwayGeometry.initialize();
27
- if (!initializationStatus) {
28
- return;
29
- }
30
33
  conwayModel = new IfcGeometryExtraction(conwayGeometry, model);
31
34
  return conwayModel.isInitialized();
32
35
  }
@@ -87,10 +90,10 @@ function correctTriangleCount() {
87
90
  // eslint-disable-next-line no-magic-numbers, new-cap
88
91
  Math.trunc(value[0].GetIndexDataSize() / 3));
89
92
  }
90
- beforeAll(async () => {
91
- await initializeGeometryExtractor();
92
- });
93
93
  describe('IfcSceneBuilder', () => {
94
+ beforeAll(async () => {
95
+ await initializeGeometryExtractor();
96
+ });
94
97
  test('packMesh()', () => {
95
98
  expect(packMesh()).toBeDefined();
96
99
  });
@@ -25,6 +25,7 @@ export default class IfcStepModel extends StepModelBase<EntityTypesIfc> {
25
25
  * Construct this model given a buffer containing the data and the parsed data index on that,
26
26
  * adding the typeIndex on top of that.
27
27
  *
28
+ * @param wasmModule
28
29
  * @param buffer The buffer to values from.
29
30
  * @param elementIndex The parsed index to elements in the STEP.
30
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_step_model.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,cAAqC,MAAM,iCAAiC,CAAA;AACnF,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,sBAAsB,MAAM,6BAA6B,CAAA;AAChE,OAAO,cAAc,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,aAAa,CAAE,cAAc,CAAE;IAEvE,SAAgB,SAAS,EAAE,aAAa,CAAE,cAAc,CAAE,CAAA;IAC1D,SAAgB,mBAAmB,gCAAyB;IAC5D,SAAgB,QAAQ,mBAA+B;IACvD,SAAgB,YAAY,mBAAqC;IACjE,SAAgB,QAAQ,kBAA4B;IACpD,SAAgB,MAAM,iBAA2B;IACjD,SAAgB,aAAa,iBAAuB;IACpD,SAAgB,SAAS,mBAA+B;IACxD,SAAgB,aAAa,mBAAqC;IAElE;;;;;;OAMG;gBACU,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,CAAE,cAAc,CAAE,EAAE;CAKlF"}
1
+ {"version":3,"file":"ifc_step_model.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_step_model.ts"],"names":[],"mappings":"AAAA,OAAO,cAAqC,MAAM,iCAAiC,CAAA;AACnF,OAAO,aAAa,MAAM,yBAAyB,CAAA;AAEnD,OAAO,EAAC,cAAc,EAAC,MAAM,6BAA6B,CAAA;AAE1D,OAAO,EAAC,aAAa,EAAC,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,sBAAsB,MAAM,6BAA6B,CAAA;AAChE,OAAO,cAAc,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAKvD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,aAAa,CAAE,cAAc,CAAE;IAEvE,SAAgB,SAAS,EAAE,aAAa,CAAE,cAAc,CAAE,CAAA;IAC1D,SAAgB,mBAAmB,gCAAyB;IAC5D,SAAgB,QAAQ,mBAA+B;IACvD,SAAgB,YAAY,mBAAqC;IACjE,SAAgB,QAAQ,kBAA4B;IACpD,SAAgB,MAAM,iBAA2B;IACjD,SAAgB,aAAa,iBAAuB;IACpD,SAAgB,SAAS,mBAA+B;IACxD,SAAgB,aAAa,mBAAqC;IAElE;;;;;;;OAOG;gBAEC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,cAAc,CAAE,cAAc,CAAE,EAAE;CAKrD"}
@@ -17,6 +17,7 @@ export default class IfcStepModel extends StepModelBase {
17
17
  * Construct this model given a buffer containing the data and the parsed data index on that,
18
18
  * adding the typeIndex on top of that.
19
19
  *
20
+ * @param wasmModule
20
21
  * @param buffer The buffer to values from.
21
22
  * @param elementIndex The parsed index to elements in the STEP.
22
23
  */
@@ -1,12 +1,20 @@
1
- import { describe, expect, test } from '@jest/globals';
1
+ import { beforeAll, describe, expect, test } from '@jest/globals';
2
2
  import fs from 'fs';
3
3
  import ParsingBuffer from '../parsing/parsing_buffer';
4
4
  import { ParseResult } from '../step/parsing/step_parser';
5
5
  import IfcStepParser from './ifc_step_parser';
6
6
  import { IfcAddressTypeEnum, IfcCartesianPoint, IfcCartesianPointList, IfcCartesianPointList3D, IfcClassification, IfcClosedShell, IfcGeometricRepresentationContext, IfcGeometricRepresentationSubContext, IfcPerson, IfcPostalAddress, IfcPropertySingleValue, IfcShapeAspect, IfcTelecomAddress, } from './ifc4_gen/index';
7
+ import { ConwayGeometry } from '../../dependencies/conway-geom';
7
8
  const parser = IfcStepParser.Instance;
8
9
  const indexIfcBuffer = fs.readFileSync('data/index.ifc');
9
10
  const EXPECTED_ENTITY_COUNT = 287;
11
+ const conwayGeometry = new ConwayGeometry();
12
+ /**
13
+ * Intialize conway geom.
14
+ */
15
+ async function initializeConwayGeom() {
16
+ await conwayGeometry.initialize();
17
+ }
10
18
  /**
11
19
  * Test of extracting the IFC data from index.ifc and getting the right number of entities.
12
20
  *
@@ -458,6 +466,9 @@ function extractWeirdArrayTest() {
458
466
  return true;
459
467
  }
460
468
  describe('IFC Step Model Test', () => {
469
+ beforeAll(async () => {
470
+ await initializeConwayGeom();
471
+ });
461
472
  test('extractIFCData()', () => {
462
473
  expect(extractIFCData()).toBe(ParseResult.COMPLETE);
463
474
  });