mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Merge branch 'v0.6.0' of https://github.com/IfcOpenShell/IfcOpenShell into presentationlayer
This commit is contained in:
@@ -74,6 +74,9 @@ if bpy is not None:
|
||||
operator.AddMaterialConstituent,
|
||||
operator.RemoveMaterialConstituent,
|
||||
operator.MoveMaterialConstituent,
|
||||
operator.AddMaterialProfile,
|
||||
operator.RemoveMaterialProfile,
|
||||
operator.MoveMaterialProfile,
|
||||
operator.AddConstraint,
|
||||
operator.RemoveConstraint,
|
||||
operator.AssignConstraint,
|
||||
@@ -213,12 +216,17 @@ if bpy is not None:
|
||||
operator.CopyPropertyToSelection,
|
||||
operator.CreateShapeFromStepId,
|
||||
operator.SelectHighPolygonMeshes,
|
||||
operator.InspectFromStepId,
|
||||
operator.InspectFromObject,
|
||||
operator.RewindInspector,
|
||||
operator.RefreshDrawingList,
|
||||
operator.GetRepresentationIfcParameters,
|
||||
operator.UpdateIfcRepresentation,
|
||||
prop.StrProperty,
|
||||
prop.Attribute,
|
||||
prop.MaterialLayer,
|
||||
prop.MaterialConstituent,
|
||||
prop.MaterialProfile,
|
||||
prop.MaterialSet,
|
||||
prop.Variable,
|
||||
prop.Role,
|
||||
@@ -254,7 +262,6 @@ if bpy is not None:
|
||||
prop.BIMLibrary,
|
||||
prop.MapConversion,
|
||||
prop.TargetCRS,
|
||||
prop.Attribute,
|
||||
prop.IfcParameter,
|
||||
prop.BoundaryCondition,
|
||||
prop.PsetQto,
|
||||
|
||||
@@ -434,7 +434,7 @@ class IfcParser:
|
||||
elif obj.BIMObjectProperties.material_type == "IfcMaterialLayerSet":
|
||||
self.rel_associates_material_layer_set[self.product_index] = obj.BIMObjectProperties.material_set
|
||||
elif obj.BIMObjectProperties.material_type == "IfcMaterialProfileSet":
|
||||
pass # TODO
|
||||
self.rel_associates_material_profile_set[self.product_index] = obj.BIMObjectProperties.material_set
|
||||
|
||||
return product
|
||||
|
||||
@@ -2063,13 +2063,11 @@ class IfcExporter:
|
||||
material_type = material["material_type"][0:-3]
|
||||
self.cast_attributes(material_type, material["attributes"])
|
||||
material["attributes"]["Material"] = material["ifc"]
|
||||
if material_type == "IfcMaterialProfile":
|
||||
material["attributes"]["Profile"] = self.create_material_profile(material)
|
||||
material["part_ifc"] = self.file.create_entity(material_type, **material["attributes"])
|
||||
|
||||
def create_material_profile(self, material):
|
||||
ifc_class = material["raw"].BIMMaterialProperties.profile_def
|
||||
attributes = {a.name: a.string_value for a in material["raw"].BIMMaterialProperties.profile_attributes}
|
||||
def create_material_profile_def(self, profile):
|
||||
ifc_class = profile.profile
|
||||
attributes = {a.name: a.string_value for a in profile.profile_attributes}
|
||||
self.cast_attributes(ifc_class, attributes)
|
||||
return self.file.create_entity(ifc_class, **attributes)
|
||||
|
||||
@@ -3163,7 +3161,7 @@ class IfcExporter:
|
||||
elif set_type == "layer":
|
||||
materials = self.create_material_layers(material_set.material_layers)
|
||||
elif set_type == "profile":
|
||||
materials = [] # TODO
|
||||
materials = self.create_material_profiles(material_set.material_profiles)
|
||||
if not materials:
|
||||
continue
|
||||
|
||||
@@ -3231,6 +3229,24 @@ class IfcExporter:
|
||||
)
|
||||
return results
|
||||
|
||||
def create_material_profiles(self, profiles):
|
||||
results = []
|
||||
for profile in profiles:
|
||||
results.append(
|
||||
self.file.create_entity(
|
||||
"IfcMaterialProfile",
|
||||
**{
|
||||
"Name": profile.name or None,
|
||||
"Description": profile.description or None,
|
||||
"Material": self.ifc_parser.materials[profile.material.name]["ifc"],
|
||||
"Profile": self.create_material_profile_def(profile),
|
||||
"Priority": profile.priority,
|
||||
"Category": profile.category or None,
|
||||
}
|
||||
)
|
||||
)
|
||||
return results
|
||||
|
||||
def relate_spaces_to_boundary_elements(self):
|
||||
for (
|
||||
relating_space_index,
|
||||
|
||||
@@ -144,8 +144,11 @@ class MaterialCreator:
|
||||
material_select = association.RelatingMaterial
|
||||
if material_select.is_a("IfcMaterialDefinition"):
|
||||
self.create_definition(material_select)
|
||||
elif material_select.is_a("IfcMaterialLayerSetUsage"):
|
||||
self.create_layer_set_usage(material_select)
|
||||
elif material_select.is_a("IfcMaterialUsageDefinition"):
|
||||
self.create_usage_definition(material_select)
|
||||
elif material_select.is_a("IfcMaterialList"):
|
||||
# Note that lists are deprecated
|
||||
self.create_material_list(material_select)
|
||||
|
||||
def create_layer_set_usage(self, usage):
|
||||
# TODO import rest of the layer set usage data
|
||||
@@ -154,33 +157,87 @@ class MaterialCreator:
|
||||
def create_definition(self, material):
|
||||
if material.is_a("IfcMaterial"):
|
||||
self.create_single(material)
|
||||
elif material.is_a("IfcMaterialLayerSet"):
|
||||
self.create_layer_set(material)
|
||||
elif material.is_a("IfcMaterialConstituentSet"):
|
||||
self.create_constituent_set(material)
|
||||
elif material.is_a("IfcMaterialList"):
|
||||
self.create_material_list(material)
|
||||
elif material.is_a("IfcMaterialLayerSet"):
|
||||
self.create_layer_set(material)
|
||||
elif material.is_a("IfcMaterialProfileSet"):
|
||||
self.create_profile_set(material)
|
||||
|
||||
def create_usage_definition(self, material):
|
||||
if material.is_a("IfcMaterialLayerSetUsage"):
|
||||
self.create_layer_set_usage(material)
|
||||
elif material.is_a("IfcMaterialProfileSetUsage"):
|
||||
pass # TODO
|
||||
|
||||
def create_single(self, material):
|
||||
if material.Name not in self.materials:
|
||||
self.create_new_single(material)
|
||||
self.obj.BIMObjectProperties.material_type = "IfcMaterial"
|
||||
self.obj.BIMObjectProperties.material = self.materials[material.Name]
|
||||
return self.assign_material_to_mesh(self.materials[material.Name])
|
||||
|
||||
def create_layer_set(self, layer_set):
|
||||
props = self.obj.BIMObjectProperties
|
||||
props.material_type = "IfcMaterialLayerSet"
|
||||
props.material_set.name = layer_set.LayerSetName or ""
|
||||
props.material_set.description = layer_set.Description or ""
|
||||
for layer in layer_set.MaterialLayers:
|
||||
new = props.material_set.material_layers.add()
|
||||
if layer.Material:
|
||||
if layer.Material.Name not in self.materials:
|
||||
# TODO import rest of the layer set data
|
||||
self.create_new_single(layer.Material)
|
||||
self.assign_material_to_mesh(self.materials[layer.Material.Name])
|
||||
new.material = self.materials[layer.Material.Name]
|
||||
new.layer_thickness = layer.LayerThickness
|
||||
new.is_ventilated = "TRUE" if layer.IsVentilated else "FALSE"
|
||||
new.name = layer.Name or ""
|
||||
new.description = layer.Description or ""
|
||||
try:
|
||||
new.category = layer.Category if layer.Category else "None"
|
||||
except:
|
||||
new.custom_category = layer.Category or ""
|
||||
new.priority = layer.Priority or 0
|
||||
|
||||
def create_constituent_set(self, constituent_set):
|
||||
props = self.obj.BIMObjectProperties
|
||||
props.material_type = "IfcMaterialConstituentSet"
|
||||
props.material_set.name = constituent_set.Name or ""
|
||||
props.material_set.description = constituent_set.Description or ""
|
||||
for constituent in constituent_set.MaterialConstituents:
|
||||
if constituent.Material:
|
||||
if constituent.Material.Name not in self.materials:
|
||||
# TODO import rest of the layer set data
|
||||
self.create_new_single(constituent.Material)
|
||||
self.assign_material_to_mesh(self.materials[constituent.Material.Name])
|
||||
new = props.material_set.material_constituents.add()
|
||||
new.name = constituent.Name or ""
|
||||
new.description = constituent.Description or ""
|
||||
if constituent.Material.Name not in self.materials:
|
||||
# TODO import rest of the layer set data
|
||||
self.create_new_single(constituent.Material)
|
||||
self.assign_material_to_mesh(self.materials[constituent.Material.Name])
|
||||
new.material = self.materials[constituent.Material.Name]
|
||||
new.fraction = constituent.Fraction or 0.0
|
||||
new.category = constituent.Category or ""
|
||||
|
||||
def create_profile_set(self, profile_set):
|
||||
props = self.obj.BIMObjectProperties
|
||||
props.material_type = "IfcMaterialProfileSet"
|
||||
props.material_set.name = profile_set.Name or ""
|
||||
props.material_set.description = profile_set.Description or ""
|
||||
for profile in profile_set.MaterialProfiles:
|
||||
new = props.material_set.material_profiles.add()
|
||||
new.name = profile.Name or ""
|
||||
new.description = profile.Description or ""
|
||||
if profile.Material.Name not in self.materials:
|
||||
# TODO import rest of the layer set data
|
||||
self.create_new_single(profile.Material)
|
||||
self.assign_material_to_mesh(self.materials[profile.Material.Name])
|
||||
new.material = self.materials[profile.Material.Name]
|
||||
new.profile = profile.Profile.is_a()
|
||||
for i, attribute in enumerate(profile.Profile):
|
||||
newa = new.profile_attributes.add()
|
||||
newa.name = profile.Profile.attribute_name(i)
|
||||
newa.string_value = str(attribute)
|
||||
new.priority = profile.Priority or 0
|
||||
new.category = profile.Category or ""
|
||||
|
||||
def create_material_list(self, material_list):
|
||||
for material in material_list.Materials:
|
||||
@@ -1853,7 +1910,12 @@ class IfcImporter:
|
||||
def add_element_attributes(self, element, obj):
|
||||
attributes = element.get_info()
|
||||
for key, value in attributes.items():
|
||||
if value is None or isinstance(value, ifcopenshell.entity_instance) or key == "id" or key == "type":
|
||||
if (
|
||||
value is None
|
||||
or isinstance(value, (tuple, ifcopenshell.entity_instance))
|
||||
or key == "id"
|
||||
or key == "type"
|
||||
):
|
||||
continue
|
||||
attribute = obj.BIMObjectProperties.attributes.add()
|
||||
attribute.name = key
|
||||
|
||||
@@ -4197,6 +4197,44 @@ class MoveMaterialConstituent(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddMaterialProfile(bpy.types.Operator):
|
||||
bl_idname = "bim.add_material_profile"
|
||||
bl_label = "Add Material Profile"
|
||||
|
||||
def execute(self, context):
|
||||
new = bpy.context.active_object.BIMObjectProperties.material_set.material_profiles.add()
|
||||
new.material = bpy.data.materials[0]
|
||||
new.name = "Material Profile"
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveMaterialProfile(bpy.types.Operator):
|
||||
bl_idname = "bim.remove_material_profile"
|
||||
bl_label = "Remove Material Profile"
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
bpy.context.active_object.BIMObjectProperties.material_set.material_profiles.remove(self.index)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class MoveMaterialProfile(bpy.types.Operator):
|
||||
bl_idname = "bim.move_material_profile"
|
||||
bl_label = "Move Material Profile"
|
||||
direction: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
props = bpy.context.active_object.BIMObjectProperties.material_set
|
||||
index = props.active_material_profile_index
|
||||
if self.direction == "UP" and index - 1 >= 0:
|
||||
props.material_profiles.move(index, index - 1)
|
||||
props.active_material_profile_index = index - 1
|
||||
elif self.direction == "DOWN" and index + 1 < len(props.material_profiles):
|
||||
props.material_profiles.move(index, index + 1)
|
||||
props.active_material_profile_index = index + 1
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class SelectScheduleFile(bpy.types.Operator):
|
||||
bl_idname = "bim.select_schedule_file"
|
||||
bl_label = "Select Documentation IFC File"
|
||||
@@ -4437,6 +4475,80 @@ class SelectHighPolygonMeshes(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class InspectFromStepId(bpy.types.Operator):
|
||||
bl_idname = "bim.inspect_from_step_id"
|
||||
bl_label = "Inspect From STEP ID"
|
||||
step_id: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
self.file = ifc.IfcStore.get_file()
|
||||
bpy.context.scene.BIMDebugProperties.active_step_id = self.step_id
|
||||
crumb = bpy.context.scene.BIMDebugProperties.step_id_breadcrumb.add()
|
||||
crumb.name = str(self.step_id)
|
||||
element = self.file.by_id(self.step_id)
|
||||
while len(bpy.context.scene.BIMDebugProperties.attributes) > 0:
|
||||
bpy.context.scene.BIMDebugProperties.attributes.remove(0)
|
||||
while len(bpy.context.scene.BIMDebugProperties.inverse_attributes) > 0:
|
||||
bpy.context.scene.BIMDebugProperties.inverse_attributes.remove(0)
|
||||
for key, value in element.get_info().items():
|
||||
self.add_attribute(bpy.context.scene.BIMDebugProperties.attributes, key, value)
|
||||
for key in dir(element):
|
||||
if (
|
||||
not key[0].isalpha()
|
||||
or key[0] != key[0].upper()
|
||||
or key in element.get_info()
|
||||
or not getattr(element, key)
|
||||
):
|
||||
continue
|
||||
self.add_attribute(bpy.context.scene.BIMDebugProperties.inverse_attributes, key, getattr(element, key))
|
||||
return {"FINISHED"}
|
||||
|
||||
def add_attribute(self, prop, key, value):
|
||||
if isinstance(value, tuple) and len(value) < 10:
|
||||
for i, item in enumerate(value):
|
||||
self.add_attribute(prop, key + f"[{i}]", item)
|
||||
return
|
||||
elif isinstance(value, tuple) and len(value) >= 10:
|
||||
key = key + "({})".format(len(value))
|
||||
new = prop.add()
|
||||
new.name = key
|
||||
new.string_value = str(value)
|
||||
if isinstance(value, ifcopenshell.entity_instance):
|
||||
new.int_value = int(value.id())
|
||||
|
||||
|
||||
class InspectFromObject(bpy.types.Operator):
|
||||
bl_idname = "bim.inspect_from_object"
|
||||
bl_label = "Inspect From Object"
|
||||
|
||||
def execute(self, context):
|
||||
global_id = bpy.context.active_object.BIMObjectProperties.attributes.get("GlobalId")
|
||||
if not global_id:
|
||||
return {"FINISHED"}
|
||||
global_id = global_id.string_value
|
||||
self.file = ifc.IfcStore.get_file()
|
||||
element = self.file.by_guid(global_id)
|
||||
if element:
|
||||
bpy.ops.bim.inspect_from_step_id(step_id=element.id())
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RewindInspector(bpy.types.Operator):
|
||||
bl_idname = "bim.rewind_inspector"
|
||||
bl_label = "Rewind Inspector"
|
||||
|
||||
def execute(self, context):
|
||||
props = bpy.context.scene.BIMDebugProperties
|
||||
total_breadcrumbs = len(props.step_id_breadcrumb)
|
||||
if total_breadcrumbs < 2:
|
||||
return {"FINISHED"}
|
||||
previous_step_id = int(props.step_id_breadcrumb[total_breadcrumbs - 2].name)
|
||||
props.step_id_breadcrumb.remove(total_breadcrumbs - 1)
|
||||
props.step_id_breadcrumb.remove(total_breadcrumbs - 2)
|
||||
bpy.ops.bim.inspect_from_step_id(step_id=previous_step_id)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RefreshDrawingList(bpy.types.Operator):
|
||||
bl_idname = "bim.refresh_drawing_list"
|
||||
bl_label = "Refresh Drawing List"
|
||||
|
||||
@@ -504,10 +504,12 @@ def getApplicableMaterialAttributes(self, context):
|
||||
|
||||
|
||||
def refreshProfileAttributes(self, context):
|
||||
while len(context.active_object.active_material.BIMMaterialProperties.profile_attributes) > 0:
|
||||
context.active_object.active_material.BIMMaterialProperties.profile_attributes.remove(0)
|
||||
for attribute in schema.ifc.IfcParameterizedProfileDef[self.profile_def]["attributes"]:
|
||||
profile_attribute = context.active_object.active_material.BIMMaterialProperties.profile_attributes.add()
|
||||
props = context.active_object.BIMObjectProperties
|
||||
profile = props.material_set.material_profiles[props.material_set.active_material_profile_index]
|
||||
while len(profile.profile_attributes) > 0:
|
||||
profile.profile_attributes.remove(0)
|
||||
for attribute in schema.ifc.IfcParameterizedProfileDef[profile.profile]["attributes"]:
|
||||
profile_attribute = profile.profile_attributes.add()
|
||||
profile_attribute.name = attribute["name"]
|
||||
|
||||
|
||||
@@ -561,6 +563,15 @@ class Variable(PropertyGroup):
|
||||
prop_key: StringProperty(name="Property Key")
|
||||
|
||||
|
||||
class Attribute(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
data_type: StringProperty(name="Data Type")
|
||||
string_value: StringProperty(name="Value")
|
||||
bool_value: BoolProperty(name="Value")
|
||||
int_value: IntProperty(name="Value")
|
||||
float_value: FloatProperty(name="Value")
|
||||
|
||||
|
||||
class Subcontext(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
context: StringProperty(name="Context")
|
||||
@@ -604,6 +615,16 @@ class MaterialConstituent(PropertyGroup):
|
||||
category: StringProperty(name="Category")
|
||||
|
||||
|
||||
class MaterialProfile(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
description: StringProperty(name="Description")
|
||||
material: PointerProperty(name="Material", type=bpy.types.Material)
|
||||
profile: EnumProperty(items=getProfileDef, name="Parameterized Profile Def", update=refreshProfileAttributes)
|
||||
profile_attributes: CollectionProperty(name="Profile Attributes", type=Attribute)
|
||||
priority: IntProperty(name="Priority")
|
||||
category: StringProperty(name="Category")
|
||||
|
||||
|
||||
class MaterialSet(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
description: StringProperty(name="Description")
|
||||
@@ -611,6 +632,8 @@ class MaterialSet(PropertyGroup):
|
||||
material_layers: CollectionProperty(name="Material Layers", type=MaterialLayer)
|
||||
active_material_constituent_index: IntProperty(name="Active Material Constituent Index")
|
||||
material_constituents: CollectionProperty(name="Material Constituents", type=MaterialConstituent)
|
||||
active_material_profile_index: IntProperty(name="Active Material Profile Index")
|
||||
material_profiles: CollectionProperty(name="Material Profiles", type=MaterialProfile)
|
||||
|
||||
|
||||
class Drawing(PropertyGroup):
|
||||
@@ -1638,15 +1661,6 @@ class BIMLibrary(PropertyGroup):
|
||||
description: StringProperty(name="Description")
|
||||
|
||||
|
||||
class Attribute(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
data_type: StringProperty(name="Data Type")
|
||||
string_value: StringProperty(name="Value")
|
||||
bool_value: BoolProperty(name="Value")
|
||||
int_value: IntProperty(name="Value")
|
||||
float_value: FloatProperty(name="Value")
|
||||
|
||||
|
||||
class IfcParameter(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
step_id: IntProperty(name="STEP ID")
|
||||
@@ -1703,6 +1717,10 @@ class BIMObjectProperties(PropertyGroup):
|
||||
class BIMDebugProperties(PropertyGroup):
|
||||
step_id: IntProperty(name="STEP ID")
|
||||
number_of_polygons: IntProperty(name="Number of Polygons")
|
||||
active_step_id: IntProperty(name="STEP ID")
|
||||
step_id_breadcrumb: CollectionProperty(name="STEP ID Breadcrumb", type=StrProperty)
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
inverse_attributes: CollectionProperty(name="Inverse Attributes", type=Attribute)
|
||||
|
||||
|
||||
class BIMMaterialProperties(PropertyGroup):
|
||||
@@ -1714,8 +1732,6 @@ class BIMMaterialProperties(PropertyGroup):
|
||||
psets: CollectionProperty(name="Psets", type=PsetQto)
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
applicable_attributes: EnumProperty(items=getApplicableMaterialAttributes, name="Attribute Names")
|
||||
profile_def: EnumProperty(items=getProfileDef, name="Parameterized Profile Def", update=refreshProfileAttributes)
|
||||
profile_attributes: CollectionProperty(name="Profile Attributes", type=Attribute)
|
||||
|
||||
|
||||
class SweptSolid(PropertyGroup):
|
||||
|
||||
@@ -194,6 +194,41 @@ class BIM_PT_object_material(Panel):
|
||||
row.prop(material, "fraction")
|
||||
row = layout.row()
|
||||
row.prop(material, "category")
|
||||
elif props.material_type == "IfcMaterialProfileSet":
|
||||
row.template_list(
|
||||
"MATERIAL_UL_matslots",
|
||||
"",
|
||||
set_props,
|
||||
"material_profiles",
|
||||
set_props,
|
||||
"active_material_profile_index",
|
||||
)
|
||||
col = row.column(align=True)
|
||||
col.operator("bim.add_material_profile", icon="ADD", text="")
|
||||
col.operator(
|
||||
"bim.remove_material_profile", icon="REMOVE", text=""
|
||||
).index = set_props.active_material_profile_index
|
||||
col.operator("bim.move_material_profile", icon="TRIA_UP", text="").direction = "UP"
|
||||
col.operator("bim.move_material_profile", icon="TRIA_DOWN", text="").direction = "DOWN"
|
||||
|
||||
if set_props.active_material_profile_index < len(set_props.material_profiles):
|
||||
material = set_props.material_profiles[set_props.active_material_profile_index]
|
||||
row = layout.row()
|
||||
row.prop(material, "material")
|
||||
row = layout.row()
|
||||
row.prop(material, "name")
|
||||
row = layout.row()
|
||||
row.prop(material, "description")
|
||||
row = layout.row()
|
||||
row.prop(material, "priority")
|
||||
row = layout.row()
|
||||
row.prop(material, "category")
|
||||
row = layout.row()
|
||||
row.prop(material, "profile")
|
||||
for index, attribute in enumerate(material.profile_attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, "name", text="")
|
||||
row.prop(attribute, "string_value", text="")
|
||||
|
||||
|
||||
class BIM_PT_object_psets(Panel):
|
||||
@@ -876,16 +911,6 @@ class BIM_PT_material(Panel):
|
||||
row = layout.row()
|
||||
row.prop(props, "psets", text="")
|
||||
|
||||
if context.active_object.BIMObjectProperties.material_type == "IfcMaterialProfileSet":
|
||||
layout.label(text="Profile Definition:")
|
||||
row = layout.row()
|
||||
row.prop(props, "profile_def")
|
||||
|
||||
for index, attribute in enumerate(props.profile_attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, "name", text="")
|
||||
row.prop(attribute, "string_value", text="")
|
||||
|
||||
|
||||
class BIM_PT_gis(Panel):
|
||||
bl_label = "IFC Georeferencing"
|
||||
@@ -2334,19 +2359,48 @@ class BIM_PT_debug(Panel):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
bim_props = scene.BIMProperties
|
||||
debug_props = scene.BIMDebugProperties
|
||||
props = scene.BIMDebugProperties
|
||||
|
||||
row = layout.row()
|
||||
row.prop(debug_props, "step_id", text="")
|
||||
row.prop(props, "step_id", text="")
|
||||
row = layout.row()
|
||||
row.operator("bim.create_shape_from_step_id")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(debug_props, "number_of_polygons", text="")
|
||||
row.prop(props, "number_of_polygons", text="")
|
||||
row = layout.row()
|
||||
row.operator("bim.select_high_polygon_meshes")
|
||||
|
||||
layout.label(text="Inspector:")
|
||||
|
||||
row = layout.row(align=True)
|
||||
if len(props.step_id_breadcrumb) >= 2:
|
||||
row.operator("bim.rewind_inspector", icon="FRAME_PREV", text="")
|
||||
row.prop(props, "active_step_id", text="")
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.inspect_from_step_id").step_id = bpy.context.scene.BIMDebugProperties.active_step_id
|
||||
row.operator("bim.inspect_from_object")
|
||||
|
||||
if props.attributes:
|
||||
layout.label(text="Direct attributes:")
|
||||
|
||||
for index, attribute in enumerate(props.attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, "name", text="")
|
||||
row.prop(attribute, "string_value", text="")
|
||||
if attribute.int_value:
|
||||
row.operator("bim.inspect_from_step_id", icon="DISCLOSURE_TRI_RIGHT", text="").step_id = attribute.int_value
|
||||
|
||||
if props.inverse_attributes:
|
||||
layout.label(text="Inverse attributes:")
|
||||
|
||||
for index, attribute in enumerate(props.inverse_attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, "name", text="")
|
||||
row.prop(attribute, "string_value", text="")
|
||||
if attribute.int_value:
|
||||
row.operator("bim.inspect_from_step_id", icon="DISCLOSURE_TRI_RIGHT", text="").step_id = attribute.int_value
|
||||
|
||||
|
||||
def ifc_units(self, context):
|
||||
scene = context.scene
|
||||
|
||||
@@ -224,6 +224,11 @@ private:
|
||||
double modelling_precision;
|
||||
double dimensionality;
|
||||
double layerset_first;
|
||||
|
||||
// For stopping PlacementRelTo recursion in convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf)
|
||||
const IfcParse::declaration* placement_rel_to;
|
||||
|
||||
faceset_helper* faceset_helper_;
|
||||
gp_Vec offset = gp_Vec{0.0, 0.0, 0.0};
|
||||
gp_Quaternion rotation = gp_Quaternion{};
|
||||
gp_Trsf offset_and_rotation = gp_Trsf();
|
||||
@@ -236,11 +241,6 @@ private:
|
||||
|
||||
const SurfaceStyle* internalize_surface_style(const std::pair<IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*>& shading_style);
|
||||
|
||||
// For stopping PlacementRelTo recursion in convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf)
|
||||
const IfcParse::declaration* placement_rel_to;
|
||||
|
||||
faceset_helper* faceset_helper_;
|
||||
|
||||
public:
|
||||
MAKE_TYPE_NAME(Kernel)()
|
||||
: IfcGeom::Kernel(0)
|
||||
|
||||
@@ -2904,7 +2904,7 @@ namespace {
|
||||
auto result_shape = split.Shape();
|
||||
std::list<TopoDS_Shape> subs;
|
||||
subshapes(result_shape, subs);
|
||||
if (subs.size() == 1 && operands.Size() - 2 > subs.size() && (subs.front().ShapeType() == TopAbs_COMPSOLID || subs.front().ShapeType() == TopAbs_COMPOUND)) {
|
||||
if (subs.size() == 1 && operands.Size() - 2 > (int)subs.size() && (subs.front().ShapeType() == TopAbs_COMPSOLID || subs.front().ShapeType() == TopAbs_COMPOUND)) {
|
||||
auto s = subs.front();
|
||||
subs.clear();
|
||||
subshapes(s, subs);
|
||||
@@ -3769,23 +3769,6 @@ namespace {
|
||||
|
||||
operator int() { return i; }
|
||||
};
|
||||
|
||||
inline std::string format_pnt(const gp_Pnt& p) {
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(4) << p.X() << " " << p.Y() << " " << p.Z();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline std::string format_edge(const TopoDS_Edge& e) {
|
||||
std::stringstream ss;
|
||||
TopoDS_Vertex v1, v2;
|
||||
TopExp::Vertices(e, v1, v2);
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(v1);
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(v2);
|
||||
ss << "edge " << format_pnt(p1) << " -> " << format_pnt(p2);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires) {
|
||||
|
||||
@@ -284,7 +284,6 @@ namespace IfcGeom {
|
||||
BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current()));
|
||||
GCPnts_QuasiUniformDeflection tessellater(crv, settings().deflection_tolerance());
|
||||
int n = tessellater.NbPoints();
|
||||
int start = (int)_verts.size() / 3;
|
||||
int previous = -1;
|
||||
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
|
||||
@@ -1302,26 +1302,6 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void segment_tiny_edges(const TopoDS_Wire& wire, std::vector<TopoDS_Wire>& wires, double eps) {
|
||||
std::vector<TopoDS_Edge> sorted_edges;
|
||||
sort_edges(wire, sorted_edges);
|
||||
|
||||
bool segment_next = true;
|
||||
|
||||
BRep_Builder B;
|
||||
|
||||
for (const auto& e : sorted_edges) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::LinearProperties(e, prop);
|
||||
const double l = prop.Mass();
|
||||
if (l < eps || segment_next) {
|
||||
wires.emplace_back();
|
||||
B.MakeWire(wires.back());
|
||||
segment_next = l < eps;
|
||||
}
|
||||
B.Add(wires.back(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// #939: a closed loop causes failed triangulation in 7.3 and artefacts
|
||||
// in 7.4 so we break up a closed wire into two equal parts.
|
||||
@@ -1335,12 +1315,11 @@ namespace {
|
||||
}
|
||||
|
||||
BRep_Builder B;
|
||||
double u, v;
|
||||
|
||||
wires.emplace_back();
|
||||
B.MakeWire(wires.back());
|
||||
|
||||
for (int i = 0; i < sorted_edges.size(); ++i) {
|
||||
for (uint i = 0; i < sorted_edges.size(); ++i) {
|
||||
if (i == sorted_edges.size() / 2) {
|
||||
wires.emplace_back();
|
||||
B.MakeWire(wires.back());
|
||||
@@ -1718,7 +1697,7 @@ namespace {
|
||||
}
|
||||
k.remove_duplicate_points_from_loop(polygon, true);
|
||||
|
||||
if (polygon.Size() < 3) {
|
||||
if (polygon.Length() < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1837,7 +1816,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalFaceSet* pfs, TopoDS_
|
||||
}
|
||||
}
|
||||
|
||||
if (faces.Size() == 0) return false;
|
||||
if (faces.IsEmpty() == 0) return false;
|
||||
|
||||
return create_solid_from_faces(faces, shape);
|
||||
}
|
||||
|
||||
@@ -100,13 +100,7 @@
|
||||
#define Kernel MAKE_TYPE_NAME(Kernel)
|
||||
|
||||
namespace {
|
||||
// Returns the other vertex of an edge
|
||||
TopoDS_Vertex other(const TopoDS_Edge& e, const TopoDS_Vertex& v) {
|
||||
TopoDS_Vertex a, b;
|
||||
TopExp::Vertices(e, a, b);
|
||||
return v.IsSame(b) ? a : b;
|
||||
}
|
||||
|
||||
// Returns the first edge of a wire
|
||||
TopoDS_Edge first_edge(const TopoDS_Wire& w) {
|
||||
TopoDS_Vertex v1, v2;
|
||||
TopExp::Vertices(w, v1, v2);
|
||||
@@ -775,7 +769,7 @@ namespace {
|
||||
BRepBuilderAPI_MakeEdge me(crv, v1, v2);
|
||||
if (!me.IsDone()) {
|
||||
const double eps2 = eps * eps;
|
||||
if (me.Error() == BRepLib_PointProjectionFailed) {
|
||||
if (me.Error() == BRepBuilderAPI_PointProjectionFailed) {
|
||||
GeomAdaptor_Curve GAC(crv);
|
||||
const gp_Pnt* ps[2] = { &p1, &p2 };
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
|
||||
@@ -366,7 +366,7 @@ protected:
|
||||
std::vector<float> diffuse_color_array_condensed;
|
||||
|
||||
int new_index = 0;
|
||||
for (int orig = 0; orig < diffuse_color_array.size(); ++orig) {
|
||||
for (uint orig = 0; orig < diffuse_color_array.size(); ++orig) {
|
||||
auto& m = diffuse_color_array[orig];
|
||||
if (m) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
|
||||
@@ -5,26 +5,34 @@ from bpy.props import StringProperty, EnumProperty
|
||||
from sverchok.node_tree import SverchCustomTreeNode
|
||||
from sverchok.data_structure import updateNode
|
||||
from blenderbim.bim import schema
|
||||
from blenderbim.bim.prop import getIfcClasses, getIfcProducts, refreshClasses, refreshPredefinedTypes
|
||||
|
||||
|
||||
class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfcCore):
|
||||
bl_idname = "SvIfcByType"
|
||||
bl_label = "IFC By Type"
|
||||
ifc_element_types = [(t, t, t) for t in schema.IfcSchema().IfcElementType.keys()]
|
||||
file: StringProperty(name="file", update=updateNode)
|
||||
type: EnumProperty(name="type", items=ifc_element_types)
|
||||
ifc_product: EnumProperty(items=getIfcProducts, name="Products", update=refreshClasses)
|
||||
ifc_class: EnumProperty(items=getIfcClasses, name="Class", update=refreshPredefinedTypes)
|
||||
ifc_element_types = [(t, t, t) for t in schema.IfcSchema().IfcElementType.keys()]
|
||||
custom_ifc_class: StringProperty(name="Custom Ifc Class", update=updateNode)
|
||||
|
||||
def sv_init(self, context):
|
||||
self.inputs.new("SvStringsSocket", "file").prop_name = "file"
|
||||
self.inputs.new("SvStringsSocket", "type").prop_name = "type"
|
||||
self.inputs.new("SvStringsSocket", "ifc_product").prop_name = "ifc_product"
|
||||
self.inputs.new("SvStringsSocket", "ifc_class").prop_name = "ifc_class"
|
||||
self.inputs.new("SvStringsSocket", "custom_ifc_class").prop_name = "custom_ifc_class"
|
||||
self.outputs.new("SvStringsSocket", "entity")
|
||||
|
||||
def process(self):
|
||||
self.sv_input_names = ["file", "type"]
|
||||
self.sv_input_names = ["file", "ifc_product", "ifc_class", "custom_ifc_class"]
|
||||
super().process()
|
||||
|
||||
def process_ifc(self, file, type):
|
||||
self.outputs["entity"].sv_set([file.by_type(type)])
|
||||
def process_ifc(self, file, ifc_product, ifc_class, custom_ifc_class):
|
||||
if custom_ifc_class:
|
||||
self.outputs["entity"].sv_set([file.by_type(custom_ifc_class)])
|
||||
else:
|
||||
self.outputs["entity"].sv_set([file.by_type(ifc_class)])
|
||||
|
||||
|
||||
def register():
|
||||
|
||||
@@ -461,7 +461,7 @@ void SvgSerializer::write(const geometry_data& data) {
|
||||
Logger::Error(e);
|
||||
}
|
||||
|
||||
if (operation_type && (*operation_type == "SINGLE_SWING_LEFT") || (*operation_type == "SINGLE_SWING_RIGHT")) {
|
||||
if (operation_type && ((*operation_type == "SINGLE_SWING_LEFT") || (*operation_type == "SINGLE_SWING_RIGHT"))) {
|
||||
const bool is_left = *operation_type == "SINGLE_SWING_LEFT";
|
||||
|
||||
Bnd_Box bb;
|
||||
|
||||
@@ -118,18 +118,18 @@ protected:
|
||||
boost::optional<std::vector<section_data>> deferred_section_data_;
|
||||
boost::optional<double> scale_, calculated_scale_, center_x_, center_y_;
|
||||
|
||||
bool rescale, print_space_names_, print_space_areas_, draw_door_arcs_;
|
||||
bool with_section_heights_from_storey_, buffer_elements_;
|
||||
bool is_floor_plan_;
|
||||
bool with_section_heights_from_storey_, rescale, print_space_names_, print_space_areas_;
|
||||
bool draw_door_arcs_, buffer_elements_, is_floor_plan_;
|
||||
|
||||
IfcParse::IfcFile* file;
|
||||
IfcUtil::IfcBaseEntity* storey_;
|
||||
std::multimap<drawing_key, path_object, storey_sorter> paths;
|
||||
|
||||
float_item_list xcoords, ycoords, radii;
|
||||
size_t xcoords_begin, ycoords_begin, radii_begin;
|
||||
|
||||
boost::optional<std::string> section_ref_, elevation_ref_;
|
||||
IfcParse::IfcFile* file;
|
||||
IfcUtil::IfcBaseEntity* storey_;
|
||||
|
||||
std::list<geometry_data> element_buffer_;
|
||||
|
||||
Handle(HLRBRep_Algo) hlr;
|
||||
|
||||
Reference in New Issue
Block a user