void create_product_from_item(IfcHierarchyHelper& file, IfcSchema::IfcRepresentationItem* item, const std::string& s) {
	IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
		guid(), 0, S("product"), null, null, 0, 0, null, null);
	file.addBuildingProduct(product);
	product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());

	product->setObjectPlacement(file.addLocalPlacement(120 * i++));

	IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
	IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
	items->push(item);

	if (s == "GeometricSet") {
		IfcSchema::IfcGeometricSet* set = new IfcSchema::IfcGeometricSet(items->generalize());
		file.AddEntity(set);
		items = IfcSchema::IfcRepresentationItem::list(new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
		items->push(set);
	}
		
	IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
		file.getSingle<IfcSchema::IfcRepresentationContext>(), S("Body"), s, items);
	reps->push(rep);

	IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
	file.AddEntity(rep);
	file.AddEntity(shape);
		
	product->setRepresentation(shape);
}
void create_products_from_curve(IfcHierarchyHelper& file, IfcSchema::IfcBoundedCurve* curve) {
	IfcSchema::IfcArbitraryOpenProfileDef* open = new IfcSchema::IfcArbitraryOpenProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE, null, curve);
	IfcSchema::IfcCenterLineProfileDef* center_line = new IfcSchema::IfcCenterLineProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, null, curve, 10.);
	file.AddEntity(open);
	file.AddEntity(center_line);

	create_surfaces_from_profile(file, open);
	create_solids_from_profile(file, center_line);
}
int main()
{
	IfcHierarchyHelper file;
	file.header().file_name().name("ifc_curve_rebar.ifc");
	create_curve_rebar(file);
	std::ofstream f("ifc_curve_rebar.ifc");
	f << file;

	return 0;
}
void create_surfaces_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileDef* profile) {
	IfcSchema::IfcSurfaceOfLinearExtrusion* extrusion = new IfcSchema::IfcSurfaceOfLinearExtrusion(profile, file.addPlacement3d(), file.addTriplet<IfcSchema::IfcDirection>(0, 0, 1), 100.);
	file.AddEntity(extrusion);

	IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet<IfcSchema::IfcCartesianPoint>(0,100,0), file.addTriplet<IfcSchema::IfcDirection>(1,0,0));
	IfcSchema::IfcSurfaceOfRevolution* revolution = new IfcSchema::IfcSurfaceOfRevolution(profile, file.addPlacement3d(), ax1);
	file.AddEntity(ax1);
	file.AddEntity(revolution);

	create_product_from_item(file, extrusion, "GeometricSet");
	create_product_from_item(file, revolution, "GeometricSet");
}
void create_solids_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileDef* profile) {
	IfcSchema::IfcExtrudedAreaSolid* extrusion = new IfcSchema::IfcExtrudedAreaSolid(profile, file.addPlacement3d(), file.addTriplet<IfcSchema::IfcDirection>(0, 0, 1), 100.);
	file.AddEntity(extrusion);

	IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet<IfcSchema::IfcCartesianPoint>(0,100,0), file.addTriplet<IfcSchema::IfcDirection>(1,0,0));
	IfcSchema::IfcRevolvedAreaSolid* revolution1 = new IfcSchema::IfcRevolvedAreaSolid(profile, file.addPlacement3d(), ax1, 360.);
	IfcSchema::IfcRevolvedAreaSolid* revolution2 = new IfcSchema::IfcRevolvedAreaSolid(profile, file.addPlacement3d(), ax1, 90.);
	file.AddEntity(ax1);
	file.AddEntity(revolution1);
	file.AddEntity(revolution2);

	create_product_from_item(file, extrusion, "SweptSolid");
	create_product_from_item(file, revolution1, "SweptSolid");
	create_product_from_item(file, revolution2, "SweptSolid");
}
int main(int argc, char** argv) {
	const char filename[] = "IfcArbitraryOpenProfileDef.ifc";
	IfcHierarchyHelper file;
	file.filename(filename);

	double coords1[] = {-50.0, 0.0};
	double coords2[] = { 50.0, 0.0};
	IfcSchema::IfcCartesianPoint::list points (new IfcTemplatedEntityList<IfcSchema::IfcCartesianPoint>());
	points->push(new IfcSchema::IfcCartesianPoint(std::vector<double>(coords1, coords1+2)));
	points->push(new IfcSchema::IfcCartesianPoint(std::vector<double>(coords2, coords2+2)));
	file.AddEntities(points->generalize());
	IfcSchema::IfcPolyline* poly = new IfcSchema::IfcPolyline(points);
	file.AddEntity(poly);

	create_products_from_curve(file, poly);

	IfcSchema::IfcEllipse* ellipse = new IfcSchema::IfcEllipse(file.addPlacement2d(), 50., 25.);
	file.AddEntity(ellipse);
	IfcEntities trim1(new IfcEntityList());
	IfcEntities trim2(new IfcEntityList());
	trim1->push(new IfcWrite::IfcSelectHelper(  0., Ifc2x3::Type::IfcParameterValue));
	trim2->push(new IfcWrite::IfcSelectHelper(180., Ifc2x3::Type::IfcParameterValue));
	IfcSchema::IfcTrimmedCurve* trim = new IfcSchema::IfcTrimmedCurve(ellipse, trim1, trim2, true, IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
	file.AddEntity(trim);

	create_products_from_curve(file, trim);

	file.getSingle<Ifc2x3::IfcProject>()->setName("IfcArbitraryOpenProfileDef");

	std::ofstream f(filename);
	f << file;
}
int main(int argc, char** argv) {
	IfcHierarchyHelper file;

	IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
		guid(), 0, S("Blender's Suzanne"), null, null, 0, 0, null, null);
	file.addBuildingProduct(product);
	product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());

	product->setObjectPlacement(file.addLocalPlacement());

	IfcSchema::IfcRepresentation::list::ptr reps (new IfcSchema::IfcRepresentation::list);
	IfcSchema::IfcRepresentationItem::list::ptr items (new IfcSchema::IfcRepresentationItem::list);

	std::vector< std::vector< double > > vertices_vector = create_vector_from_array(vertices, sizeof(vertices) / sizeof(vertices[0]));
	std::vector< std::vector< int > > indices_vector = create_vector_from_array(indices, sizeof(indices) / sizeof(indices[0]));

	IfcSchema::IfcCartesianPointList3D* coordinates = new IfcSchema::IfcCartesianPointList3D(vertices_vector);	
	IfcSchema::IfcTriangulatedFaceSet* faceset = new IfcSchema::IfcTriangulatedFaceSet(coordinates, null, null, indices_vector, null);
		
	items->push(faceset);
	IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
		file.getRepresentationContext("Model"), S("Body"), S("SurfaceModel"), items);
	reps->push(rep);

	IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
	file.addEntity(shape);
		
	product->setRepresentation(shape);

	const std::string filename = "tesselated_faceset.ifc";
	file.header().file_name().name(filename);
	std::ofstream f(filename.c_str());
	f << file;
}
int main(int argc, char** argv) {
	const char filename[] = "IfcCompositeProfileDef.ifc";
	IfcHierarchyHelper file;
	file.filename(filename);

	double coords1[] = {100.0, 0.0};
	double coords2[] = {200.0, 0.0};
	double coords3[] = {300.0, 0.0};

	IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());

	IfcSchema::IfcCartesianTransformationOperator2D* transform1 = new IfcSchema::IfcCartesianTransformationOperator2D(file.addDoublet<IfcSchema::IfcDirection>(1, 0), file.addDoublet<IfcSchema::IfcDirection>(0, -1), file.addDoublet<IfcSchema::IfcCartesianPoint>(40, 0), null);
	IfcSchema::IfcCartesianTransformationOperator2D* transform2 = new IfcSchema::IfcCartesianTransformationOperator2D(file.addDoublet<IfcSchema::IfcDirection>(0, -1), file.addDoublet<IfcSchema::IfcDirection>(1, 0), file.addDoublet<IfcSchema::IfcCartesianPoint>(40, 0), 0.3);
	
	IfcSchema::IfcProfileDef* p1 = new Ifc2x3::IfcIShapeProfileDef(
		IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
		null, file.addPlacement2d(),    25.0,    50.0,     5.0,     5.0,     2.0);

	IfcSchema::IfcProfileDef* p2 = new Ifc2x3::IfcLShapeProfileDef(
		IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
		null, file.addPlacement2d(),    50.0,    25.0,     5.0,      1.0,     2.0,     2.0,    null,    null);

	IfcSchema::IfcProfileDef* p3 = new Ifc2x3::IfcTShapeProfileDef(
		IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
		null, file.addPlacement2d(),    50.0,    40.0,    10.0,     10.0,     3.0,     2.0,     1.0,     2.0,     2.0,    null);

	IfcSchema::IfcProfileDef* p4 = new Ifc2x3::IfcCShapeProfileDef(
		IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
		null, file.addPlacement2d(80.),    50.0,    25.0,     5.0,    10.0,     2.0,    null);

	file.AddEntity(p2);
	file.AddEntity(p3);
	
	file.AddEntity(transform1);
	file.AddEntity(transform2);
	
	IfcSchema::IfcDerivedProfileDef* p5 = new IfcSchema::IfcDerivedProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, null, p2, transform1, null);
	IfcSchema::IfcDerivedProfileDef* p6 = new IfcSchema::IfcDerivedProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, null, p3, transform2, null);
	
	profiles->push(p1);
	profiles->push(p5);
	profiles->push(p6);
	profiles->push(p4);

	file.AddEntities(profiles->generalize());

	IfcSchema::IfcCompositeProfileDef* composite = new IfcSchema::IfcCompositeProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, S("IFC"), profiles, null);

	IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
			guid(), 0, S("profile"), null, null, 0, 0, null, null);

	file.addBuildingProduct(product);

	product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());

	product->setObjectPlacement(file.addLocalPlacement());

	IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(composite,
		file.addPlacement3d(), file.addTriplet<IfcSchema::IfcDirection>(0, 0, 1), 20.0);

	file.AddEntity(composite);
	file.AddEntity(solid);
		
	IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
	IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
		
	items->push(solid);
	IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
		file.getSingle<IfcSchema::IfcRepresentationContext>(), S("Body"), S("SweptSolid"), items);
	reps->push(rep);

	IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
	file.AddEntity(rep);
	file.AddEntity(shape);
		
	product->setRepresentation(shape);

	file.getSingle<IfcSchema::IfcProject>()->setName("IfcCompositeProfileDef");

	std::ofstream f(filename);
	f << file;
}
Example #9
0
void create_testcase_for(IfcHierarchyHelper& file, const EllipsePie& pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference pref) {
	const double deg = 1. / 180. * 3.141592653;
	double flt1[] = {0.                      , 0.                      };
	double flt2[] = {pie.r1 * cos(pie.t1*deg), pie.r2 * sin(pie.t1*deg)};
	double flt3[] = {pie.r1 * cos(pie.t2*deg), pie.r2 * sin(pie.t2*deg)};

	std::vector<double> coords1(flt1, flt1 + 2);
	std::vector<double> coords2(flt2, flt2 + 2);
	std::vector<double> coords3(flt3, flt3 + 2);
	
	Ifc2x3::IfcCartesianPoint* p1 = new Ifc2x3::IfcCartesianPoint(coords1);
	Ifc2x3::IfcCartesianPoint* p2 = new Ifc2x3::IfcCartesianPoint(coords2);
	Ifc2x3::IfcCartesianPoint* p3 = new Ifc2x3::IfcCartesianPoint(coords3);
	
	Ifc2x3::IfcCartesianPoint::list points(new IfcTemplatedEntityList<Ifc2x3::IfcCartesianPoint>());
	points->push(p3);
	points->push(p1);
	points->push(p2);
	file.AddEntities(points->generalize());

	
	Ifc2x3::IfcEllipse* ellipse = new Ifc2x3::IfcEllipse(file.addPlacement2d(), pie.r1, pie.r2);
	file.AddEntity(ellipse);
	IfcEntities trim1(new IfcEntityList());
	IfcEntities trim2(new IfcEntityList());
	if (pref == Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER) {
		trim1->push(new IfcWrite::IfcSelectHelper(pie.t1, Ifc2x3::Type::IfcParameterValue));
		trim2->push(new IfcWrite::IfcSelectHelper(pie.t2, Ifc2x3::Type::IfcParameterValue));
	} else {
		trim1->push(p2);
		trim2->push(p3);
	}
	Ifc2x3::IfcTrimmedCurve* trim = new Ifc2x3::IfcTrimmedCurve(ellipse, trim1, trim2, true, pref);
	file.AddEntity(trim);
	
	Ifc2x3::IfcCompositeCurveSegment::list segments(new IfcTemplatedEntityList<Ifc2x3::IfcCompositeCurveSegment>());
	Ifc2x3::IfcCompositeCurveSegment* s2 = new Ifc2x3::IfcCompositeCurveSegment(Ifc2x3::IfcTransitionCode::IfcTransitionCode_CONTINUOUS, true, trim);
	
	Ifc2x3::IfcPolyline* poly = new Ifc2x3::IfcPolyline(points);	
	file.AddEntity(poly);
	Ifc2x3::IfcCompositeCurveSegment* s1 = new Ifc2x3::IfcCompositeCurveSegment(Ifc2x3::IfcTransitionCode::IfcTransitionCode_CONTINUOUS, true, poly);
	segments->push(s1);
	
	segments->push(s2);
	file.AddEntities(segments->generalize());
	
	Ifc2x3::IfcCompositeCurve* ccurve = new Ifc2x3::IfcCompositeCurve(segments, false);
	Ifc2x3::IfcArbitraryClosedProfileDef* profile = new Ifc2x3::IfcArbitraryClosedProfileDef(Ifc2x3::IfcProfileTypeEnum::IfcProfileType_AREA, null, ccurve);
	file.AddEntity(ccurve);
	file.AddEntity(profile);

	IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
		guid(), 0, S("profile"), null, null, 0, 0, null, null);
	file.addBuildingProduct(product);
	product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());

	product->setObjectPlacement(file.addLocalPlacement(200 * i++));

	IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(profile,
		file.addPlacement3d(), file.addTriplet<IfcSchema::IfcDirection>(0, 0, 1), 20.0);

	file.AddEntity(solid);
		
	IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
	IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
		
	items->push(solid);
	IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
		file.getSingle<IfcSchema::IfcRepresentationContext>(), S("Body"), S("SweptSolid"), items);
	reps->push(rep);

	IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
	file.AddEntity(rep);
	file.AddEntity(shape);
		
	product->setRepresentation(shape);
}
void create_curve_rebar(IfcHierarchyHelper& file)
{
	int dia = 24;
	int R = 3 * dia;
	int length = 12 * dia;

	double crossSectionarea = M_PI * (dia / 2) * 2;
	IfcSchema::IfcReinforcingBar* rebar = new IfcSchema::IfcReinforcingBar(
		guid(), 0, S("test"), null,
		null, 0, 0,
		null, S("SR24"),		//SteelGrade
		dia,						//diameter
		crossSectionarea,		//crossSectionarea = math.pi*(12.0/2)**2
		0,
		IfcSchema::IfcReinforcingBarRoleEnum::IfcReinforcingBarRoleEnum::IfcReinforcingBarRole_LIGATURE,
		IfcSchema::IfcReinforcingBarSurfaceEnum::IfcReinforcingBarSurfaceEnum::IfcReinforcingBarSurface_PLAIN	//PLAIN or TEXTURED
		);

	file.addBuildingProduct(rebar);
	rebar->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());

	IfcSchema::IfcCompositeCurveSegment::list::ptr segments(new IfcSchema::IfcCompositeCurveSegment::list());

	IfcSchema::IfcCartesianPoint* p1 = file.addTriplet<IfcSchema::IfcCartesianPoint>(0, 0, 1000.);
	IfcSchema::IfcCartesianPoint* p2 = file.addTriplet<IfcSchema::IfcCartesianPoint>(0, 0, 0);
	IfcSchema::IfcCartesianPoint* p3 = file.addTriplet<IfcSchema::IfcCartesianPoint>(0, R, 0);
	IfcSchema::IfcCartesianPoint* p4 = file.addTriplet<IfcSchema::IfcCartesianPoint>(0, R, -R);
	IfcSchema::IfcCartesianPoint* p5 = file.addTriplet<IfcSchema::IfcCartesianPoint>(0, R + length, -R);

	/*first segment - line */
	IfcSchema::IfcCartesianPoint::list::ptr points1(new IfcSchema::IfcCartesianPoint::list());
	points1->push(p1);
	points1->push(p2);
	file.addEntities(points1->generalize());
	IfcSchema::IfcPolyline* poly1 = new IfcSchema::IfcPolyline(points1);
	file.addEntity(poly1);

	IfcSchema::IfcCompositeCurveSegment* segment1 = new IfcSchema::IfcCompositeCurveSegment(IfcSchema::IfcTransitionCode::IfcTransitionCode_CONTINUOUS, true, poly1);
	file.addEntity(segment1);
	segments->push(segment1);

	/*second segment - arc */
	IfcSchema::IfcAxis2Placement3D* axis1 = new IfcSchema::IfcAxis2Placement3D(p3, file.addTriplet<IfcSchema::IfcDirection>(1, 0, 0), file.addTriplet<IfcSchema::IfcDirection>(0, 1, 0));
	file.addEntity(axis1);
	IfcSchema::IfcCircle* circle = new IfcSchema::IfcCircle(axis1, R);
	file.addEntity(circle);

	IfcEntityList::ptr trim1(new IfcEntityList);
	IfcEntityList::ptr trim2(new IfcEntityList);

	trim1->push(new IfcSchema::IfcParameterValue(180));
	trim1->push(p2);

	trim2->push(new IfcSchema::IfcParameterValue(270));
	trim2->push(p4);
	IfcSchema::IfcTrimmedCurve* trimmed_curve = new IfcSchema::IfcTrimmedCurve(circle, trim1, trim2, false, IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
	file.addEntity(trimmed_curve);

	IfcSchema::IfcCompositeCurveSegment* segment2 = new IfcSchema::IfcCompositeCurveSegment(IfcSchema::IfcTransitionCode::IfcTransitionCode_CONTSAMEGRADIENT, false, trimmed_curve);
	file.addEntity(segment2);
	segments->push(segment2);

	/*third segment - line */
	IfcSchema::IfcCartesianPoint::list::ptr points2(new IfcSchema::IfcCartesianPoint::list());
	points2->push(p4);
	points2->push(p5);
	file.addEntities(points2->generalize());
	IfcSchema::IfcPolyline* poly2 = new IfcSchema::IfcPolyline(points2);
	file.addEntity(poly2);

	IfcSchema::IfcCompositeCurveSegment* segment3 = new IfcSchema::IfcCompositeCurveSegment(IfcSchema::IfcTransitionCode::IfcTransitionCode_CONTINUOUS, true, poly2);
	file.addEntity(segment3);
	segments->push(segment3);

	IfcSchema::IfcCompositeCurve* curve = new IfcSchema::IfcCompositeCurve(segments, false);
	file.addEntity(curve);

	IfcSchema::IfcSweptDiskSolid* solid = new IfcSchema::IfcSweptDiskSolid(curve, dia / 2, null, 0, 1);

	IfcSchema::IfcRepresentation::list::ptr reps(new IfcSchema::IfcRepresentation::list());
	IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list());
	items->push(solid);
	IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
		file.getSingle<IfcSchema::IfcRepresentationContext>(), S("Body"), S("AdvancedSweptSolid"), items);
	reps->push(rep);

	IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(null, null, reps);
	file.addEntity(shape);

	rebar->setRepresentation(shape);

	IfcSchema::IfcObjectPlacement* storey_placement = file.getSingle<IfcSchema::IfcBuildingStorey>()->ObjectPlacement();
	rebar->setObjectPlacement(file.addLocalPlacement(storey_placement, 0, 0, 0));
}
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().name("IfcAdvancedHouse.ifc");

	IfcSchema::IfcBuilding* 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<IfcSchema::IfcProject>()->setName("IfcOpenHouse");

	// 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 
	// modeled separately, with rich parametric and relational semantics. Creating geometry in this
	// way does not preserve any history and is merely a demonstration of technical capabilities.
	TopoDS_Shape outer =   BRepPrimAPI_MakeBox(gp_Pnt(-5000., -180., -2000.), gp_Pnt(5000., 5180., 3000.)).Shape();
	TopoDS_Shape inner =   BRepPrimAPI_MakeBox(gp_Pnt(-4640.,  180.,     0.), gp_Pnt(4640., 4820., 3000.)).Shape();
	TopoDS_Shape window1 = BRepPrimAPI_MakeBox(gp_Pnt(-5000., -180.,   400.), gp_Pnt( 500., 1180., 2000.)).Shape();
	TopoDS_Shape window2 = BRepPrimAPI_MakeBox(gp_Pnt( 2070., -180.,   400.), gp_Pnt(3930.,  180., 2000.)).Shape();

	TopoDS_Shape building_shell = BRepAlgoAPI_Cut(
		BRepAlgoAPI_Cut(
			BRepAlgoAPI_Cut(outer, inner),
			window1
			),
		window2
	);

	// Since the solid consists only of planar faces and straight edges it can be serialized as an
	// 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(building_shell, false);
	
	file.addEntity(building_shape);
	IfcSchema::IfcRepresentation* rep = *building_shape->Representations()->begin();
	rep->setContextOfItems(file.getRepresentationContext("model"));

	building->setRepresentation(building_shape);

	// A pale white colour is assigned to the building.
	file.setSurfaceColour(
		building_shape, 0.75, 0.73, 0.68);

	// For the ground mesh of the IfcSite we will use a Nurbs surface created in Open Cascade. Only
	// in IFC4 the surface can be directly serialized. In IFC2X3 the it will have to be tesselated.
	TopoDS_Shape shape;
	createGroundShape(shape);

	IfcSchema::IfcProductDefinitionShape* ground_representation = IfcGeom::serialise(shape, true);
	if (!ground_representation) {
		ground_representation = IfcGeom::tesselate(shape, 100.);
	}
	file.getSingle<IfcSchema::IfcSite>()->setRepresentation(ground_representation);
	
	IfcSchema::IfcRepresentation::list::ptr ground_reps = file.getSingle<IfcSchema::IfcSite>()->Representation()->Representations();
	for (IfcSchema::IfcRepresentation::list::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
		(*it)->setContextOfItems(file.getRepresentationContext("Model"));
	}
	file.addEntity(ground_representation);
	file.setSurfaceColour(ground_representation, 0.15, 0.25, 0.05);

    /*
    // Note that IFC lacks elementary surfaces that STEP does have, such as spherical_surface.
    // BRepBuilderAPI_NurbsConvert can be used to serialize such surfaces as nurbs surfaces.
	TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(), 1000.).Shape();
	IfcSchema::IfcProductDefinitionShape* sphere_representation = IfcGeom::serialise(sphere, true);
	if (S(IfcSchema::Identifier) == "IFC4") {
		sphere = BRepBuilderAPI_NurbsConvert(sphere, true).Shape();
		sphere_representation = IfcGeom::serialise(sphere, true);
	}
    */

	// Finally create a file stream for our output and write the IFC file to it.
	std::ofstream f("IfcAdvancedHouse.ifc");
	f << file;
}