- Assembly instaiated operations

- assembly forward proagation
This commit is contained in:
bklronin
2026-08-19 20:14:14 +02:00
parent 6b6f7de5ab
commit 9abeb6266a
16 changed files with 3463 additions and 382 deletions
+89
View File
@@ -0,0 +1,89 @@
"""Round-trip smoke test: instance-local sketches + modifiers survive save/load.
Builds a minimal project (component with a body, assembly with two instances,
one carrying an instance sketch + cut modifier + fillet modifier), saves to a
temp .fluency, reloads, and asserts:
1. the shared component is untouched by instance work,
2. the instance sketch + modifiers round-trip with sketch refs intact,
3. the plain instance has none.
"""
import os
import tempfile
import numpy as np
from fluency.models.data_model import (
Project, Component, Body, Sketch, Feature, Assembly, AssemblyComponent,
)
from fluency.io.project_io import save_project, load_project
def main():
project = Project(name="inst test")
comp = project.add_component()
comp.name = "BasePart"
body = comp.add_body(Body(name="MainBody"))
base_sketch = comp.add_sketch(Sketch(name="BaseSketch"))
body.features.append(
Feature(operation="extrude", sketch=base_sketch, length=10.0)
)
asm = project.add_assembly(Assembly(name="TestAsm"))
ac1 = asm.add_component_instance(comp.id, name="Instance A")
ac1.position = np.array([0.0, 0.0, 0.0])
ac2 = asm.add_component_instance(comp.id, name="Instance B")
ac2.position = np.array([50.0, 0.0, 0.0])
# Instance A: local sketch + cut modifier referencing it + fillet.
inst_sketch = ac1.add_instance_sketch()
inst_sketch.name = "InstCutSketch"
ac1.add_modifier(body.id, Feature(operation="cut", sketch=inst_sketch,
length=5.0, through_all=True))
ac1.add_modifier(body.id, Feature(operation="fillet", radius=1.0))
# ---- save / load ----
fd, path = tempfile.mkstemp(suffix=".fluency")
os.close(fd)
try:
save_project(project, path)
loaded, _view = load_project(path)
lcomp = loaded.components[comp.id]
lac1 = None
lac2 = None
for lasm in loaded.assemblies.values():
for ac in lasm.components.values():
if ac.name == "Instance A":
lac1 = ac
elif ac.name == "Instance B":
lac2 = ac
assert lac1 is not None and lac2 is not None, "instances missing"
# 1. component untouched
assert len(lcomp.sketches) == 1, "component sketch count changed"
assert len(lcomp.bodies[body.id].features) == 1, "feature chain changed"
assert not getattr(lcomp.bodies[body.id], "modifiers", None)
# 2. instance A round-trip
assert len(lac1.sketches) == 1, "instance sketch missing"
lsk_id, lsk = next(iter(lac1.sketches.items()))
assert lsk.name == "InstCutSketch"
mods = lac1.modifiers
lbody_id = next(iter(lcomp.bodies))
assert len(mods.get(lbody_id, [])) == 2, f"modifiers missing: {mods}"
cut, fil = mods[lbody_id][0], mods[lbody_id][1]
assert cut.operation == "cut" and fil.operation == "fillet"
assert cut.sketch is not None and cut.sketch.id == lsk_id, \
"cut sketch ref did not resolve to instance sketch"
assert cut.length == 5.0 and cut.through_all
# 3. plain instance clean
assert not lac2.sketches and not lac2.modifiers
print("ROUND_TRIP_OK")
finally:
os.unlink(path)
if __name__ == "__main__":
main()