edit_object
Modify existing 3D objects in FreeCAD when creation tools are insufficient. Specify document name, object name, and properties to customize or edit designs, with success confirmation and a screenshot provided.
Instructions
Edit an object in FreeCAD.
This tool is used when the create_object tool cannot handle the object creation.
Args:
doc_name: The name of the document to edit the object in.
obj_name: The name of the object to edit.
obj_properties: The properties of the object to edit.
Returns:
A message indicating the success or failure of the object editing and a screenshot of the object.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| doc_name | Yes | ||
| obj_name | Yes | ||
| obj_properties | Yes |
Implementation Reference
- src/freecad_mcp/server.py:336-371 (handler)Primary MCP tool handler for 'edit_object'. Calls the FreeCADConnection proxy to edit object properties via RPC and returns success message with optional screenshot.@mcp.tool() def edit_object( ctx: Context, doc_name: str, obj_name: str, obj_properties: dict[str, Any] ) -> list[TextContent | ImageContent]: """Edit an object in FreeCAD. This tool is used when the `create_object` tool cannot handle the object creation. Args: doc_name: The name of the document to edit the object in. obj_name: The name of the object to edit. obj_properties: The properties of the object to edit. Returns: A message indicating the success or failure of the object editing and a screenshot of the object. """ freecad = get_freecad_connection() try: res = freecad.edit_object(doc_name, obj_name, {"Properties": obj_properties}) screenshot = freecad.get_active_screenshot() if res["success"]: response = [ TextContent(type="text", text=f"Object '{res['object_name']}' edited successfully"), ] return add_screenshot_if_available(response, screenshot) else: response = [ TextContent(type="text", text=f"Failed to edit object: {res['error']}"), ] return add_screenshot_if_available(response, screenshot) except Exception as e: logger.error(f"Failed to edit object: {str(e)}") return [ TextContent(type="text", text=f"Failed to edit object: {str(e)}") ]
- src/freecad_mcp/server.py:33-34 (helper)Proxy method in FreeCADConnection class that forwards edit_object calls to the XML-RPC server.def edit_object(self, doc_name: str, obj_name: str, obj_data: dict[str, Any]) -> dict[str, Any]: return self.server.edit_object(doc_name, obj_name, obj_data)
- Core implementation of object editing in the GUI thread. Handles property setting, special cases like References for FEM constraints, and document recompute.def _edit_object_gui(self, doc_name: str, obj: Object): doc = FreeCAD.getDocument(doc_name) if not doc: FreeCAD.Console.PrintError(f"Document '{doc_name}' not found.\n") return f"Document '{doc_name}' not found.\n" obj_ins = doc.getObject(obj.name) if not obj_ins: FreeCAD.Console.PrintError(f"Object '{obj.name}' not found in document '{doc_name}'.\n") return f"Object '{obj.name}' not found in document '{doc_name}'.\n" try: # For Fem::ConstraintFixed if hasattr(obj_ins, "References") and "References" in obj.properties: refs = [] for ref_name, face in obj.properties["References"]: ref_obj = doc.getObject(ref_name) if ref_obj: refs.append((ref_obj, face)) else: raise ValueError(f"Referenced object '{ref_name}' not found.") obj_ins.References = refs FreeCAD.Console.PrintMessage( f"References updated for '{obj.name}' in '{doc_name}'.\n" ) # delete References from properties del obj.properties["References"] set_object_property(doc, obj_ins, obj.properties) doc.recompute() FreeCAD.Console.PrintMessage(f"Object '{obj.name}' updated via RPC.\n") return True except Exception as e: return str(e)
- RPC server entry point for edit_object. Queues the GUI task and returns success/error response.def edit_object(self, doc_name: str, obj_name: str, properties: dict[str, Any]) -> dict[str, Any]: obj = Object( name=obj_name, properties=properties.get("Properties", {}), ) rpc_request_queue.put(lambda: self._edit_object_gui(doc_name, obj)) res = rpc_response_queue.get() if res is True: return {"success": True, "object_name": obj.name} else: return {"success": False, "error": res}
- Utility function to set object properties, handling special FreeCAD types like Placement, Vector, References, and ViewObject properties.def set_object_property( doc: FreeCAD.Document, obj: FreeCAD.DocumentObject, properties: dict[str, Any] ): for prop, val in properties.items(): try: if prop in obj.PropertiesList: if prop == "Placement" and isinstance(val, dict): if "Base" in val: pos = val["Base"] elif "Position" in val: pos = val["Position"] else: pos = {} rot = val.get("Rotation", {}) placement = FreeCAD.Placement( FreeCAD.Vector( pos.get("x", 0), pos.get("y", 0), pos.get("z", 0), ), FreeCAD.Rotation( FreeCAD.Vector( rot.get("Axis", {}).get("x", 0), rot.get("Axis", {}).get("y", 0), rot.get("Axis", {}).get("z", 1), ), rot.get("Angle", 0), ), ) setattr(obj, prop, placement) elif isinstance(getattr(obj, prop), FreeCAD.Vector) and isinstance( val, dict ): vector = FreeCAD.Vector( val.get("x", 0), val.get("y", 0), val.get("z", 0) ) setattr(obj, prop, vector) elif prop in ["Base", "Tool", "Source", "Profile"] and isinstance( val, str ): ref_obj = doc.getObject(val) if ref_obj: setattr(obj, prop, ref_obj) else: raise ValueError(f"Referenced object '{val}' not found.") elif prop == "References" and isinstance(val, list): refs = [] for ref_name, face in val: ref_obj = doc.getObject(ref_name) if ref_obj: refs.append((ref_obj, face)) else: raise ValueError(f"Referenced object '{ref_name}' not found.") setattr(obj, prop, refs) else: setattr(obj, prop, val) # ShapeColor is a property of the ViewObject elif prop == "ShapeColor" and isinstance(val, (list, tuple)): setattr(obj.ViewObject, prop, (float(val[0]), float(val[1]), float(val[2]), float(val[3]))) elif prop == "ViewObject" and isinstance(val, dict): for k, v in val.items(): if k == "ShapeColor": setattr(obj.ViewObject, k, (float(v[0]), float(v[1]), float(v[2]), float(v[3]))) else: setattr(obj.ViewObject, k, v) else: setattr(obj, prop, val) except Exception as e: FreeCAD.Console.PrintError(f"Property '{prop}' assignment error: {e}\n")