← Commit history

Update 3 file(s)

Colby Knox ·3478df1545 ·6d ago ·parent dfab5f6
3 files changed +18−7 diff truncated
addin/AdomBridge/commands/mechanical/exploded_render.py+9−7
@@ -10,7 +10,7 @@ import adsk.core import adsk.fusion  from .core import SESSION_ID, concrete, current_target, digest, identity, ref, require, resolve, target-from .exploded_view import MAX_INSTANCES, compile_steps, matrix, request_arguments, sample_plan, text+from .exploded_view import MAX_TRACKED, SPLIT_HINT, compile_steps, matrix, request_arguments, sample_plan, text from .glyphs import Glyphs  MAX_FRAMES = 3600@@ -30,7 +30,7 @@ def to_matrix(pose):     return matrix  -def moved_scope(design, value, steps, limit=MAX_INSTANCES):+def moved_scope(design, value, steps, limit=MAX_TRACKED):     """Full paths of the occurrences the steps move, and of their ancestors (for inherited motion).     Children of a moved occurrence follow it by themselves, so they are not tracked."""     scope = set()@@ -39,7 +39,8 @@ def moved_scope(design, value, steps, limit=MAX_INSTANCES):             path = text(resolve(design, value, move["occurrence"], ("Occurrence",)).fullPathName)             parts = path.split("+")             scope.update("+".join(parts[:n]) for n in range(1, len(parts) + 1))-    require(len(scope) <= limit, "plan_budget", "The steps move more than %d occurrences (with their parents)." % limit)+    require(len(scope) <= limit, "plan_budget", "The steps move more than %d occurrences (with their parents)." % limit,+            hint=SPLIT_HINT.replace("plans", "runs"), tracked=len(scope), limit=limit)     return scope  @@ -55,17 +56,17 @@ def capture(design, value, scope):             require(path not in found, "ambiguous_context", "Every root-context occurrence needs a unique full path.")             found[path] = occurrence     require(set(found) == scope, "invalid_context", "A moved occurrence or one of its parents is no longer in the design.")-    rows, handles = [], {}+    rows, handles, ids = [], {}, {}     for path in sorted(scope, key=lambda p: (p.count("+"), p)):         occurrence = found[path]         parent_path = path.rsplit("+", 1)[0] if "+" in path else None         comp = concrete(occurrence.component)         comp_id = identity(comp)         instance_id = digest([SESSION_ID, value["documentId"], path, comp_id])-        parent = next((r for r in rows if r["path"] == parent_path), None)         rows.append({"instanceId": instance_id, "path": path, "occurrence": ref(occurrence, value),-                     "parentInstanceId": parent["instanceId"] if parent else None, "componentId": comp_id,+                     "parentInstanceId": ids.get(parent_path), "componentId": comp_id,                      "componentName": text(comp.name, 256), "homeMatrix": matrix(occurrence.transform2)})+        ids[path] = instance_id  # parents sort first, so a child finds its parent here (a dict, not a scan of the rows)         handles[instance_id] = occurrence     return {"instances": rows, "rootBodyGroup": {}}, handles @@ -80,11 +81,12 @@ class Mover:         self.home = {row["instanceId"]: row["homeMatrix"] for row in self.rows}         self.applied = {key: [0.0, 0.0, 0.0] for key in self.home}         self.below = {key: [] for key in self.home}+        parent_of = {row["instanceId"]: row.get("parentInstanceId") for row in self.rows}         for row in self.rows:             parent = row.get("parentInstanceId")             while parent is not None:                 self.below[parent].append(row["instanceId"])-                parent = next(r.get("parentInstanceId") for r in self.rows if r["instanceId"] == parent)+                parent = parent_of[parent]      def offset(self, key, pose):         home = self.home[key]
docs/MECHANICAL.md+9
@@ -87,6 +87,15 @@ explicit child offsets add. `playback: "assemble"` reverses the same timeline an returns exact home poses at its endpoint. Optional titles and instructions accompany the step/progress sequence. See [the contract and limits](EXPLODED-VIEWS.md). +A design over 256 occurrences gets a plan of just the occurrences the steps move and their+parents (`instanceScope: "moved"`), each found by name level by level, never by walking the whole+tree; other occurrences keep their home pose and children follow their parent. Components inserted+by reference are planned too. Every bound refuses with `plan_budget` and a `hint`, and the native+reads stop at 40 s, inside the relay's 60 s for a read. Measured: 128 moves in a 4,590-occurrence+design planned in 4.5 s, most of it the revision checks every guarded operation runs.+`exploded_view_render` now tracks up to 4,096 moved parts with their parents, like+`exploded_view_stills` (it stopped at 256).+ This operation performs native reads and pure pose calculations only. It does not move occurrences, suppress joints, create graphics, change BOM quantities, create a storyboard, render images or export video. Native module-function qualification
rust/core/tests/golden/mech_validation.json
@@ -1 +1 @@