482 lines
27 KiB
Python
482 lines
27 KiB
Python
from __future__ import annotations
|
|
|
|
from copy import deepcopy
|
|
import tempfile, unittest
|
|
from pathlib import Path
|
|
from cadfs_to_cdsl.compare import compare_steps
|
|
from cadfs_to_cdsl.featurescript_parser import parse_featurescript
|
|
from cadfs_to_cdsl.lowering import lower_model
|
|
from cadfs_to_cdsl.rebuild import rebuild_candidate
|
|
|
|
|
|
class IntegrationTests(unittest.TestCase):
|
|
def test_known_rp_source_preserves_prefix_when_selector_query_is_deferred(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0000/00000173.txt"; gold = root / "step_abc/0000/00000173.step"
|
|
if not feature.exists() or not gold.exists(): self.skipTest("CADFS sample is not installed")
|
|
cdsl = lower_model(parse_featurescript(feature.read_text(), "00000173"), {}).cdsl
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
result = rebuild_candidate(cdsl, rebuilt)
|
|
self.assertEqual(result["status"], "rebuild_failed")
|
|
self.assertEqual(result["error"]["message"], "f_F2: selector_query_unsupported during incremental replay")
|
|
self.assertEqual(result["last_executable_prefix"]["last_feature_id"], "f_F1")
|
|
|
|
def test_standard_tapped_through_counterbore_00002243(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0000/00002243.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00002243"), {})
|
|
first = next(item for item in result.cdsl["features"] if item["id"] == "f_F1")
|
|
self.assertEqual(first["atomic_id"], "extrude_add_two_sided")
|
|
self.assertEqual(first["params"]["distance_mm"], 125.0)
|
|
self.assertEqual(first["params"]["reverse_distance_mm"], 125.0)
|
|
cut = next(item for item in result.cdsl["features"] if item["id"] == "f_F3")
|
|
self.assertEqual(cut["atomic_id"], "extrude_cut_two_sided")
|
|
hole = next(item for item in result.cdsl["features"] if item["atomic_id"] == "hole_wizard")
|
|
self.assertEqual(hole["params"]["hole_type"], "c_bore")
|
|
self.assertEqual(hole["params"]["diameter_mm"], 15.0)
|
|
self.assertEqual(hole["params"]["end_condition"]["type"], "through_all")
|
|
self.assertNotIn("counterbore", hole["params"])
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(result.cdsl, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuild_failed")
|
|
self.assertEqual(outcome["error"]["message"], "f_F4: selector_query_unsupported during incremental replay")
|
|
self.assertEqual(outcome["last_executable_prefix"]["last_feature_id"], "f_F3")
|
|
|
|
def test_direct_sketch_vertex_holes_preserve_scoped_body_00406667(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0040/00406667.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00406667"), {}).cdsl
|
|
holes = [item for item in candidate["features"] if item["atomic_id"] == "hole_wizard"]
|
|
self.assertEqual([item["id"] for item in holes], ["f_F3", "f_F5"])
|
|
self.assertEqual([item["params"]["scope_feature_id"] for item in holes], ["f_F1", "f_F1"])
|
|
self.assertEqual([item["params"]["positions"] for item in holes], [
|
|
[{"mm": [0.0, 0.0, 0.0]}], [{"mm": [0.0, 26.69, 0.0]}],
|
|
])
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(candidate, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in outcome["result"]["feature_results"]],
|
|
["f_F1", "f_F3", "f_F5"],
|
|
)
|
|
|
|
def test_rectilinear_fillet_arcs_00129362_preserve_recovered_sketch_geometry(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0012/00129362.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00129362"), {})
|
|
profile = next(item for item in result.cdsl["geometry"]["sketches"] if item["id"] == "sketch_F0")["profile"]
|
|
arcs = [segment for segment in profile["contours"][0]["segments"] if segment["type"] == "arc"]
|
|
self.assertEqual(sorted(arc["center"] for arc in arcs), [[25.4, 12.7], [25.4, 63.5]])
|
|
self.assertTrue(all(abs(arc["radius_mm"] - 12.7) <= 1e-12 for arc in arcs))
|
|
triangle = next(item for item in result.cdsl["geometry"]["sketches"] if item["id"] == "sketch_F5")["profile"]
|
|
self.assertEqual(
|
|
sorted({coordinate for contour in triangle["contours"] for segment in contour["segments"] for point in (segment.get("start"), segment.get("end")) if point for coordinate in point}),
|
|
[-12.7, -6.35, 0.0, 6.35, 12.7, 25.4, 34.925, 41.275],
|
|
)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(result.cdsl, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
|
|
def test_cylindrical_swept_face_selector_00111611(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0011/00111611.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00111611"), {})
|
|
fillet = next(item for item in result.cdsl["features"] if item["id"] == "f_F3")
|
|
self.assertEqual(fillet["atomic_id"], "fillet")
|
|
self.assertEqual(fillet["selectors"][0]["kind"], "face")
|
|
self.assertNotIn("geometry", fillet["selectors"][0])
|
|
self.assertEqual(fillet["selectors"][0]["selector_intent"]["query_family"], "SWEPT_FACE")
|
|
self.assertEqual(
|
|
fillet["selectors"][0]["selector_intent"]["source_entity"],
|
|
{"sketch_id": "F0", "entity_id": "E0"},
|
|
)
|
|
self.assertEqual(
|
|
fillet["selectors"][0]["selector_intent"]["derivation_policy"],
|
|
{"allowed": ["boundary"], "multiplicity": "one"},
|
|
)
|
|
|
|
chamfer = next(item for item in result.cdsl["features"] if item["id"] == "f_F5")
|
|
self.assertEqual(
|
|
sorted(selector["geometry"]["axis_origin_mm"] for selector in chamfer["selectors"]),
|
|
sorted([[0.0, 25.4, 33.37], [33.38, 25.4, 0.0], [0.0, 25.4, -33.38], [-33.38, 25.4, 0.0]]),
|
|
)
|
|
|
|
sketches = {item["id"]: item for item in result.cdsl["geometry"]["sketches"]}
|
|
f4 = next(item for item in result.cdsl["features"] if item["id"] == "f_F4")
|
|
self.assertEqual(
|
|
sorted(segment["center"] for contour in sketches[f4["sketch_id"]]["profile"]["contours"] for segment in contour["segments"]),
|
|
sorted([[0.0, 33.37], [33.38, 0.0], [-33.38, 0.0], [0.0, -33.38]]),
|
|
)
|
|
f7 = next(item for item in result.cdsl["features"] if item["id"] == "f_F7")
|
|
self.assertEqual(
|
|
[segment["radius_mm"] for contour in sketches[f7["sketch_id"]]["profile"]["contours"] for segment in contour["segments"]],
|
|
[4.48, 2.36],
|
|
)
|
|
|
|
self.assertEqual(
|
|
next(item for item in result.cdsl["features"] if item["id"] == "f_F7")["params"]["result_mode"],
|
|
"new_body",
|
|
)
|
|
self.assertEqual(next(item for item in result.cdsl["features"] if item["id"] == "f_F9")["params"]["result_mode"], "new_body")
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(result.cdsl, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuild_failed")
|
|
self.assertEqual(outcome["error"]["message"], "f_F5: selector_query_unsupported during incremental replay")
|
|
self.assertEqual(outcome["last_executable_prefix"]["last_feature_id"], "f_F4")
|
|
|
|
def test_swept_face_extent_continues_through_primary_cuts_00925274(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0092/00925274.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00925274"), {}).cdsl
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(candidate, rebuilt)
|
|
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
result = outcome["result"]
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in result["feature_results"]],
|
|
["f_F1", "f_F3", "f_F4", "f_F6", "f_F7", "f_F9", "f_F10", "f_F12", "f_F13", "f_F15", "f_F17", "f_F18_plane", "f_F18"],
|
|
)
|
|
f9_resolution = next(
|
|
item for item in result["selector_resolution"] if item["feature_id"] == "f_F9"
|
|
)
|
|
self.assertEqual(f9_resolution["status"], "resolved")
|
|
self.assertEqual(f9_resolution["resolution_mode"], "kernel_lineage")
|
|
self.assertEqual(f9_resolution["evidence"]["result_records"], ["body:f_F6:face:0"])
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in f9_resolution["evidence"]["relations"]],
|
|
["f_F1", "f_F3", "f_F6"],
|
|
)
|
|
|
|
def test_direct_hole_prism_swept_edge_resolves_00007264(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0000/00007264.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00007264"), {})
|
|
fillet = next(item for item in result.cdsl["features"] if item["id"] == "f_F2")
|
|
self.assertEqual(fillet["atomic_id"], "fillet")
|
|
self.assertEqual(len(fillet["selectors"]), 1)
|
|
query_set = fillet["selectors"][0]
|
|
self.assertEqual(query_set["selector_intent"]["query_family"], "QUERY_SET")
|
|
self.assertEqual(query_set["selector_intent"]["query_set_contract"], "proven_operand_union")
|
|
self.assertTrue(all(
|
|
operand["selector_intent"]["query_family"] == "SWEPT_EDGE"
|
|
for operand in query_set["query_operands"]
|
|
))
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
outcome = rebuild_candidate(result.cdsl, Path(tmp) / "rebuild.step")
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
binding = next(item for item in outcome["selector_binding"] if item["feature_id"] == "f_F2")
|
|
self.assertEqual(len(binding["resolved"]), 4)
|
|
resolution = next(item for item in outcome["result"]["selector_resolution"] if item["feature_id"] == "f_F2")
|
|
self.assertEqual(resolution["resolution_mode"], "query_set_union")
|
|
vertical_edges = [
|
|
relation
|
|
for delta in outcome["result"]["topology_deltas"]
|
|
if not any(str(snapshot_id).startswith("transient:") for snapshot_id in delta["output_snapshot_ids"])
|
|
for relation in delta["relations"]
|
|
if relation["source_kind"] == "vertex"
|
|
and relation["result_kind"] == "edge"
|
|
and relation["source_record_ids"]
|
|
]
|
|
self.assertEqual(
|
|
len({(tuple(item["source_record_ids"]), tuple(item["result_record_ids"])) for item in vertical_edges}),
|
|
4,
|
|
)
|
|
self.assertTrue(all(
|
|
relation["coverage"] == "complete" and relation["lineage_status"] == "proven"
|
|
for relation in vertical_edges
|
|
))
|
|
|
|
def test_annular_swept_face_selector_00974931(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0097/00974931.txt"
|
|
gold = root / "step_abc/0097/00974931.step"
|
|
if not feature.exists() or not gold.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00974931"), {}).cdsl
|
|
fillet = next(item for item in candidate["features"] if item["id"] == "f_F2")
|
|
selector = fillet["selectors"][0]
|
|
self.assertEqual(fillet["atomic_id"], "fillet")
|
|
self.assertNotIn("geometry", selector)
|
|
self.assertNotIn("stable_id", selector)
|
|
self.assertEqual(selector["selector_intent"]["query_family"], "SWEPT_FACE")
|
|
self.assertEqual(
|
|
selector["selector_intent"]["source_entity"],
|
|
{"sketch_id": "F0", "entity_id": "E0"},
|
|
)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(candidate, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuild_failed")
|
|
|
|
f2_resolution = next(
|
|
item for item in outcome["last_executable_prefix"]["result"]["selector_resolution"]
|
|
if item["feature_id"] == "f_F2"
|
|
)
|
|
self.assertEqual(f2_resolution["status"], "resolved")
|
|
self.assertEqual(f2_resolution["resolution_mode"], "kernel_lineage")
|
|
self.assertEqual(f2_resolution["evidence"]["semantic_anchor"], {
|
|
"type": "source_entity", "sketch_id": "F0", "entity_id": "E0",
|
|
})
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in outcome["last_executable_prefix"]["result"]["feature_results"]],
|
|
["f_F1", "f_F2"],
|
|
)
|
|
self.assertEqual(outcome["error"]["message"], "f_F3: selector_query_unsupported during incremental replay")
|
|
|
|
def test_direct_prism_cap_edge_lineage_00021014(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0002/00021014.txt"
|
|
gold = root / "step_abc/0002/00021014.step"
|
|
if not feature.exists() or not gold.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00021014"), {}).cdsl
|
|
fillet = next(item for item in candidate["features"] if item["id"] == "f_F2")
|
|
cap_edges = [
|
|
selector for selector in fillet["selectors"]
|
|
if (selector.get("selector_intent") or {}).get("query_family") == "CAP_EDGE"
|
|
]
|
|
self.assertEqual(len(cap_edges), 9)
|
|
self.assertTrue(all("stable_id" not in selector and "geometry" not in selector for selector in cap_edges))
|
|
self.assertEqual(
|
|
{selector["selector_intent"]["lineage_role"] for selector in cap_edges},
|
|
{"extrude.start", "extrude.end"},
|
|
)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(candidate, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
comparison = compare_steps(gold, rebuilt)
|
|
|
|
cap_resolutions = [
|
|
item for item in outcome["result"]["selector_resolution"]
|
|
if item.get("feature_id") == "f_F2"
|
|
and item.get("evidence", {}).get("semantic_anchor", {}).get("type") == "source_entity"
|
|
]
|
|
self.assertEqual(len(cap_resolutions), 10)
|
|
direct_caps = [
|
|
item for item in cap_resolutions
|
|
if item["evidence"]["relations"][0].get("output_role") in {"extrude.start", "extrude.end"}
|
|
]
|
|
self.assertEqual(len(direct_caps), 9)
|
|
self.assertTrue(all(item["resolution_mode"] == "kernel_lineage" for item in direct_caps))
|
|
self.assertTrue(comparison["strict"]["passed"])
|
|
|
|
def test_direct_mixed_hole_cap_edge_lineage_00735367(self):
|
|
"""A solver-split circular hole restores one proven source cap edge."""
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0073/00735367.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00735367"), {}).cdsl
|
|
fillet = next(item for item in candidate["features"] if item["id"] == "f_F2")
|
|
selector = fillet["selectors"][0]
|
|
self.assertEqual(selector["selector_intent"]["query_family"], "CAP_EDGE")
|
|
self.assertEqual(selector["selector_intent"]["source_entity"], {"sketch_id": "F0", "entity_id": "E1"})
|
|
self.assertEqual(selector["selector_intent"]["lineage_role"], "extrude.end")
|
|
self.assertNotIn("geometry", selector)
|
|
self.assertNotIn("stable_id", selector)
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(candidate, rebuilt)
|
|
self.assertTrue(rebuilt.exists())
|
|
|
|
self.assertEqual(outcome["status"], "runtime_ineligible")
|
|
prefix = outcome["last_executable_prefix"]["result"]
|
|
self.assertEqual(outcome["last_executable_prefix"]["last_feature_id"], "f_F3")
|
|
self.assertEqual([item["feature_id"] for item in prefix["feature_results"]], ["f_F1", "f_F2", "f_F3"])
|
|
resolution = next(item for item in prefix["selector_resolution"] if item["feature_id"] == "f_F2")
|
|
self.assertEqual(resolution["status"], "resolved")
|
|
self.assertEqual(resolution["resolution_mode"], "kernel_lineage")
|
|
self.assertEqual(resolution["evidence"]["semantic_anchor"], {
|
|
"type": "source_entity", "sketch_id": "F0", "entity_id": "E1",
|
|
})
|
|
self.assertEqual(resolution["evidence"]["relations"][0]["output_role"], "extrude.end")
|
|
self.assertTrue(resolution["evidence"]["relations"][0]["source_record_ids"])
|
|
|
|
def test_inward_shells_00789939_preserve_prefix_when_face_query_is_deferred(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0078/00789939.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00789939"), {})
|
|
features = {item["id"]: item for item in result.cdsl["features"]}
|
|
self.assertEqual(features["f_F2"]["atomic_id"], "shell")
|
|
self.assertEqual(features["f_F5"]["atomic_id"], "shell")
|
|
self.assertEqual(features["f_F2"]["params"], {"thickness_mm": 2.5, "inward": True})
|
|
self.assertEqual(features["f_F5"]["params"], {"thickness_mm": 2.5, "inward": True})
|
|
self.assertNotIn("F2", [item.get("feature_id") for item in result.diagnostics])
|
|
self.assertNotIn("F5", [item.get("feature_id") for item in result.diagnostics])
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = Path(tmp) / "rebuild.step"
|
|
outcome = rebuild_candidate(result.cdsl, rebuilt)
|
|
self.assertEqual(outcome["status"], "rebuild_failed")
|
|
self.assertEqual(outcome["error"]["message"], "f_F6: selector_query_unsupported during incremental replay")
|
|
self.assertEqual(outcome["last_executable_prefix"]["last_feature_id"], "f_F5")
|
|
self.assertEqual(outcome["last_executable_prefix"]["result"]["solid_count"], 2)
|
|
|
|
def test_outward_cap_shells_lower_and_rebuild_prefixes(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
cases = (("00090436", 2.5), ("00107631", 3.8))
|
|
for sample_id, thickness in cases:
|
|
with self.subTest(sample_id=sample_id):
|
|
feature = root / "featurescript_rp" / sample_id[:4] / f"{sample_id}.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
result = lower_model(parse_featurescript(feature.read_text(), sample_id), {})
|
|
shell_index, shell = next(
|
|
(index, item)
|
|
for index, item in enumerate(result.cdsl["features"])
|
|
if item["id"] == "f_F2"
|
|
)
|
|
|
|
self.assertEqual(shell["atomic_id"], "shell")
|
|
self.assertEqual(shell["params"], {"thickness_mm": thickness, "inward": False})
|
|
self.assertNotIn("shell_outward", {item.get("capability") for item in result.diagnostics})
|
|
|
|
prefix = deepcopy(result.cdsl)
|
|
prefix["features"] = prefix["features"][:shell_index + 1]
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
outcome = rebuild_candidate(prefix, Path(tmp) / "outward-shell.step")
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in outcome["result"]["feature_results"]],
|
|
["f_F1", "f_F2"],
|
|
)
|
|
|
|
def test_sweep_00542223_preserves_its_open_bspline_path(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0054/00542223.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00542223"), {})
|
|
sweep = next(item for item in result.cdsl["features"] if item["id"] == "f_F5")
|
|
segment = sweep["params"]["path"]["segment"]
|
|
self.assertEqual(result.status, "converted_partial")
|
|
self.assertEqual(sweep["atomic_id"], "sweep_add")
|
|
self.assertEqual(sweep["sketch_id"], "sketch_F4")
|
|
self.assertEqual(segment["points"], [[-40.0, -50.0], [-20.0, -14.96], [0.0, 5.0]])
|
|
self.assertEqual(segment["start_tangent"], [27.94, 92.49])
|
|
self.assertEqual(segment["end_tangent"], [52.88, 49.52])
|
|
self.assertNotIn("F2", [item.get("feature_id") for item in result.diagnostics])
|
|
self.assertNotIn("F5", [item.get("feature_id") for item in result.diagnostics])
|
|
self.assertIn("F7", [item.get("feature_id") for item in result.diagnostics])
|
|
|
|
def test_direct_sketch_wire_qbodytype_path_lowers_and_rebuilds_00896761(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0089/00896761.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00896761"), {}).cdsl
|
|
sweep = next(item for item in candidate["features"] if item["id"] == "f_F2")
|
|
segment = sweep["params"]["path"]["segment"]
|
|
self.assertEqual(sweep["atomic_id"], "sweep_add")
|
|
self.assertEqual(segment["type"], "bspline")
|
|
self.assertEqual(segment["source_entity_id"], "E2")
|
|
self.assertEqual(segment["points"], [[0.0, 0.0], [87.21, 282.41]])
|
|
self.assertEqual(segment["start_tangent"], [0.0, 936.12])
|
|
self.assertEqual(segment["end_tangent"], [168.9, 48.72])
|
|
|
|
from engine.cdsl_engine.runtime import analyze_cdsl
|
|
self.assertTrue(analyze_cdsl(candidate).runtime_eligible)
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
outcome = rebuild_candidate(candidate, Path(tmp) / "rebuild.step")
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
self.assertEqual([item["feature_id"] for item in outcome["result"]["feature_results"]], ["f_F2"])
|
|
|
|
def test_multi_entity_sketch_wire_qbodytype_path_lowers_as_a_source_ordered_wire_00786708(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0078/00786708.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00786708"), {})
|
|
self.assertEqual(result.status, "converted_complete")
|
|
first_sweep = next(item for item in result.cdsl["features"] if item["id"] == "f_F2")
|
|
self.assertEqual(
|
|
[(item["source_entity_id"], item["type"]) for item in first_sweep["params"]["path"]["segments"]],
|
|
[("E1", "arc"), ("E0", "line"), ("E2.MirrorCS", "arc")],
|
|
)
|
|
later_sweep = next(item for item in result.cdsl["features"] if item["id"] == "f_F5")
|
|
self.assertEqual(later_sweep["params"]["path"]["segment"]["source_entity_id"], "E5")
|
|
|
|
def test_circular_pattern_00542223_preserves_all_sweep_arms(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0054/00542223.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00542223"), {})
|
|
candidate = dict(result.cdsl)
|
|
candidate["features"] = result.cdsl["features"][:4]
|
|
|
|
from engine.cdsl_engine.runtime import rebuild_cdsl
|
|
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
rebuilt = rebuild_cdsl(candidate, Path(tmp) / "pattern.step")
|
|
|
|
self.assertEqual(rebuilt["solid_count"], 2)
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in rebuilt["feature_results"]],
|
|
["f_F1", "f_F3", "f_F5", "f_F6"],
|
|
)
|
|
|
|
def test_deferred_pattern_shell_keeps_later_executable_feature_00542223(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0054/00542223.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00542223"), {}).cdsl
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
outcome = rebuild_candidate(candidate, Path(tmp) / "rebuild.step")
|
|
|
|
self.assertEqual(outcome["status"], "rebuilt")
|
|
self.assertEqual(
|
|
[item["feature_id"] for item in outcome["result"]["feature_results"]],
|
|
["f_F1", "f_F3", "f_F5", "f_F6", "f_F10"],
|
|
)
|
|
|
|
def test_face_chamfer_source_query_is_not_geometry_bound_00111611(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0011/00111611.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
from cadfs_to_cdsl.selector_binding import bind_candidate_selectors
|
|
|
|
candidate = lower_model(parse_featurescript(feature.read_text(), "00111611"), {}).cdsl
|
|
with self.assertRaisesRegex(ValueError, "f_F5: selector_query_unsupported after prefix rebuild"):
|
|
bind_candidate_selectors(candidate)
|
|
|
|
def test_circular_remove_pattern_replays_cut_sources_00159804(self):
|
|
root = Path(__file__).parents[2] / "data/cadfs-sample/CADFS_test"
|
|
feature = root / "featurescript_rp/0015/00159804.txt"
|
|
if not feature.exists(): self.skipTest("CADFS sample is not installed")
|
|
|
|
result = lower_model(parse_featurescript(feature.read_text(), "00159804"), {})
|
|
source = next(item for item in result.cdsl["features"] if item["id"] == "f_F8")
|
|
pattern = next(item for item in result.cdsl["features"] if item["id"] == "f_F9")
|
|
|
|
self.assertEqual(source["atomic_id"], "extrude_cut_blind")
|
|
self.assertNotIn("result_mode", source["params"])
|
|
self.assertEqual(pattern["params"]["operation_mode"], "remove")
|
|
|
|
|
|
if __name__ == "__main__": unittest.main()
|