Skip to main content
Glama

create_object

Add 3D objects like boxes, cylinders, circles, FEM elements, or mechanical parts to FreeCAD documents with customizable properties.

Instructions

Create a new object in FreeCAD. Object type is starts with "Part::" or "Draft::" or "PartDesign::" or "Fem::".

Args:
    doc_name: The name of the document to create the object in.
    obj_type: The type of the object to create (e.g. 'Part::Box', 'Part::Cylinder', 'Draft::Circle', 'PartDesign::Body', etc.).
    obj_name: The name of the object to create.
    obj_properties: The properties of the object to create.

Returns:
    A message indicating the success or failure of the object creation and a screenshot of the object.

Examples:
    If you want to create a cylinder with a height of 30 and a radius of 10, you can use the following data.
    ```json
    {
        "doc_name": "MyCylinder",
        "obj_name": "Cylinder",
        "obj_type": "Part::Cylinder",
        "obj_properties": {
            "Height": 30,
            "Radius": 10,
            "Placement": {
                "Base": {
                    "x": 10,
                    "y": 10,
                    "z": 0
                },
                "Rotation": {
                    "Axis": {
                        "x": 0,
                        "y": 0,
                        "z": 1
                    },
                    "Angle": 45
                }
            },
            "ViewObject": {
                "ShapeColor": [0.5, 0.5, 0.5, 1.0]
            }
        }
    }
    ```

    If you want to create a circle with a radius of 10, you can use the following data.
    ```json
    {
        "doc_name": "MyCircle",
        "obj_name": "Circle",
        "obj_type": "Draft::Circle",
    }
    ```

    If you want to create a FEM analysis, you can use the following data.
    ```json
    {
        "doc_name": "MyFEMAnalysis",
        "obj_name": "FemAnalysis",
        "obj_type": "Fem::AnalysisPython",
    }
    ```

    If you want to create a FEM constraint, you can use the following data.
    ```json
    {
        "doc_name": "MyFEMConstraint",
        "obj_name": "FemConstraint",
        "obj_type": "Fem::ConstraintFixed",
        "analysis_name": "MyFEMAnalysis",
        "obj_properties": {
            "References": [
                {
                    "object_name": "MyObject",
                    "face": "Face1"
                }
            ]
        }
    }
    ```

    If you want to create a FEM mechanical material, you can use the following data.
    ```json
    {
        "doc_name": "MyFEMAnalysis",
        "obj_name": "FemMechanicalMaterial",
        "obj_type": "Fem::MaterialCommon",
        "analysis_name": "MyFEMAnalysis",
        "obj_properties": {
            "Material": {
                "Name": "MyMaterial",
                "Density": "7900 kg/m^3",
                "YoungModulus": "210 GPa",
                "PoissonRatio": 0.3
            }
        }
    }
    ```

    If you want to create a FEM mesh, you can use the following data.
    The `Part` property is required.
    ```json
    {
        "doc_name": "MyFEMMesh",
        "obj_name": "FemMesh",
        "obj_type": "Fem::FemMeshGmsh",
        "analysis_name": "MyFEMAnalysis",
        "obj_properties": {
            "Part": "MyObject",
            "ElementSizeMax": 10,
            "ElementSizeMin": 0.1,
            "MeshAlgorithm": 2
        }
    }
    ```

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
doc_nameYes
obj_typeYes
obj_nameYes
analysis_nameNo
obj_propertiesNo

Implementation Reference

  • MCP tool handler for 'create_object'. Registers the tool and handles the MCP call by proxying to FreeCADConnection.create_object RPC method, adding screenshot feedback.
    @mcp.tool()
    def create_object(
        ctx: Context,
        doc_name: str,
        obj_type: str,
        obj_name: str,
        analysis_name: str | None = None,
        obj_properties: dict[str, Any] = None,
    ) -> list[TextContent | ImageContent]:
        """Create a new object in FreeCAD.
        Object type is starts with "Part::" or "Draft::" or "PartDesign::" or "Fem::".
    
        Args:
            doc_name: The name of the document to create the object in.
            obj_type: The type of the object to create (e.g. 'Part::Box', 'Part::Cylinder', 'Draft::Circle', 'PartDesign::Body', etc.).
            obj_name: The name of the object to create.
            obj_properties: The properties of the object to create.
    
        Returns:
            A message indicating the success or failure of the object creation and a screenshot of the object.
    
        Examples:
            If you want to create a cylinder with a height of 30 and a radius of 10, you can use the following data.
            ```json
            {
                "doc_name": "MyCylinder",
                "obj_name": "Cylinder",
                "obj_type": "Part::Cylinder",
                "obj_properties": {
                    "Height": 30,
                    "Radius": 10,
                    "Placement": {
                        "Base": {
                            "x": 10,
                            "y": 10,
                            "z": 0
                        },
                        "Rotation": {
                            "Axis": {
                                "x": 0,
                                "y": 0,
                                "z": 1
                            },
                            "Angle": 45
                        }
                    },
                    "ViewObject": {
                        "ShapeColor": [0.5, 0.5, 0.5, 1.0]
                    }
                }
            }
            ```
    
            If you want to create a circle with a radius of 10, you can use the following data.
            ```json
            {
                "doc_name": "MyCircle",
                "obj_name": "Circle",
                "obj_type": "Draft::Circle",
            }
            ```
    
            If you want to create a FEM analysis, you can use the following data.
            ```json
            {
                "doc_name": "MyFEMAnalysis",
                "obj_name": "FemAnalysis",
                "obj_type": "Fem::AnalysisPython",
            }
            ```
    
            If you want to create a FEM constraint, you can use the following data.
            ```json
            {
                "doc_name": "MyFEMConstraint",
                "obj_name": "FemConstraint",
                "obj_type": "Fem::ConstraintFixed",
                "analysis_name": "MyFEMAnalysis",
                "obj_properties": {
                    "References": [
                        {
                            "object_name": "MyObject",
                            "face": "Face1"
                        }
                    ]
                }
            }
            ```
    
            If you want to create a FEM mechanical material, you can use the following data.
            ```json
            {
                "doc_name": "MyFEMAnalysis",
                "obj_name": "FemMechanicalMaterial",
                "obj_type": "Fem::MaterialCommon",
                "analysis_name": "MyFEMAnalysis",
                "obj_properties": {
                    "Material": {
                        "Name": "MyMaterial",
                        "Density": "7900 kg/m^3",
                        "YoungModulus": "210 GPa",
                        "PoissonRatio": 0.3
                    }
                }
            }
            ```
    
            If you want to create a FEM mesh, you can use the following data.
            The `Part` property is required.
            ```json
            {
                "doc_name": "MyFEMMesh",
                "obj_name": "FemMesh",
                "obj_type": "Fem::FemMeshGmsh",
                "analysis_name": "MyFEMAnalysis",
                "obj_properties": {
                    "Part": "MyObject",
                    "ElementSizeMax": 10,
                    "ElementSizeMin": 0.1,
                    "MeshAlgorithm": 2
                }
            }
            ```
        """
        freecad = get_freecad_connection()
        try:
            obj_data = {"Name": obj_name, "Type": obj_type, "Properties": obj_properties or {}, "Analysis": analysis_name}
            res = freecad.create_object(doc_name, obj_data)
            screenshot = freecad.get_active_screenshot()
            
            if res["success"]:
                response = [
                    TextContent(type="text", text=f"Object '{res['object_name']}' created successfully"),
                ]
                return add_screenshot_if_available(response, screenshot)
            else:
                response = [
                    TextContent(type="text", text=f"Failed to create object: {res['error']}"),
                ]
                return add_screenshot_if_available(response, screenshot)
        except Exception as e:
            logger.error(f"Failed to create object: {str(e)}")
            return [
                TextContent(type="text", text=f"Failed to create object: {str(e)}")
            ]
  • Core FreeCAD GUI-thread-safe handler for object creation. Handles special cases for FEM meshes and objects, uses doc.addObject for primitives, sets properties, and recomputes the document.
    def _create_object_gui(self, doc_name, obj: Object):
        doc = FreeCAD.getDocument(doc_name)
        if doc:
            try:
                if obj.type == "Fem::FemMeshGmsh" and obj.analysis:
                    from femmesh.gmshtools import GmshTools
                    res = getattr(doc, obj.analysis).addObject(ObjectsFem.makeMeshGmsh(doc, obj.name))[0]
                    if "Part" in obj.properties:
                        target_obj = doc.getObject(obj.properties["Part"])
                        if target_obj:
                            res.Part = target_obj
                        else:
                            raise ValueError(f"Referenced object '{obj.properties['Part']}' not found.")
                        del obj.properties["Part"]
                    else:
                        raise ValueError("'Part' property not found in properties.")
    
                    for param, value in obj.properties.items():
                        if hasattr(res, param):
                            setattr(res, param, value)
                    doc.recompute()
    
                    gmsh_tools = GmshTools(res)
                    gmsh_tools.create_mesh()
                    FreeCAD.Console.PrintMessage(
                        f"FEM Mesh '{res.Name}' generated successfully in '{doc_name}'.\n"
                    )
                elif obj.type.startswith("Fem::"):
                    fem_make_methods = {
                        "MaterialCommon": ObjectsFem.makeMaterialSolid,
                        "AnalysisPython": ObjectsFem.makeAnalysis,
                    }
                    obj_type_short = obj.type.split("::")[1]
                    method_name = "make" + obj_type_short
                    make_method = fem_make_methods.get(obj_type_short, getattr(ObjectsFem, method_name, None))
    
                    if callable(make_method):
                        res = make_method(doc, obj.name)
                        set_object_property(doc, res, obj.properties)
                        FreeCAD.Console.PrintMessage(
                            f"FEM object '{res.Name}' created with '{method_name}'.\n"
                        )
                    else:
                        raise ValueError(f"No creation method '{method_name}' found in ObjectsFem.")
                    if obj.type != "Fem::AnalysisPython" and obj.analysis:
                        getattr(doc, obj.analysis).addObject(res)
                else:
                    res = doc.addObject(obj.type, obj.name)
                    set_object_property(doc, res, obj.properties)
                    FreeCAD.Console.PrintMessage(
                        f"{res.TypeId} '{res.Name}' added to '{doc_name}' via RPC.\n"
                    )
    
                doc.recompute()
                return True
            except Exception as e:
                return str(e)
        else:
            FreeCAD.Console.PrintError(f"Document '{doc_name}' not found.\n")
            return f"Document '{doc_name}' not found.\n"
  • RPC server entry point for create_object. Parses obj_data into Object dataclass and queues the GUI-thread-safe _create_object_gui task.
    def create_object(self, doc_name, obj_data: dict[str, Any]):
        obj = Object(
            name=obj_data.get("Name", "New_Object"),
            type=obj_data["Type"],
            analysis=obj_data.get("Analysis", None),
            properties=obj_data.get("Properties", {}),
        )
        rpc_request_queue.put(lambda: self._create_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}
  • Helper function to set object properties, handling special FreeCAD types like Placement, Vector, References, 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")
  • Proxy method in FreeCADConnection class that forwards create_object calls to the XML-RPC server.
    def create_object(self, doc_name: str, obj_data: dict[str, Any]) -> dict[str, Any]:
        return self.server.create_object(doc_name, obj_data)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/heok-yongssun/freecad-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server