mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
178 lines
8.6 KiB
C++
178 lines
8.6 KiB
C++
/********************************************************************************
|
|
* *
|
|
* This file is part of IfcOpenShell. *
|
|
* *
|
|
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the Lesser GNU General Public License as published by *
|
|
* the Free Software Foundation, either version 3.0 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* IfcOpenShell is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* Lesser GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the Lesser GNU General Public License *
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
* *
|
|
********************************************************************************/
|
|
|
|
// This example illustrates the basic of building an alignment model.
|
|
// The alignment is based on "Bridge Geometry Manual", April 2022
|
|
// US Department of Transportation, Federal Highway Administration (FHWA)
|
|
// https://www.fhwa.dot.gov/bridge/pubs/hif22034.pdf
|
|
//
|
|
// Sections and page number for this document are cited in the code comments.
|
|
//
|
|
// This examples differs from IfcAlignment because it uses utility methods
|
|
// to simplify alignment construction
|
|
|
|
// Disable warnings coming from IfcOpenShell
|
|
#pragma warning(disable : 4018 4267 4250 4984 4985)
|
|
|
|
#include "../ifcparse/Ifc4x3_add2.h"
|
|
#include "../ifcparse/alignment_helper.h"
|
|
|
|
#include <fstream>
|
|
|
|
#define Schema Ifc4x3_add2
|
|
|
|
// performs basic project setup including created the IfcProject object
|
|
// and initializing the project units to FEET
|
|
Schema::IfcProject setup_project(hierarchy_helper<Schema>& file) {
|
|
std::vector<std::string> file_description;
|
|
file_description.push_back("ViewDefinition[Alignment-basedReferenceView]");
|
|
file.header().file_description().setdescription(file_description);
|
|
|
|
auto project = file.addProject();
|
|
project.setName(std::string("FHWA Bridge Geometry Manual Example Alignment"));
|
|
project.setDescription(std::string("C++ Example - Simplified"));
|
|
|
|
// set up project units for feet
|
|
// the call to file.addProject() sets up length units as millimeter.
|
|
auto units_in_context = project.UnitsInContext();
|
|
auto units = units_in_context.Units();
|
|
auto begin = units.begin();
|
|
auto iter = begin;
|
|
auto end = units.end();
|
|
for (; iter != end; iter++) {
|
|
auto unit = *iter;
|
|
if (unit.as<Schema::IfcSIUnit>() && unit.as<Schema::IfcSIUnit>().UnitType() == Schema::IfcUnitEnum::IfcUnit_LENGTHUNIT) {
|
|
auto dimensions = file.create<Schema::IfcDimensionalExponents>();
|
|
dimensions.setLengthExponent(1);
|
|
dimensions.setMassExponent(0);
|
|
dimensions.setTimeExponent(0);
|
|
dimensions.setElectricCurrentExponent(0);
|
|
dimensions.setThermodynamicTemperatureExponent(0);
|
|
dimensions.setAmountOfSubstanceExponent(0);
|
|
dimensions.setLuminousIntensityExponent(0);
|
|
|
|
auto conversion_factor = file.create<Schema::IfcMeasureWithUnit>();
|
|
auto length = file.create<Schema::IfcLengthMeasure>();
|
|
length.set_attribute_value(0, 304.80);
|
|
conversion_factor.setValueComponent(length);
|
|
conversion_factor.setUnitComponent(unit);
|
|
|
|
auto conversion_based_unit = file.create<Schema::IfcConversionBasedUnit>();
|
|
conversion_based_unit.setDimensions(dimensions);
|
|
conversion_based_unit.setUnitType(Schema::IfcUnitEnum::IfcUnit_LENGTHUNIT);
|
|
conversion_based_unit.setName("FEET");
|
|
conversion_based_unit.setConversionFactor(conversion_factor);
|
|
|
|
units.erase(std::remove(units.begin(), units.end(), unit)); // remove the millimeter unit
|
|
units.push_back(conversion_based_unit); // add the feet unit
|
|
units_in_context.setUnits(units); // update the UnitsInContext
|
|
|
|
break; // Done!, the length unit was found, so break out of the loop
|
|
}
|
|
}
|
|
|
|
return project;
|
|
}
|
|
|
|
int main() {
|
|
hierarchy_helper<Schema> file;
|
|
|
|
auto project = setup_project(file);
|
|
|
|
//
|
|
// Define horizontal alignment
|
|
//
|
|
|
|
// PI Data
|
|
// B.1.1 pg 211
|
|
std::vector<std::pair<double, double>> points{
|
|
{ 500.0, 2500.0}, // beginning
|
|
{3340.0, 660.0}, // Point of intersection (PI), Curve #1
|
|
{4340.0, 5000.0}, // Point of intersection (PI), Curve #2
|
|
{7600.0, 4560.0}, // Point of intersection (PI), Curve #3
|
|
{8480.0, 2010.0} // ending
|
|
};
|
|
|
|
// Curve Data
|
|
// B.1.3 pg 212
|
|
std::vector<double> radii{ 1000,1250,950 };
|
|
|
|
//
|
|
// Define vertical profile segments
|
|
//
|
|
|
|
// Vertical Profile Data
|
|
// Figure B.2 pg 213
|
|
double xStart = 10000.0; // subtract xStart so the points are distance along, not station
|
|
std::vector<std::pair<double,double>> vpoints {
|
|
{10000.0-xStart,100.0}, // Vertical point of beginning (VPOB)
|
|
{12000.0-xStart,135.0}, // Point of vertical intersection (VPI), Curve #1
|
|
{15000.0-xStart,105.0}, // Point of vertical intersection (VPI), Curve #2
|
|
{17400.0-xStart,153.0}, // Point of vertical intersection (VPI), Curve #3
|
|
{19800.0-xStart,105.0}, // Point of vertical intersection (VPI), Curve #4
|
|
{22800.0-xStart, 90.0} // Vertical poitn of ending (VPOE)
|
|
};
|
|
|
|
// Vertical Curve Lengths
|
|
// Figure B.2 pg 213
|
|
std::vector<double> vclengths{1600.0, 1200.0, 2000.0, 800.0};
|
|
|
|
// Use utility function to create alignment
|
|
auto alignment = addAlignment(file, "Example Alignment", points, radii, vpoints, vclengths);
|
|
|
|
// Define the alignment's relationship with the project
|
|
|
|
// IFC 4.1.4.1.1 "Every IfcAlignment must be related to IfcProject using the IfcRelAggregates relationship"
|
|
// https://standards.buildingsmart.org/IFC/RELEASE/IFC4_3/HTML/concepts/Object_Composition/Aggregation/Alignment_Aggregation_To_Project/content.html
|
|
// IfcProject <-> IfcRelAggregates <-> IfcAlignment
|
|
auto aggregate_alignments_with_project = file.create<Schema::IfcRelAggregates>();
|
|
aggregate_alignments_with_project.setGlobalId(ifcopenshell::global_id());
|
|
aggregate_alignments_with_project.setName("Alignments in project");
|
|
aggregate_alignments_with_project.setRelatingObject(project);
|
|
aggregate_alignments_with_project.setRelatedObjects({alignment});
|
|
|
|
// Define the spatial structure of the alignment with respect to the site
|
|
|
|
// IFC 4.1.5.1 alignment is referenced in spatial structure of an IfcSpatialElement. In this case IfcSite is the highest level IfcSpatialElement
|
|
// https://standards.buildingsmart.org/IFC/RELEASE/IFC4_3/HTML/concepts/Object_Connectivity/Alignment_Spatial_Reference/content.html
|
|
// IfcSite <-> IfcRelReferencedInSpatialStructure <-> IfcAlignment
|
|
// This means IfcAlignment is not part of the IfcSite (it is not an aggregate component) but instead IfcAlignment is used within
|
|
// the IfcSite by reference. This implies an IfcAlignment can traverse many IfcSite instances within an IfcProject
|
|
// Complete the model by creating sites for the 3 bridges
|
|
for (int i = 1; i <= 3; i++) {
|
|
std::ostringstream os;
|
|
os << "Site of Bridge " << i;
|
|
auto site = file.addSite(project);
|
|
site.setName(os.str());
|
|
|
|
std::ostringstream description;
|
|
description << "Alignments referenced into the spatial structure of Bridge Site " << i;
|
|
|
|
auto rel_referenced_in_spatial_structure = file.create<Schema::IfcRelReferencedInSpatialStructure>();
|
|
rel_referenced_in_spatial_structure.setGlobalId(ifcopenshell::global_id());
|
|
rel_referenced_in_spatial_structure.setDescription(description.str());
|
|
rel_referenced_in_spatial_structure.setRelatedElements(std::vector<Schema::IfcSpatialReferenceSelect>{alignment});
|
|
rel_referenced_in_spatial_structure.setRelatingStructure(site);
|
|
}
|
|
|
|
// That's it - save the model to a file
|
|
std::ofstream ofs("FHWA_Bridge_Geometry_Alignment_Example_Simplified.ifc");
|
|
ofs << file;
|
|
}
|