mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-02 13:04:49 +00:00
Assigning a parametric profile type now auto switches from non parametric geometry to parametric geometry
This commit is contained in:
@@ -17,13 +17,13 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import bmesh
|
|
||||||
import math
|
import math
|
||||||
|
import bmesh
|
||||||
|
import mathutils.geometry
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.util.type
|
import ifcopenshell.util.type
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import mathutils.geometry
|
|
||||||
import blenderbim.bim.handler
|
import blenderbim.bim.handler
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.core.type
|
import blenderbim.core.type
|
||||||
@@ -100,9 +100,7 @@ def ensure_solid(usecase_path, ifc_file, settings):
|
|||||||
material = ifcopenshell.util.element.get_material(product)
|
material = ifcopenshell.util.element.get_material(product)
|
||||||
if material and material.is_a("IfcMaterialProfileSetUsage"):
|
if material and material.is_a("IfcMaterialProfileSetUsage"):
|
||||||
settings["profile_set_usage"] = material
|
settings["profile_set_usage"] = material
|
||||||
else:
|
settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
||||||
return
|
|
||||||
settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
|
||||||
|
|
||||||
|
|
||||||
class DumbProfileGenerator:
|
class DumbProfileGenerator:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class AssignType(bpy.types.Operator, Operator):
|
|||||||
else context.selected_objects or [context.active_object]
|
else context.selected_objects or [context.active_object]
|
||||||
)
|
)
|
||||||
for obj in related_objects:
|
for obj in related_objects:
|
||||||
core.assign_type(tool.Ifc, tool.Geometry, tool.Type, element=tool.Ifc.get_entity(obj), type=type)
|
core.assign_type(tool.Ifc, tool.Type, element=tool.Ifc.get_entity(obj), type=type)
|
||||||
oprops = obj.BIMObjectProperties
|
oprops = obj.BIMObjectProperties
|
||||||
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
Data.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||||
GeometryData.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
GeometryData.load(IfcStore.get_file(), oprops.ifc_definition_id)
|
||||||
|
|||||||
@@ -74,12 +74,7 @@ def add_representation(
|
|||||||
|
|
||||||
|
|
||||||
def switch_representation(
|
def switch_representation(
|
||||||
geometry,
|
geometry, obj=None, representation=None, should_reload=True, enable_dynamic_voids=True, is_global=True
|
||||||
obj=None,
|
|
||||||
representation=None,
|
|
||||||
should_reload=True,
|
|
||||||
enable_dynamic_voids=True,
|
|
||||||
is_global=True,
|
|
||||||
):
|
):
|
||||||
representation = geometry.resolve_mapped_representation(representation)
|
representation = geometry.resolve_mapped_representation(representation)
|
||||||
data = geometry.get_representation_data(representation)
|
data = geometry.get_representation_data(representation)
|
||||||
|
|||||||
@@ -197,8 +197,15 @@ class Surveyor:
|
|||||||
class Type:
|
class Type:
|
||||||
def disable_editing(cls, obj): pass
|
def disable_editing(cls, obj): pass
|
||||||
def get_any_representation(cls, element): pass
|
def get_any_representation(cls, element): pass
|
||||||
|
def get_body_context(cls): pass
|
||||||
def get_body_representation(cls, element): pass
|
def get_body_representation(cls, element): pass
|
||||||
|
def get_ifc_representation_class(cls, element): pass
|
||||||
|
def get_profile_set_usage(cls, element): pass
|
||||||
|
def get_representation_context(cls, representation): pass
|
||||||
def has_dynamic_voids(cls, obj): pass
|
def has_dynamic_voids(cls, obj): pass
|
||||||
|
def has_material_usage(cls, element): pass
|
||||||
|
def run_geometry_add_representation(cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None): pass
|
||||||
|
def run_geometry_switch_representation(cls, obj=None, representation=None, should_reload=None, enable_dynamic_voids=None, is_global=None): pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
|
|||||||
@@ -19,18 +19,34 @@
|
|||||||
import blenderbim.core.geometry
|
import blenderbim.core.geometry
|
||||||
|
|
||||||
|
|
||||||
def assign_type(ifc, geometry, type_tool, element=None, type=None):
|
def assign_type(ifc, type_tool, element=None, type=None):
|
||||||
ifc.run("type.assign_type", related_object=element, relating_type=type)
|
ifc.run("type.assign_type", related_object=element, relating_type=type)
|
||||||
representation = type_tool.get_body_representation(element)
|
|
||||||
if not representation:
|
|
||||||
representation = type_tool.get_any_representation(element)
|
|
||||||
obj = ifc.get_object(element)
|
obj = ifc.get_object(element)
|
||||||
|
if type_tool.has_material_usage(element):
|
||||||
|
representation = type_tool.get_body_representation(element)
|
||||||
|
if representation:
|
||||||
|
body_context = type_tool.get_representation_context(representation)
|
||||||
|
ifc.run("geometry.unassign_representation", product=element, representation=representation)
|
||||||
|
ifc.run("geometry.remove_representation", representation=representation)
|
||||||
|
else:
|
||||||
|
body_context = type_tool.get_body_context()
|
||||||
|
representation = type_tool.run_geometry_add_representation(
|
||||||
|
obj=obj,
|
||||||
|
context=body_context,
|
||||||
|
ifc_representation_class=type_tool.get_ifc_representation_class(element),
|
||||||
|
profile_set_usage=type_tool.get_profile_set_usage(element),
|
||||||
|
)
|
||||||
|
should_reload = True
|
||||||
|
else:
|
||||||
|
representation = type_tool.get_body_representation(element)
|
||||||
|
if not representation:
|
||||||
|
representation = type_tool.get_any_representation(element)
|
||||||
|
should_reload = False
|
||||||
if representation:
|
if representation:
|
||||||
blenderbim.core.geometry.switch_representation(
|
type_tool.run_geometry_switch_representation(
|
||||||
geometry,
|
|
||||||
obj=obj,
|
obj=obj,
|
||||||
representation=representation,
|
representation=representation,
|
||||||
should_reload=False,
|
should_reload=should_reload,
|
||||||
enable_dynamic_voids=type_tool.has_dynamic_voids(obj),
|
enable_dynamic_voids=type_tool.has_dynamic_voids(obj),
|
||||||
is_global=False,
|
is_global=False,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
|
import blenderbim.core.geometry
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
import blenderbim.bim.helper
|
import blenderbim.bim.helper
|
||||||
|
|
||||||
@@ -34,6 +35,10 @@ class Type(blenderbim.core.tool.Type):
|
|||||||
elif element.is_a("IfcTypeProduct") and element.RepresentationMaps:
|
elif element.is_a("IfcTypeProduct") and element.RepresentationMaps:
|
||||||
return element.RepresentationMaps[0].MappedRepresentation
|
return element.RepresentationMaps[0].MappedRepresentation
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_body_context(cls):
|
||||||
|
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_body_representation(cls, element):
|
def get_body_representation(cls, element):
|
||||||
if element.is_a("IfcProduct") and element.Representation and element.Representation.Representations:
|
if element.is_a("IfcProduct") and element.Representation and element.Representation.Representations:
|
||||||
@@ -45,9 +50,64 @@ class Type(blenderbim.core.tool.Type):
|
|||||||
if representation_map.MappedRepresentation.ContextOfItems.ContextIdentifier == "Body":
|
if representation_map.MappedRepresentation.ContextOfItems.ContextIdentifier == "Body":
|
||||||
return representation_map.MappedRepresentation
|
return representation_map.MappedRepresentation
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_ifc_representation_class(cls, element):
|
||||||
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
|
if material:
|
||||||
|
if material.is_a("IfcMaterialProfileSetUsage"):
|
||||||
|
return "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
||||||
|
elif material.is_a("IfcMaterialLayerSetUsage"):
|
||||||
|
return "IfcExtrudedAreaSolid/IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_profile_set_usage(cls, element):
|
||||||
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
|
if material:
|
||||||
|
if material.is_a("IfcMaterialProfileSetUsage"):
|
||||||
|
return material
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_representation_context(cls, representation):
|
||||||
|
return representation.ContextOfItems
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def has_dynamic_voids(cls, obj):
|
def has_dynamic_voids(cls, obj):
|
||||||
for modifier in obj.modifiers:
|
for modifier in obj.modifiers:
|
||||||
if modifier.name == "IfcOpeningElement" and modifier.type == "BOOLEAN":
|
if modifier.name == "IfcOpeningElement" and modifier.type == "BOOLEAN":
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def has_material_usage(cls, element):
|
||||||
|
material = ifcopenshell.util.element.get_material(element)
|
||||||
|
if material:
|
||||||
|
return "Usage" in material.is_a()
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run_geometry_add_representation(
|
||||||
|
cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None
|
||||||
|
):
|
||||||
|
return blenderbim.core.geometry.add_representation(
|
||||||
|
tool.Ifc,
|
||||||
|
tool.Geometry,
|
||||||
|
tool.Style,
|
||||||
|
tool.Surveyor,
|
||||||
|
obj=obj,
|
||||||
|
context=context,
|
||||||
|
ifc_representation_class=ifc_representation_class,
|
||||||
|
profile_set_usage=profile_set_usage,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def run_geometry_switch_representation(
|
||||||
|
cls, obj=None, representation=None, should_reload=None, enable_dynamic_voids=None, is_global=None
|
||||||
|
):
|
||||||
|
return blenderbim.core.geometry.switch_representation(
|
||||||
|
tool.Geometry,
|
||||||
|
obj=obj,
|
||||||
|
representation=representation,
|
||||||
|
should_reload=should_reload,
|
||||||
|
enable_dynamic_voids=enable_dynamic_voids,
|
||||||
|
is_global=is_global,
|
||||||
|
)
|
||||||
|
|||||||
@@ -17,45 +17,84 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import blenderbim.core.type as subject
|
import blenderbim.core.type as subject
|
||||||
from test.core.bootstrap import ifc, geometry, type
|
from test.core.bootstrap import ifc, type
|
||||||
|
|
||||||
|
|
||||||
class TestAssignType:
|
class TestAssignType:
|
||||||
def test_assigning_and_switching_preferably_to_a_body_representation(self, ifc, geometry, type):
|
def test_assigning_and_switching_preferably_to_a_body_representation(self, ifc, type):
|
||||||
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
||||||
|
type.has_material_usage("element").should_be_called().will_return(False)
|
||||||
type.get_body_representation("element").should_be_called().will_return("mapped_rep")
|
type.get_body_representation("element").should_be_called().will_return("mapped_rep")
|
||||||
ifc.get_object("element").should_be_called().will_return("obj")
|
ifc.get_object("element").should_be_called().will_return("obj")
|
||||||
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
||||||
|
type.run_geometry_switch_representation(
|
||||||
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
|
obj="obj", representation="mapped_rep", should_reload=False, enable_dynamic_voids=False, is_global=False
|
||||||
geometry.get_representation_data("representation").should_be_called().will_return("data")
|
).should_be_called()
|
||||||
geometry.change_object_data("obj", "data", is_global=False).should_be_called()
|
|
||||||
geometry.clear_dynamic_voids("obj").should_be_called()
|
|
||||||
|
|
||||||
type.disable_editing("obj").should_be_called()
|
type.disable_editing("obj").should_be_called()
|
||||||
|
subject.assign_type(ifc, type, element="element", type="type")
|
||||||
|
|
||||||
subject.assign_type(ifc, geometry, type, element="element", type="type")
|
def test_assigning_and_switching_to_any_representation_as_a_fallback(self, ifc, type):
|
||||||
|
|
||||||
def test_assigning_and_switching_to_any_representation_as_a_fallback(self, ifc, geometry, type):
|
|
||||||
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
||||||
|
type.has_material_usage("element").should_be_called().will_return(False)
|
||||||
type.get_body_representation("element").should_be_called().will_return(None)
|
type.get_body_representation("element").should_be_called().will_return(None)
|
||||||
type.get_any_representation("element").should_be_called().will_return("mapped_rep")
|
type.get_any_representation("element").should_be_called().will_return("mapped_rep")
|
||||||
ifc.get_object("element").should_be_called().will_return("obj")
|
ifc.get_object("element").should_be_called().will_return("obj")
|
||||||
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
||||||
|
type.run_geometry_switch_representation(
|
||||||
geometry.resolve_mapped_representation("mapped_rep").should_be_called().will_return("representation")
|
obj="obj", representation="mapped_rep", should_reload=False, enable_dynamic_voids=False, is_global=False
|
||||||
geometry.get_representation_data("representation").should_be_called().will_return("data")
|
).should_be_called()
|
||||||
geometry.change_object_data("obj", "data", is_global=False).should_be_called()
|
|
||||||
geometry.clear_dynamic_voids("obj").should_be_called()
|
|
||||||
|
|
||||||
type.disable_editing("obj").should_be_called()
|
type.disable_editing("obj").should_be_called()
|
||||||
|
subject.assign_type(ifc, type, element="element", type="type")
|
||||||
|
|
||||||
subject.assign_type(ifc, geometry, type, element="element", type="type")
|
def test_assigning_and_not_changing_representation_if_there_is_no_representation_to_change_to(self, ifc, type):
|
||||||
|
|
||||||
def test_assigning_and_not_changing_representation_if_not_available(self, ifc, type):
|
|
||||||
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
||||||
|
type.has_material_usage("element").should_be_called().will_return(False)
|
||||||
type.get_body_representation("element").should_be_called().will_return(None)
|
type.get_body_representation("element").should_be_called().will_return(None)
|
||||||
type.get_any_representation("element").should_be_called().will_return(None)
|
type.get_any_representation("element").should_be_called().will_return(None)
|
||||||
ifc.get_object("element").should_be_called().will_return("obj")
|
ifc.get_object("element").should_be_called().will_return("obj")
|
||||||
type.disable_editing("obj").should_be_called()
|
type.disable_editing("obj").should_be_called()
|
||||||
subject.assign_type(ifc, geometry, type, element="element", type="type")
|
subject.assign_type(ifc, type, element="element", type="type")
|
||||||
|
|
||||||
|
def test_updating_an_existing_body_if_there_is_a_parametric_material_usage(self, ifc, type):
|
||||||
|
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
||||||
|
|
||||||
|
type.has_material_usage("element").should_be_called().will_return(True)
|
||||||
|
type.get_body_representation("element").should_be_called().will_return("representation")
|
||||||
|
type.get_representation_context("representation").should_be_called().will_return("context")
|
||||||
|
ifc.run(
|
||||||
|
"geometry.unassign_representation", product="element", representation="representation"
|
||||||
|
).should_be_called()
|
||||||
|
ifc.run("geometry.remove_representation", representation="representation").should_be_called()
|
||||||
|
type.get_ifc_representation_class("element").should_be_called().will_return("class")
|
||||||
|
type.get_profile_set_usage("element").should_be_called().will_return("usage")
|
||||||
|
type.run_geometry_add_representation(
|
||||||
|
obj="obj", context="context", ifc_representation_class="class", profile_set_usage="usage"
|
||||||
|
).should_be_called().will_return("mapped_rep")
|
||||||
|
|
||||||
|
ifc.get_object("element").should_be_called().will_return("obj")
|
||||||
|
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
||||||
|
type.run_geometry_switch_representation(
|
||||||
|
obj="obj", representation="mapped_rep", should_reload=True, enable_dynamic_voids=False, is_global=False
|
||||||
|
).should_be_called()
|
||||||
|
type.disable_editing("obj").should_be_called()
|
||||||
|
subject.assign_type(ifc, type, element="element", type="type")
|
||||||
|
|
||||||
|
def test_creating_a_new_body_if_there_is_a_parametric_material_usage(self, ifc, type):
|
||||||
|
ifc.run("type.assign_type", related_object="element", relating_type="type").should_be_called()
|
||||||
|
|
||||||
|
type.has_material_usage("element").should_be_called().will_return(True)
|
||||||
|
type.get_body_representation("element").should_be_called().will_return(None)
|
||||||
|
type.get_body_context().should_be_called().will_return("context")
|
||||||
|
type.get_ifc_representation_class("element").should_be_called().will_return("class")
|
||||||
|
type.get_profile_set_usage("element").should_be_called().will_return("usage")
|
||||||
|
type.run_geometry_add_representation(
|
||||||
|
obj="obj", context="context", ifc_representation_class="class", profile_set_usage="usage"
|
||||||
|
).should_be_called().will_return("mapped_rep")
|
||||||
|
|
||||||
|
ifc.get_object("element").should_be_called().will_return("obj")
|
||||||
|
type.has_dynamic_voids("obj").should_be_called().will_return(False)
|
||||||
|
type.run_geometry_switch_representation(
|
||||||
|
obj="obj", representation="mapped_rep", should_reload=True, enable_dynamic_voids=False, is_global=False
|
||||||
|
).should_be_called()
|
||||||
|
type.disable_editing("obj").should_be_called()
|
||||||
|
subject.assign_type(ifc, type, element="element", type="type")
|
||||||
|
|||||||
@@ -53,6 +53,16 @@ class TestGetAnyRepresentation(NewFile):
|
|||||||
assert subject.get_any_representation(element) == representation
|
assert subject.get_any_representation(element) == representation
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetBodyContext(NewFile):
|
||||||
|
def test_run(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
context = ifc.createIfcGeometricRepresentationSubContext(
|
||||||
|
ContextType="Model", ContextIdentifier="Body", TargetView="MODEL_VIEW"
|
||||||
|
)
|
||||||
|
tool.Ifc.set(ifc)
|
||||||
|
assert subject.get_body_context() == context
|
||||||
|
|
||||||
|
|
||||||
class TestGetBodyRepresentation(NewFile):
|
class TestGetBodyRepresentation(NewFile):
|
||||||
def test_get_product_representation(self):
|
def test_get_product_representation(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
@@ -78,6 +88,49 @@ class TestGetBodyRepresentation(NewFile):
|
|||||||
assert subject.get_body_representation(element) == body_rep
|
assert subject.get_body_representation(element) == body_rep
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetIfcRepresentationClass(NewFile):
|
||||||
|
def test_detecting_profile_set_representations(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(
|
||||||
|
RelatingMaterial=ifc.createIfcMaterialProfileSetUsage(), RelatedObjects=[element]
|
||||||
|
)
|
||||||
|
assert subject.get_ifc_representation_class(element) == "IfcExtrudedAreaSolid/IfcMaterialProfileSetUsage"
|
||||||
|
|
||||||
|
def test_detecting_layer_set_representations(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(
|
||||||
|
RelatingMaterial=ifc.createIfcMaterialLayerSetUsage(), RelatedObjects=[element]
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
subject.get_ifc_representation_class(element)
|
||||||
|
== "IfcExtrudedAreaSolid/IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_returning_null_for_non_parametric_represntations(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
assert subject.get_ifc_representation_class(ifc.createIfcColumn()) is None
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetProfileSetUsage(NewFile):
|
||||||
|
def test_getting_a_profile_set_usage(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
assert subject.get_profile_set_usage(element) is None
|
||||||
|
usage = ifc.createIfcMaterialProfileSetUsage()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(RelatingMaterial=usage, RelatedObjects=[element])
|
||||||
|
assert subject.get_profile_set_usage(element) == usage
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetRepresentationContext(NewFile):
|
||||||
|
def test_getting_a_profile_set_usage(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
context = ifc.createIfcGeometricRepresentationSubContext()
|
||||||
|
representation = ifc.createIfcShapeRepresentation(ContextOfItems=context)
|
||||||
|
assert subject.get_representation_context(representation) == context
|
||||||
|
|
||||||
|
|
||||||
class TestHasDynamicVoids(NewFile):
|
class TestHasDynamicVoids(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
@@ -87,3 +140,23 @@ class TestHasDynamicVoids(NewFile):
|
|||||||
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
|
||||||
obj.modifiers.new("IfcOpeningElement", "BOOLEAN")
|
obj.modifiers.new("IfcOpeningElement", "BOOLEAN")
|
||||||
assert subject.has_dynamic_voids(obj) is True
|
assert subject.has_dynamic_voids(obj) is True
|
||||||
|
|
||||||
|
|
||||||
|
class TestHasMaterialUsage(NewFile):
|
||||||
|
def test_getting_a_profile_set_usage(self):
|
||||||
|
ifc = ifcopenshell.file()
|
||||||
|
element = ifc.createIfcColumn()
|
||||||
|
assert subject.has_material_usage(element) is False
|
||||||
|
usage = ifc.createIfcMaterialProfileSetUsage()
|
||||||
|
ifc.createIfcRelAssociatesMaterial(RelatingMaterial=usage, RelatedObjects=[element])
|
||||||
|
assert subject.has_material_usage(element) is True
|
||||||
|
|
||||||
|
|
||||||
|
class TestRunGeometryAddRepresentation(NewFile):
|
||||||
|
def test_nothing(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestRunGeometrySwitchRepresentation(NewFile):
|
||||||
|
def test_nothing(self):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ class Usecase:
|
|||||||
ifcopenshell.util.element.remove_deep2(
|
ifcopenshell.util.element.remove_deep2(
|
||||||
self.file,
|
self.file,
|
||||||
self.settings["representation"],
|
self.settings["representation"],
|
||||||
extra_subgraph_elements=list(styled_items | presentation_layer_assignments),
|
also_consider=list(styled_items | presentation_layer_assignments),
|
||||||
|
do_not_delete=self.file.by_type("IfcGeometricRepresentationContext"),
|
||||||
)
|
)
|
||||||
|
|
||||||
for element in styled_items:
|
for element in styled_items:
|
||||||
|
|||||||
@@ -136,17 +136,21 @@ def remove_deep(ifc_file, element):
|
|||||||
ifc_file.unbatch()
|
ifc_file.unbatch()
|
||||||
|
|
||||||
|
|
||||||
def remove_deep2(ifc_file, element, extra_subgraph_elements=[]):
|
def remove_deep2(ifc_file, element, also_consider=[], do_not_delete=[]):
|
||||||
# Experimental remove deep proposal. No batch for now until this is more certain. See #1812.
|
# Experimental remove deep proposal. No batch for now until this is more certain. See #1812.
|
||||||
# ifc_file.batch()
|
# ifc_file.batch()
|
||||||
to_delete = set()
|
to_delete = set()
|
||||||
subgraph = list(ifc_file.traverse(element, breadth_first=True))
|
subgraph = list(ifc_file.traverse(element, breadth_first=True))
|
||||||
subgraph.extend(extra_subgraph_elements)
|
subgraph.extend(also_consider)
|
||||||
subgraph_set = set(subgraph)
|
subgraph_set = set(subgraph)
|
||||||
subelement_queue = ifc_file.traverse(element, max_levels=1)
|
subelement_queue = ifc_file.traverse(element, max_levels=1)
|
||||||
while subelement_queue:
|
while subelement_queue:
|
||||||
subelement = subelement_queue.pop(0)
|
subelement = subelement_queue.pop(0)
|
||||||
if subelement.id() and len(set(ifc_file.get_inverse(subelement)) - subgraph_set) == 0:
|
if (
|
||||||
|
subelement.id()
|
||||||
|
and len(set(ifc_file.get_inverse(subelement)) - subgraph_set) == 0
|
||||||
|
and subelement not in do_not_delete
|
||||||
|
):
|
||||||
to_delete.add(subelement)
|
to_delete.add(subelement)
|
||||||
subelement_queue.extend(ifc_file.traverse(subelement, max_levels=1)[1:])
|
subelement_queue.extend(ifc_file.traverse(subelement, max_levels=1)[1:])
|
||||||
for subelement in to_delete:
|
for subelement in to_delete:
|
||||||
|
|||||||
@@ -77,3 +77,9 @@ class TestRemoveRepresentation(test.bootstrap.IFC4):
|
|||||||
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
|
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
|
||||||
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 1
|
assert len(self.file.by_type("IfcPresentationLayerAssignment")) == 1
|
||||||
assert len(self.file.by_type("IfcShapeRepresentation")) == 1
|
assert len(self.file.by_type("IfcShapeRepresentation")) == 1
|
||||||
|
|
||||||
|
def test_not_purging_geometric_representation_contexts(self):
|
||||||
|
context = self.file.createIfcGeometricRepresentationSubContext()
|
||||||
|
representation = self.file.createIfcShapeRepresentation(ContextOfItems=context)
|
||||||
|
ifcopenshell.api.run("geometry.remove_representation", self.file, representation=representation)
|
||||||
|
assert len(self.file.by_type("IfcGeometricRepresentationContext")) == 1
|
||||||
|
|||||||
Reference in New Issue
Block a user