修改agent流程,分步构建cdsl

This commit is contained in:
2026-08-27 18:59:33 +08:00
parent 7fc1dfa84d
commit b26db86d78
54 changed files with 6835 additions and 9984 deletions
@@ -306,9 +306,14 @@ class Build123dGeometryAdapter:
@staticmethod
def body_geometry(body: Any) -> dict[str, Any]:
bbox = body.bounding_box()
# A feature history can contain several body IDs while still ending in
# one connected solid (for example, a base extrusion followed by hole
# cuts). Count the current OCC result, never feature history entries.
solids = list(body.solids()) if hasattr(body, "solids") else [body]
return {
"bbox_mm": [bbox.min.X, bbox.min.Y, bbox.min.Z, bbox.max.X, bbox.max.Y, bbox.max.Z],
"volume_mm3": float(body.volume),
"solid_count": len(solids),
}
@staticmethod
+17 -12
View File
@@ -46,22 +46,27 @@
"additionalProperties": false
},
"hostFace": {
"type": "object",
"properties": {
"frame": {
"oneOf": [
{
"type": "object",
"properties": {
"origin_mm": {"$ref": "#/$defs/point3"},
"x_dir": {"$ref": "#/$defs/point3"},
"y_dir": {"$ref": "#/$defs/point3"},
"normal": {"$ref": "#/$defs/point3"}
"frame": {
"type": "object",
"properties": {
"origin_mm": {"$ref": "#/$defs/point3"},
"x_dir": {"$ref": "#/$defs/point3"},
"y_dir": {"$ref": "#/$defs/point3"},
"normal": {"$ref": "#/$defs/point3"}
},
"required": ["origin_mm", "x_dir", "y_dir", "normal"],
"additionalProperties": false
}
},
"required": ["origin_mm", "x_dir", "y_dir", "normal"],
"required": ["frame"],
"additionalProperties": false
}
},
"required": ["frame"],
"additionalProperties": false
},
{"$ref": "#/$defs/selectorRef"}
]
},
"holePosition": {
"type": "object",
+11 -11
View File
@@ -7,22 +7,22 @@
"runtime_supported_atomic_ids": ["extrude_add_blind", "extrude_add_two_sided", "extrude_cut_blind", "revolve_add", "revolve_cut", "hole_blind", "hole_countersink", "hole_counterbore", "sphere_add", "reference_plane", "reference_axis", "hole_wizard", "fillet", "chamfer", "pattern_linear", "pattern_mirror"],
"runtime_supported_profiles": ["circle", "polygon", "analytic_contours"],
"feature_atomic_ids": {
"extrude_add_blind": {"summary": "Add the closed profile by one signed extrusion distance.", "required_params": ["distance_mm"], "optional_params": ["reverse"], "requires_sketch": true},
"extrude_add_two_sided": {"summary": "Add the closed profile with independently captured forward and reverse terminations.", "required_params": ["distance_mm", "reverse_distance_mm"], "optional_params": ["reverse", "end_condition", "reverse_end_condition"], "requires_sketch": true},
"extrude_add_blind": {"summary": "Add the closed profile by one signed extrusion distance.", "required_params": ["distance_mm"], "optional_params": ["reverse"], "requires_sketch": true, "produces_body": true},
"extrude_add_two_sided": {"summary": "Add the closed profile with independently captured forward and reverse terminations.", "required_params": ["distance_mm", "reverse_distance_mm"], "optional_params": ["reverse", "end_condition", "reverse_end_condition"], "requires_sketch": true, "produces_body": true},
"extrude_cut_blind": {"summary": "Remove the closed profile by one signed extrusion distance.", "required_params": ["distance_mm"], "optional_params": ["reverse"], "requires_sketch": true},
"revolve_add": {"summary": "Add the closed profile by revolving it around an axis.", "required_params": ["angle_deg", "axis"], "optional_params": ["reverse"], "requires_sketch": true},
"revolve_add": {"summary": "Add the closed profile by revolving it around an axis.", "required_params": ["angle_deg", "axis"], "optional_params": ["reverse"], "requires_sketch": true, "produces_body": true},
"revolve_cut": {"summary": "Remove the closed profile by revolving it around an axis.", "required_params": ["angle_deg", "axis"], "optional_params": ["reverse"], "requires_sketch": true},
"hole_blind": {"summary": "Cut one or more blind cylindrical holes in the current body.", "required_params": ["diameter_mm", "depth_mm", "positions", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face must provide a strict selector or an explicit frame.", "requires_sketch": true},
"hole_countersink": {"summary": "Cut one or more blind holes with countersink dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "countersink_diameter_mm", "countersink_angle_rad", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face must provide a strict selector or an explicit frame.", "requires_sketch": true},
"hole_counterbore": {"summary": "Cut one or more blind holes with counterbore dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "counterbore_diameter_mm", "counterbore_depth_mm", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face must provide a strict selector or an explicit frame.", "requires_sketch": true},
"sphere_add": {"summary": "Add one spherical solid at an explicit model-space center.", "required_params": ["radius_mm", "center_mm"], "optional_params": [], "requires_sketch": true},
"fillet": {"summary": "Apply a radius to selected edges or faces.", "required_params": ["radius_mm"], "optional_params": ["tangent_propagation"], "requires_sketch": false},
"chamfer": {"summary": "Apply an equal-distance or angle-distance chamfer to selected edges or faces.", "required_params": ["distance_mm"], "optional_params": ["distance_2_mm", "angle_rad"], "requires_sketch": false},
"hole_blind": {"summary": "Cut one or more blind cylindrical holes in the current body.", "required_params": ["diameter_mm", "depth_mm", "positions", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face is injected from exactly one face selector token.", "requires_sketch": false},
"hole_countersink": {"summary": "Cut one or more blind holes with countersink dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "countersink_diameter_mm", "countersink_angle_rad", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face is injected from exactly one face selector token.", "requires_sketch": false},
"hole_counterbore": {"summary": "Cut one or more blind holes with counterbore dimensions.", "required_params": ["diameter_mm", "depth_mm", "positions", "counterbore_diameter_mm", "counterbore_depth_mm", "host_face"], "optional_params": ["drill_angle_rad"], "position_format": "positions is a non-empty array of objects: [{\"mm\":[u_mm,v_mm,w_mm]}]. A bare coordinate array is invalid. host_face is injected from exactly one face selector token.", "requires_sketch": false},
"sphere_add": {"summary": "Add one spherical solid at an explicit model-space center.", "required_params": ["radius_mm", "center_mm"], "optional_params": [], "requires_sketch": true, "produces_body": true},
"fillet": {"summary": "Apply a radius to selected edges or faces.", "required_params": ["radius_mm"], "optional_params": ["tangent_propagation"], "requires_sketch": false, "selector_slot": {"path": "feature.selectors", "min_items": 1, "max_items": 64}},
"chamfer": {"summary": "Apply an equal-distance or angle-distance chamfer to selected edges or faces.", "required_params": ["distance_mm"], "optional_params": ["distance_2_mm", "angle_rad"], "requires_sketch": false, "selector_slot": {"path": "feature.selectors", "min_items": 1, "max_items": 64}},
"pattern_linear": {"summary": "Repeat source features along one or two directions.", "required_params": ["source_feature_ids", "direction_1", "spacing_1_mm", "pattern_count_1"], "optional_params": ["direction_2", "spacing_2_mm", "pattern_count_2"], "requires_sketch": false},
"pattern_mirror": {"summary": "Mirror source features about a selected plane.", "required_params": ["source_feature_ids", "mirror_plane"], "optional_params": [], "requires_sketch": false},
"pattern_mirror": {"summary": "Mirror source features about a selected plane.", "required_params": ["source_feature_ids", "mirror_plane"], "optional_params": [], "requires_sketch": false, "selector_slot": {"path": "params.mirror_plane", "min_items": 1, "max_items": 1}},
"reference_plane": {"summary": "A named reference plane used by sketches or patterns.", "required_params": ["plane"], "optional_params": [], "requires_sketch": false},
"reference_axis": {"summary": "A named reference axis used by revolve or pattern features.", "required_params": ["axis"], "optional_params": [], "requires_sketch": false},
"hole_wizard": {"summary": "A SolidWorks Hole Wizard feature including its typed dimensional contract and placement selectors.", "required_params": ["hole_type", "diameter_mm", "depth_mm"], "optional_params": ["positions", "host_face", "thread", "countersink", "counterbore"], "requires_sketch": false}
"hole_wizard": {"summary": "A SolidWorks Hole Wizard feature including its typed dimensional contract and placement selectors.", "required_params": ["hole_type", "diameter_mm", "depth_mm"], "optional_params": ["positions", "host_face", "thread", "countersink", "counterbore"], "requires_sketch": false, "selector_slot": {"path": "params.host_face", "min_items": 1, "max_items": 1}}
},
"profiles": {
"circle": {
+8 -3
View File
@@ -483,9 +483,13 @@ def _execute_hole(node: FeaturePlanNode, session: ExecutionSession, *, wizard: b
positions_are_local = False
# 3. 解析孔规格 HoleSpec(直径、深度、类型等,wizard 模式提供额外默认值)。
spec = HoleSpec.from_feature(node.atomic_id, node.params, wizard=wizard)
# 4. 确定孔轴向:默认沿宿主面法向,但需保证指向主体内部(按主体中心与面原点的相对位置取反)。
normal = host.normal
inward = normal if vector_dot(vector_subtract(session.adapter.body_center(session.body), host.origin_mm), normal) >= 0 else vector_scale(normal, -1)
# 4. A host-face normal is an outward B-rep orientation, so its inverse
# always enters the material. Inferring direction from the global body
# centre fails for concave or multi-leg parts: for example, the top face
# of an L bracket can sit below the whole body's centre and the old rule
# drilled outward, producing a no-op feature reported as successful.
# The selected topology face is the local, authoritative orientation.
inward = vector_scale(host.normal, -1)
# 5. 生成孔切除工具:按孔规格、起始位置、内方向及“贯穿到主体底面”的深度构造工具实体。
tool = session.adapter.hole_tool(
spec,
@@ -895,6 +899,7 @@ def rebuild_cdsl(cdsl: dict[str, Any], out_step: Path, *, strict: bool = True) -
"out_step": str(out_step),
"volume_mm3": float(geometry["volume_mm3"]),
"bbox_mm": {"min": bbox[:3], "max": bbox[3:]},
"solid_count": int(geometry.get("solid_count") or 0),
"feature_results": [result.as_dict() for result in session.results.values()],
"runtime_diagnostics": [diagnostic.as_dict() for diagnostic in diagnostics],
"topology_records": [record.public_dict() for record in session.topology.records()],