update memory and performance

This commit is contained in:
NLSA
2026-03-10 15:22:59 +01:00
parent bdd030ba86
commit 63082a881c
4 changed files with 46 additions and 26 deletions
+1
View File
@@ -30,3 +30,4 @@ jobs:
speckle_function_id: ${{ secrets.SPECKLE_FUNCTION_ID }}
speckle_function_input_schema_file_path: ${{ env.FUNCTION_SCHEMA_FILE_NAME }}
speckle_function_command: "python -u main.py run"
speckle_function_recommended_memory_mi: 10000
+7 -1
View File
@@ -178,7 +178,13 @@ def automate_function(
ifc_filename = f"{file_name}_{timestamp}.ifc"
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" Export complete!")
+12 -9
View File
@@ -10,6 +10,7 @@
# =============================================================================
import ifcopenshell
from collections import defaultdict
from specklepy.objects.base import Base
@@ -70,7 +71,6 @@ def _find_connected_components(snapped_faces: list) -> list:
else:
edge_to_face[edge] = fi
from collections import defaultdict
groups: dict = defaultdict(list)
for fi in range(n):
groups[find(fi)].append(fi)
@@ -384,15 +384,19 @@ def mesh_to_ifc(
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 = []
for mesh in meshes:
raw_verts = _get(mesh, "vertices") or []
verts = unwrap_chunks(list(raw_verts))
if not verts:
mesh_cache.append(None)
continue
ms = _resolve_scale(mesh, obj_scale)
mesh_cache.append((verts, ms))
for i in range(0, len(verts) - 2, 3):
all_scaled.extend([
float(verts[i]) * ms,
@@ -406,21 +410,20 @@ def mesh_to_ifc(
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 = []
for mesh in meshes:
raw_verts = _get(mesh, "vertices") or []
for mesh, cached in zip(meshes, mesh_cache):
if cached is None:
continue
verts, ms = cached
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:
if not faces_raw:
continue
ms = _resolve_scale(mesh, obj_scale)
try:
face_groups = decode_faces(faces_raw)
except Exception as e:
+26 -16
View File
@@ -74,9 +74,8 @@ def build_definition_map(root: Base) -> dict:
# Diagnostic: dump first 3 instanceDefinitionProxies to understand structure
print("\n [PROXY DIAG] First 3 instanceDefinitionProxies from root:")
proxies_raw2 = _get(root, "instanceDefinitionProxies")
if proxies_raw2:
sample = proxies_raw2 if isinstance(proxies_raw2, list) else [proxies_raw2]
if proxies_raw:
sample = proxies_raw if isinstance(proxies_raw, list) else [proxies_raw]
for i, proxy in enumerate(sample[:3]):
app_id = _get(proxy, "applicationId") 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}
_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": 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
brep_items = []
for mesh in meshes:
raw_verts = _get(mesh, "vertices") or []
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_id = _get(mesh, "id") or _get(mesh, "applicationId")
if mesh_id and mesh_id in _mesh_data_cache:
verts, face_groups, ms = _mesh_data_cache[mesh_id]
else:
raw_verts = _get(mesh, "vertices") or []
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")
ms = _MM_SCALES.get(mesh_units.lower().strip(), 1.0)
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)
try:
face_groups = decode_faces(faces_raw)
except Exception as e:
print(f" ⚠️ Instance face decode: {e}")
continue
try:
face_groups = decode_faces(faces_raw)
except Exception as e:
print(f" ⚠️ Instance face decode: {e}")
continue
if mesh_id:
_mesh_data_cache[mesh_id] = (verts, face_groups, ms)
# Pre-compute world coords for all vertices in this mesh
verts_world = []