mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
Fix #1956. One-button upgrade from IFC2X3 to IFC4.
This commit is contained in:
@@ -102,7 +102,7 @@ classes = [
|
||||
ui.BIM_UL_generic,
|
||||
ui.BIM_UL_topics,
|
||||
ui.BIM_ADDON_preferences,
|
||||
#scene panel groups -->
|
||||
# scene panel groups -->
|
||||
ui.BIM_PT_project_setup,
|
||||
ui.BIM_PT_utilities,
|
||||
ui.BIM_PT_collaboration,
|
||||
@@ -112,12 +112,12 @@ classes = [
|
||||
ui.BIM_PT_services,
|
||||
ui.BIM_PT_misc,
|
||||
ui.BIM_PT_quality_control,
|
||||
#object panel groups -->
|
||||
# object panel groups -->
|
||||
ui.BIM_PT_object_metadata,
|
||||
ui.BIM_PT_geometry_object,
|
||||
ui.BIM_PT_services_object,
|
||||
ui.BIM_PT_utilities_object,
|
||||
ui.BIM_PT_misc_object
|
||||
ui.BIM_PT_misc_object,
|
||||
]
|
||||
|
||||
for mod in modules.values():
|
||||
|
||||
@@ -128,6 +128,6 @@ class IFCHeaderSpecs:
|
||||
self.name = part
|
||||
elif i == 3:
|
||||
self.time_stamp = part
|
||||
elif line.startswith("FILE_SCHEMA"):
|
||||
elif line.startswith("FILE_SCHEMA"):
|
||||
self.schema_name = line.split("'")[1]
|
||||
break
|
||||
|
||||
@@ -433,7 +433,6 @@ class OverrideOutlinerDelete(bpy.types.Operator, OverrideDeleteTrait):
|
||||
while queue:
|
||||
collection = queue.pop()
|
||||
for obj in collection.objects:
|
||||
print('obj is', obj)
|
||||
objects.add(obj)
|
||||
queue.extend(collection.children)
|
||||
children = children.union(collection.children)
|
||||
|
||||
@@ -20,9 +20,10 @@ import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.ExecuteIfcPatch,
|
||||
operator.RunMigratePatch,
|
||||
operator.SelectIfcPatchInput,
|
||||
operator.SelectIfcPatchOutput,
|
||||
operator.ExecuteIfcPatch,
|
||||
operator.UpdateIfcPatchArguments,
|
||||
prop.BIMPatchProperties,
|
||||
ui.BIM_PT_patch,
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.patch as core
|
||||
import blenderbim.bim.handler
|
||||
|
||||
try:
|
||||
import ifcpatch
|
||||
@@ -114,3 +117,17 @@ class UpdateIfcPatchArguments(bpy.types.Operator):
|
||||
new_attr.name = arg_name
|
||||
new_attr.set_value(arg_info.get("default", new_attr.get_value_default()))
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RunMigratePatch(bpy.types.Operator):
|
||||
bl_idname = "bim.run_migrate_patch"
|
||||
bl_label = "Execute IFCPatch"
|
||||
infile: bpy.props.StringProperty()
|
||||
outfile: bpy.props.StringProperty()
|
||||
schema: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
core.run_migrate_patch(tool.Patch, infile=self.infile, outfile=self.outfile, schema=self.schema)
|
||||
bpy.ops.file.refresh()
|
||||
blenderbim.bim.handler.refresh_ui_data()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -47,6 +47,16 @@ class IFCFileSelector:
|
||||
split = box.split()
|
||||
split.label(text=attr_name.title().replace("_", " "))
|
||||
split.label(text=str(attr_value))
|
||||
if (
|
||||
attr_name.lower() == "schema_name"
|
||||
and str(attr_value).lower() == "ifc2x3"
|
||||
and filepath[-4:].lower() == ".ifc"
|
||||
):
|
||||
row = box.row()
|
||||
op = row.operator("bim.run_migrate_patch")
|
||||
op.infile = filepath
|
||||
op.outfile = filepath[0:-4] + "-IFC4.ifc"
|
||||
op.schema = "IFC4"
|
||||
|
||||
|
||||
class BIM_PT_section_plane(Panel):
|
||||
@@ -178,7 +188,7 @@ class BIM_PT_utilities(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -204,7 +214,7 @@ class BIM_PT_geometry(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -219,7 +229,7 @@ class BIM_PT_4D5D(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -234,7 +244,7 @@ class BIM_PT_structural(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -249,7 +259,7 @@ class BIM_PT_services(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -290,11 +300,11 @@ class BIM_PT_object_metadata(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
class BIM_PT_geometry_object(Panel):
|
||||
bl_label = "IFC Geometry"
|
||||
bl_space_type = "PROPERTIES"
|
||||
@@ -305,7 +315,7 @@ class BIM_PT_geometry_object(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -320,7 +330,7 @@ class BIM_PT_services_object(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -335,7 +345,7 @@ class BIM_PT_utilities_object(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -350,6 +360,6 @@ class BIM_PT_misc_object(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
def run_migrate_patch(patch, infile=None, outfile=None, schema=None):
|
||||
patch.run_migrate_patch(infile, outfile, schema)
|
||||
@@ -196,6 +196,11 @@ class Misc:
|
||||
def split_objects_with_cutter(cls, objs, cutter): pass
|
||||
|
||||
|
||||
@interface
|
||||
class Patch:
|
||||
def run_migrate_patch(cls, infile, outfile, schema): pass
|
||||
|
||||
|
||||
@interface
|
||||
class Owner:
|
||||
def add_address_attribute(cls, name): pass
|
||||
|
||||
@@ -29,6 +29,7 @@ from blenderbim.tool.library import Library
|
||||
from blenderbim.tool.material import Material
|
||||
from blenderbim.tool.misc import Misc
|
||||
from blenderbim.tool.owner import Owner
|
||||
from blenderbim.tool.patch import Patch
|
||||
from blenderbim.tool.pset import Pset
|
||||
from blenderbim.tool.qto import Qto
|
||||
from blenderbim.tool.root import Root
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
|
||||
try:
|
||||
import ifcpatch
|
||||
except:
|
||||
print("IfcPatch not available")
|
||||
|
||||
|
||||
class Patch(blenderbim.core.tool.Patch):
|
||||
@classmethod
|
||||
def run_migrate_patch(cls, infile, outfile, schema):
|
||||
log = os.path.join(bpy.context.scene.BIMProperties.data_dir, "process.log")
|
||||
ifcpatch.execute({"input": infile, "output": outfile, "recipe": "Migrate", "arguments": [schema], "log": log})
|
||||
@@ -9,3 +9,8 @@ Scenario: Execute IFC Patch
|
||||
And I set "scene.BIMPatchProperties.ifc_patch_args" to "[123454321,0,0,0]"
|
||||
When I press "bim.execute_ifc_patch"
|
||||
Then the file "{cwd}/test/files/basic-patched.ifc" should contain "123454321"
|
||||
|
||||
Scenario: Run migrate patch
|
||||
Given an empty Blender session
|
||||
When I press "bim.run_migrate_patch(infile='{cwd}/test/files/ifc2x3.ifc', outfile='{cwd}/test/files/ifc2x3-migrated.ifc', schema='IFC4')"
|
||||
Then the file "{cwd}/test/files/ifc2x3-migrated.ifc" should contain "IFC4"
|
||||
|
||||
@@ -112,6 +112,13 @@ def owner():
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def patch():
|
||||
prophet = Prophecy(blenderbim.core.tool.Patch)
|
||||
yield prophet
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def pset():
|
||||
prophet = Prophecy(blenderbim.core.tool.Pset)
|
||||
|
||||
@@ -122,7 +122,9 @@ class TestAddBrick:
|
||||
brick.add_brick_from_element("element", "namespace", "brick_class").should_be_called().will_return("brick_uri")
|
||||
brick.run_assign_brick_reference(element="element", library="library", brick_uri="brick_uri").should_be_called()
|
||||
brick.run_refresh_brick_viewer().should_be_called()
|
||||
subject.add_brick(ifc, brick, element="element", namespace="namespace", brick_class="brick_class", library="library")
|
||||
subject.add_brick(
|
||||
ifc, brick, element="element", namespace="namespace", brick_class="brick_class", library="library"
|
||||
)
|
||||
|
||||
def test_adding_a_plain_brick(self, ifc, brick):
|
||||
brick.add_brick("namespace", "brick_class").should_be_called()
|
||||
|
||||
@@ -60,7 +60,9 @@ class TestEditTextProduct:
|
||||
def test_run(self, ifc, drawing):
|
||||
ifc.get_entity("obj").should_be_called().will_return("element")
|
||||
drawing.get_text_product("element").should_be_called().will_return("existing_product")
|
||||
ifc.run("drawing.unassign_product", relating_product="existing_product", related_object="element").should_be_called()
|
||||
ifc.run(
|
||||
"drawing.unassign_product", relating_product="existing_product", related_object="element"
|
||||
).should_be_called()
|
||||
ifc.run("drawing.assign_product", relating_product="product", related_object="element").should_be_called()
|
||||
drawing.update_text_value("obj").should_be_called()
|
||||
drawing.disable_editing_text_product("obj").should_be_called()
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import blenderbim.core.owner as subject
|
||||
from test.core.bootstrap import patch
|
||||
|
||||
|
||||
class TestRunMigratePatch:
|
||||
def test_run(self, patch):
|
||||
patch.run_migrate_patch("infile", "outfile", "schema").should_be_called()
|
||||
assert subject.run_migrate_patch(patch, infile="infile", outfile="outfile", schema="schema")
|
||||
@@ -0,0 +1,12 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
|
||||
FILE_NAME('','2021-09-03T08:40:25',(),(),'IfcOpenShell 0.6.0b0','IfcOpenShell 0.6.0b0','');
|
||||
FILE_SCHEMA(('IFC2X3'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPERSON($,$,$,$,$,$,$,$);
|
||||
#2=IFCORGANIZATION('abc','Foobar','http://www.example.com',$,$);
|
||||
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
@@ -37,12 +37,12 @@ class TestImplementsTool(NewFile):
|
||||
class TestAddBrick(NewFile):
|
||||
def test_run(self):
|
||||
BrickStore.graph = brickschema.Graph()
|
||||
result = subject.add_brick(
|
||||
"http://example.org/digitaltwin#", "https://brickschema.org/schema/Brick#Equipment"
|
||||
)
|
||||
result = subject.add_brick("http://example.org/digitaltwin#", "https://brickschema.org/schema/Brick#Equipment")
|
||||
assert "http://example.org/digitaltwin#" in result
|
||||
assert list(
|
||||
BrickStore.graph.triples((URIRef(result), RDF.type, URIRef("https://brickschema.org/schema/Brick#Equipment")))
|
||||
BrickStore.graph.triples(
|
||||
(URIRef(result), RDF.type, URIRef("https://brickschema.org/schema/Brick#Equipment"))
|
||||
)
|
||||
)
|
||||
assert list(
|
||||
BrickStore.graph.triples(
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
from test.bim.bootstrap import NewFile
|
||||
from blenderbim.tool.patch import Patch as subject
|
||||
|
||||
|
||||
class TestImplementsTool(NewFile):
|
||||
def test_run(self):
|
||||
assert isinstance(subject(), blenderbim.core.tool.Patch)
|
||||
|
||||
|
||||
class TestRunMigratePatch(NewFile):
|
||||
def test_run(self):
|
||||
cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
infile = os.path.join(cwd, "..", "files", "ifc2x3.ifc")
|
||||
outfile = os.path.join(cwd, "..", "files", "ifc2x3-migrated.ifc")
|
||||
subject.run_migrate_patch(infile, outfile, "IFC4")
|
||||
ifc = ifcopenshell.open(outfile)
|
||||
assert ifc.schema == "IFC4"
|
||||
Reference in New Issue
Block a user