diff --git a/src/blenderbim/blenderbim/bim/module/patch/operator.py b/src/blenderbim/blenderbim/bim/module/patch/operator.py index 14a7067cf3..44b48969bd 100644 --- a/src/blenderbim/blenderbim/bim/module/patch/operator.py +++ b/src/blenderbim/blenderbim/bim/module/patch/operator.py @@ -82,7 +82,8 @@ class ExecuteIfcPatch(bpy.types.Operator): output = ifcpatch.execute( { - "input": ifcopenshell.open(props.ifc_patch_input), + "input": props.ifc_patch_input, + "file": ifcopenshell.open(props.ifc_patch_input), "recipe": props.ifc_patch_recipes, "arguments": arguments, "log": os.path.join(context.scene.BIMProperties.data_dir, "process.log"), diff --git a/src/ifcpatch/ifcpatch/__init__.py b/src/ifcpatch/ifcpatch/__init__.py index f336e9c2ba..3ad25ee8b3 100644 --- a/src/ifcpatch/ifcpatch/__init__.py +++ b/src/ifcpatch/ifcpatch/__init__.py @@ -37,8 +37,10 @@ def execute(args): :param args: A dictionary of arguments, corresponding to the parameters listed subsequent to this in this docstring. :type args: dict - :param input: An IFC model to apply the patch recipe to. - :type input: ifcopenshell.file.file + :param input: A filepath to the incoming IFC file. + :type input: str + :param file: An IFC model to apply the patch recipe to. + :type file: ifcopenshell.file.file :param recipe: The name of the recipe. This is the same as the filename of the recipe. E.g. "ExtractElements". :type recipe: str @@ -57,7 +59,8 @@ def execute(args): .. code:: python output = ifcpatch.execute({ - "input": ifcopenshell.open("input.ifc"), + "input": "input.ifc", + "file": ifcopenshell.open("input.ifc"), "recipe": "ExtractElements", "arguments": [".IfcWall"], }) @@ -70,9 +73,9 @@ def execute(args): recipes = getattr(__import__("ifcpatch.recipes.{}".format(args["recipe"])), "recipes") recipe = getattr(recipes, args["recipe"]) if recipe.Patcher.__init__.__doc__ is not None: - patcher = recipe.Patcher(args["input"], ifc_file, logger, *args["arguments"]) + patcher = recipe.Patcher(args["input"], args["file"], logger, *args["arguments"]) else: - patcher = recipe.Patcher(args["input"], ifc_file, logger, args["arguments"]) + patcher = recipe.Patcher(args["input"], args["file"], logger, args["arguments"]) patcher.patch() output = getattr(patcher, "file_patched", patcher.file) return output diff --git a/src/ifcpatch/ifcpatch/__main__.py b/src/ifcpatch/ifcpatch/__main__.py index db931616c2..178259694d 100644 --- a/src/ifcpatch/ifcpatch/__main__.py +++ b/src/ifcpatch/ifcpatch/__main__.py @@ -31,7 +31,7 @@ parser.add_argument("-a", "--arguments", nargs="+", help="Specify custom argumen args = vars(parser.parse_args()) print("# Loading IFC file ...") -args["input"] = ifcopenshell.open(args["input"]) +args["file"] = ifcopenshell.open(args["input"]) print("# Patching ...") output = ifcpatch.execute(args) diff --git a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py index ef9cbea64c..53203a35dd 100644 --- a/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py +++ b/src/ifcpatch/ifcpatch/recipes/FixArchiCADToRevitSpaces.py @@ -7,9 +7,9 @@ class Patcher: broken for at least 3 years and counting. This is a problem typically for ArchiCAD architects who want to send rooms to MEP folks using Revit. - + See bug: https://github.com/Autodesk/revit-ifc/issues/15 - + The solution is to open an IFC in Revit instead of linking it, which will convert IFC spaces into Revit rooms. However, there are very specific scenarios where Revit will convert these rooms, which have @@ -21,7 +21,7 @@ class Patcher: robust results. Finally, changing the Precision value to an obscene number very strangely seems to cause a lot more rooms to be converted successfully. - + This patch is designed to only work on ArchiCAD IFC exports where the only contents of the IFC is IFC space and `nothing else`. It also requires you to run it using Blender, as the geometric modification @@ -39,6 +39,9 @@ class Patcher: def patch(self): import bpy + import blenderbim.tool as tool + import ifcopenshell + import ifcopenshell.util.element from blenderbim.bim.ifc import IfcStore from mathutils import Vector, Matrix @@ -59,14 +62,16 @@ class Patcher: ) wall.matrix_world.translation = new_origin - for obj in bpy.context.visible_objects: - if "IfcBuildingStorey" in obj.name and len(bpy.data.collections.get(obj.name).children) > 0: - target_z = obj.location.z - for obj in bpy.context.visible_objects: bpy.context.view_layer.update() if "IfcSpace" not in obj.name: continue + + element = tool.Ifc.get_entity(obj) + storey = ifcopenshell.util.element.get_aggregate(element) + storey_obj = tool.Ifc.get_object(storey) + target_z = storey_obj.location.z + local_target_z = (obj.matrix_world.inverted() @ Vector((0, 0, target_z))).z local_target_zup = (obj.matrix_world.inverted() @ Vector((0, 0, target_z + 3))).z for v in obj.data.vertices: @@ -79,7 +84,7 @@ class Patcher: bpy.ops.bim.update_representation( ifc_representation_class="IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids" ) - for context in IfcStore.get_file().by_type("IfcGeometricRepresentationContext"): + for context in IfcStore.get_file().by_type("IfcGeometricRepresentationContext", include_subtypes=False): if context.Precision: context.Precision = 10