"""Apply OBJ Mesh.Mesh patch to export.py - targeting only export_obj.""" with open("src/freecad_mcp/tools/export.py", "r") as f: content = f.read() old = """ async def export_obj( file_path: str, object_names: list[str] | None = None, doc_name: str | None = None, mesh_tolerance: float = 0.1, ) -> dict[str, Any]: \"\"\"Export objects to OBJ format. OBJ (Wavefront) is a common 3D model format supported by many 3D graphics applications and game engines. Args:\"\"\" bridge = await get_bridge() code = f\"\"\" import Mesh doc = FreeCAD.ActiveDocument if {doc_name!r} is None else FreeCAD.getDocument({doc_name!r}) if doc is None: raise ValueError(\"No document found\") {_build_object_selection_code(object_names)} # Create mesh from shapes meshes = [] for obj in objects: mesh = Mesh.Mesh() mesh.addFacets(obj.Shape.tessellate({mesh_tolerance})[0]) meshes.append(mesh)""" new = """ async def export_obj( file_path: str, object_names: list[str] | None = None, doc_name: str | None = None, mesh_tolerance: float = 0.1, ) -> dict[str, Any]: \"\"\"Export objects to OBJ format. OBJ (Wavefront) is a common 3D model format supported by many 3D graphics applications and game engines. Args:\"\"\" bridge = await get_bridge() code = f\"\"\" import Mesh doc = FreeCAD.ActiveDocument if {doc_name!r} is None else FreeCAD.getDocument({doc_name!r}) if doc is None: raise ValueError(\"No document found\") {_build_object_selection_code(object_names)} # Create mesh from shapes (FC 1.1.1: Mesh.Mesh(shape.tessellate()) instead of addFacets) meshes = [] for obj in objects: mesh = Mesh.Mesh(obj.Shape.tessellate({mesh_tolerance})) meshes.append(mesh)""" count = content.count(old) print(f"OBJ: found {count} occurrences") if count == 1: content = content.replace(old, new) with open("src/freecad_mcp/tools/export.py", "w") as f: f.write(content) print("OBJ patch applied") else: print("Not unique - need manual edit")