mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-26 10:21:00 +00:00
CAD: Project feature — convert solid edges into a parametric sketch
Onshape-style "Use / Convert entities": pick edges (or a whole face) of an existing solid and get sketch geometry projected onto a target plane, then extrude/revolve/edit it like any sketch. Parametric: apply_project re-derives the feature's entities from the source body on every recompute, so editing the source updates the projection. Line edges -> Line entities (exact); circles/arcs whose plane is parallel to the sketch plane -> Circle/Arc (exact); everything else (incl. non-parallel circles that project to ellipses) -> sampled Line chain. Append-only: new enum value Project + project_source_body/project_edges/ project_face fields at the end of save/load; recipe version stays 2. Recompute loop made non-const solely so apply_project can write back f.entities. Suite 67->71 cases, 1178->1229 assertions, RC=0. Fixture 25493->26835 B. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVzKmX6Y1aEteit1HTXG4Q
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
07b39d45cb
commit
161d006e92
@@ -76,6 +76,7 @@ const char* feature_type_name(CadFeatureType t)
|
||||
case CadFeatureType::Helix: return "Helix";
|
||||
case CadFeatureType::Transform: return "Transform";
|
||||
case CadFeatureType::Thicken: return "Thicken";
|
||||
case CadFeatureType::Project: return "Project";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -248,6 +249,13 @@ json describe_tools()
|
||||
json{{"name", "keep_upper"},{"type", "boolean"}, {"default", true}},
|
||||
json{{"name", "keep_lower"},{"type", "boolean"}, {"default", true}},
|
||||
})}},
|
||||
json{{"name", "project"}, {"summary", "Project edges of a solid onto a sketch plane, producing a new sketch feature."},
|
||||
{"params", json::array({
|
||||
json{{"name", "source_body"}, {"type", "integer"}, {"default", -1}, {"description", "body owning the edges; -1 = last body"}},
|
||||
json{{"name", "face"}, {"type", "integer"}, {"default", -1}, {"description", "global face id on the source body; when set, all its edges are projected"}},
|
||||
json{{"name", "edges"}, {"type", "array"}, {"default", json::array()}, {"description", "global edge ids to project; empty => project the face"}},
|
||||
json{{"name", "plane"}, {"type", "string"}, {"default", "XY"}, {"description", "target sketch plane (XY/XZ/YZ)"}},
|
||||
})}},
|
||||
json{{"name", "query_topology"}, {"summary", "Measured faces (centroid/normal/cylinder) and edges (length/circle) of a body."},
|
||||
{"params", json::array({
|
||||
json{{"name", "body"}, {"type", "integer"}, {"default", 0}},
|
||||
@@ -932,6 +940,24 @@ json action_split(DesignPanel* panel, const json& params)
|
||||
return json{{"ok", ok}, {"split_index", idx}, {"bodies", int(doc.bodies.size())}, {"error", doc.error}};
|
||||
}
|
||||
|
||||
json action_project(DesignPanel* panel, const json& params)
|
||||
{
|
||||
CadDocument& doc = panel->mcp_doc();
|
||||
if (doc.bodies.empty()) throw std::runtime_error("no source body to project from");
|
||||
int source_body = params.value("source_body", -1);
|
||||
int face = params.value("face", -1);
|
||||
std::vector<int> edges;
|
||||
if (params.contains("edges") && params["edges"].is_array())
|
||||
for (const auto& v : params["edges"]) edges.push_back(v.get<int>());
|
||||
SketchPlane pl = plane_from(params, doc);
|
||||
doc.checkpoint();
|
||||
int idx = doc.add_project_edges(source_body, edges, face, pl, "Project");
|
||||
bool ok = doc.recompute();
|
||||
if (!ok) doc.undo();
|
||||
panel->mcp_after_change();
|
||||
return json{{"ok", ok}, {"project_index", idx}, {"bodies", int(doc.bodies.size())}, {"error", doc.error}};
|
||||
}
|
||||
|
||||
json action_axis(DesignPanel* panel, const json& params)
|
||||
{
|
||||
CadDocument& doc = panel->mcp_doc();
|
||||
@@ -1033,6 +1059,7 @@ std::string handle_on_main(const std::string& method, const json& params, const
|
||||
if (method == "transform") return rpc_result(id, action_transform(panel, params));
|
||||
if (method == "thicken") return rpc_result(id, action_thicken(panel, params));
|
||||
if (method == "split") return rpc_result(id, action_split(panel, params));
|
||||
if (method == "project") return rpc_result(id, action_project(panel, params));
|
||||
if (method == "axis") return rpc_result(id, action_axis(panel, params));
|
||||
if (method == "coordsys") return rpc_result(id, action_coordsys(panel, params));
|
||||
if (method == "helix") return rpc_result(id, action_helix(panel, params));
|
||||
|
||||
Reference in New Issue
Block a user