- Take better care of inverse cardinalities and respect more CoordinationView agreements in IfcOpenHouse

- Track inverse relationships in an IfcWrite context as well
- Fix for lists of SELECT types
This commit is contained in:
Thomas Krijnen
2014-05-05 16:17:28 +00:00
parent 1b54ba039d
commit 948d7675f0
7 changed files with 375 additions and 111 deletions
+114 -65
View File
@@ -83,17 +83,23 @@ int main(int argc, char** argv) {
// An IfcOwnerHistory has been initialized as well, which should be assigned to the wall.
south_wall->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
// The wall will be shaped as a box, with the dimensions specified in millimeters.
IfcSchema::IfcProductDefinitionShape* south_wall_shape = file.addBox(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.
IfcSchema::IfcProductDefinitionShape* 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<IfcSchema::IfcBuildingStorey>()->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());
south_wall->setObjectPlacement(file.addLocalPlacement(storey_placement));
// A pale white colour is assigned to the wall.
IfcSchema::IfcPresentationStyleAssignment* wall_colour = file.setSurfaceColour(
south_wall->Representation(), 0.75, 0.73, 0.68);
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<IfcSchema::IfcOwnerHistory>(),
@@ -104,18 +110,19 @@ int main(int argc, char** argv) {
// 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, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()));
footing->setObjectPlacement(file.addLocalPlacement(0, 2500, -2000));
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 = file.setSurfaceColour(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.
// An opening element is created with rectangular geometry
// An opening element is created with rectangular geometry:
IfcSchema::IfcOpeningElement* west_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, file.addLocalPlacement(-2500, 0, 400),
file.addBox(6000, 3630, 1600, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()), null
null, null, null, file.addLocalPlacement(south_wall->ObjectPlacement(), -2500, 0, 400),
file.addBox(6000, 3630, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
@@ -129,8 +136,8 @@ int main(int argc, char** argv) {
// Now create an additional opening
IfcSchema::IfcOpeningElement* south_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, file.addLocalPlacement(3000, 0, 400),
file.addBox(1860, 3000, 1600, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()), null
null, null, null, file.addLocalPlacement(storey_placement, 3000, 0, 400),
file.addBox(1860, 3000, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
@@ -138,69 +145,104 @@ int main(int argc, char** argv) {
file.AddEntity(south_opening);
file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null, null, south_wall, south_opening));
// Create a roof element
IfcSchema::IfcRoof* south_roof = new IfcSchema::IfcRoof(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("South roof"), null, null,
0, 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
// The roof geometry is slanted 45 degrees by specifying a direction for the box extrusion
south_roof->setRepresentation(file.addBox(10200, 360, sqrt(2.0*2900*2900), 0, file.addPlacement3d(0, 0, 0, 0, 1, 0),
file.addTriplet<IfcSchema::IfcDirection>(0, -sqrt(0.5), sqrt(0.5)), file.getSingle<IfcSchema::IfcRepresentationContext>()));
south_roof->setObjectPlacement(file.addLocalPlacement(0, -400, 2700));
file.addBuildingProduct(south_roof);
// Create a roof element that will consist of two slabs:
IfcSchema::IfcRoof* roof = new IfcSchema::IfcRoof(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("Roof"), 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<IfcSchema::IfcDirection>(0, -sqrt(0.5), sqrt(0.5)));
// 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<IfcSchema::IfcOwnerHistory>(), S("South roof"),
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::IfcRoof* north_roof = new IfcSchema::IfcRoof(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("North roof"),
null, null, 0, 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
north_roof->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
north_roof->setRepresentation(south_roof->Representation());
north_roof->setObjectPlacement(file.addLocalPlacement(0, 5400, 2700, 0, 0, 1, -1, 0, 0));
file.addBuildingProduct(north_roof);
IfcSchema::IfcSlab* north_roof_part = new IfcSchema::IfcSlab(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("North roof"),
null, null, 0, 0, null, IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF);
north_roof_part->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
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<IfcSchema::IfcOwnerHistory>(),
null, null, roof, roof_parts);
file.AddEntity(roof_decomposition);
// By specifying a surface style for the south part of the roof, it gets assigned to the other
// roof part as well, because they share the same representation.
file.setSurfaceColour(south_roof->Representation(), 0.24, 0.08, 0.04);
file.addBuildingProduct(south_roof_part);
file.addBuildingProduct(north_roof_part);
file.addBuildingProduct(roof);
file.setSurfaceColour(roof_rep, 0.24, 0.08, 0.04);
// Copy the south wall to the north
file.addBuildingProduct(new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("North wall"),
null, null, file.addLocalPlacement(0, 5000, 0), south_wall->Representation(), null
IfcSchema::IfcWallStandardCase* north_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("North wall"),
null, null, file.addLocalPlacement(storey_placement, 0, 5000, 0), file.addAxisBox(10000, 360, 3000), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
));
);
file.addBuildingProduct(north_wall);
file.setSurfaceColour(north_wall->Representation(), wall_colour);
IfcSchema::IfcShapeRepresentation* clipped_wall_body_rep = file.addEmptyRepresentation();
file.addBox(clipped_wall_body_rep, 5000, 360, 6000);
// The east 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(clipped_wall_body_rep, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
file.clipRepresentation(clipped_wall_body_rep, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
// 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<IfcSchema::IfcOwnerHistory>(),
S("East wall"), null, null, file.addLocalPlacement(4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addBox(5000, 360, 6000), null
S("East wall"), null, null, file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addMappedItem(clipped_wall_body_rep), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(east_wall);
// The east 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(east_wall->Representation(), file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
file.clipRepresentation(east_wall->Representation(), file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
file.setSurfaceColour(east_wall->Representation(), wall_colour);
file.setSurfaceColour(clipped_wall_body_rep, wall_colour);
// The east wall is copied to the west location of the house
IfcSchema::IfcWallStandardCase* west_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
S("West wall"), null, null, file.addLocalPlacement(-4820, 2500, 0, 0, 0, 1, 0, -1, 0), east_wall->Representation(), null
S("West wall"), null, null, file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0), file.addMappedItem(clipped_wall_body_rep), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(west_wall);
for (int i = 0; i < 2; ++i) {
// CV-2x3-161: MappedItems are not allowed for Axis representations
IfcSchema::IfcWallStandardCase* wall = i == 0 ? east_wall : west_wall;
IfcSchema::IfcShapeRepresentation* wall_axis_rep = file.addEmptyRepresentation("Axis", "Curve2D");
file.addAxis(wall_axis_rep, 5000);
IfcSchema::IfcRepresentation::list::ptr reps = wall->Representation()->Representations();
reps->push(wall_axis_rep);
wall->Representation()->setRepresentations(reps);
}
// The west wall is assigned an opening element we created for the south wall, opening elements are
// not shared accross 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.
IfcSchema::IfcOpeningElement* west_opening_copy = new IfcSchema::IfcOpeningElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, west_opening->ObjectPlacement(), west_opening->Representation(), null
null, null, null, file.addLocalPlacement(west_wall->ObjectPlacement(), 2500, -2500+4820, 400, 0, 0, 1, 0, 1, 0),
file.addBox(6000, 3630, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
@@ -219,7 +261,7 @@ int main(int argc, char** argv) {
file.AddEntities(geometrical_entities);
IfcSchema::IfcShapeRepresentation::list::ptr ground_reps = geometrical_entities->as<IfcSchema::IfcShapeRepresentation>();
for (IfcSchema::IfcShapeRepresentation::list::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
(*it)->setContextOfItems(file.getSingle<IfcSchema::IfcRepresentationContext>());
(*it)->setContextOfItems(file.getRepresentationContext("Model"));
}
file.setSurfaceColour(ground_representation, 0.15, 0.25, 0.05);
@@ -293,7 +335,7 @@ int main(int argc, char** argv) {
stair_points.push_back(XY(500, 400));
stair_points.push_back(XY( 0, 400));
IfcSchema::IfcStairFlight* stair = new IfcSchema::IfcStairFlight(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, file.addLocalPlacement(5050, 1000, 0, 0, 1, 0, 1, 0, 0),
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
#ifdef USE_IFC4
, IfcSchema::IfcStairFlightTypeEnum::IfcStairFlightType_STRAIGHT
@@ -304,7 +346,7 @@ int main(int argc, char** argv) {
file.setSurfaceColour(stair->Representation(), footing_colour);
IfcSchema::IfcOpeningElement* door_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, file.addLocalPlacement(5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null
null, null, null, file.addLocalPlacement(storey_placement, 5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
@@ -316,7 +358,7 @@ int main(int argc, char** argv) {
// 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<IfcSchema::IfcOwnerHistory>(), null, null, null,
file.addLocalPlacement(4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000
file.addLocalPlacement(storey_placement, 4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000
#ifdef USE_IFC4
, IfcSchema::IfcDoorTypeEnum::IfcDoorType_DOOR
, IfcSchema::IfcDoorTypeOperationEnum::IfcDoorTypeOperation_SINGLE_SWING_LEFT
@@ -350,30 +392,37 @@ int main(int argc, char** argv) {
// 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::IfcProductDefinitionShape::list::ptr frame_representations (new IfcTemplatedEntityList<IfcSchema::IfcProductDefinitionShape>());
frame_representations->push(file.addBox(1860, 90, 90));
frame_representations->push(*frame_representations->begin()); // Add a reference to the shape created above
frame_representations->push(file.addBox(90, 90, 1420));
frame_representations->push(*(frame_representations->end()-1)); // Add a reference to the shape created above
IfcSchema::IfcShapeRepresentation::list::ptr frame_representations(new IfcSchema::IfcShapeRepresentation::list);
IfcSchema::IfcShapeRepresentation* horizontal_bar = file.addEmptyRepresentation();
IfcSchema::IfcShapeRepresentation* 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
// The beams all have the same surface style assigned
IfcSchema::IfcPresentationStyleAssignment* frame_style = 0;
for (IfcSchema::IfcProductDefinitionShape::list::it i = frame_representations->begin(); i != frame_representations->end(); ++i) {
for (IfcSchema::IfcShapeRepresentation::list::it i = frame_representations->begin(); i != frame_representations->end(); i += 2) {
if (frame_style) {
file.setSurfaceColour(*i, frame_style);
} else {
frame_style = file.setSurfaceColour(*i, 0.5, 0.4, 0.3);
}
// Because of the duplication the iterator is incremented twice
}
// 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 IfcTemplatedEntityList<IfcSchema::IfcLocalPlacement>());
window_placements->push(file.addLocalPlacement(2*-1770-430-930, -45, 400));
window_placements->push(file.addLocalPlacement( -1770-430-930, -45, 400));
window_placements->push(file.addLocalPlacement( -430-930, -45, 400));
window_placements->push(file.addLocalPlacement( 3000-930, -45, 400));
window_placements->push(file.addLocalPlacement( -4855+45, 885-930, 400, 0, 0, 1, 0, 1, 0));
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));
for (IfcSchema::IfcLocalPlacement::list::it it = window_placements->begin(); it != window_placements->end(); ++it) {
@@ -395,20 +444,20 @@ int main(int argc, char** argv) {
// The placements for the beams are not shared accross the different windows because every
// beam is placed relative to its parent window entity.
IfcSchema::IfcLocalPlacement::list::ptr frame_placements (new IfcTemplatedEntityList<IfcSchema::IfcLocalPlacement>());
frame_placements->push(file.addLocalPlacement( 930,45));
frame_placements->push(file.addLocalPlacement( 930, 45, 1510));
frame_placements->push(file.addLocalPlacement(-885+930, 45, 90));
frame_placements->push(file.addLocalPlacement( 885+930, 45, 90));
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));
// Now iterate over the placements and representations of the beam and add them to list of parts
IfcSchema::IfcLocalPlacement::list::it frame_placement;
IfcSchema::IfcProductDefinitionShape::list::it frame_representation;
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();
++frame_placement, ++frame_representation)
{
IfcSchema::IfcMember* frame_part = new IfcSchema::IfcMember(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, *frame_placement, *frame_representation, null
null, null, null, *frame_placement, file.addMappedItem(*frame_representation), null
#ifdef USE_IFC4
, IfcSchema::IfcMemberTypeEnum::IfcMemberType_MULLION
#endif
@@ -420,7 +469,7 @@ int main(int argc, char** argv) {
// Add the glass plate to the list of parts
IfcSchema::IfcPlate* glass_part = new IfcSchema::IfcPlate(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null,
null, null, file.addLocalPlacement(930, 45, 90), file.addBox(1680, 10, 1420), null
null, null, file.addLocalPlacement(storey_placement, 930, 45, 90), file.addBox(1680, 10, 1420), null
#ifdef USE_IFC4
, IfcSchema::IfcPlateTypeEnum::IfcPlateType_SHEET
#endif
@@ -479,6 +528,6 @@ void createGroundShape(TopoDS_Shape& shape) {
#if OCC_VERSION_HEX < 0x60502
shape = BRepBuilderAPI_MakeFace(surf);
#else
shape = BRepBuilderAPI_MakeFace(surf, 1);
shape = BRepBuilderAPI_MakeFace(surf, Precision::Confusion());
#endif
}
+1 -1
View File
@@ -657,7 +657,7 @@ void IfcGeomObjects::InitUnits() {
}
} catch (const IfcParse::IfcException&) {}
if (!units) {
if (!units || !units->Size()) {
// No units eh... Since tolerances and deflection are specified internally in meters
// we will try to find another indication of the model size.
IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = ifc_file->EntitiesByType<IfcSchema::IfcExtrudedAreaSolid>();
+184 -41
View File
@@ -53,12 +53,12 @@ IfcSchema::IfcAxis2Placement2D* IfcHierarchyHelper::addPlacement2d(
return p2d;
}
IfcSchema::IfcLocalPlacement* IfcHierarchyHelper::addLocalPlacement(
IfcSchema::IfcLocalPlacement* IfcHierarchyHelper::addLocalPlacement(IfcSchema::IfcObjectPlacement* parent,
double ox, double oy, double oz,
double zx, double zy, double zz,
double xx, double xy, double xz)
{
IfcSchema::IfcLocalPlacement* lp = new IfcSchema::IfcLocalPlacement(0,
IfcSchema::IfcLocalPlacement* lp = new IfcSchema::IfcLocalPlacement(parent,
addPlacement3d(ox, oy, oz, zx, zy, zz, xx, xy, xz));
AddEntity(lp);
@@ -78,7 +78,7 @@ IfcSchema::IfcOwnerHistory* IfcHierarchyHelper::addOwnerHistory() {
int timestamp = (int) time(0);
IfcSchema::IfcOwnerHistory* owner_hist = new IfcSchema::IfcOwnerHistory(person_and_org, application,
boost::none, IfcSchema::IfcChangeActionEnum::IfcChangeAction_ADDED, boost::none, person_and_org, application, timestamp);
boost::none, IfcSchema::IfcChangeActionEnum::IfcChangeAction_ADDED, timestamp, person_and_org, application, timestamp);
AddEntity(person);
AddEntity(organization);
@@ -91,10 +91,6 @@ IfcSchema::IfcOwnerHistory* IfcHierarchyHelper::addOwnerHistory() {
IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory* owner_hist) {
IfcSchema::IfcRepresentationContext::list::ptr rep_contexts (new IfcSchema::IfcRepresentationContext::list);
IfcSchema::IfcGeometricRepresentationContext* rep_context = new IfcSchema::IfcGeometricRepresentationContext(
std::string("Plan"), std::string("Model"), 3, 1e-5, addPlacement3d(), addTriplet<IfcSchema::IfcDirection>(0, 1, 0));
rep_contexts->push(rep_context);
IfcEntityList::ptr units (new IfcEntityList);
IfcSchema::IfcDimensionalExponents* dimexp = new IfcSchema::IfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0);
@@ -115,7 +111,6 @@ IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory
IfcSchema::IfcProject* project = new IfcSchema::IfcProject(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none,
boost::none, boost::none, boost::none, rep_contexts, unit_assignment);
AddEntity(rep_context);
AddEntity(dimexp);
AddEntity(unit1);
AddEntity(unit2a);
@@ -227,8 +222,24 @@ IfcSchema::IfcBuildingStorey* IfcHierarchyHelper::addBuildingProduct(IfcSchema::
storey = addBuildingStorey(0, owner_hist);
}
AddEntity(product);
addRelatedObject<IfcSchema::IfcRelContainedInSpatialStructure>(storey, product);
relatePlacements(storey, product);
// CV-2x3-158: Don't add decompositions directly to a building storey
bool is_decomposition = false;
#ifdef USE_IFC4
IfcSchema::IfcRelAggregates::list::ptr decomposes = product->Decomposes();
for (IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++it) {
#else
IfcSchema::IfcRelDecomposes::list::ptr decomposes = product->Decomposes();
for (IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++it) {
#endif
if ((*it)->RelatingObject() != product) {
is_decomposition = true;
break;
}
}
if (!is_decomposition) {
addRelatedObject<IfcSchema::IfcRelContainedInSpatialStructure>(storey, product);
relatePlacements(storey, product);
}
return storey;
}
@@ -265,7 +276,7 @@ IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addExtrudedPolyline(co
IfcSchema::IfcRepresentationItem::list::ptr items (new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(context
? context
: getSingle<IfcSchema::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
: getRepresentationContext("Model"), std::string("Body"), std::string("SweptSolid"), items);
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
AddEntity(rep);
@@ -301,13 +312,26 @@ void IfcHierarchyHelper::addBox(IfcSchema::IfcShapeRepresentation* rep, double w
}
}
void IfcHierarchyHelper::addAxis(IfcSchema::IfcShapeRepresentation* rep, double l, IfcSchema::IfcRepresentationContext* context) {
IfcSchema::IfcCartesianPoint* p1 = addDoublet<IfcSchema::IfcCartesianPoint>(-l / 2., 0.);
IfcSchema::IfcCartesianPoint* p2 = addDoublet<IfcSchema::IfcCartesianPoint>(+l / 2., 0.);
IfcSchema::IfcCartesianPoint::list::ptr pts(new IfcSchema::IfcCartesianPoint::list);
pts->push(p1); pts->push(p2);
IfcSchema::IfcPolyline* poly = new IfcSchema::IfcPolyline(pts);
AddEntity(poly);
IfcSchema::IfcRepresentationItem::list::ptr items = rep->Items();
items->push(poly);
rep->setItems(items);
}
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addBox(double w, double d, double h, IfcSchema::IfcAxis2Placement2D* place,
IfcSchema::IfcAxis2Placement3D* place2, IfcSchema::IfcDirection* dir, IfcSchema::IfcRepresentationContext* context)
{
IfcSchema::IfcRepresentation::list::ptr reps (new IfcSchema::IfcRepresentation::list);
IfcSchema::IfcRepresentationItem::list::ptr items (new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
context ? context : getSingle<IfcSchema::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
context ? context : getRepresentationContext("Model"), std::string("Body"), std::string("SweptSolid"), items);
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
AddEntity(rep);
@@ -316,34 +340,61 @@ IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addBox(double w, doubl
return shape;
}
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addAxisBox(double w, double d, double h, IfcSchema::IfcRepresentationContext* context)
{
IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list);
IfcSchema::IfcRepresentationItem::list::ptr body_items(new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcRepresentationItem::list::ptr axis_items(new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcShapeRepresentation* body_rep = new IfcSchema::IfcShapeRepresentation(
context ? context : getRepresentationContext("Model"), std::string("Body"), std::string("SweptSolid"), body_items);
IfcSchema::IfcShapeRepresentation* axis_rep = new IfcSchema::IfcShapeRepresentation(
context ? context : getRepresentationContext("Plan"), std::string("Axis"), std::string("Curve2D"), axis_items);
reps->push(axis_rep);
reps->push(body_rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
AddEntity(shape);
AddEntity(body_rep);
addBox(body_rep, w, d, h, 0, 0, 0, context);
AddEntity(axis_rep);
addAxis(axis_rep, w);
return shape;
}
void IfcHierarchyHelper::clipRepresentation(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcAxis2Placement3D* place, bool agree)
{
IfcSchema::IfcPlane* plane = new IfcSchema::IfcPlane(place);
IfcSchema::IfcHalfSpaceSolid* half_space = new IfcSchema::IfcHalfSpaceSolid(plane, agree);
IfcSchema::IfcRepresentation::list::ptr reps = shape->Representations();
for (IfcSchema::IfcRepresentation::list::it j = reps->begin(); j != reps->end(); ++j) {
IfcSchema::IfcRepresentation* rep = *j;
if (rep->RepresentationIdentifier() != "Body") continue;
rep->setRepresentationType("Clipping");
IfcSchema::IfcRepresentationItem::list::ptr items = rep->Items();
IfcSchema::IfcRepresentationItem::list::ptr new_items (new IfcSchema::IfcRepresentationItem::list);
AddEntity(plane);
AddEntity(half_space);
for (IfcSchema::IfcRepresentationItem::list::it i = items->begin(); i != items->end(); ++i) {
IfcSchema::IfcRepresentationItem* item = *i;
IfcSchema::IfcBooleanClippingResult* clip = new IfcSchema::IfcBooleanClippingResult(
IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE, item, half_space);
AddEntity(clip);
new_items->push(clip);
}
rep->setItems(new_items);
clipRepresentation(*j, place, agree);
}
}
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
IfcSchema::IfcProductRepresentation* shape, double r, double g, double b, double a)
void IfcHierarchyHelper::clipRepresentation(IfcSchema::IfcRepresentation* rep,
IfcSchema::IfcAxis2Placement3D* place, bool agree)
{
if (rep->RepresentationIdentifier() != "Body") return;
IfcSchema::IfcPlane* plane = new IfcSchema::IfcPlane(place);
IfcSchema::IfcHalfSpaceSolid* half_space = new IfcSchema::IfcHalfSpaceSolid(plane, agree);
AddEntity(plane);
AddEntity(half_space);
rep->setRepresentationType("Clipping");
IfcSchema::IfcRepresentationItem::list::ptr items = rep->Items();
IfcSchema::IfcRepresentationItem::list::ptr new_items (new IfcSchema::IfcRepresentationItem::list);
for (IfcSchema::IfcRepresentationItem::list::it i = items->begin(); i != items->end(); ++i) {
IfcSchema::IfcRepresentationItem* item = *i;
IfcSchema::IfcBooleanClippingResult* clip = new IfcSchema::IfcBooleanClippingResult(
IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE, item, half_space);
AddEntity(clip);
new_items->push(clip);
}
rep->setItems(new_items);
}
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::addStyleAssignment(double r, double g, double b, double a) {
IfcSchema::IfcColourRgb* colour = new IfcSchema::IfcColourRgb(boost::none, r, g, b);
IfcSchema::IfcSurfaceStyleRendering* rendering = a == 1.0
? new IfcSchema::IfcSurfaceStyleRendering(colour, boost::none, boost::none, boost::none, boost::none, boost::none,
@@ -363,12 +414,36 @@ IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
AddEntity(rendering);
AddEntity(surface_style);
AddEntity(style_assignment);
return style_assignment;
}
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
IfcSchema::IfcProductRepresentation* shape, double r, double g, double b, double a)
{
IfcSchema::IfcPresentationStyleAssignment* style_assignment = addStyleAssignment(r, g, b, a);
setSurfaceColour(shape, style_assignment);
return style_assignment;
}
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
IfcSchema::IfcRepresentation* shape, double r, double g, double b, double a)
{
IfcSchema::IfcPresentationStyleAssignment* style_assignment = addStyleAssignment(r, g, b, a);
setSurfaceColour(shape, style_assignment);
return style_assignment;
}
void IfcHierarchyHelper::setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* style_assignment)
{
IfcSchema::IfcRepresentation::list::ptr reps = shape->Representations();
for (IfcSchema::IfcRepresentation::list::it j = reps->begin(); j != reps->end(); ++j) {
setSurfaceColour(*j, style_assignment);
}
}
void IfcHierarchyHelper::setSurfaceColour(IfcSchema::IfcRepresentation* rep,
IfcSchema::IfcPresentationStyleAssignment* style_assignment)
{
#ifdef USE_IFC4
IfcEntityList::ptr style_assignments (new IfcEntityList);
@@ -376,15 +451,83 @@ void IfcHierarchyHelper::setSurfaceColour(IfcSchema::IfcProductRepresentation* s
IfcSchema::IfcPresentationStyleAssignment::list::ptr style_assignments (new IfcSchema::IfcPresentationStyleAssignment::list);
#endif
style_assignments->push(style_assignment);
IfcSchema::IfcRepresentation::list::ptr reps = shape->Representations();
for (IfcSchema::IfcRepresentation::list::it j = reps->begin(); j != reps->end(); ++j) {
IfcSchema::IfcRepresentation* rep = *j;
if (rep->RepresentationIdentifier() != "Body" && rep->RepresentationIdentifier() != "Facetation") continue;
IfcSchema::IfcRepresentationItem::list::ptr items = rep->Items();
for (IfcSchema::IfcRepresentationItem::list::it i = items->begin(); i != items->end(); ++i) {
IfcSchema::IfcRepresentationItem* item = *i;
IfcSchema::IfcStyledItem* styled_item = new IfcSchema::IfcStyledItem(item, style_assignments, boost::none);
AddEntity(styled_item);
}
IfcSchema::IfcRepresentationItem::list::ptr items = rep->Items();
for (IfcSchema::IfcRepresentationItem::list::it i = items->begin(); i != items->end(); ++i) {
IfcSchema::IfcRepresentationItem* item = *i;
IfcSchema::IfcStyledItem* styled_item = new IfcSchema::IfcStyledItem(item, style_assignments, boost::none);
AddEntity(styled_item);
}
}
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addMappedItem(
IfcSchema::IfcShapeRepresentation* rep,
IfcSchema::IfcCartesianTransformationOperator3D* transform,
IfcSchema::IfcProductDefinitionShape* def)
{
IfcSchema::IfcRepresentationMap::list::ptr maps = rep->RepresentationMap();
IfcSchema::IfcRepresentationMap* map;
if (maps->Size() == 1) {
map = *maps->begin();
} else {
map = new IfcSchema::IfcRepresentationMap(addPlacement3d(), rep);
AddEntity(map);
}
IfcSchema::IfcRepresentation::list::ptr representations(new IfcSchema::IfcRepresentation::list);
if (def) representations = def->Representations();
if (!transform) {
transform = new IfcSchema::IfcCartesianTransformationOperator3D(0, 0, addTriplet<IfcSchema::IfcCartesianPoint>(0,0,0), boost::none, 0);
AddEntity(transform);
}
IfcSchema::IfcMappedItem* item = new IfcSchema::IfcMappedItem(map, transform);
IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list);
items->push(item);
IfcSchema::IfcRepresentation* new_rep = new IfcSchema::IfcShapeRepresentation(rep->ContextOfItems(), boost::none, std::string("MappedRepresentation"), items);
if (rep->hasRepresentationIdentifier()) {
new_rep->setRepresentationIdentifier(rep->RepresentationIdentifier());
}
AddEntity(item);
AddEntity(new_rep);
representations->push(new_rep);
if (!def) {
def = new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, representations);
AddEntity(def);
} else {
def->setRepresentations(representations);
}
return def;
}
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addMappedItem(
IfcSchema::IfcShapeRepresentation::list::ptr reps,
IfcSchema::IfcCartesianTransformationOperator3D* transform)
{
IfcSchema::IfcProductDefinitionShape* def = 0;
for (IfcSchema::IfcShapeRepresentation::list::it it = reps->begin(); it != reps->end(); ++it) {
def = addMappedItem(*it, transform, def);
}
return def;
}
IfcSchema::IfcShapeRepresentation* IfcHierarchyHelper::addEmptyRepresentation(const std::string& repid, const std::string& reptype) {
IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list);
IfcSchema::IfcShapeRepresentation* shape_rep = new IfcSchema::IfcShapeRepresentation(getRepresentationContext(reptype == "Curve2D" ? "Plan" : "Model"), repid, reptype, items);
AddEntity(shape_rep);
return shape_rep;
}
IfcSchema::IfcGeometricRepresentationContext* IfcHierarchyHelper::getRepresentationContext(const std::string& s) {
std::map<std::string, IfcSchema::IfcGeometricRepresentationContext*>::const_iterator it = contexts.find(s);
if (it != contexts.end()) return it->second;
else {
IfcSchema::IfcProject* project = getSingle<IfcSchema::IfcProject>();
IfcSchema::IfcRepresentationContext::list::ptr project_contexts = project->RepresentationContexts();
IfcSchema::IfcGeometricRepresentationContext* context = new IfcSchema::IfcGeometricRepresentationContext(
boost::none, s, 3, 1e-5, addPlacement3d(), addDoublet<IfcSchema::IfcDirection>(0, 1));
AddEntity(context);
project_contexts->push(context);
project->setRepresentationContexts(project_contexts);
return contexts[s] = context;
}
}
+32 -1
View File
@@ -28,6 +28,8 @@
#ifndef IFCHIERARCHYHELPER_H
#define IFCHIERARCHYHELPER_H
#include <map>
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
@@ -68,7 +70,8 @@ public:
IfcSchema::IfcAxis2Placement2D* addPlacement2d(double ox=0.0, double oy=0.0,
double xx=1.0, double xy=0.0);
IfcSchema::IfcLocalPlacement* addLocalPlacement(double ox=0.0, double oy=0.0, double oz=0.0,
IfcSchema::IfcLocalPlacement* addLocalPlacement(IfcSchema::IfcObjectPlacement* parent = 0,
double ox=0.0, double oy=0.0, double oz=0.0,
double zx=0.0, double zy=0.0, double zz=1.0,
double xx=1.0, double xy=0.0, double xz=0.0);
@@ -129,15 +132,43 @@ public:
IfcSchema::IfcProductDefinitionShape* addBox(double w, double d, double h, IfcSchema::IfcAxis2Placement2D* place=0,
IfcSchema::IfcAxis2Placement3D* place2=0, IfcSchema::IfcDirection* dir=0, IfcSchema::IfcRepresentationContext* context=0);
void addAxis(IfcSchema::IfcShapeRepresentation* rep, double l, IfcSchema::IfcRepresentationContext* context=0);
IfcSchema::IfcProductDefinitionShape* addAxisBox(double w, double d, double h, IfcSchema::IfcRepresentationContext* context=0);
void clipRepresentation(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcAxis2Placement3D* place, bool agree);
void clipRepresentation(IfcSchema::IfcRepresentation* shape,
IfcSchema::IfcAxis2Placement3D* place, bool agree);
IfcSchema::IfcPresentationStyleAssignment* addStyleAssignment(double r, double g, double b, double a=1.0);
IfcSchema::IfcPresentationStyleAssignment* setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
double r, double g, double b, double a=1.0);
IfcSchema::IfcPresentationStyleAssignment* setSurfaceColour(IfcSchema::IfcRepresentation* shape,
double r, double g, double b, double a=1.0);
void setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* style_assignment);
void setSurfaceColour(IfcSchema::IfcRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* style_assignment);
IfcSchema::IfcProductDefinitionShape* addMappedItem(IfcSchema::IfcShapeRepresentation*,
IfcSchema::IfcCartesianTransformationOperator3D* transform = 0,
IfcSchema::IfcProductDefinitionShape* def = 0);
IfcSchema::IfcProductDefinitionShape* addMappedItem(IfcSchema::IfcShapeRepresentation::list::ptr,
IfcSchema::IfcCartesianTransformationOperator3D* transform = 0);
IfcSchema::IfcShapeRepresentation* addEmptyRepresentation(const std::string& repid = "Body", const std::string& reptype = "SweptSolid");
IfcSchema::IfcGeometricRepresentationContext* getRepresentationContext(const std::string&);
private:
std::map<std::string, IfcSchema::IfcGeometricRepresentationContext*> contexts;
};
template <>
+30
View File
@@ -834,6 +834,36 @@ void IfcFile::AddEntity(IfcUtil::IfcBaseClass* entity) {
}
byid[new_id] = entity;
unsigned arg_count = entity->entity->getArgumentCount();
for (unsigned i = 0; i < arg_count; ++i) {
Argument* arg = entity->entity->getArgument(i);
IfcEntityList::ptr entity_attributes(new IfcEntityList);
try {
IfcUtil::IfcBaseClass* entity_attribute = *arg;
entity_attributes->push(entity_attribute);
} catch(IfcParse::IfcException&) {
try {
IfcEntityList::ptr entity_list_attribute = *arg;
entity_attributes->push(entity_list_attribute);
} catch(IfcParse::IfcException&) {}
}
for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) {
IfcUtil::IfcBaseClass* entity_attribute = *it;
try {
if (entity_attribute->entity->isWritable()) {
if ( ! entity_attribute->entity->file ) entity_attribute->entity->file = this;
((IfcWrite::IfcWritableEntity*)(entity_attribute->entity))->setId();
}
unsigned entity_attribute_id = entity_attribute->entity->id();
IfcEntityList::ptr refs = EntitiesByReference(entity_attribute_id);
if (!refs) {
refs = IfcEntityList::ptr(new IfcEntityList);
byref[entity_attribute_id] = refs;
}
refs->push(entity);
} catch (IfcParse::IfcException&) {}
}
}
}
IfcEntityList::ptr IfcFile::EntitiesByType(IfcSchema::Type::Enum t) {
MapEntitiesByType::const_iterator it = bytype.find(t);
+4 -2
View File
@@ -77,7 +77,8 @@ public:
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
for ( it i = begin(); i != end(); ++ i ) if ((*i)->is(U::Class())) r->push((U*)*i);
const bool all = U::Class() == IfcSchema::Type::ALL;
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->is(U::Class())) r->push((U*)*i);
return r;
}
};
@@ -101,7 +102,8 @@ public:
template <class U>
typename U::list::ptr as() {
typename U::list::ptr r(new typename U::list);
for ( it i = begin(); i != end(); ++ i ) if ((*i)->is(U::Class())) r->push(*i);
const bool all = U::Class() == IfcSchema::Type::ALL;
for ( it i = begin(); i != end(); ++ i ) if (all || (*i)->is(U::Class())) r->push(*i);
return r;
}
};
+10 -1
View File
@@ -33,7 +33,16 @@ IfcWritableEntity::~IfcWritableEntity() {
delete _id;
}
int IfcWritableEntity::setId(int i) {
return *(_id = new int(i > 0 ? i : file->FreshId()));
if (i > 0) {
delete _id;
return *(_id = new int(i));
} else {
if (_id) { return *_id; }
else {
delete _id;
return *(_id = new int(file->FreshId()));
}
}
}
IfcWritableEntity::IfcWritableEntity(IfcAbstractEntity* e)
{