diff --git a/src/examples/IfcAdvancedHouse.cpp b/src/examples/IfcAdvancedHouse.cpp index ad238a22fd..1950e425e7 100644 --- a/src/examples/IfcAdvancedHouse.cpp +++ b/src/examples/IfcAdvancedHouse.cpp @@ -41,7 +41,6 @@ #define IfcSchema Ifc2x3 #include "../ifcparse/macros.h" #include "../ifcparse/Ifc2x3.h" -#include "../ifcparse/IfcBaseClass.h" #include "../ifcparse/IfcHierarchyHelper.h" #include "../ifcgeom/Serialization/Serialization.h" @@ -60,15 +59,15 @@ int main() { // The IfcHierarchyHelper is a subclass of the regular IfcFile that provides several // convenience functions for working with geometry in IFC files. IfcHierarchyHelper file; - file.header().file_name()->setname("IfcAdvancedHouse.ifc"); + file.header().file_name().setname("IfcAdvancedHouse.ifc"); - IfcSchema::IfcBuilding* building = file.addBuilding(); + auto building = file.addBuilding(); // By adding a building, a hierarchy has been automatically created that consists of the following // structure: IfcProject > IfcSite > IfcBuilding // Lateron changing the name of the IfcProject can be done by obtaining a reference to the // project, which has been created automatically. - file.getSingle()->setName("IfcAdvancedHouse"s); + file.getSingle().setName("IfcAdvancedHouse"s); // To demonstrate the ability to serialize arbitrary opencascade solids a building envelope is // constructed by applying boolean operations. Naturally, in IFC, building elements should be @@ -91,13 +90,13 @@ int main() { // IfcFacetedBRep. If it would not be a polyhedron, serialise() can only be successful when linked // to the IFC4 model and with `advanced` set to `true` which introduces IfcAdvancedFace. It would // return `0` otherwise. - IfcSchema::IfcProductDefinitionShape* building_shape = IfcGeom::serialise(STRINGIFY(IfcSchema), building_shell, false)->as(); + auto building_shape = IfcGeom::serialise(file, building_shell, false).as(); file.addEntity(building_shape); - IfcSchema::IfcRepresentation* rep = *building_shape->Representations()->begin(); + auto rep = building_shape.Representations().begin(); rep->setContextOfItems(file.getRepresentationContext("model")); - building->setRepresentation(building_shape); + building.setRepresentation(building_shape); // A pale white colour is assigned to the building. setSurfaceColour(file, building_shape, 0.75, 0.73, 0.68); @@ -107,18 +106,18 @@ int main() { TopoDS_Shape shape; createGroundShape(shape); - auto ground_representation = IfcGeom::serialise(STRINGIFY(IfcSchema), shape, true); + auto ground_representation = IfcGeom::serialise(file, shape, true); if (!ground_representation) { - ground_representation = IfcGeom::tesselate(STRINGIFY(IfcSchema), shape, 100.); + ground_representation = IfcGeom::tesselate(file, shape, 100.); } - file.getSingle()->setRepresentation(ground_representation->as()); + file.getSingle().setRepresentation(ground_representation.as()); - IfcSchema::IfcRepresentation::list::ptr ground_reps = file.getSingle()->Representation()->Representations(); - for (IfcSchema::IfcRepresentation::list::it it = ground_reps->begin(); it != ground_reps->end(); ++it) { - (*it)->setContextOfItems(file.getRepresentationContext("Model")); + auto ground_reps = file.getSingle().Representation().Representations(); + for (auto& rep : ground_reps) { + rep.setContextOfItems(file.getRepresentationContext("Model")); } file.addEntity(ground_representation); - setSurfaceColour(file, ground_representation->as(), 0.15, 0.25, 0.05); + setSurfaceColour(file, ground_representation.as(), 0.15, 0.25, 0.05); /* // Note that IFC lacks elementary surfaces that STEP does have, such as spherical_surface. diff --git a/src/examples/IfcOpenHouse.cpp b/src/examples/IfcOpenHouse.cpp index accac737fb..6215c376f3 100644 --- a/src/examples/IfcOpenHouse.cpp +++ b/src/examples/IfcOpenHouse.cpp @@ -38,7 +38,6 @@ #define IfcSchema Ifc2x3 #include "../ifcparse/macros.h" #include "../ifcparse/Ifc2x3.h" -#include "../ifcparse/IfcBaseClass.h" #include "../ifcparse/IfcHierarchyHelper.h" #include "../ifcgeom/Serialization/Serialization.h" @@ -59,233 +58,268 @@ void createGroundShape(TopoDS_Shape& shape); int main() { - // The IfcHierarchyHelper is a subclass of the regular IfcFile that provides several - // convenience functions for working with geometry in IFC files. - IfcHierarchyHelper file; - file.header().file_name()->setname("IfcOpenHouse.ifc"); + // The IfcHierarchyHelper is a subclass of the regular IfcFile that provides several + // convenience functions for working with geometry in IFC files. + IfcHierarchyHelper file; + file.header().file_name().setname("IfcOpenHouse.ifc"); - // Start by adding a wall to the file, initially leaving most attributes blank. - IfcSchema::IfcWallStandardCase* south_wall = new IfcSchema::IfcWallStandardCase( - guid(), // GlobalId - 0, // OwnerHistory - "South wall"s, // Name - null, // Description - null, // ObjectType - 0, // ObjectPlacement - 0, // Representation - null // Tag + // Start by adding a wall to the file, initially leaving most attributes blank. + auto south_wall = file.create(); + south_wall.setGlobalId(guid()); + south_wall.setName("South wall"); #ifdef USE_IFC4 - , IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD + south_wall.setPredefinedType(IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD); #endif - ); - file.addBuildingProduct(south_wall); + file.addBuildingProduct(south_wall); - // By adding a wall, a hierarchy has been automatically created that consists of the following - // structure: IfcProject > IfcSite > IfcBuilding > IfcBuildingStorey > IfcWall + // By adding a wall, a hierarchy has been automatically created that consists of the following + // structure: IfcProject > IfcSite > IfcBuilding > IfcBuildingStorey > IfcWall - // Lateron changing the name of the IfcProject can be done by obtaining a reference to the - // project, which has been created automatically. - file.getSingle()->setName("IfcOpenHouse"s); + // Lateron changing the name of the IfcProject can be done by obtaining a reference to the + // project, which has been created automatically. + file.getSingle().setName("IfcOpenHouse"s); - // An IfcOwnerHistory has been initialized as well, which should be assigned to the wall. - south_wall->setOwnerHistory(file.getSingle()); + // An IfcOwnerHistory has been initialized as well, which should be assigned to the wall. + south_wall.setOwnerHistory(file.getSingle()); - // The wall will be shaped as a box, with the dimensions specified in millimeters. The resulting - // product definition will consist of both a body representation as well as an axis representation - // that runs over the centerline of the box in the X-axis. - IfcSchema::IfcProductDefinitionShape* south_wall_shape = file.addAxisBox(10000, 360, 3000); + // The wall will be shaped as a box, with the dimensions specified in millimeters. The resulting + // product definition will consist of both a body representation as well as an axis representation + // that runs over the centerline of the box in the X-axis. + auto south_wall_shape = file.addAxisBox(10000, 360, 3000); - // Obtain a reference to the placement of the IfcBuildingStorey in order to create a hierarchy - // of placements for the products - IfcSchema::IfcObjectPlacement* storey_placement = file.getSingle()->ObjectPlacement(); + // Obtain a reference to the placement of the IfcBuildingStorey in order to create a hierarchy + // of placements for the products + auto storey_placement = file.getSingle().ObjectPlacement(); - // The shape has to be assigned to the representation of the wall and is placed at the origin - // of the coordinate system. - south_wall->setRepresentation(south_wall_shape); - south_wall->setObjectPlacement(file.addLocalPlacement(storey_placement)); + // The shape has to be assigned to the representation of the wall and is placed at the origin + // of the coordinate system. + south_wall.setRepresentation(south_wall_shape); + south_wall.setObjectPlacement(file.addLocalPlacement(storey_placement)); - // A pale white colour is assigned to the wall. - IfcSchema::IfcPresentationStyleAssignment* wall_colour = setSurfaceColour(file, south_wall_shape, 0.75, 0.73, 0.68); + // A pale white colour is assigned to the wall. + auto wall_colour = setSurfaceColour(file, south_wall_shape, 0.75, 0.73, 0.68); - // Now create a footing for the wall to rest on. - IfcSchema::IfcFooting* footing = new IfcSchema::IfcFooting(guid(), file.getSingle(), - "Footing"s, null, null, 0, 0, null, IfcSchema::IfcFootingTypeEnum::IfcFootingType_STRIP_FOOTING); + // Now create a footing for the wall to rest on. + auto footing = file.create(); + footing.setGlobalId(guid()); + footing.setOwnerHistory(file.getSingle()); + footing.setName("Footing"); + footing.setPredefinedType(IfcSchema::IfcFootingTypeEnum::IfcFootingType_STRIP_FOOTING); - file.addBuildingProduct(footing); + file.addBuildingProduct(footing); - // The footing will span the entire floor plan of our building. The IfcRepresentationContext is - // something that has been created automatically as well, but representations could have been - // assigned to a specific context, for example to add a two dimensional plan representation as well. - footing->setRepresentation(file.addBox(10100, 5460, 2000)); - footing->setObjectPlacement(file.addLocalPlacement(storey_placement, 0, 2500, -2000)); - // The footing will have a dark gray colour - IfcSchema::IfcPresentationStyleAssignment* footing_colour = setSurfaceColour(file,footing->Representation(), 0.26, 0.22, 0.18); + // The footing will span the entire floor plan of our building. The IfcRepresentationContext is + // something that has been created automatically as well, but representations could have been + // assigned to a specific context, for example to add a two dimensional plan representation as well. + footing.setRepresentation(file.addBox(10100, 5460, 2000)); + footing.setObjectPlacement(file.addLocalPlacement(storey_placement, 0, 2500, -2000)); + // The footing will have a dark gray colour + auto footing_colour = setSurfaceColour(file, footing.Representation(), 0.26, 0.22, 0.18); - // IFC has two ways to apply boolean operations to geometry. IfcBooleanResults are commonly used - // to clip geometry to a surface, for example to a slanted roof. For openings that are filled - // with another element, for example a door or a window, an IfcOpeningElement is used instead. + // IFC has two ways to apply boolean operations to geometry. IfcBooleanResults are commonly used + // to clip geometry to a surface, for example to a slanted roof. For openings that are filled + // with another element, for example a door or a window, an IfcOpeningElement is used instead. - // An opening element is created with rectangular geometry: - IfcSchema::IfcOpeningElement* west_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(), - null, null, null, file.addLocalPlacement(south_wall->ObjectPlacement(), -2500, 0, 400), - file.addBox(6000, 3630, 1600), null + // An opening element is created with rectangular geometry: + auto west_opening = file.create(); + west_opening.setGlobalId(guid()); + west_opening.setOwnerHistory(file.getSingle()); + west_opening.setObjectPlacement(file.addLocalPlacement(south_wall.ObjectPlacement(), -2500, 0, 400)); + west_opening.setRepresentation(file.addBox(6000, 3630, 1600)); #ifdef USE_IFC4 - , IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING + west_opening.setPredefinedType(IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING); #endif - ); - file.addEntity(west_opening); - // Relate the opening element to the wall. - IfcSchema::IfcRelVoidsElement* void_element = new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), - null, null, south_wall, west_opening); - file.addEntity(void_element); + // Relate the opening element to the wall. + auto void_element = file.create(); + void_element.setGlobalId(guid()); + void_element.setOwnerHistory(file.getSingle()); + void_element.setRelatingBuildingElement(south_wall); + void_element.setRelatedOpeningElement(west_opening); - // Now create an additional opening - IfcSchema::IfcOpeningElement* south_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(), - null, null, null, file.addLocalPlacement(storey_placement, 3000, 0, 400), - file.addBox(1860, 3000, 1600), null + // Now create an additional opening + auto south_opening = file.create(); + south_opening.setGlobalId(guid()); + south_opening.setOwnerHistory(file.getSingle()); + south_opening.setObjectPlacement(file.addLocalPlacement(storey_placement, 3000, 0, 400)); + south_opening.setRepresentation(file.addBox(1860, 3000, 1600)); #ifdef USE_IFC4 - , IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING + south_opening.setPredefinedType(IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING); #endif - ); - file.addEntity(south_opening); - file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, south_wall, south_opening)); - - // Create a roof element that will consist of two slabs: - IfcSchema::IfcRoof* roof = new IfcSchema::IfcRoof(guid(), file.getSingle(), "Roof"s, null, null, - file.addLocalPlacement(storey_placement), 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF); - // The roof geometry is slanted 45 degrees by specifying a direction for the box extrusion - IfcSchema::IfcShapeRepresentation* roof_rep = file.addEmptyRepresentation(); - file.addBox(roof_rep, 10200, 360, sqrt(2.0*2900*2900), 0, file.addPlacement3d(0, 0, 0, 0, 1, 0), - file.addTriplet(0, -sqrt(0.5), sqrt(0.5))); + // Relate the opening element to the wall. + auto void_element2 = file.create(); + void_element2.setGlobalId(guid()); + void_element2.setOwnerHistory(file.getSingle()); + void_element2.setRelatingBuildingElement(south_wall); + void_element2.setRelatedOpeningElement(south_opening); - // CV-2x3-144: Roofs are aggregates and shall have at least one contained element and no own geometry - IfcSchema::IfcSlab* south_roof_part = new IfcSchema::IfcSlab(guid(), file.getSingle(), "South roof"s, - null, null, 0, 0, null, IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF); - - // The geometry is instantiated by using IfcMappedItems. This way geometry definitions can - // be reused while maintaining the cardinality constraint that the ShapeOfProduct relation - // imposes on the IfcProductDefinitionShape. Note that this constrained is lifted in IFC4. - south_roof_part->setRepresentation(file.addMappedItem(roof_rep)); - south_roof_part->setObjectPlacement(file.addLocalPlacement(roof->ObjectPlacement(), 0, -400, 2700)); - - // The same roof geometry is re-used on the north side of the roof, by inverting the X-axis of - // the local placement the roof is rotated 180 degrees around the Z-axis - IfcSchema::IfcSlab* north_roof_part = new IfcSchema::IfcSlab(guid(), file.getSingle(), "North roof"s, - null, null, 0, 0, null, IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF); - north_roof_part->setOwnerHistory(file.getSingle()); - north_roof_part->setRepresentation(file.addMappedItem(roof_rep)); - north_roof_part->setObjectPlacement(file.addLocalPlacement(roof->ObjectPlacement(), 0, 5400, 2700, 0, 0, 1, -1, 0, 0)); - - IfcSchema::IfcObjectDefinition::list::ptr roof_parts(new IfcSchema::IfcObjectDefinition::list); - roof_parts->push(south_roof_part); - roof_parts->push(north_roof_part); - IfcSchema::IfcRelDecomposes* roof_decomposition = new IfcSchema::IfcRelAggregates(guid(), file.getSingle(), - null, null, roof, roof_parts); - file.addEntity(roof_decomposition); + // Create a roof element that will consist of two slabs: + auto roof = file.create(); + roof.setGlobalId(guid()); + roof.setOwnerHistory(file.getSingle()); + roof.setName("Roof"); + roof.setObjectPlacement(file.addLocalPlacement(storey_placement)); + roof.setShapeType(IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF); - file.addBuildingProduct(south_roof_part); - file.addBuildingProduct(north_roof_part); - file.addBuildingProduct(roof); + // The roof geometry is slanted 45 degrees by specifying a direction for the box extrusion + auto roof_rep = file.addEmptyRepresentation(); + file.addBox(roof_rep, 10200, 360, sqrt(2.0 * 2900 * 2900), IfcSchema::IfcAxis2Placement2D{}, file.addPlacement3d(0, 0, 0, 0, 1, 0), file.addTriplet(0, -sqrt(0.5), sqrt(0.5))); - setSurfaceColour(file, roof_rep, 0.24, 0.08, 0.04); + // CV-2x3-144: Roofs are aggregates and shall have at least one contained element and no own geometry + auto south_roof_part = file.create(); + south_roof_part.setGlobalId(guid()); + south_roof_part.setOwnerHistory(file.getSingle()); + south_roof_part.setName("South roof"); + south_roof_part.setPredefinedType(IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF); - // Copy the south wall to the north - IfcSchema::IfcWallStandardCase* north_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(), "North wall"s, - null, null, file.addLocalPlacement(storey_placement, 0, 5000, 0), file.addAxisBox(10000, 360, 3000), null + // The geometry is instantiated by using IfcMappedItems. This way geometry definitions can + // be reused while maintaining the cardinality constraint that the ShapeOfProduct relation + // imposes on the IfcProductDefinitionShape. Note that this constrained is lifted in IFC4. + south_roof_part.setRepresentation(file.addMappedItem(roof_rep)); + south_roof_part.setObjectPlacement(file.addLocalPlacement(roof.ObjectPlacement(), 0, -400, 2700)); + + // The same roof geometry is re-used on the north side of the roof, by inverting the X-axis of + // the local placement the roof is rotated 180 degrees around the Z-axis + auto north_roof_part = file.create(); + north_roof_part.setGlobalId(guid()); + north_roof_part.setOwnerHistory(file.getSingle()); + north_roof_part.setName("North roof"); + north_roof_part.setPredefinedType(IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF); + + north_roof_part.setRepresentation(file.addMappedItem(roof_rep)); + north_roof_part.setObjectPlacement(file.addLocalPlacement(roof.ObjectPlacement(), 0, 5400, 2700, 0, 0, 1, -1, 0, 0)); + + auto rel = file.create(); + rel.setGlobalId(guid()); + rel.setOwnerHistory(file.getSingle()); + rel.setRelatingObject(roof); + rel.setRelatedObjects({south_roof_part, north_roof_part}); + + file.addBuildingProduct(south_roof_part); + file.addBuildingProduct(north_roof_part); + file.addBuildingProduct(roof); + + setSurfaceColour(file, roof_rep, 0.24, 0.08, 0.04); + + // Copy the south wall to the north + auto north_wall = file.create(); + north_wall.setGlobalId(guid()); + north_wall.setOwnerHistory(file.getSingle()); + north_wall.setName("North wall"); + north_wall.setObjectPlacement(file.addLocalPlacement(storey_placement, 0, 5000, 0)); + north_wall.setRepresentation(file.addAxisBox(10000, 360, 3000)); #ifdef USE_IFC4 - , IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD -#endif - ); - file.addBuildingProduct(north_wall); - setSurfaceColour(file,north_wall->Representation(), wall_colour); + north_wall.setPredefinedType(IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD); +#endif - // Two identical representations are created for the two remaining walls. Mapped items - // are not used, because it is not allowed by the standard for wall body representations. - // MappedItems are not allowed for Axis representations as per CV-2x3-161 - IfcSchema::IfcProductDefinitionShape* clipped_wall_body_reps[2]; - for (int i = 0; i < 2; ++i) { - IfcSchema::IfcShapeRepresentation* body = file.addEmptyRepresentation(); - file.addBox(body, 5000, 360, 6000); - // The wall geometry is clipped using two IfcHalfSpaceSolids, created from an - // 'axis 3d placement' that specifies the plane against which the geometry is clipped. - file.clipRepresentation(body, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false); - file.clipRepresentation(body, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false); - setSurfaceColour(file, body, wall_colour); + file.addBuildingProduct(north_wall); + setSurfaceColour(file, north_wall.Representation(), wall_colour); - IfcSchema::IfcShapeRepresentation* axis = file.addEmptyRepresentation("Axis", "Curve2D"); - file.addAxis(axis, 5000); + // Two identical representations are created for the two remaining walls. Mapped items + // are not used, because it is not allowed by the standard for wall body representations. + // MappedItems are not allowed for Axis representations as per CV-2x3-161 + IfcSchema::IfcProductDefinitionShape clipped_wall_body_reps[2]; + for (int i = 0; i < 2; ++i) { + auto body = file.addEmptyRepresentation(); + file.addBox(body, 5000, 360, 6000); + // The wall geometry is clipped using two IfcHalfSpaceSolids, created from an + // 'axis 3d placement' that specifies the plane against which the geometry is clipped. + file.clipRepresentation(body, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false); + file.clipRepresentation(body, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false); + setSurfaceColour(file, body, wall_colour); - IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list); - reps->push(body); - reps->push(axis); - clipped_wall_body_reps[i] = new IfcSchema::IfcProductDefinitionShape(null, null, reps); - } + auto axis = file.addEmptyRepresentation("Axis", "Curve2D"); + file.addAxis(axis, 5000); - // Now create a wall on the east of the building, again starting with just a box shape - IfcSchema::IfcWallStandardCase* east_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(), - "East wall"s, null, null, file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0), clipped_wall_body_reps[0], null + clipped_wall_body_reps[i] = file.create(); + clipped_wall_body_reps[i].setRepresentations({body, axis}); + } + + // Now create a wall on the east of the building, again starting with just a box shape + auto east_wall = file.create(); + east_wall.setGlobalId(guid()); + east_wall.setOwnerHistory(file.getSingle()); + east_wall.setName("East wall"); + east_wall.setObjectPlacement(file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0)); + east_wall.setRepresentation(clipped_wall_body_reps[0]); #ifdef USE_IFC4 - , IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD -#endif - ); - file.addBuildingProduct(east_wall); + east_wall.setPredefinedType(IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD); +#endif - // The east wall is copied to the west location of the house - IfcSchema::IfcWallStandardCase* west_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(), - "West wall"s, null, null, file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0), clipped_wall_body_reps[1], null + file.addBuildingProduct(east_wall); + + // The east wall is copied to the west location of the house + auto west_wall = file.create(); + west_wall.setGlobalId(guid()); + west_wall.setOwnerHistory(file.getSingle()); + west_wall.setName("West wall"); + west_wall.setObjectPlacement(file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0)); + west_wall.setRepresentation(clipped_wall_body_reps[1]); #ifdef USE_IFC4 - , IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD -#endif - ); - file.addBuildingProduct(west_wall); + west_wall.setPredefinedType(IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD); +#endif - // The west wall is assigned an opening element we created for the south wall, opening elements are - // not shared across building elements, even if they share the same representation. Hence, the east - // wall will not feature this opening. - // NB: an Opening Element can only be used to create a single void within a single Element, as per: - // http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcproductextension/lexical/ifcfeatureelementsubtraction.htm + file.addBuildingProduct(west_wall); - // Not all viewers support opening elements with mapped representations, hence an exact copy of the - // same subtraction box is instantiated for the otherwise identical opening element. - IfcSchema::IfcOpeningElement* west_opening_copy = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(), - null, null, null, file.addLocalPlacement(west_wall->ObjectPlacement(), 2500, -2500+4820, 400, 0, 0, 1, 0, 1, 0), - file.addBox(6000, 3630, 1600), null + // The west wall is assigned an opening element we created for the south wall, opening elements are + // not shared across building elements, even if they share the same representation. Hence, the east + // wall will not feature this opening. + // NB: an Opening Element can only be used to create a single void within a single Element, as per: + // http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcproductextension/lexical/ifcfeatureelementsubtraction.htm + + // Not all viewers support opening elements with mapped representations, hence an exact copy of the + // same subtraction box is instantiated for the otherwise identical opening element. + auto west_opening_copy = file.create(); + west_opening_copy.setGlobalId(guid()); + west_opening_copy.setOwnerHistory(file.getSingle()); + west_opening_copy.setObjectPlacement(file.addLocalPlacement(west_wall.ObjectPlacement(), 2500, -2500 + 4820, 400, 0, 0, 1, 0, 1, 0)); + west_opening_copy.setRepresentation(file.addBox(6000, 3630, 1600)); #ifdef USE_IFC4 - , IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING -#endif - ); - file.addEntity(west_opening_copy); - file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, west_wall, west_opening_copy)); - + west_opening_copy.setPredefinedType(IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING); +#endif + + { + auto rel = file.create(); + rel.setGlobalId(guid()); + rel.setOwnerHistory(file.getSingle()); + rel.setRelatingBuildingElement(west_wall); + rel.setRelatedOpeningElement(west_opening_copy); + } + // Up until now we have only used simple extrusions for the creation of the geometry. For the // ground mesh of the IfcSite we will use a Nurbs surface created in Open Cascade. The surface // will be tessellated using the deflection specified. TopoDS_Shape shape; createGroundShape(shape); - IfcSchema::IfcProductDefinitionShape* ground_representation = IfcGeom::tesselate(STRINGIFY(IfcSchema), shape, 100.)->as(); - file.getSingle()->setRepresentation(ground_representation); + auto ground_representation = IfcGeom::tesselate(file, shape, 100.).as(); + file.getSingle().setRepresentation(ground_representation); GProp_GProps prop; BRepGProp::SurfaceProperties(shape, prop); const double site_area = prop.Mass() / 1000 / 1000; - IfcSchema::IfcProperty::list::ptr properties(new IfcSchema::IfcProperty::list); - properties->push(new IfcSchema::IfcPropertySingleValue("TotalArea", null, new IfcSchema::IfcAreaMeasure(site_area), 0)); - IfcSchema::IfcPropertySet* pset = new IfcSchema::IfcPropertySet(guid(), file.getSingle(), "Pset_SiteCommon"s, null, properties); -#ifdef USE_IFC4 - IfcSchema::IfcObjectDefinition::list::ptr related_objs(new IfcSchema::IfcObjectDefinition::list); -#else - IfcSchema::IfcObject::list::ptr related_objs(new IfcSchema::IfcObject::list); -#endif - related_objs->push(file.getSingle()); - IfcSchema::IfcRelDefinesByProperties* site_prop = new IfcSchema::IfcRelDefinesByProperties(guid(), file.getSingle(), null, null, related_objs, pset); - file.addEntity(site_prop); + auto total_area = file.create(); + total_area.setName("TotalArea"); + auto area = file.create(); + area.set_attribute_value(0, site_area); + total_area.setNominalValue(area); - IfcSchema::IfcRepresentation::list::ptr ground_reps = file.getSingle()->Representation()->Representations(); - for (IfcSchema::IfcRepresentation::list::it it = ground_reps->begin(); it != ground_reps->end(); ++it) { - (*it)->setContextOfItems(file.getRepresentationContext("Model")); + auto pset = file.create(); + pset.setGlobalId(guid()); + pset.setOwnerHistory(file.getSingle()); + pset.setName("Pset_SiteCommon"); + pset.setHasProperties({total_area}); + + auto site_prop = file.create(); + site_prop.setGlobalId(guid()); + site_prop.setOwnerHistory(file.getSingle()); + site_prop.setRelatedObjects({file.getSingle()}); + site_prop.setRelatingPropertyDefinition(pset); + + auto ground_reps = file.getSingle().Representation().Representations(); + for (auto& rep : ground_reps) { + rep.setContextOfItems(file.getRepresentationContext("Model")); } file.addEntity(ground_representation); setSurfaceColour(file,ground_representation, 0.15, 0.25, 0.05); @@ -297,58 +331,28 @@ int main() { // Some BIM authoring applications, such as Autodesk Revit, ignore the geometrical representation // by and large and construct native walls using the layer thickness and reference line offset // provided here. -#ifdef USE_IFC4 - IfcSchema::IfcMaterial* material = new IfcSchema::IfcMaterial("Brick", null, null); -#else - IfcSchema::IfcMaterial* material = new IfcSchema::IfcMaterial("Brick"); -#endif - IfcSchema::IfcMaterialLayer* layer = new IfcSchema::IfcMaterialLayer( - material, - 360, - null -#ifdef USE_IFC4 - , null - , null - , null - , null -#endif - ); - IfcSchema::IfcMaterialLayer::list::ptr layers (new aggregate_of()); - layers->push(layer); - IfcSchema::IfcMaterialLayerSet* layer_set = new IfcSchema::IfcMaterialLayerSet( - layers, - "Wall"s -#ifdef USE_IFC4 - , null -#endif - ); - IfcSchema::IfcMaterialLayerSetUsage* layer_usage = new IfcSchema::IfcMaterialLayerSetUsage( - layer_set, - IfcSchema::IfcLayerSetDirectionEnum::IfcLayerSetDirection_AXIS2, - IfcSchema::IfcDirectionSenseEnum::IfcDirectionSense_POSITIVE, - -180 -#ifdef USE_IFC4 - , null -#endif - ); + auto material = file.create(); + material.setName("Brick"); - IfcSchema::IfcRelAssociatesMaterial* associates_material = new IfcSchema::IfcRelAssociatesMaterial( - guid(), - file.getSingle(), - null, - null, -#ifdef USE_IFC4 - file.instances_by_type()->as(), -#else - file.instances_by_type()->as(), -#endif - layer_usage); + auto layer = file.create(); + layer.setMaterial(material); + layer.setLayerThickness(360); - file.addEntity(material); - file.addEntity(layer); - file.addEntity(layer_set); - file.addEntity(layer_usage); - file.addEntity(associates_material); + auto layer_set = file.create(); + layer_set.setMaterialLayers({layer}); + layer_set.setLayerSetName("Wall"); + + auto layer_usage = file.create(); + layer_usage.setForLayerSet(layer_set); + layer_usage.setDirectionSense(IfcSchema::IfcDirectionSenseEnum::IfcDirectionSense_POSITIVE); + layer_usage.setLayerSetDirection(IfcSchema::IfcLayerSetDirectionEnum::IfcLayerSetDirection_AXIS1); + layer_usage.setOffsetFromReferenceLine(-180); + + auto associates_material = file.create(); + associates_material.setGlobalId(guid()); + associates_material.setOwnerHistory(file.getSingle()); + associates_material.setRelatedObjects({south_wall, north_wall, east_wall, west_wall}); + associates_material.setRelatingMaterial(layer_usage); // In addition, another common way to represent geometry in IFC files is to use extrusions of // planar areas bounded by a polygon. @@ -359,55 +363,84 @@ int main() { stair_points.push_back(XY(500, 200)); stair_points.push_back(XY(500, 400)); stair_points.push_back(XY( 0, 400)); - IfcSchema::IfcStairFlight* stair = new IfcSchema::IfcStairFlight(guid(), file.getSingle(), - null, null, null, file.addLocalPlacement(storey_placement, 5050, 1000, 0, 0, 1, 0, 1, 0, 0), - file.addExtrudedPolyline(stair_points, 1200), null, 2, 2, 0.2, 0.25 + auto stair = file.create(); + stair.setGlobalId(guid()); + stair.setOwnerHistory(file.getSingle()); + stair.setObjectPlacement(file.addLocalPlacement(storey_placement, 5050, 1000, 0, 0, 1, 0, 1, 0, 0)); + stair.setRepresentation(file.addExtrudedPolyline(stair_points, 1200)); + stair.setNumberOfRiser(2); + stair.setNumberOfTreads(2); + stair.setRiserHeight(0.2); + stair.setTreadLength(0.25); #ifdef USE_IFC4 - , IfcSchema::IfcStairFlightTypeEnum::IfcStairFlightType_STRAIGHT + stair.setPredefinedType(IfcSchema::IfcStairFlightTypeEnum::IfcStairFlightType_STRAIGHT); #endif - ); file.addBuildingProduct(stair); - setSurfaceColour(file, stair->Representation(), footing_colour); + setSurfaceColour(file, stair.Representation(), footing_colour); - IfcSchema::IfcOpeningElement* door_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(), - null, null, null, file.addLocalPlacement(storey_placement, 5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null + auto door_opening = file.create(); + door_opening.setGlobalId(guid()); + door_opening.setOwnerHistory(file.getSingle()); + door_opening.setObjectPlacement(file.addLocalPlacement(storey_placement, 5000 - 180, 2500 - 900, 0)); + door_opening.setRepresentation(file.addBox(1000, 1000, 2200)); #ifdef USE_IFC4 - , IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING -#endif - ); - file.addEntity(door_opening); - file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, east_wall, door_opening)); + door_opening.setPredefinedType(IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING); +#endif + + auto rel3 = file.create(); + rel3.setGlobalId(guid()); + rel3.setOwnerHistory(file.getSingle()); + rel3.setRelatingBuildingElement(east_wall); + rel3.setRelatedOpeningElement(door_opening); // A single shape representation can contain multiple representiation items. This way a product // can be a composition of multiple solids. The following door will be composed of four boxes // which constitute the door and its frame. - IfcSchema::IfcDoor* door = new IfcSchema::IfcDoor(guid(), file.getSingle(), null, null, null, - file.addLocalPlacement(storey_placement, 4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000 + auto door = file.create(); + door.setGlobalId(guid()); + door.setOwnerHistory(file.getSingle()); + door.setObjectPlacement(file.addLocalPlacement(storey_placement, 4800, 1600, 0, 0, 0, 1, 0, 1, 0)); + door.setOverallWidth(1000); + door.setOverallHeight(2200); #ifdef USE_IFC4 - , IfcSchema::IfcDoorTypeEnum::IfcDoorType_DOOR - , IfcSchema::IfcDoorTypeOperationEnum::IfcDoorTypeOperation_SINGLE_SWING_LEFT - , null + door.setPredefinedType(IfcSchema::IfcDoorTypeEnum::IfcDoorType_DOOR); + door.setOperationType(IfcSchema::IfcDoorTypeOperationEnum::IfcDoorTypeOperation_SINGLE_SWING_LEFT); #endif - ); - door->setRepresentation(file.addBox(80, 80, 2120, 0, file.addPlacement3d(460, 0, 0))); - IfcSchema::IfcRepresentation::list::ptr door_representations = door->Representation()->Representations(); - IfcSchema::IfcShapeRepresentation* door_body = 0; - for (IfcSchema::IfcRepresentation::list::it i = door_representations->begin(); i != door_representations->end(); ++i) { - IfcSchema::IfcRepresentation* rep = *i; - if (rep->declaration().is(IfcSchema::IfcShapeRepresentation::Class()) && rep->RepresentationIdentifier().get_value_or("") == "Body") { - door_body = (IfcSchema::IfcShapeRepresentation*) rep; + + door.setRepresentation(file.addBox(80, 80, 2120, IfcSchema::IfcAxis2Placement2D{}, file.addPlacement3d(460, 0, 0))); + + auto door_representations = door.Representation().Representations(); + IfcSchema::IfcShapeRepresentation door_body; + for (auto& rep : door_representations) { + if (rep.declaration().is(IfcSchema::IfcShapeRepresentation::Class()) && rep.RepresentationIdentifier().value_or("") == "Body") { + door_body = rep.as(); } } - file.addBox(door_body, 80, 80, 2120, 0, file.addPlacement3d(-460, 0, 0)); - file.addBox(door_body, 1000, 80, 80, 0, file.addPlacement3d( 0, 0, 2120)); + + file.addBox(door_body, 80, 80, 2120, IfcSchema::IfcAxis2Placement2D{}, file.addPlacement3d(-460, 0, 0)); + file.addBox(door_body, 1000, 80, 80, IfcSchema::IfcAxis2Placement2D{}, file.addPlacement3d( 0, 0, 2120)); file.addBox(door_body, 860, 30, 2120); file.addBuildingProduct(door); - setSurfaceColour(file, door->Representation(), 0.9, 0.9, 0.9); - file.addEntity(new IfcSchema::IfcRelFillsElement(guid(), file.getSingle(), null, null, door_opening, door)); - IfcSchema::IfcDoorStyle* door_style = new IfcSchema::IfcDoorStyle(guid(), file.getSingle(), "Door type"s, null, null, null, null, null, - IfcSchema::IfcDoorStyleOperationEnum::IfcDoorStyleOperation_SINGLE_SWING_LEFT, IfcSchema::IfcDoorStyleConstructionEnum::IfcDoorStyleConstruction_WOOD, false, false); + setSurfaceColour(file, door.Representation(), 0.9, 0.9, 0.9); + { + auto rel = file.create(); + rel.setGlobalId(guid()); + rel.setOwnerHistory(file.getSingle()); + rel.setRelatingOpeningElement(door_opening); + rel.setRelatedBuildingElement(door); + } + + auto door_style = file.create(); + door_style.setGlobalId(guid()); + door_style.setOwnerHistory(file.getSingle()); + door_style.setName("Door type"); + door_style.setOperationType(IfcSchema::IfcDoorStyleOperationEnum::IfcDoorStyleOperation_SINGLE_SWING_LEFT); + door_style.setConstructionType(IfcSchema::IfcDoorStyleConstructionEnum::IfcDoorStyleConstruction_WOOD); + door_style.setParameterTakesPrecedence(false); + door_style.setSizeable(false); + // NOTE: typing by IfcDoorStyle will cause validation errors in IFC4+ but it's allowed for backwards compatibility // better to use IfcDoorType in the actual use case file.addRelatedObject(door_style, door); @@ -423,23 +456,23 @@ int main() { // Therefore the OverallWidth and OverallHeight of the window attributes will need to // match the bounding box of the representation. Furthermore, the window placement needs // to align with the lowerleft corner of the constituent parts. - IfcSchema::IfcShapeRepresentation::list::ptr frame_representations(new IfcSchema::IfcShapeRepresentation::list); + std::vector frame_representations; - IfcSchema::IfcShapeRepresentation* horizontal_bar = file.addEmptyRepresentation(); - IfcSchema::IfcShapeRepresentation* vertical_bar = file.addEmptyRepresentation(); + auto horizontal_bar = file.addEmptyRepresentation(); + auto vertical_bar = file.addEmptyRepresentation(); file.addBox(horizontal_bar, 1860, 90, 90); file.addBox(vertical_bar, 90, 90, 1420); - frame_representations->push(horizontal_bar); - frame_representations->push(horizontal_bar); // Add another reference to the horizontal bar created above - frame_representations->push(vertical_bar); - frame_representations->push(vertical_bar); // Add another reference to the vertical bar created above + frame_representations.push_back(horizontal_bar); + frame_representations.push_back(horizontal_bar); // Add another reference to the horizontal bar created above + frame_representations.push_back(vertical_bar); + frame_representations.push_back(vertical_bar); // Add another reference to the vertical bar created above // The beams all have the same surface style assigned - IfcSchema::IfcPresentationStyleAssignment* frame_style = 0; - for (IfcSchema::IfcShapeRepresentation::list::it i = frame_representations->begin(); i != frame_representations->end(); i += 2) { + IfcSchema::IfcPresentationStyleAssignment frame_style; + for (auto i = frame_representations.begin(); i != frame_representations.end(); i += 2) { if (frame_style) { - setSurfaceColour(file,*i, frame_style); + setSurfaceColour(file, *i, frame_style); } else { frame_style = setSurfaceColour(file,*i, 0.5, 0.4, 0.3); } @@ -448,73 +481,80 @@ int main() { // This window will be placed at five locations within the building. A list of placements is // created and is iterated over to create all window instances. - IfcSchema::IfcLocalPlacement::list::ptr window_placements (new IfcSchema::IfcLocalPlacement::list); - window_placements->push(file.addLocalPlacement(storey_placement, 2*-1770-430-930, -45, 400)); - window_placements->push(file.addLocalPlacement(storey_placement, -1770-430-930, -45, 400)); - window_placements->push(file.addLocalPlacement(storey_placement, -430-930, -45, 400)); - window_placements->push(file.addLocalPlacement(storey_placement, 3000-930, -45, 400)); - window_placements->push(file.addLocalPlacement(storey_placement, -4855+45, 885-930, 400, 0, 0, 1, 0, 1, 0)); + std::vector window_placements; + window_placements.push_back(file.addLocalPlacement(storey_placement, 2*-1770-430-930, -45, 400)); + window_placements.push_back(file.addLocalPlacement(storey_placement, -1770-430-930, -45, 400)); + window_placements.push_back(file.addLocalPlacement(storey_placement, -430-930, -45, 400)); + window_placements.push_back(file.addLocalPlacement(storey_placement, 3000-930, -45, 400)); + window_placements.push_back(file.addLocalPlacement(storey_placement, -4855+45, 885-930, 400, 0, 0, 1, 0, 1, 0)); - for (IfcSchema::IfcLocalPlacement::list::it it = window_placements->begin(); it != window_placements->end(); ++it) { - - // Create the window at the current location - IfcSchema::IfcLocalPlacement* place = *it; - IfcSchema::IfcWindow* window = new IfcSchema::IfcWindow(guid(), file.getSingle(), - null, null, null, place, 0, null, 1600, 1860 + for (auto& place : window_placements) { + auto window = file.create(); + window.setGlobalId(guid()); + window.setOwnerHistory(file.getSingle()); + window.setObjectPlacement(place); + window.setOverallWidth(1860); + window.setOverallHeight(1600); #ifdef USE_IFC4 - , IfcSchema::IfcWindowTypeEnum::IfcWindowType_WINDOW - , IfcSchema::IfcWindowTypePartitioningEnum::IfcWindowTypePartitioning_SINGLE_PANEL - , null + window.setPredefinedType(IfcSchema::IfcWindowTypeEnum::IfcWindowType_WINDOW); + window.setPartitioningType(IfcSchema::IfcWindowTypePartitioningEnum::IfcWindowTypePartitioning_SINGLE_PANEL); #endif - ); - file.addBuildingProduct(window); + file.addBuildingProduct(window); // Initialize a list of parts for the window to be composed of - IfcSchema::IfcObjectDefinition::list::ptr window_parts(new aggregate_of()); + std::vector window_parts; // The placements for the beams are not shared across the different windows because every // beam is placed relative to its parent window entity. - IfcSchema::IfcLocalPlacement::list::ptr frame_placements (new aggregate_of()); - frame_placements->push(file.addLocalPlacement(storey_placement, 930,45)); - frame_placements->push(file.addLocalPlacement(storey_placement, 930, 45, 1510)); - frame_placements->push(file.addLocalPlacement(storey_placement, -885+930, 45, 90)); - frame_placements->push(file.addLocalPlacement(storey_placement, 885+930, 45, 90)); + std::vector frame_placements; + frame_placements.push_back(file.addLocalPlacement(storey_placement, 930,45)); + frame_placements.push_back(file.addLocalPlacement(storey_placement, 930, 45, 1510)); + frame_placements.push_back(file.addLocalPlacement(storey_placement, -885+930, 45, 90)); + frame_placements.push_back(file.addLocalPlacement(storey_placement, 885+930, 45, 90)); // Now iterate over the placements and representations of the beam and add them to list of parts - IfcSchema::IfcLocalPlacement::list::it frame_placement; - IfcSchema::IfcShapeRepresentation::list::it frame_representation; - for (frame_placement = frame_placements->begin(), frame_representation = frame_representations->begin(); - frame_placement != frame_placements->end() && frame_representation != frame_representations->end(); + std::vector::const_iterator frame_placement; + std::vector::const_iterator frame_representation; + for (frame_placement = frame_placements.begin(), frame_representation = frame_representations.begin(); + frame_placement != frame_placements.end() && frame_representation != frame_representations.end(); ++frame_placement, ++frame_representation) { - IfcSchema::IfcMember* frame_part = new IfcSchema::IfcMember(guid(), file.getSingle(), - null, null, null, *frame_placement, file.addMappedItem(*frame_representation), null + auto frame_part = file.create(); + frame_part.setGlobalId(guid()); + frame_part.setOwnerHistory(file.getSingle()); + frame_part.setObjectPlacement(*frame_placement); + frame_part.setRepresentation(file.addMappedItem(*frame_representation)); #ifdef USE_IFC4 - , IfcSchema::IfcMemberTypeEnum::IfcMemberType_MULLION + frame_part.setPredefinedType(IfcSchema::IfcMemberTypeEnum::IfcMemberType_MULLION); #endif - ); - file.addEntity(frame_part); - window_parts->push(frame_part); + window_parts.push_back(frame_part); file.relatePlacements(window, frame_part); } // Add the glass plate to the list of parts - IfcSchema::IfcPlate* glass_part = new IfcSchema::IfcPlate(guid(), file.getSingle(), null, - null, null, file.addLocalPlacement(storey_placement, 930, 45, 90), file.addBox(1680, 10, 1420), null + auto glass_part = file.create(); + glass_part.setGlobalId(guid()); + glass_part.setOwnerHistory(file.getSingle()); + glass_part.setObjectPlacement(file.addLocalPlacement(storey_placement, 930, 45, 90)); + glass_part.setRepresentation(file.addBox(1860, 10, 1420)); #ifdef USE_IFC4 - , IfcSchema::IfcPlateTypeEnum::IfcPlateType_SHEET + glass_part.setPredefinedType(IfcSchema::IfcPlateTypeEnum::IfcPlateType_SHEET); #endif - ); - file.addEntity(glass_part); - window_parts->push(glass_part); + + window_parts.push_back(glass_part); file.relatePlacements(window, glass_part); - setSurfaceColour(file,glass_part->Representation(), 0.6, 0.7, 0.75, 0.1); + setSurfaceColour(file, glass_part.Representation(), 0.6, 0.7, 0.75, 0.1); // Now create a decomposition relation between the window and the parts. Most viewers and authoring // tools will consider the window a single entity that can be selected as a whole. - IfcSchema::IfcRelDecomposes* decomposition = new IfcSchema::IfcRelAggregates(guid(), file.getSingle(), - null, null, window, window_parts); - file.addEntity(decomposition); + { + + auto rel = file.create(); + rel.setGlobalId(guid()); + rel.setOwnerHistory(file.getSingle()); + rel.setRelatingObject(window); + rel.setRelatedObjects(window_parts); + } } // Finally create a file stream for our output and write the IFC file to it. diff --git a/src/examples/IfcParseExamples.cpp b/src/examples/IfcParseExamples.cpp index dcd3654d83..c98268598e 100644 --- a/src/examples/IfcParseExamples.cpp +++ b/src/examples/IfcParseExamples.cpp @@ -114,44 +114,42 @@ std::string format_string(const AttributeValue& argument) { } template -void process_pset(element_properties& props, const T* inst) { +void process_pset(element_properties& props, const T& inst) { // Process an individual Property or Quantity set. - if (auto pset = inst->template as()) { + if (auto pset = inst.template as()) { if (!pset->Name()) { return; } auto ps = pset->HasProperties(); - for (auto it = ps->begin(); it != ps->end(); ++it) { - auto& p = *it; - if (auto singleval = p->template as()) { + for (auto& p : ps) { + if (auto singleval = p.template as()) { std::string propname, propvalue; if constexpr (is_ifc4_or_higher::value) { - if (!singleval->Name()) { + if (!singleval.Name()) { continue; } - propname = *singleval->Name(); + propname = *singleval.Name(); } if constexpr (!is_ifc4_or_higher::value) { - propname = singleval->Name(); + propname = singleval.Name(); } - if (!singleval->NominalValue()) { + if (!singleval.NominalValue()) { propvalue = "-"; } else { - props[*pset->Name()][propname] = format_string(singleval->NominalValue()->template as()->get_attribute_value(0)); + props[*pset.Name()][propname] = format_string(singleval.NominalValue().concrete().get_attribute_value(0)); } } } } - if (auto qset = inst->template as()) { - if (!qset->Name()) { + if (auto qset = inst.template as()) { + if (!qset.Name()) { return; } - auto qs = qset->Quantities(); - for (auto it = qs->begin(); it != qs->end(); ++it) { - auto& q = *it; - if (q->template as() && q->get_attribute_value(3).type() == IfcUtil::Argument_DOUBLE) { - double v = q->get_attribute_value(3); - props[*qset->Name()][q->Name()] = std::to_string(v); + auto qs = qset.Quantities(); + for (auto& q : qs) { + if (q.template as() && q.get_attribute_value(3).type() == IfcUtil::Argument_DOUBLE) { + double v = q.get_attribute_value(3); + props[*qset.Name()][q.Name()] = std::to_string(v); } } } @@ -163,48 +161,43 @@ void process_pset(element_properties& props, const T* inst) { } template -void get_psets_s(element_properties& props, const typename Schema::IfcObjectDefinition* inst) { +void get_psets_s(element_properties& props, const typename Schema::IfcObjectDefinition& inst) { // Extracts the property definitions for an IFC instance. - if (auto tyob = inst->template as()) { - if (tyob->HasPropertySets()) { - auto defs = *tyob->HasPropertySets(); - for (auto it = defs->begin(); it != defs->end(); ++it) { - auto& def = *it; + if (auto tyob = inst.template as()) { + if (tyob.HasPropertySets()) { + auto defs = *tyob.HasPropertySets(); + for (auto& def : defs) { process_pset(props, def); } } } if constexpr (is_ifc4_or_higher::value) { - if (auto mdef = inst->template as()) { - auto defs = mdef->HasProperties(); - for (auto it = defs->begin(); it != defs->end(); ++it) { - auto& def = *it; + if (auto mdef = inst.template as()) { + auto defs = mdef.HasProperties(); + for (auto& def : defs) { process_pset(props, def); } } - if (auto pdef = inst->template as()) { + if (auto pdef = inst.template as()) { auto defs = pdef->HasProperties(); - for (auto it = defs->begin(); it != defs->end(); ++it) { - auto& def = *it; + for (auto& def : defs) { process_pset(props, def); } } } - if (auto ob = inst->template as()) { + if (auto ob = inst.template as()) { if constexpr (is_ifc4_or_higher::value) { - auto rels = ob->IsTypedBy(); - for (auto it = rels->begin(); it != rels->end(); ++it) { - auto& rel = *it; + auto rels = ob.IsTypedBy(); + for (auto& rel : rels) { get_psets_s(props, rel->RelatingType()); } } { - auto rels = ob->IsDefinedBy(); - for (auto it = rels->begin(); it != rels->end(); ++it) { - auto& rel = *it; - if (auto bytype = rel->template as()) { + auto rels = ob.IsDefinedBy(); + for (auto& rel : rels) { + if (auto bytype = rel.template as()) { get_psets_s(props, bytype->RelatingType()); - } else if (auto byprops = rel->template as()) { + } else if (auto byprops = rel.template as()) { process_pset(props, byprops->RelatingPropertyDefinition()); } } @@ -220,10 +213,10 @@ void get_psets_s(element_properties& props, const typename Schema::IfcObjectDefi #define GENERATE_LITERAL_STRING(elem) "Ifc" # elem #define TEST_AND_DISPATCH(r, data, elem) \ - if (strcasecmp(schema_name, GENERATE_LITERAL_STRING(elem)) == 0) { get_psets_s(props, inst->as()); } + if (strcasecmp(schema_name, GENERATE_LITERAL_STRING(elem)) == 0) { get_psets_s(props, inst.as()); } -void get_psets(element_properties& props, const IfcUtil::IfcBaseClass* inst) { - auto schema_name = inst->declaration().schema()->name().c_str(); +void get_psets(element_properties& props, const express::Base& inst) { + auto schema_name = inst.declaration().schema()->name().c_str(); BOOST_PP_SEQ_FOR_EACH(TEST_AND_DISPATCH, , SCHEMA_SEQ) } @@ -259,19 +252,17 @@ int main(int argc, char** argv) { // we need to cast them to IfcWindows. Since these properties // are optional we need to make sure the properties are // defined for the window in question before accessing them. - IfcSchema::IfcBuildingElement::list::ptr elements = file.instances_by_type(); + auto elements = file.instances_by_type(); - std::cout << "Found " << elements->size() << " elements in " << argv[1] << ":" << std::endl; + std::cout << "Found " << elements.size() << " elements in " << argv[1] << ":" << std::endl; - for (auto it = elements->begin(); it != elements->end(); ++it) { - const auto* element = *it; - element->toString(std::cout); + for (auto& element : elements) { + element.toString(std::cout); std::cout << std::endl; - const IfcSchema::IfcWindow* window; - if ((window = element->as()) != 0) { - if (window->OverallWidth() && window->OverallHeight()) { - const double area = *window->OverallWidth() * *window->OverallHeight(); + if (auto window = element.as()) { + if (window.OverallWidth() && window.OverallHeight()) { + const double area = *window.OverallWidth() * *window.OverallHeight(); std::cout << "The area of this window is " << area << std::endl; } } diff --git a/src/ifcparse/IfcFile.cpp b/src/ifcparse/IfcFile.cpp index 243ded9473..916bb2fced 100644 --- a/src/ifcparse/IfcFile.cpp +++ b/src/ifcparse/IfcFile.cpp @@ -780,8 +780,8 @@ express::Base IfcParse::impl::in_memory_file_storage::create(const IfcParse::dec } auto ptr = byid_.insert({instance_name, std::make_shared(file, decl, instance_name, decl->as_entity() ? in_memory_attribute_storage(decl->as_entity()->attribute_count()) : in_memory_attribute_storage(1))}).first; express::Base inst(ptr->second); - // @todo addEntity should only be used for copying behaviour now, not during creation - file->addEntity(inst); + + add_type_ref(inst); return inst; } diff --git a/src/ifcparse/IfcFile.h b/src/ifcparse/IfcFile.h index cb3a606c2d..450fcbd34a 100644 --- a/src/ifcparse/IfcFile.h +++ b/src/ifcparse/IfcFile.h @@ -36,6 +36,7 @@ #include #ifdef IFOPSH_WITH_ROCKSDB + #include namespace { diff --git a/src/ifcparse/IfcHierarchyHelper.cpp b/src/ifcparse/IfcHierarchyHelper.cpp index eb43e2647d..84742cf863 100644 --- a/src/ifcparse/IfcHierarchyHelper.cpp +++ b/src/ifcparse/IfcHierarchyHelper.cpp @@ -310,9 +310,17 @@ void IfcHierarchyHelper::addExtrudedPolyline(typename Schema::IfcShapeRe solid.setSweptArea(profile); solid.setPosition(place2 ? place2 : addPlacement3d()); solid.setExtrudedDirection(dir ? dir : addTriplet(0, 0, 1)); + solid.setDepth(h); - // @nb this overwrites, not appends - rep.setItems(std::vector{solid}); + std::vector items; + try { + auto existing_items = rep.Items(); + items.insert(items.end(), existing_items.begin(), existing_items.end()); + } catch (...) { + // ignore + } + items.push_back(solid); + rep.setItems(items); } template @@ -535,7 +543,7 @@ void setSurfaceColour_4x3(IfcHierarchyHelper& file, typename Schema::Ifc } #ifdef HAS_SCHEMA_2x3 -Ifc2x3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc2x3::IfcRepresentationItem item, Ifc2x3::IfcPresentationStyleAssignment style_assignment) { +Ifc2x3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc2x3::IfcRepresentationItem& item, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style_assignment}); @@ -553,7 +561,7 @@ Ifc4::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4::IfcReprese #endif #ifdef HAS_SCHEMA_4x1 -Ifc4x1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x1::IfcRepresentationItem item, Ifc4x1::IfcPresentationStyleAssignment style_assignment) { +Ifc4x1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x1::IfcRepresentationItem& item, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style_assignment}); @@ -562,7 +570,7 @@ Ifc4x1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x1::IfcRep #endif #ifdef HAS_SCHEMA_4x2 -Ifc4x2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x2::IfcRepresentationItem item, Ifc4x2::IfcPresentationStyleAssignment style_assignment) { +Ifc4x2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x2::IfcRepresentationItem& item, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style_assignment}); @@ -571,7 +579,7 @@ Ifc4x2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x2::IfcRep #endif #ifdef HAS_SCHEMA_4x3_rc1 -Ifc4x3_rc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc1::IfcRepresentationItem item, Ifc4x3_rc1::IfcPresentationStyleAssignment style_assignment) { +Ifc4x3_rc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_rc1::IfcRepresentationItem& item, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style_assignment}); @@ -580,7 +588,7 @@ Ifc4x3_rc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc1 #endif #ifdef HAS_SCHEMA_4x3_rc2 -Ifc4x3_rc2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc2::IfcRepresentationItem item, Ifc4x3_rc2::IfcPresentationStyleAssignment style_assignment) { +Ifc4x3_rc2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_rc2::IfcRepresentationItem& item, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style_assignment}); @@ -589,7 +597,7 @@ Ifc4x3_rc2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc2 #endif #ifdef HAS_SCHEMA_4x3_rc3 -Ifc4x3_rc3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc3::IfcRepresentationItem item, Ifc4x3_rc3::IfcPresentationStyle style) { +Ifc4x3_rc3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_rc3::IfcRepresentationItem& item, const Ifc4x3_rc3::IfcPresentationStyle& style) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -598,7 +606,7 @@ Ifc4x3_rc3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc3 #endif #ifdef HAS_SCHEMA_4x3_rc4 -Ifc4x3_rc4::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc4::IfcRepresentationItem item, Ifc4x3_rc4::IfcPresentationStyle style) { +Ifc4x3_rc4::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_rc4::IfcRepresentationItem& item, const Ifc4x3_rc4::IfcPresentationStyle& style) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -607,7 +615,7 @@ Ifc4x3_rc4::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_rc4 #endif #ifdef HAS_SCHEMA_4x3 -Ifc4x3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3::IfcRepresentationItem item, Ifc4x3::IfcPresentationStyle style) { +Ifc4x3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3::IfcRepresentationItem& item, const Ifc4x3::IfcPresentationStyle& style) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -616,7 +624,7 @@ Ifc4x3::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3::IfcRep #endif #ifdef HAS_SCHEMA_4x3_tc1 -Ifc4x3_tc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_tc1::IfcRepresentationItem item, Ifc4x3_tc1::IfcPresentationStyle style) { +Ifc4x3_tc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_tc1::IfcRepresentationItem& item, const Ifc4x3_tc1::IfcPresentationStyle& style) { auto sitem = file.crefile->createate(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -625,7 +633,7 @@ Ifc4x3_tc1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_tc1 #endif #ifdef HAS_SCHEMA_4x3_add1 -Ifc4x3_add1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_add1::IfcRepresentationItem item, Ifc4x3_add1::IfcPresentationStyle style) { +Ifc4x3_add1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_add1::IfcRepresentationItem& item, const Ifc4x3_add1::IfcPresentationStyle& style) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -634,7 +642,7 @@ Ifc4x3_add1::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_ad #endif #ifdef HAS_SCHEMA_4x3_add2 -Ifc4x3_add2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, Ifc4x3_add2::IfcRepresentationItem item, Ifc4x3_add2::IfcPresentationStyle style) { +Ifc4x3_add2::IfcStyledItem create_styled_item(IfcParse::IfcFile* file, const Ifc4x3_add2::IfcRepresentationItem& item, const Ifc4x3_add2::IfcPresentationStyle& style) { auto sitem = file->create(); sitem.setItem(item); sitem.setStyles(std::vector{style}); @@ -664,19 +672,19 @@ Ifc2x3::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, Ifc2x3::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc2x3::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc2x3::IfcProductRepresentation shape, Ifc2x3::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcProductRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc2x3::IfcRepresentation shape, Ifc2x3::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } #endif @@ -708,19 +716,19 @@ Ifc4x1::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, Ifc4x1::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x1::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x1::IfcProductRepresentation shape, Ifc4x1::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcProductRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x1::IfcRepresentation shape, Ifc4x1::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } #endif @@ -730,19 +738,19 @@ Ifc4x2::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, Ifc4x2::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x2::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x2::IfcProductRepresentation shape, Ifc4x2::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcProductRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x2::IfcRepresentation shape, Ifc4x2::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } #endif @@ -752,19 +760,19 @@ Ifc4x3_rc1::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper return addStyleAssignment_2x3(file, r, g, b, a); } -Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc1::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc1::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc1::IfcProductRepresentation shape, Ifc4x3_rc1::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc1::IfcRepresentation shape, Ifc4x3_rc1::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } #endif @@ -774,19 +782,19 @@ Ifc4x3_rc2::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper return addStyleAssignment_2x3(file, r, g, b, a); } -Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc2::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc2::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_2x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc2::IfcProductRepresentation shape, Ifc4x3_rc2::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc2::IfcRepresentation shape, Ifc4x3_rc2::IfcPresentationStyleAssignment style_assignment) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment) { setSurfaceColour_2x3(file, shape, style_assignment); } #endif @@ -796,19 +804,19 @@ Ifc4x3_rc3::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file, Ifc4x3_rc3::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc3::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc3::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc3::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc3::IfcProductRepresentation shape, Ifc4x3_rc3::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc3::IfcProductRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc3::IfcRepresentation shape, Ifc4x3_rc3::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc3::IfcRepresentation& shape, const Ifc4x3_rc3::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif @@ -818,19 +826,19 @@ Ifc4x3_rc4::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file, Ifc4x3_rc4::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc4::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc4::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_rc4::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc4::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc4::IfcProductRepresentation shape, Ifc4x3_rc4::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc4::IfcProductRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_rc4::IfcRepresentation shape, Ifc4x3_rc4::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc4::IfcRepresentation& shape, const Ifc4x3_rc4::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif @@ -840,19 +848,19 @@ Ifc4x3::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file return addStyleAssignment_4x3(file, r, g, b, a); } -Ifc4x3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3::IfcProductRepresentation shape, Ifc4x3::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3::IfcProductRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3::IfcRepresentation shape, Ifc4x3::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3::IfcRepresentation& shape, const Ifc4x3::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif @@ -862,19 +870,19 @@ Ifc4x3_tc1::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file, Ifc4x3_tc1::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_tc1::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_tc1::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_tc1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_tc1::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_tc1::IfcProductRepresentation shape, Ifc4x3_tc1::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_tc1::IfcProductRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_tc1::IfcRepresentation shape, Ifc4x3_tc1::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_tc1::IfcRepresentation& shape, const Ifc4x3_tc1::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif @@ -884,19 +892,19 @@ Ifc4x3_add1::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file, Ifc4x3_add1::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add1::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add1::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_add1::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add1::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add1::IfcProductRepresentation shape, Ifc4x3_add1::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add1::IfcProductRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add1::IfcRepresentation shape, Ifc4x3_add1::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add1::IfcRepresentation& shape, const Ifc4x3_add1::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif @@ -906,19 +914,19 @@ Ifc4x3_add2::IfcPresentationStyle addStyleAssignment(IfcHierarchyHelper& file, Ifc4x3_add2::IfcProductRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add2::IfcProductRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add2::IfcRepresentation shape, double r, double g, double b, double a) { +Ifc4x3_add2::IfcPresentationStyle setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add2::IfcRepresentation& shape, double r, double g, double b, double a) { return setSurfaceColour_4x3(file, shape, r, g, b, a); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add2::IfcProductRepresentation shape, Ifc4x3_add2::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add2::IfcProductRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } -void setSurfaceColour(IfcHierarchyHelper& file, Ifc4x3_add2::IfcRepresentation shape, Ifc4x3_add2::IfcPresentationStyle style) { +void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_add2::IfcRepresentation& shape, const Ifc4x3_add2::IfcPresentationStyle& style) { setSurfaceColour_4x3(file, shape, style); } #endif diff --git a/src/ifcparse/IfcHierarchyHelper.h b/src/ifcparse/IfcHierarchyHelper.h index 2ae59cb300..0c4981ebbc 100644 --- a/src/ifcparse/IfcHierarchyHelper.h +++ b/src/ifcparse/IfcHierarchyHelper.h @@ -411,8 +411,8 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile { auto li = instances_by_type(); bool found = false; for (auto & rel : li) { - if (rel->RelatingType() == relating_object) { - auto objects = rel->RelatedObjects(); + if (rel.RelatingType() == relating_object) { + auto objects = rel.RelatedObjects(); objects.push_back(addEntity(related_object).template as()); rel.setRelatedObjects(objects); found = true; @@ -427,7 +427,7 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile { owner_hist = addOwnerHistory(); } std::vector related_objects = {related_object.template as()}; - auto t = create(); + auto t = create(); t.setGlobalId(IfcParse::IfcGlobalId()); t.setOwnerHistory(owner_hist); t.setRelatedObjects(related_objects); @@ -531,48 +531,48 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile { IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc2x3::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcProductRepresentation& shape, Ifc2x3::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcRepresentation& shape, Ifc2x3::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcProductRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc2x3::IfcRepresentation& shape, const Ifc2x3::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4 IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcProductRepresentation& shape, Ifc4::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcRepresentation& shape, Ifc4::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcProductRepresentation& shape, const Ifc4::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4::IfcRepresentation& shape, const Ifc4::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4x1 IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcProductRepresentation& shape, Ifc4x1::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcRepresentation& shape, Ifc4x1::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcProductRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x1::IfcRepresentation& shape, const Ifc4x1::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4x2 IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcProductRepresentation& shape, Ifc4x2::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcRepresentation& shape, Ifc4x2::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcProductRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x2::IfcRepresentation& shape, const Ifc4x2::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4x3_rc1 IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x3_rc1::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, Ifc4x3_rc1::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcRepresentation& shape, Ifc4x3_rc1::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcProductRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc1::IfcRepresentation& shape, const Ifc4x3_rc1::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4x3_rc2 IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment addStyleAssignment(IfcHierarchyHelper& file, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, double r, double g, double b, double a = 1.0); IFC_PARSE_API Ifc4x3_rc2::IfcPresentationStyleAssignment setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcRepresentation& shape, double r, double g, double b, double a = 1.0); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, Ifc4x3_rc2::IfcPresentationStyleAssignment* style_assignment); -IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcRepresentation& shape, Ifc4x3_rc2::IfcPresentationStyleAssignment* style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcProductRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment); +IFC_PARSE_API void setSurfaceColour(IfcHierarchyHelper& file, const Ifc4x3_rc2::IfcRepresentation& shape, const Ifc4x3_rc2::IfcPresentationStyleAssignment& style_assignment); #endif #ifdef HAS_SCHEMA_4x3_rc3 diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index 2e617fbc1c..a4ea94b139 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -1975,6 +1975,7 @@ express::Base IfcFile::addEntity(const express::Base& entity) { entity_file_map_.insert(entity_entity_map_t::value_type(entity.identity(), new_entity)); // For subtypes of IfcRoot, the GUID mapping needs to be updated. + /* if (decl->is(*ifcroot_type_)) { try { const std::string guid = new_entity.get_attribute_value(0); @@ -1988,8 +1989,9 @@ express::Base IfcFile::addEntity(const express::Base& entity) { Logger::Message(Logger::LOG_ERROR, ex.what()); } } + */ - add_type_ref(new_entity); + // add_type_ref(new_entity); return new_entity; } diff --git a/src/ifcparse/express.h b/src/ifcparse/express.h index f327241f00..d4714981f8 100644 --- a/src/ifcparse/express.h +++ b/src/ifcparse/express.h @@ -51,21 +51,24 @@ class IFC_PARSE_API Base { protected: std::weak_ptr data_; public: - operator bool() const { return !data_.expired(); - } + } - bool operator<(const Base& other) const { - return data() < other.data(); - } + bool operator<(const Base& other) const { + return data() < other.data(); + } - bool operator==(const Base& other) const { - return data() == other.data(); - } + bool operator==(const Base& other) const { + return data() == other.data(); + } - Base() {}; - Base(const std::weak_ptr& data) : data_(data) {} + bool operator!=(const Base& other) const { + return !(*this == other); + } + + Base() {}; + Base(const std::weak_ptr& data) : data_(data) {} const InstanceData* data() const; InstanceData* data(); diff --git a/src/ifcparse/storage.h b/src/ifcparse/storage.h index 5bfd8e4c76..382106adcf 100644 --- a/src/ifcparse/storage.h +++ b/src/ifcparse/storage.h @@ -1,6 +1,10 @@ #ifndef STORAGE_H #define STORAGE_H +// Avoid conflicts with OpenCascade HANDLE type and RocksDB Handle +#pragma push_macro("Handle") +#undef Handle + #ifndef IFOPSH_WITH_ROCKSDB namespace rocksdb { @@ -483,4 +487,7 @@ namespace IfcParse { } } +// redefine Handle macro. +#pragma pop_macro("Handle") + #endif // STORAGE_H diff --git a/src/serializers/RocksDbSerializer.cpp b/src/serializers/RocksDbSerializer.cpp index 69d57a3a78..5dad5aa831 100644 --- a/src/serializers/RocksDbSerializer.cpp +++ b/src/serializers/RocksDbSerializer.cpp @@ -35,15 +35,15 @@ namespace { { auto s = sizeof(size_t); val.resize(s + 2); - val[0] = TypeEncoder::encode_type(); + val[0] = TypeEncoder::encode_type(); // 1 = entity - stored by id (entity name) // 2 = type - stored by identity (internal counter in class) val[1] = t.index() == 0 ? 'i' : 't'; size_t iden; if (auto* name = std::get_if(&t)) { iden = *name; - } else if (auto* inst = std::get_if(&t)) { - iden = (*inst)->identity(); + } else if (auto* inst = std::get_if(&t)) { + iden = (*inst).identity(); } memcpy(val.data() + 2, &iden, s); return true; @@ -53,7 +53,7 @@ namespace { { // no attempt at alignment val.resize(t.size() * (sizeof(size_t) + 1) + 1); - val[0] = TypeEncoder::encode_type(); + val[0] = TypeEncoder::encode_type>(); char* ptr = val.data() + 1; for (auto it = t.begin(); it != t.end(); ++it) { *ptr = it->index() == 0 ? 'i' : 't'; @@ -61,8 +61,8 @@ namespace { size_t iden = 0; if (auto* name = std::get_if(&*it)) { iden = *name; - } else if (auto* inst = std::get_if(&*it)) { - iden = (*inst)->identity(); + } else if (auto* inst = std::get_if(&*it)) { + iden = (*inst).identity(); } memcpy(ptr, &iden, sizeof(size_t)); ptr += sizeof(size_t); @@ -73,7 +73,7 @@ namespace { bool serialize(std::string& val, const std::vector>& t) { std::ostringstream oss; - oss.put(TypeEncoder::encode_type()); + oss.put(TypeEncoder::encode_type>>()); auto write_size = [&oss](size_t sz) { std::string size_str; @@ -95,8 +95,8 @@ namespace { size_t iden = 0; if (auto* name = std::get_if(&*jt)) { iden = *name; - } else if (auto* inst = std::get_if(&*jt)) { - iden = (*inst)->identity(); + } else if (auto* inst = std::get_if(&*jt)) { + iden = (*inst).identity(); } std::string iden_str; iden_str.resize(sizeof(size_t)); @@ -144,13 +144,13 @@ void RocksDbSerializer::write_streaming_() { const bool is_header = decl->schema() == &Header_section_schema::get_schema(); - std::vector simple_type_instances; + std::vector simple_type_instances; - for (size_t i = 0; i < data.storage_->size(); i++) { - auto val = data.get_attribute_value(nullptr, decl, 0, i); + for (size_t i = 0; i < data->storage_->size(); i++) { + auto val = data->get_attribute_value(i); val.apply_visitor([&](const auto& t) { using T = std::decay_t; - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { // instance is per definition a simple type here, because instance // references are not resolved yet, but provided in vector of // references @@ -170,7 +170,7 @@ void RocksDbSerializer::write_streaming_() { (is_header ? decl->name() : std::to_string(p.first.name_)) + "|" + std::to_string(index); - if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == TypeEncoder::encode_type() && tmp[1] == 't') + if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == TypeEncoder::encode_type() && tmp[1] == 't') { size_t iden; memcpy(&iden, tmp.data() + 2, sizeof(size_t)); @@ -184,20 +184,20 @@ void RocksDbSerializer::write_streaming_() { using T = std::decay_t; if constexpr (std::is_same_v) { - if (auto* inst = std::get_if(&v)) { + if (auto* inst = std::get_if(&v)) { // So this never happens? simple_type_instances.push_back(*inst); } } else if constexpr (std::is_same_v>) { for (auto const& inner : v) { - if (auto* inst = std::get_if(&inner)) { + if (auto* inst = std::get_if(&inner)) { simple_type_instances.push_back(*inst); } } } else if constexpr (std::is_same_v>>) { for (auto const& inner : v) { for (auto const& innermost : inner) { - if (auto* inst = std::get_if(&innermost)) { + if (auto* inst = std::get_if(&innermost)) { simple_type_instances.push_back(*inst); } } @@ -236,27 +236,28 @@ void RocksDbSerializer::write_streaming_() { }, p.second); } - for (const auto* inst : simple_type_instances) { + for (const auto& inst : simple_type_instances) { std::string s(sizeof(size_t), ' '); - size_t v = inst->declaration().index_in_schema(); + size_t v = inst.declaration().index_in_schema(); memcpy(s.data(), &v, sizeof(size_t)); storage.db->Put( storage.wopts, - (inst->declaration().as_entity() ? "i|" : "t|") + std::to_string(inst->identity()) + "|_", s); + (inst.declaration().as_entity() ? "i|" : "t|") + std::to_string(inst.identity()) + "|_", s); - if (type_identities_wrote_as_refs.find(inst->identity()) != type_identities_wrote_as_refs.end()) { + if (type_identities_wrote_as_refs.find(inst.identity()) != type_identities_wrote_as_refs.end()) { // already written as reference, skip // only applies to the value though, the type declaration still needs to be written continue; } - auto val = inst->get_attribute_value(0); - if (val.array_.storage_ptr->size() > 0) { + auto val = inst.get_attribute_value(0); + // @todo if statement? + // if (val.array_.storage_ptr->size() > 0) { val.apply_visitor([&](const auto& t) { - rocks_db_attribute_storage{}.set(&storage, &inst->declaration(), inst->identity(), 0, t); + rocks_db_attribute_storage{}.set(&storage, &inst.declaration(), inst.identity(), 0, t); }); - } + // } // @nb we also need to delete them // not anymore, as they are now registered as unique_ptr in the in_memory_file_storage @@ -286,89 +287,9 @@ void RocksDbSerializer::write_streaming_() { } } - -void RocksDbSerializer::write_non_streaming_() { - // Build a map of instances and their references/dependencies - std::map> dependencies, dependencies_inv; - std::visit([&dependencies](const auto& m) { - if constexpr (std::is_same_v, IfcParse::impl::in_memory_file_storage>) { - for (const auto& ps : m.byref_excl_) { - for (const auto& p : ps.second) { - dependencies[p].insert(std::get<0>(ps.first)); - } - } - } - }, std::get(file_)->storage_); - // Add bottom-rank nodes, inv mapping does not contain them - for (const auto& p : *std::get(file_)) { - dependencies[p.first]; - } - - for (auto& ps : dependencies) { - for (auto& p : ps.second) { - dependencies_inv[p].insert(ps.first); - } - } - - // Do a topological sort over the nodes - std::vector deps_topo_order; - while (dependencies.size() > 0) { - std::vector no_deps; - for (auto& ps : dependencies) { - if (ps.second.size() == 0) { - no_deps.push_back(ps.first); - } - } - - if (no_deps.size() == 0) { - throw std::runtime_error("cyclic dependencies in model, unable to serialize"); - } - - for (auto& i : no_deps) { - deps_topo_order.push_back(i); - } - - // mutate mapping - for (auto& i : no_deps) { - dependencies.erase(i); - } - for (auto& i : no_deps) { - for (auto& j : dependencies_inv[i]) { - auto it = dependencies.find(j); - if (it != dependencies.end()) { - it->second.erase(i); - } - } - } - } - - // Add them in topological order, so that add() never recurses into something not previously visited - for (auto& i : deps_topo_order) { - output_file_->addEntity(std::get(file_)->instance_by_id(i), i); - } - - // Copy inverses - /* - // These are now back to being added in addEntity() / set_attribute_value() - std::visit([this](const auto& m) { - if constexpr (std::is_same_v, IfcParse::impl::in_memory_file_storage>) { - for (auto& p : m.byref_excl_) { - // This is much slower than need be, because: - // - insert() first checks for existance [we know it does not] because insert() should not overwrite - // - insert() returns an pair [which is not used] which requires an expensive seek after the put. - // This is left as-is for now, because anyway we want to build a streaming converter - std::get(output_file_->storage_).byref_excl_.insert(p); - } - } - }, file_->storage_); - */ - - delete output_file_; -} - void RocksDbSerializer::finalize() { if (file_.index() == 0) { - write_non_streaming_(); + throw std::runtime_error("Non-streaming mode no longer supported"); } else { write_streaming_(); } diff --git a/src/serializers/RocksDbSerializer.h b/src/serializers/RocksDbSerializer.h index 2ed7a0771d..369f893bd5 100644 --- a/src/serializers/RocksDbSerializer.h +++ b/src/serializers/RocksDbSerializer.h @@ -16,7 +16,6 @@ private: IfcParse::IfcFile* output_file_; void write_streaming_(); - void write_non_streaming_(); public: RocksDbSerializer(IfcParse::IfcFile* file, const std::string& rocksdb_filename); RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, bool stream); diff --git a/src/serializers/schema_dependent/XmlSerializer.cpp b/src/serializers/schema_dependent/XmlSerializer.cpp index ed6ec61a3b..1c9e9f611a 100644 --- a/src/serializers/schema_dependent/XmlSerializer.cpp +++ b/src/serializers/schema_dependent/XmlSerializer.cpp @@ -787,7 +787,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { ptree node; node.put(".id", qualify_unrooted_instance(mat)); // @todo this does not handle IfcMaterialProfileSetUsage and IfcMaterialConstituentSet - if (mat.concrete().as() || mat.concrete().as()) { + if (mat.concrete().as() || mat.concrete().as()) { IfcSchema::IfcMaterialLayerSet layerset = mat.concrete().as(); if (!layerset) { layerset = mat.concrete().as().ForLayerSet();