From b37ea7793487d0747dd82a9c2b4d1cfc43f71aaf Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 8 Nov 2020 21:52:34 +1100 Subject: [PATCH 01/19] Implement IFC element inspector interface, useful for training and teaching OpenBIM --- .../blenderbim/bim/__init__.py | 4 +- .../blenderbim/bim/operator.py | 43 +++++++++++++++++++ src/ifcblenderexport/blenderbim/bim/prop.py | 4 ++ src/ifcblenderexport/blenderbim/bim/ui.py | 35 +++++++++++++-- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 37aa0c1dab..ae40e3b53c 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -208,6 +208,8 @@ if bpy is not None: operator.CopyPropertyToSelection, operator.CreateShapeFromStepId, operator.SelectHighPolygonMeshes, + operator.InspectFromStepId, + operator.InspectFromObject, operator.RefreshDrawingList, operator.GetRepresentationIfcParameters, operator.UpdateIfcRepresentation, @@ -241,6 +243,7 @@ if bpy is not None: prop.BcfTopicDocumentReference, prop.BcfTopicRelatedTopic, prop.Subcontext, + prop.Attribute, prop.BIMProperties, prop.BIMDebugProperties, prop.BCFProperties, @@ -248,7 +251,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/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 79d94930e9..7780caca8b 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -4341,6 +4341,49 @@ 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() + guid: bpy.props.StringProperty() + + def execute(self, context): + self.file = ifc.IfcStore.get_file() + if self.step_id: + bpy.context.scene.BIMDebugProperties.active_step_id = self.step_id + element = self.file.by_id(self.step_id) + else: + pass + 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(): + new = bpy.context.scene.BIMDebugProperties.attributes.add() + new.name = key + new.string_value = str(value) + if isinstance(value, ifcopenshell.entity_instance): + new.int_value = int(value.id()) + + 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 + new = bpy.context.scene.BIMDebugProperties.inverse_attributes.add() + new.name = key + new.string_value = str(getattr(element, key)) + if isinstance(value, ifcopenshell.entity_instance): + new.int_value = int(value.id()) + return {"FINISHED"} + + +class InspectFromObject(bpy.types.Operator): + bl_idname = "bim.inspect_from_object" + bl_label = "Inspect From Object" + + def execute(self, context): + 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 54c3da6005..904c7c9162 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -1668,6 +1668,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): diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 5cb69efbc3..ca3ecab3bf 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -2228,19 +2228,46 @@ 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() + 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 From e7936836687cab67164fb45808542e5a47854b11 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Mon, 2 Nov 2020 15:43:07 +0100 Subject: [PATCH 02/19] [g++-warning-fix] Removed unused variable --- src/ifcgeom/IfcGeomRepresentation.h | 1 - 1 file changed, 1 deletion(-) 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) { From 4ea56ba987b7dd60989ef89722b2229c80feace2 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Mon, 2 Nov 2020 15:48:32 +0100 Subject: [PATCH 03/19] [g++-warning-fix] Fixed initialization reorder --- src/ifcgeom/IfcGeom.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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) From b8e0c21dcc5f71ec6297f52a9002e7afbef8d680 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Mon, 2 Nov 2020 16:03:50 +0100 Subject: [PATCH 04/19] [g++-warning-fix] Fixed comparison between signed and unsigned integer expressions --- src/ifcgeom/IfcGeomFunctions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index ecc8798ba3..8a74958c4c 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); From f17702c66abba1d6dfbe99a218372860d61d3d74 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Mon, 2 Nov 2020 17:20:20 +0100 Subject: [PATCH 05/19] [g++-warning-fix] Fix sign comparison, unused function, unused variables in IfcGeomShapes.cpp --- src/ifcgeom/IfcGeomShapes.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index ef3146df5f..dd97364bbe 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()); From e4662cf209e2a2bea2a07f6a1406d78c63cb7f26 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Tue, 3 Nov 2020 10:21:52 +0100 Subject: [PATCH 06/19] [g++-warning-fix] Fix wrong enum compare --- src/ifcgeom/IfcGeomWires.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index 8cde7f8e03..08b4ebcfbf 100644 --- a/src/ifcgeom/IfcGeomWires.cpp +++ b/src/ifcgeom/IfcGeomWires.cpp @@ -775,7 +775,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) { From 1aa3e70d89214306c6aa78a71709ce4f3c80404a Mon Sep 17 00:00:00 2001 From: tpaviot Date: Tue, 3 Nov 2020 10:24:04 +0100 Subject: [PATCH 07/19] [g++-warning-fix] Removed unused function --- src/ifcgeom/IfcGeomWires.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index 08b4ebcfbf..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); From 28d9bccb6e983893de6c42b79a1e8046c14e12c3 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Tue, 3 Nov 2020 12:20:57 +0100 Subject: [PATCH 08/19] [g++-warning-fix] Fix sign comparison in IfcGeomServer.cpp --- src/ifcgeomserver/IfcGeomServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From 640dc7cf5a7567036a369dbe7ebb52c70111a6aa Mon Sep 17 00:00:00 2001 From: tpaviot Date: Tue, 3 Nov 2020 15:48:11 +0100 Subject: [PATCH 09/19] [g++-warning-fix] Fix ambiguous parenthesis in SvgSerializer.cpp --- src/serializers/SvgSerializer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 8c507ea007010dd34357bf781218a4e02566bada Mon Sep 17 00:00:00 2001 From: tpaviot Date: Tue, 3 Nov 2020 15:54:48 +0100 Subject: [PATCH 10/19] [g++-warning-fix] Fix wrong initialization order in SvgSerializer.h --- src/serializers/SvgSerializer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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; From ba094f2967a62d315f356ebc130a452bc840f910 Mon Sep 17 00:00:00 2001 From: tpaviot Date: Wed, 4 Nov 2020 06:10:28 +0100 Subject: [PATCH 11/19] [clang-warning-fix] Removed unused format_edge and format_pnt functions from IfcGeomFunctions.cpp --- src/ifcgeom/IfcGeomFunctions.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 8a74958c4c..5444aa7a17 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -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) { From 4a6c9807795f5232429e522d3d4f86b0d0b2654b Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 9 Nov 2020 11:45:53 +1100 Subject: [PATCH 12/19] You can now rewind a breadcrumb trail when inspecting IFCs and show attribute lists --- .../blenderbim/bim/__init__.py | 1 + .../blenderbim/bim/operator.py | 67 ++++++++++++++----- src/ifcblenderexport/blenderbim/bim/ui.py | 4 +- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index ae40e3b53c..780f55086d 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -210,6 +210,7 @@ if bpy is not None: operator.SelectHighPolygonMeshes, operator.InspectFromStepId, operator.InspectFromObject, + operator.RewindInspector, operator.RefreshDrawingList, operator.GetRepresentationIfcParameters, operator.UpdateIfcRepresentation, diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 7780caca8b..9eaf01843e 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -4345,42 +4345,73 @@ class InspectFromStepId(bpy.types.Operator): bl_idname = "bim.inspect_from_step_id" bl_label = "Inspect From STEP ID" step_id: bpy.props.IntProperty() - guid: bpy.props.StringProperty() def execute(self, context): self.file = ifc.IfcStore.get_file() - if self.step_id: - bpy.context.scene.BIMDebugProperties.active_step_id = self.step_id - element = self.file.by_id(self.step_id) - else: - pass + 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(): - new = bpy.context.scene.BIMDebugProperties.attributes.add() - new.name = key - new.string_value = str(value) - if isinstance(value, ifcopenshell.entity_instance): - new.int_value = int(value.id()) - + 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): + if ( + not key[0].isalpha() + or key[0] != key[0].upper() + or key in element.get_info() + or not getattr(element, key) + ): continue - new = bpy.context.scene.BIMDebugProperties.inverse_attributes.add() - new.name = key - new.string_value = str(getattr(element, key)) - if isinstance(value, ifcopenshell.entity_instance): - new.int_value = int(value.id()) + 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"} diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index ca3ecab3bf..5eb3b5c123 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -2242,7 +2242,9 @@ class BIM_PT_debug(Panel): layout.label(text="Inspector:") - row = layout.row() + 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 From 8bdd24ba16019e9f67d010e5a4f51aaf6ce537df Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 9 Nov 2020 15:01:39 +1100 Subject: [PATCH 13/19] Add support for importing all attributes of material layers and consitutents --- .../blenderbim/bim/import_ifc.py | 57 +++++++++++++++---- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 0fe458f506..484a655559 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,65 @@ 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"): + pass # TODO + + 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. + new.category = constituent.Category or "" def create_material_list(self, material_list): for material in material_list.Materials: From 527e6b0ca7edadf068fb653263b96dacf38124d0 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 9 Nov 2020 15:26:16 +1100 Subject: [PATCH 14/19] Minor fix --- src/ifcblenderexport/blenderbim/bim/import_ifc.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 484a655559..6c24b0eea9 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -162,13 +162,13 @@ class MaterialCreator: elif material.is_a("IfcMaterialLayerSet"): self.create_layer_set(material) elif material.is_a("IfcMaterialProfileSet"): - pass # TODO + pass # TODO def create_usage_definition(self, material): if material.is_a("IfcMaterialLayerSetUsage"): self.create_layer_set_usage(material) elif material.is_a("IfcMaterialProfileSetUsage"): - pass # TODO + pass # TODO def create_single(self, material): if material.Name not in self.materials: @@ -214,7 +214,7 @@ class MaterialCreator: 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. + new.fraction = constituent.Fraction or 0.0 new.category = constituent.Category or "" def create_material_list(self, material_list): @@ -1888,7 +1888,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 From 40e30eaa367c531cf4f380bbda7577d89970637f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 9 Nov 2020 19:15:23 +1100 Subject: [PATCH 15/19] Support exporting more metadata labels like names and descriptions for profile sets --- .../blenderbim/bim/__init__.py | 6 ++- .../blenderbim/bim/export_ifc.py | 30 ++++++++++--- .../blenderbim/bim/operator.py | 38 ++++++++++++++++ src/ifcblenderexport/blenderbim/bim/prop.py | 42 ++++++++++------- src/ifcblenderexport/blenderbim/bim/ui.py | 45 ++++++++++++++----- 5 files changed, 128 insertions(+), 33 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 780f55086d..ad955586dc 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, @@ -215,8 +218,10 @@ if bpy is not None: operator.GetRepresentationIfcParameters, operator.UpdateIfcRepresentation, prop.StrProperty, + prop.Attribute, prop.MaterialLayer, prop.MaterialConstituent, + prop.MaterialProfile, prop.MaterialSet, prop.Variable, prop.Role, @@ -244,7 +249,6 @@ if bpy is not None: prop.BcfTopicDocumentReference, prop.BcfTopicRelatedTopic, prop.Subcontext, - prop.Attribute, prop.BIMProperties, prop.BIMDebugProperties, prop.BCFProperties, diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index 98a6d8d94a..37afa66bf1 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 @@ -2047,13 +2047,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) @@ -3147,7 +3145,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 @@ -3215,6 +3213,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, relationships,) in self.ifc_parser.rel_space_boundaries.items(): for relationship in relationships: diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 9eaf01843e..31de9faebc 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -4195,6 +4195,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" diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index 904c7c9162..6e08108be5 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -484,10 +484,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"] @@ -541,6 +543,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") @@ -584,6 +595,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") @@ -591,6 +612,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): @@ -1605,15 +1628,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") @@ -1683,8 +1697,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 5eb3b5c123..692369405f 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): @@ -834,16 +869,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" From 09847513ab1346aba287fcbb0b301ea547089450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20C=2E=20P=C3=A9rez=20Tato?= Date: Sun, 8 Nov 2020 12:30:10 +0100 Subject: [PATCH 16/19] Fixes #1038 --- src/ifcgeom/IfcGeomShapes.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index dd97364bbe..b3b54ede24 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -1697,7 +1697,7 @@ namespace { } k.remove_duplicate_points_from_loop(polygon, true); - if (polygon.Size() < 3) { + if (polygon.Length() < 3) { return false; } @@ -1816,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); } From 84509b7cc2c3d4af4412e52f5592bd3be62b296c Mon Sep 17 00:00:00 2001 From: htlcnn Date: Mon, 9 Nov 2020 16:21:20 +0700 Subject: [PATCH 17/19] add IfcClass selector for Ifc By Type node --- src/ifcsverchok/nodes/ifc/by_type.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ifcsverchok/nodes/ifc/by_type.py b/src/ifcsverchok/nodes/ifc/by_type.py index 26c570e0f0..92b63ff085 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 not custom_ifc_class: + self.outputs["entity"].sv_set([file.by_type(ifc_class)]) + else: + self.outputs["entity"].sv_set([file.by_type(custom_ifc_class)]) def register(): From caa167718172899022e53f6e5b07fa057c5d346a Mon Sep 17 00:00:00 2001 From: htlcnn Date: Mon, 9 Nov 2020 16:23:33 +0700 Subject: [PATCH 18/19] rearrange logic --- src/ifcsverchok/nodes/ifc/by_type.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ifcsverchok/nodes/ifc/by_type.py b/src/ifcsverchok/nodes/ifc/by_type.py index 92b63ff085..718bfe8003 100644 --- a/src/ifcsverchok/nodes/ifc/by_type.py +++ b/src/ifcsverchok/nodes/ifc/by_type.py @@ -29,10 +29,10 @@ class SvIfcByType(bpy.types.Node, SverchCustomTreeNode, ifcsverchok.helper.SvIfc super().process() def process_ifc(self, file, ifc_product, ifc_class, custom_ifc_class): - if not custom_ifc_class: - self.outputs["entity"].sv_set([file.by_type(ifc_class)]) - else: + 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(): From 3477d3f1a255d1b75a0ffb79e30bb2c8b2cb13e4 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 9 Nov 2020 21:03:21 +1100 Subject: [PATCH 19/19] Implement import support for material profile sets --- .../blenderbim/bim/import_ifc.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 6c24b0eea9..89f2024b91 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -162,7 +162,7 @@ class MaterialCreator: elif material.is_a("IfcMaterialLayerSet"): self.create_layer_set(material) elif material.is_a("IfcMaterialProfileSet"): - pass # TODO + self.create_profile_set(material) def create_usage_definition(self, material): if material.is_a("IfcMaterialLayerSetUsage"): @@ -217,6 +217,28 @@ class MaterialCreator: 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: if material.Material: