/* * Copyright (c) 1991-2023 by STEP Tools Inc. * All Rights Reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation is hereby granted, provided that this copyright * notice and license appear on all copies of the software. * * STEP TOOLS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. STEP TOOLS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. * * Author: Dave Loffredo (loffredo@steptools.com) */ #include #include // some utilities for making ifc data #include "make_guid.h" #include "make_history.h" #include "make_units.h" // BUILD GEOMETRY - This IFC "hello world" program creates a building // then attaches simple 1x4x9 block shape representation. Use this as // the starting point for a more sophisticated program. // This program writes a Part 21 file called "output_file.ifc". You // can look at this text file with a text editor or STEP Part 21 file // browser to see how the information is represented. IfcShapeRepresentation * create_block_shape( IfcRepresentationContext * ctx ); IfcProject * create_project ( IfcRepresentationContext * ctx ); IfcBuilding * create_building_with_geometry( IfcShapeRepresentation * rep ); IfcRelAggregates * create_rel_aggregates( IfcObjectDefinition * relating ); // some utility functions IfcCartesianPoint * make_point ( RoseDesign * d, double x, double y, double z ); IfcRepresentationContext * make_geometry_context( RoseDesign * d ); int main(int /*argc*/, char** /*argv*/) { ifclib_init(); // force optimizing linkers to use all C++ classes // Make create a RoseDesign to hold the data RoseDesign * design = new RoseDesign ("output_file.ifc"); // Fill in some file header information design-> initialize_header(); design-> header_name()-> originating_system ("IFC Hello World"); design-> header_description()-> description ()-> add ("Empty Project Sample File"); // Make one shared representation context that gives the origin, // precision information, and the number of dimensions. See the // function below for the details. // IfcRepresentationContext * ctx = make_geometry_context (design); // Make some ifc geometry to describe the building shape IfcShapeRepresentation * shape = create_block_shape (ctx); // Make a building with the shape representation IfcBuilding * bldg = create_building_with_geometry (shape); // Create the project instance for the file, then attach the // building as a child in the spatial structure // IfcProject * proj = create_project (ctx); IfcRelAggregates * rel = create_rel_aggregates (proj); rel-> RelatedObjects()-> add(bldg); design-> save(); return 0; } IfcShapeRepresentation * create_block_shape( IfcRepresentationContext * ctx ) { // CREATE A BLOCK SHAPE REPRESENTATION - Make and fill a // representation with geometry items that describe a block shape // for a building. // // create in the same design as the context RoseDesign * d = ctx-> design(); IfcShapeRepresentation * rep = pnewIn(d) IfcShapeRepresentation; rep-> RepresentationIdentifier ("Body"); rep-> RepresentationType ("SweptSolid"); rep-> ContextOfItems (ctx); // Create a faceted brep 2001 Space Odyssey monolith with // height=9, width=4, and thickness=1 IfcCartesianPoint * origin = make_point (d, 0,0,0); // Define a rectangular profile IfcRectangleProfileDef * prof = pnewIn(d) IfcRectangleProfileDef; prof-> ProfileType(IfcProfileTypeEnum_AREA); prof-> ProfileName(""); prof-> Position (pnewIn(d) IfcAxis2Placement2D); prof-> Position()-> Location(origin); prof-> XDim (4.0); prof-> YDim (1.0); // sweep in the positive Z direction IfcDirection * dir = pnewIn(d) IfcDirection; dir-> DirectionRatios()-> add(0.0); dir-> DirectionRatios()-> add(0.0); dir-> DirectionRatios()-> add(1.0); // Solid that puts all of the pieces together IfcExtrudedAreaSolid * sol = pnewIn(d) IfcExtrudedAreaSolid; sol-> SweptArea (prof); sol-> Position (pnewIn(d) IfcAxis2Placement3D); sol-> Position()-> Location(origin); sol-> ExtrudedDirection (dir); sol-> Depth (9); // add the solid to the representation rep-> Items()-> add (sol); return rep; } IfcProject * create_project ( IfcRepresentationContext * ctx ) { // CREATE A PROJECT - Create the project object for the file, // assign the units for the file, and geometry context. // // create in the same design as the context RoseDesign * d = ctx-> design(); IfcProject * p = pnewIn(d) IfcProject(); assign_ifc_guid (p); assign_ifc_owner_history (p); p-> Name ("project"); p-> RepresentationContexts()-> add (ctx); // Declare units so we know what the numbers in the geometry mean. // See the make_units.cxx file for details. // IfcUnitAssignment * units = make_units(d); p-> UnitsInContext (units); return p; } IfcBuilding * create_building_with_geometry( IfcShapeRepresentation * rep ) { // CREATE THE BUILDING - Create a building object, and fill it in // with some sample information // // create in the same design as the shape rep RoseDesign * d = rep-> design(); IfcBuilding * bldg = pnewIn(d) IfcBuilding(); assign_ifc_guid (bldg); assign_ifc_owner_history (bldg); bldg-> Name ("fortress of solitude"); bldg-> Description ("secret lair"); //---------------------------------------- // ADD SHAPE REPRESENTATION AND ADD LOCAL PLACEMENT // // Attach the shape rep to the building using a product definition // shape instance, which can refer to one or more representations. // bldg-> Representation (pnewIn(d) IfcProductDefinitionShape); bldg-> Representation()-> Representations()-> add (rep); // Create an axis placement that describes the location and // orientation of the building geometry // IfcCartesianPoint* p1 = make_point (d, 0, 0, 0); IfcAxis2Placement3D* ap3d = pnewIn(d) IfcAxis2Placement3D; ap3d-> Location(p1); IfcLocalPlacement * lp = pnewIn(d) IfcLocalPlacement; lp-> PlacementRelTo(NULL); // The placement is referenced through a select type lp-> RelativePlacement (pnewIn(d) IfcAxis2Placement); lp-> RelativePlacement()-> _IfcAxis2Placement3D (ap3d); bldg-> ObjectPlacement(lp); return bldg; } IfcRelAggregates * create_rel_aggregates( IfcObjectDefinition * relating ) { // CREATE AGGREGATES RELATIONSHIP -- Assign the relating pointer // and then return the relationship so that we can add children to // the related attribute // create in the same design as the relating object RoseDesign * d = relating-> design(); IfcRelAggregates * rel = pnewIn(d) IfcRelAggregates(); assign_ifc_guid (rel); assign_ifc_owner_history (rel); rel-> Name (""); rel-> Description (""); rel-> RelatingObject(relating); return rel; } // ------------------------------------------------------------ // ------------------------------------------------------------ // SUPPORT FUNCTIONS -- Adjust these as needed // ------------------------------------------------------------ // ------------------------------------------------------------ IfcRepresentationContext * make_geometry_context( RoseDesign * d ) { // Create a geometric context IfcGeometricRepresentationContext * ctx = pnewIn(d) IfcGeometricRepresentationContext; // A file can have a "Model" context for the 3D view and a "Plan" // context for the 2D view // ctx-> ContextIdentifier ("Model"); ctx-> ContextType ("Design"); ctx-> CoordinateSpaceDimension (3); // geometric uncertainty for points ctx-> Precision (1e-6); // Create a coordinate system origin for the context IfcCartesianPoint* p1 = make_point (d, 0, 0, 0); IfcAxis2Placement3D* ap3d = pnewIn(d) IfcAxis2Placement3D; ap3d-> Location(p1); // The placement is referenced through a select type ctx-> WorldCoordinateSystem (pnewIn(d) IfcAxis2Placement); ctx-> WorldCoordinateSystem()-> _IfcAxis2Placement3D (ap3d); return ctx; } IfcCartesianPoint * make_point ( RoseDesign * d, double x, double y, double z ) { IfcCartesianPoint * pt = pnewIn(d) IfcCartesianPoint; pt-> Coordinates()->add(x); pt-> Coordinates()->add(y); pt-> Coordinates()->add(z); return pt; }