diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index a2df9ed70c..cf2ee98499 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -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, diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index 8ad5f9a3d2..c2cd93bcb6 100644 --- a/src/ifcblenderexport/blenderbim/bim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/export_ifc.py @@ -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, diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 0fe458f506..89f2024b91 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -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 diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 2cfa233d4a..99b4bde62d 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -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" diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index 932b1041de..db74a431d6 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -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): diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index efe02f1739..dbc035671d 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -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 diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index ec98989770..a1852aab22 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -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& 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) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index ecc8798ba3..5444aa7a17 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -2904,7 +2904,7 @@ namespace { auto result_shape = split.Shape(); std::list 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) { diff --git a/src/ifcgeom/IfcGeomRepresentation.h b/src/ifcgeom/IfcGeomRepresentation.h index 63d99c1eb8..0ca0717e1f 100644 --- a/src/ifcgeom/IfcGeomRepresentation.h +++ b/src/ifcgeom/IfcGeomRepresentation.h @@ -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) { diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index ef3146df5f..b3b54ede24 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -1302,26 +1302,6 @@ namespace { } } - void segment_tiny_edges(const TopoDS_Wire& wire, std::vector& wires, double eps) { - std::vector 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); } diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index 8cde7f8e03..4274295526 100644 --- a/src/ifcgeom/IfcGeomWires.cpp +++ b/src/ifcgeom/IfcGeomWires.cpp @@ -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) { diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index 65d64b0f55..7835614ffe 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -366,7 +366,7 @@ protected: std::vector 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) { diff --git a/src/ifcsverchok/nodes/ifc/by_type.py b/src/ifcsverchok/nodes/ifc/by_type.py index 26c570e0f0..718bfe8003 100644 --- a/src/ifcsverchok/nodes/ifc/by_type.py +++ b/src/ifcsverchok/nodes/ifc/by_type.py @@ -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(): diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 0fd71c7709..35c7259522 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -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; diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index 382b059088..b69e1feb71 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -118,18 +118,18 @@ protected: boost::optional> deferred_section_data_; boost::optional 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 paths; float_item_list xcoords, ycoords, radii; size_t xcoords_begin, ycoords_begin, radii_begin; boost::optional section_ref_, elevation_ref_; - IfcParse::IfcFile* file; - IfcUtil::IfcBaseEntity* storey_; + std::list element_buffer_; Handle(HLRBRep_Algo) hlr;