feat: 增强一级共面同轴事实识别
This commit is contained in:
@@ -10,10 +10,13 @@ for path in (PROJECT_ROOT, SCRIPTS_DIR):
|
||||
if str(path) not in sys.path:
|
||||
sys.path.insert(0, str(path))
|
||||
|
||||
from step_editor.geometry_utils import _int_values
|
||||
from step_editor.model import StepModel
|
||||
from step_editor.ui_helpers import INFO_LABELS
|
||||
from step_editor.window_state import WindowStateMixin
|
||||
|
||||
from verify_face_coplanar_push_pull import _top_faces, _write_split_top_box # noqa: E402
|
||||
from verify_face_mixed_surface_guard import _top_planar_cap_face, _write_hollow_cylinder # noqa: E402
|
||||
from verify_hole_resize import _first_hole_face, _write_through_hole_model # noqa: E402
|
||||
from verify_shell_thickness_resize import _first_shell_face, _write_plate_model # noqa: E402
|
||||
from verify_slot_resize import _first_slot_face, _write_half_round_slot_model # noqa: E402
|
||||
@@ -121,6 +124,19 @@ def _verify_planar_face_facts() -> None:
|
||||
"一级平面关系" in str(facts.get("first_level_fact_summary") or ""),
|
||||
f"cube planar Face fact summary should include planar relation facts: {facts}",
|
||||
)
|
||||
_assert(facts.get("first_level_same_domain_status") == "ready", f"cube same-domain status: {facts}")
|
||||
_assert(
|
||||
facts.get("first_level_same_domain_relation") == "coplanar",
|
||||
f"cube same-domain relation should be coplanar: {facts}",
|
||||
)
|
||||
_assert(
|
||||
int(facts.get("first_level_same_domain_face_count", 0) or 0) == 1,
|
||||
f"cube should expose a single same-domain planar Face: {facts}",
|
||||
)
|
||||
_assert(
|
||||
"first_level_coaxial_cylinder_summary" in facts,
|
||||
f"cube should still expose coaxial-cylinder fact fields: {facts}",
|
||||
)
|
||||
|
||||
probe = _FactProbe(model)
|
||||
fields = probe._face_first_level_selection_fields(face_id)
|
||||
@@ -154,6 +170,80 @@ def _verify_planar_face_facts() -> None:
|
||||
_assert_plan_facts(plan, label, "face")
|
||||
|
||||
|
||||
def _verify_coplanar_same_domain_facts(root: Path) -> None:
|
||||
split_path = root / "split_top_box.step"
|
||||
_write_split_top_box(split_path)
|
||||
model = StepModel.load(split_path)
|
||||
top_faces = _top_faces(model, 10.0, 2e-4)
|
||||
_assert(len(top_faces) == 2, f"split-top box should have two coplanar top Faces, got {top_faces}")
|
||||
|
||||
face_id = top_faces[0]
|
||||
facts = model.face_first_level_facts(face_id, scope="face")
|
||||
_assert_common_facts(facts, "split coplanar Face")
|
||||
_assert(
|
||||
facts.get("first_level_same_domain_status") == "ready",
|
||||
f"split coplanar Face should expose same-domain facts: {facts}",
|
||||
)
|
||||
_assert(
|
||||
facts.get("first_level_same_domain_relation") == "coplanar",
|
||||
f"split coplanar Face should be marked coplanar: {facts}",
|
||||
)
|
||||
_assert(
|
||||
set(_int_values(facts.get("first_level_same_domain_face_ids"))) == set(top_faces),
|
||||
f"split coplanar facts should include both top Faces: {facts}",
|
||||
)
|
||||
_assert(
|
||||
int(facts.get("first_level_same_domain_fragment_face_count", 0) or 0) == 1,
|
||||
f"split coplanar facts should expose one synchronized fragment: {facts}",
|
||||
)
|
||||
_assert(
|
||||
"共面" in str(facts.get("first_level_same_domain_summary") or ""),
|
||||
f"split coplanar summary should mention coplanar relation: {facts}",
|
||||
)
|
||||
|
||||
plan = model.push_pull_plan(face_id, 1.0)
|
||||
_assert_plan_facts(plan, "split coplanar push-pull plan", "face")
|
||||
_assert(
|
||||
set(_int_values(plan.get("first_level_same_domain_face_ids"))) == set(top_faces),
|
||||
f"split coplanar plan should carry same-domain facts: {plan}",
|
||||
)
|
||||
|
||||
|
||||
def _verify_coaxial_cylinder_facts(root: Path) -> None:
|
||||
hollow_path = root / "hollow_cylinder.step"
|
||||
_write_hollow_cylinder(hollow_path)
|
||||
model = StepModel.load(hollow_path)
|
||||
cap_face_id = _top_planar_cap_face(model)
|
||||
facts = model.face_first_level_facts(cap_face_id, scope="face")
|
||||
_assert_common_facts(facts, "hollow cylinder cap")
|
||||
_assert(
|
||||
facts.get("first_level_coaxial_cylinder_status") == "ready",
|
||||
f"hollow cylinder cap should expose ready coaxial-cylinder facts: {facts}",
|
||||
)
|
||||
_assert(
|
||||
int(facts.get("first_level_coaxial_cylinder_count", 0) or 0) >= 1,
|
||||
f"hollow cylinder cap should have at least one coaxial cylinder relation: {facts}",
|
||||
)
|
||||
_assert(
|
||||
int(facts.get("first_level_coaxial_cylinder_face_count", 0) or 0) >= 2,
|
||||
f"hollow cylinder cap should include inner and outer cylindrical Faces: {facts}",
|
||||
)
|
||||
rows = tuple(row for row in facts.get("first_level_coaxial_cylinder_rows", ()) or () if isinstance(row, dict))
|
||||
radii = sorted({round(float(radius), 4) for row in rows for radius in tuple(row.get("radii") or ())})
|
||||
_assert(radii == [3.0, 8.0], f"hollow cylinder cap should expose inner/outer coaxial radii, got {radii}: {facts}")
|
||||
_assert(
|
||||
"同轴圆柱" in str(facts.get("first_level_coaxial_cylinder_summary") or ""),
|
||||
f"hollow cylinder cap summary should mention coaxial cylinders: {facts}",
|
||||
)
|
||||
|
||||
plan = model.push_pull_plan(cap_face_id, 1.0)
|
||||
_assert_plan_facts(plan, "hollow cylinder cap push-pull plan", "face")
|
||||
_assert(
|
||||
plan.get("first_level_coaxial_cylinder_status") == "ready",
|
||||
f"hollow cylinder cap plan should carry coaxial-cylinder facts: {plan}",
|
||||
)
|
||||
|
||||
|
||||
def _verify_shell_plan_facts(root: Path) -> None:
|
||||
shell_path = root / "thin_plate.step"
|
||||
_write_plate_model(shell_path)
|
||||
@@ -217,12 +307,16 @@ def main() -> int:
|
||||
"first_level_fact_summary",
|
||||
"first_level_fact_subject_face_count",
|
||||
"first_level_fact_adjacent_face_count",
|
||||
"first_level_same_domain_summary",
|
||||
"first_level_coaxial_cylinder_summary",
|
||||
):
|
||||
_assert(key in INFO_LABELS, f"{key} should have a user-facing label")
|
||||
|
||||
_verify_planar_face_facts()
|
||||
with tempfile.TemporaryDirectory(prefix="geom_param_first_level_facts_") as temp_dir:
|
||||
root = Path(temp_dir)
|
||||
_verify_coplanar_same_domain_facts(root)
|
||||
_verify_coaxial_cylinder_facts(root)
|
||||
_verify_shell_plan_facts(root)
|
||||
_verify_cylindrical_facts(root)
|
||||
_verify_slot_facts(root)
|
||||
|
||||
Reference in New Issue
Block a user