update memory and performance
This commit is contained in:
@@ -30,3 +30,4 @@ jobs:
|
|||||||
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
|
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
|
||||||
speckle_function_input_schema_file_path: ${{ env.FUNCTION_SCHEMA_FILE_NAME }}
|
speckle_function_input_schema_file_path: ${{ env.FUNCTION_SCHEMA_FILE_NAME }}
|
||||||
speckle_function_command: "python -u main.py run"
|
speckle_function_command: "python -u main.py run"
|
||||||
|
speckle_function_recommended_memory_mi: 10000
|
||||||
|
|||||||
@@ -178,7 +178,13 @@ def automate_function(
|
|||||||
ifc_filename = f"{file_name}_{timestamp}.ifc"
|
ifc_filename = f"{file_name}_{timestamp}.ifc"
|
||||||
|
|
||||||
ifc.write(ifc_filename)
|
ifc.write(ifc_filename)
|
||||||
automate_context.store_file_result(f"./{ifc_filename}")
|
print(f"\n💾 IFC file written: {ifc_filename}")
|
||||||
|
try:
|
||||||
|
automate_context.mark_run_success("Success! You can download the IFC file below.")
|
||||||
|
automate_context.store_file_result(f"./{ifc_filename}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ⚠️ Could not upload file result (network issue?): {e}")
|
||||||
|
automate_context.mark_run_failed(f"Something went wrong when storing file result. Exception detail: {e}")
|
||||||
|
|
||||||
print(f"\n{'=' * 60}")
|
print(f"\n{'=' * 60}")
|
||||||
print(f" Export complete!")
|
print(f" Export complete!")
|
||||||
|
|||||||
+12
-9
@@ -10,6 +10,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
from collections import defaultdict
|
||||||
from specklepy.objects.base import Base
|
from specklepy.objects.base import Base
|
||||||
|
|
||||||
|
|
||||||
@@ -70,7 +71,6 @@ def _find_connected_components(snapped_faces: list) -> list:
|
|||||||
else:
|
else:
|
||||||
edge_to_face[edge] = fi
|
edge_to_face[edge] = fi
|
||||||
|
|
||||||
from collections import defaultdict
|
|
||||||
groups: dict = defaultdict(list)
|
groups: dict = defaultdict(list)
|
||||||
for fi in range(n):
|
for fi in range(n):
|
||||||
groups[find(fi)].append(fi)
|
groups[find(fi)].append(fi)
|
||||||
@@ -384,15 +384,19 @@ def mesh_to_ifc(
|
|||||||
obj_scale = _resolve_scale(obj, scale)
|
obj_scale = _resolve_scale(obj, scale)
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# Pass 1: collect all scaled vertices to compute world origin
|
# Pass 1: unpack vertices once per mesh, collect all scaled coords
|
||||||
|
# to compute world origin. Cache (verts, ms) for Pass 2.
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
|
mesh_cache = [] # [(verts_list, ms)] or None per mesh
|
||||||
all_scaled = []
|
all_scaled = []
|
||||||
for mesh in meshes:
|
for mesh in meshes:
|
||||||
raw_verts = _get(mesh, "vertices") or []
|
raw_verts = _get(mesh, "vertices") or []
|
||||||
verts = unwrap_chunks(list(raw_verts))
|
verts = unwrap_chunks(list(raw_verts))
|
||||||
if not verts:
|
if not verts:
|
||||||
|
mesh_cache.append(None)
|
||||||
continue
|
continue
|
||||||
ms = _resolve_scale(mesh, obj_scale)
|
ms = _resolve_scale(mesh, obj_scale)
|
||||||
|
mesh_cache.append((verts, ms))
|
||||||
for i in range(0, len(verts) - 2, 3):
|
for i in range(0, len(verts) - 2, 3):
|
||||||
all_scaled.extend([
|
all_scaled.extend([
|
||||||
float(verts[i]) * ms,
|
float(verts[i]) * ms,
|
||||||
@@ -406,21 +410,20 @@ def mesh_to_ifc(
|
|||||||
ox, oy, oz = compute_origin(all_scaled)
|
ox, oy, oz = compute_origin(all_scaled)
|
||||||
|
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
# Pass 2: one brep per mesh (so each can have its own material style)
|
# Pass 2: one brep per mesh — reuse cached verts, only unpack faces
|
||||||
# ------------------------------------------------------------------ #
|
# ------------------------------------------------------------------ #
|
||||||
brep_items = []
|
brep_items = []
|
||||||
|
|
||||||
for mesh in meshes:
|
for mesh, cached in zip(meshes, mesh_cache):
|
||||||
raw_verts = _get(mesh, "vertices") or []
|
if cached is None:
|
||||||
|
continue
|
||||||
|
verts, ms = cached
|
||||||
raw_faces = _get(mesh, "faces") or []
|
raw_faces = _get(mesh, "faces") or []
|
||||||
verts = unwrap_chunks(list(raw_verts))
|
|
||||||
faces_raw = unwrap_chunks(list(raw_faces))
|
faces_raw = unwrap_chunks(list(raw_faces))
|
||||||
|
|
||||||
if not verts or not faces_raw:
|
if not faces_raw:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
ms = _resolve_scale(mesh, obj_scale)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
face_groups = decode_faces(faces_raw)
|
face_groups = decode_faces(faces_raw)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
+26
-16
@@ -74,9 +74,8 @@ def build_definition_map(root: Base) -> dict:
|
|||||||
|
|
||||||
# Diagnostic: dump first 3 instanceDefinitionProxies to understand structure
|
# Diagnostic: dump first 3 instanceDefinitionProxies to understand structure
|
||||||
print("\n [PROXY DIAG] First 3 instanceDefinitionProxies from root:")
|
print("\n [PROXY DIAG] First 3 instanceDefinitionProxies from root:")
|
||||||
proxies_raw2 = _get(root, "instanceDefinitionProxies")
|
if proxies_raw:
|
||||||
if proxies_raw2:
|
sample = proxies_raw if isinstance(proxies_raw, list) else [proxies_raw]
|
||||||
sample = proxies_raw2 if isinstance(proxies_raw2, list) else [proxies_raw2]
|
|
||||||
for i, proxy in enumerate(sample[:3]):
|
for i, proxy in enumerate(sample[:3]):
|
||||||
app_id = _get(proxy, "applicationId") or "?"
|
app_id = _get(proxy, "applicationId") or "?"
|
||||||
name = _get(proxy, "name") or "?"
|
name = _get(proxy, "name") or "?"
|
||||||
@@ -239,6 +238,10 @@ def _make_ifc_placement(ifc, tx, ty, tz, x_axis, z_axis):
|
|||||||
_stats = {"found": 0, "not_found": 0}
|
_stats = {"found": 0, "not_found": 0}
|
||||||
_dbg_cnt = [0]
|
_dbg_cnt = [0]
|
||||||
|
|
||||||
|
# Cache: mesh id → (verts_flat, faces_raw_flat, ms) to avoid re-unpacking
|
||||||
|
# the same definition mesh across many instances that share it.
|
||||||
|
_mesh_data_cache: dict = {}
|
||||||
|
|
||||||
|
|
||||||
_MM_SCALES = {
|
_MM_SCALES = {
|
||||||
"mm": 1.0, "millimeter": 1.0, "millimeters": 1.0,
|
"mm": 1.0, "millimeter": 1.0, "millimeters": 1.0,
|
||||||
@@ -313,21 +316,28 @@ def instance_to_ifc(ifc, body_context, obj: Base, definition_map: dict,
|
|||||||
# One brep per mesh so each can have its own material style
|
# One brep per mesh so each can have its own material style
|
||||||
brep_items = []
|
brep_items = []
|
||||||
for mesh in meshes:
|
for mesh in meshes:
|
||||||
raw_verts = _get(mesh, "vertices") or []
|
mesh_id = _get(mesh, "id") or _get(mesh, "applicationId")
|
||||||
raw_faces = _get(mesh, "faces") or []
|
if mesh_id and mesh_id in _mesh_data_cache:
|
||||||
verts = unwrap_chunks(list(raw_verts))
|
verts, face_groups, ms = _mesh_data_cache[mesh_id]
|
||||||
faces_raw = unwrap_chunks(list(raw_faces))
|
else:
|
||||||
if not verts or not faces_raw:
|
raw_verts = _get(mesh, "vertices") or []
|
||||||
continue
|
raw_faces = _get(mesh, "faces") or []
|
||||||
|
verts = unwrap_chunks(list(raw_verts))
|
||||||
|
faces_raw = unwrap_chunks(list(raw_faces))
|
||||||
|
if not verts or not faces_raw:
|
||||||
|
continue
|
||||||
|
|
||||||
mesh_units = _get(mesh, "units") or _get(mesh, "_units") or ("m" if ifc_format else "mm")
|
mesh_units = _get(mesh, "units") or _get(mesh, "_units") or ("m" if ifc_format else "mm")
|
||||||
ms = _MM_SCALES.get(mesh_units.lower().strip(), 1.0)
|
ms = _MM_SCALES.get(mesh_units.lower().strip(), 1.0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
face_groups = decode_faces(faces_raw)
|
face_groups = decode_faces(faces_raw)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" ⚠️ Instance face decode: {e}")
|
print(f" ⚠️ Instance face decode: {e}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if mesh_id:
|
||||||
|
_mesh_data_cache[mesh_id] = (verts, face_groups, ms)
|
||||||
|
|
||||||
# Pre-compute world coords for all vertices in this mesh
|
# Pre-compute world coords for all vertices in this mesh
|
||||||
verts_world = []
|
verts_world = []
|
||||||
|
|||||||
Reference in New Issue
Block a user