Compare commits

..

76 Commits

Author SHA1 Message Date
Thomas Krijnen ba00526e1b Update documentation for filename change 2014-11-05 18:15:27 +01:00
Yorik van Havre e744ba404e Renamed ifc.py to ifcopenshell.py and made it installable 2014-07-29 11:26:49 -03:00
Yorik van Havre eb39eeb30b Added a function to add a new entity without inserting it into the ifc file 2014-07-25 18:03:40 -03:00
Yorik van Havre 286e9d183a Made ifc.py compatible with python2 2014-07-20 12:43:10 -03:00
Thomas Krijnen d4e4ca3a2a Add id() and is_a() functions to entity_instance class Make filename argument to open() function optional 2014-07-19 13:57:47 +02:00
Thomas Krijnen f7adeb9cc1 parse units and precision when a file is opened from the python interface 2014-07-10 16:51:26 +02:00
Thomas Krijnen 607f7bd015 Update CMakeLists for new SWIG module name 2014-07-07 13:52:39 +02:00
Thomas Krijnen bd00d3287e Add missing #include 2014-07-07 13:42:00 +02:00
Thomas Krijnen f674493843 Fixed retrieving attributes derived in subtype Convert argument type enumeration to python string Add ability to iterate over all instances from python 2014-07-04 16:37:21 +02:00
Thomas Krijnen dbc60bedd6 Update install directives in cmake script for wrapper 2014-07-04 14:10:35 +02:00
Thomas Krijnen f7f949b37b Qualify typename rather than 'auto' keyword 2014-07-02 11:53:44 +02:00
Thomas Krijnen 31ca1ac1b5 IfcConvert segfaults #12 2014-07-02 11:53:03 +02:00
Ivano Ras 99d83fce42 Update README.md 2014-06-27 15:11:27 +02:00
Thomas Krijnen 4158424c25 Wrap values of attributes that return entity instances 2014-06-26 15:13:11 +02:00
Thomas Krijnen 1d8616883c Missing file for more idiomatic wrapper wrapper 2014-06-21 19:02:51 +02:00
Thomas Krijnen 8851641d94 Add more idiomatic wrapper wrapper 2014-06-20 14:18:29 +02:00
Thomas Krijnen 0a7b1dd7f4 Merge pull request #13 from iras/patch-1 2014-06-26 16:52:13 +02:00
Thomas Krijnen bb2a983a00 Expose the option to sew shells from connected face sets 2014-06-08 19:32:25 +02:00
Thomas Krijnen 604358b48e Increase precision for writing floats 2014-06-07 14:28:30 +02:00
Thomas Krijnen 68e60f0586 Fix serialization of simple type attributes 2014-06-07 11:47:26 +02:00
Thomas Krijnen e4f141b107 Fixes for inverse attributes 2014-06-03 18:50:29 +02:00
Thomas Krijnen fe172672e9 Add function to retrieve inverse attributes from Python 2014-06-03 16:33:38 +02:00
aothms 69a27e3591 More fixes for parsing files with comments 2014-04-19 09:35:08 +00:00
Thomas Krijnen d91e5d31f6 DISABLE_OPENING_SUBTRACTIONS and DISABLE_OBJECT_PLACEMENT settings for create_shape() / create_brep_data() 2014-04-17 10:50:42 +02:00
aothms a4c3fdfd18 Add support for IfcSweptDiskSolid 2014-04-16 16:51:03 +00:00
aothms b235320d8c Process IfcStyledItems directly applied to an IfcFacetedBrep 2014-04-09 10:57:45 +00:00
aothms e9a3464c26 Account for unit magnitude in matrix translation part when CONVERT_BACK_UNITS is enabled 2014-04-08 07:28:07 +00:00
aothms e08db74706 Fix product's 4x4 matrix on the IfcGeomServer 2014-04-07 17:59:20 +00:00
aothms 3a971d63f8 When writing collada files, postfix geometry instance nodes to make them distinct from their geometry library references 2014-04-07 14:01:16 +00:00
aothms 9a75a1f12d IfcGeomServer, small fixes: refrain from using auto type and restore std::cout rdbuf on exit so implicit flush doesn't segfault 2014-04-06 12:50:51 +00:00
aothms 64f88cbf25 Revamp the 'IfcGeomServer' idea to have an executable rather than a library to interface with. This way IFC processing runs in a separate process from the client application, so that crashes or out of memory issues do not bring down the client application. 2014-04-06 11:16:20 +00:00
aothms ca66aac1c1 Increased verbosity in unsupported entity instances 2014-04-02 15:28:04 +00:00
aothms 9262ea1890 Fixes for parsing files with comments 2014-04-02 15:04:09 +00:00
aothms 81537bee95 Measure conversion time of IfcConvert more faithfully 2014-03-31 14:03:06 +00:00
aothms f9e94f5e01 IfcSurfaceCurveSweptAreaSolid improvements 2014-03-31 14:00:02 +00:00
aothms 691e5766c4 Take into account face location when serializing shape as tesselated faceset. 2014-03-22 21:13:02 +00:00
aothms 0770d91a3c IfcConvert: Handle invalid command line options gracefully and notify user 2014-03-22 13:12:22 +00:00
aothms f3531276c8 No longer accept and silently convert invalid REAL tokens to zero 2014-03-22 13:02:21 +00:00
aothms ffe1eddb00 Handle missing or invalid unit and precision information more gracefully during IfcGeomObject initialization 2014-03-22 12:56:08 +00:00
aothms ba0ba1973a For .obj conversion terminate lines with "\n" rather than std::endl causing a significant speed increase due to longer intermittently flushing the stream 2014-03-22 11:12:50 +00:00
aothms b4e1b15da5 Add support for IfcBooleanResult, IfcBlock, IfcRectangularPyramid, IfcRightCircularCylinder, IfcRightCircularCone, IfcSphere, IfcCsgSolid, IfcCurveBoundedPlane, IfcRectangularTrimmedSurface, IfcSurfaceCurveSweptAreaSolid, IfcCylindricalSurface. Add CSG example. 2014-03-22 10:31:51 +00:00
aothms a2b2add58f Add missing header to installation files. Thanks Fred. 2014-03-22 09:22:27 +00:00
aothms c70517f3ba Update build scripts to include TKOffset 2014-03-19 09:47:24 +00:00
aothms d79e28157f Add example file to generate file with IfcCompositeProfileDef and IfcDerivedProfileDef 2014-03-16 13:35:14 +00:00
aothms 4a36816f8f Support for IfcCompositeProfileDef and IfcDerivedProfileDef 2014-03-16 13:34:01 +00:00
aothms 83ac741b59 Add support for IfcGeometricSet IfcRevolvedAreaSolid IfcSurfaceOfLinearExtrusion IfcSurfaceOfRevolution IfcCenterLineProfileDef IfcArbitraryOpenProfileDef 2014-03-15 11:51:23 +00:00
aothms 2fb4be2edc Implementations for more parameterized profile definitions 2014-03-08 17:21:39 +00:00
aothms 868bd6efc8 Add support for ellipses with SemiAxis2 > SemiAxis1 2014-03-03 19:07:39 +00:00
aothms 27e18386d2 Add parameterized profile test files and script to generate them 2014-02-23 11:25:35 +00:00
Thomas Krijnen 562210b862 Fix for products with openings 2014-04-12 23:20:21 +02:00
Yorik van Havre 39b3e03fc5 Added a clean() function to the python wrapper 2014-04-11 15:24:41 -03:00
Thomas Krijnen ba7eec2c0b Fix for empty shape reps 2014-02-26 10:56:22 +01:00
Thomas Krijnen 357357ad78 Initialise string to type map 2014-02-26 10:12:25 +01:00
Yorik van Havre b3bf86e697 Fixes includes for building on Linux 2014-02-24 20:54:48 -03:00
Thomas Krijnen 6b65402611 Merge developments from master into the python_wrapper branch 2014-02-22 11:38:03 +01:00
aothms c7355f03e7 Add Boost as a required dependency in the CMake build file 2012-11-04 11:04:55 +00:00
aothms 5274d73fd0 Add an option to disable the subtraction of IfcOpeningElements from relating building elements to the IfcGeomObject settings 2012-10-19 08:20:43 +00:00
Yorik van Havre 88f6242804 Allowed to enter booleans as arguments, and removed unused line that cause compilation error 2013-12-13 16:22:37 -02:00
Yorik van Havre e936ba8391 Fix for building with gcc 2013-08-02 11:48:26 -03:00
Thomas Krijnen 9136b83223 Accept list of entity instances from Python 2013-07-27 15:55:23 -07:00
Thomas Krijnen 4987753a47 Allow setting enumeration values from python based on string 2013-07-23 23:17:37 -07:00
Thomas Krijnen 871ee13e05 Merge branch 'master' of https://github.com/aothms/IfcOpenShell.git 2013-07-22 20:09:38 -07:00
Yorik van Havre 9c4040345a Merge branch 'master' of https://github.com/aothms/IfcOpenShell 2013-07-22 15:41:10 -03:00
Thomas Krijnen aa4f6c0a7b Merge pull request #1 from yorikvanhavre/master 2013-07-21 14:10:52 -07:00
Yorik van Havre 5471f345d8 Fixed character encoding bug 2013-07-22 15:38:37 -03:00
Yorik van Havre 9679d450fc Fixed string conversion error 2013-07-21 13:41:27 -03:00
Yorik van Havre d8d221dce3 Merge branch 'master' of https://github.com/aothms/IfcOpenShell 2013-07-21 13:31:24 -03:00
Yorik van Havre ed5f879b9f Merge pull request #1 from aothms/master 2012-10-30 04:47:28 -07:00
Thomas Krijnen 3bc3331983 Increase reference count when returning Py_None 2013-07-22 20:06:52 -07:00
Thomas Krijnen 10657416ea Allow optional arguments to be set from Python with None, e.g: ifc_person.set_argument(0, None) 2013-07-20 13:51:06 -07:00
Thomas Krijnen e5abdb7de8 Fix for inline entity instance regression 2013-07-09 09:04:33 -07:00
Thomas Krijnen 7b57c8b5b3 Merge branch 'master' of https://github.com/aothms/IfcOpenShell 2013-07-09 09:01:06 -07:00
Thomas Krijnen 22563f7283 Use a char* instead of a std::string for the std::ofstream constructor 2013-06-21 10:25:05 -07:00
Thomas Krijnen d35e775407 Return empty list when for ifc datatypes not encountered in file 2013-07-09 08:57:09 -07:00
Thomas Krijnen a5684f0996 Correctly take inline entity instances for select types into account in the Python wrapper 2013-06-21 08:49:08 -07:00
Thomas Krijnen 509c34d66a Initial attempt at new python wrapper 2012-10-21 17:54:09 +02:00
89 changed files with 96694 additions and 11320 deletions
-165
View File
@@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
-65
View File
@@ -1,65 +0,0 @@
IfcOpenShell
============
open source (LGPL) software library for working with the IFC file format
http://IfcOpenShell.org
Compiling on Windows
====================
Users are advised to use the Visual Studio .sln file in the win/ folder.
For Windows users a prebuilt Open CASCADE version is available from the
http://opencascade.org website. Download and install this version and
provide the paths to the Open CASCADE header and library files to MS
Visual Studio C++.
For building the Autodesk 3ds Max plugin, the 3ds Max SDK needs to be
installed as well as 3ds Max itself. Please provide the include and
library paths to Visual Studio.
For building the IfcPython wrapper, SWIG needs to be installed. Please
download the latest swigwin version from http://www.swig.org/download.html.
After extracting the .zip file, please add the extracted folder to the PATH
environment variable. Python needs to be installed, please provide the
include and library paths to Visual Studio.
Compiling on *nix
====================
Users are advised to build IfcOpenShell using the cmake file provided in
the cmake/ folder. There might be an Open CASCADE package in your operating
system's software repository. If not, you will need to compile Open
CASCADE yourself. See http://opencascade.org.
For building the IfcPython wrapper, SWIG and Python development are
required.
To build IfcOpenShell please take the following steps:
$ cd /path/to/IfcOpenShell/cmake
$ mkdir build
$ cd build
Optionally:
$ OCC_INCLUDE_PATH="/path/to/OpenCASCADE/include"
$ OCC_LIBRARY_PATH="/path/to/OpenCASCADE/lib"
$ export OCC_INCLUDE_PATH
$ export OCC_LIBRARY_PATH
$ cmake ../
$ make
If all worked out correctly you can now use IfcOpenShell. For example:
$ wget ftp://ftp.dds.no/pub/ifc/Munkerud/Munkerud_hus6_BE.zip
$ unzip Munkerud_hus6_BE.zip
$ ./IfcObj Munkerud_hus6_BE.ifc
$ less Munkerud_hus6_BE.obj
Or:
$ wget ftp://ftp.dds.no/pub/ifc/Munkerud/Munkerud_hus6_BE.zip
$ unzip Munkerud_hus6_BE.zip
$ python
>>> import IfcImport
>>> IfcImport.Init('Munkerud_hus6_BE.ifc')
>>> geom = IfcImport.Get()
>>> geom.name
>>> for v in geom.mesh.verts: v
+132
View File
@@ -0,0 +1,132 @@
IfcOpenShell
============
open source (LGPL) software library for working with the IFC file format
http://IfcOpenShell.org
About this repository
=====================
This is an initiative to expose the functionality of IfcOpenShell for parsing and writing IFC files to a Python interface. The creation of a topological representation for building elements using Open Cascade is also wrapped by returning a string serialization of the Open Cascade TopoDS_Shape. Using SWIG, a wrapper is obtained for a C++ Class which evaluates its Express attribute names at runtime. The functions created by the SWIG wrapper closely resemble the C++ structure. An additional Python wrapper around these functions is created that is more idiomatic to Python.
The following interactive session illustrates its use:
>>> import ifcopenshell
>>> f = ifcopenshell.open("Duplex_A_20110907_optimized.ifc")
>>> f.by_type("ifcwall")[:2]
[#91=IfcWallStandardCase('2O2Fr$t4X7Zf8NOew3FL9r',#1,'Basic Wall:Interior - Partition (92mm Stud):144586',$,'Basic Wall:Interior - Partition (92mm Stud):128360',#5198,#18806,'144586'), #92=IfcWallStandardCase('2O2Fr$t4X7Zf8NOew3FLIE',#1,'Basic Wall:Interior - Partition (92mm Stud):143921',$,'Basic Wall:Interior - Partition (92mm Stud):128360',#5206,#18805,'143921')]
>>> wall = _[0]
>>> brep_data = ifcopenshell.create_shape(wall, ifcopenshell.SEW_SHELLS)
>>> len(wall) # number of EXPRESS attributes
8
>>> wall.GlobalId
'2O2Fr$t4X7Zf8NOew3FL9r'
>>> wall.Name = "My wall"
>>> wall.NonExistingAttr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\ifcopenshell.py", line 14, in __getattr__
except: raise AttributeError("entity instance of type '%s' has no attribute'%s'"%(self.wrapped_data.is_a(), name)) from None
AttributeError: entity instance of type 'IfcWallStandardCase' has no attribute 'NonExistingAttr'
>>> wall.GlobalId = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".\ifcopenshell.py", line 26, in __setattr__
self[self.wrapped_data.get_argument_index(key)] = value
File ".\ifcopenshell.py", line 30, in __setitem__
self.wrapped_data.set_argument(idx, entity_instance.map_value(value))
File ".\ifc_wrapper.py", line 118, in <lambda>
set_argument = lambda self,x,y: self._set_argument(x) if y is None else self
._set_argument(x,y)
File ".\ifc_wrapper.py", line 114, in _set_argument
def _set_argument(self, *args): return _ifc_wrapper.entity_instance__set_argument(self, *args)
RuntimeError: INT is not a valid type for 'GlobalId'
>>> f.createIfcCartesianPoint(Coordinates=(1.0,1.5,2.0))
#27530=IfcCartesianPoint((1.,1.5,2.))
>>> import uuid
>>> ifcopenshell.guid.compress(uuid.uuid1().hex)
'3x4C8Q_6qHuv$P$FYkANRX'
>>> new_guid = _
>>> owner_hist = f.by_type("IfcOwnerHistory")[0]
>>> new_wall = f.createIfcWallStandardCase(new_guid, owner_hist, None, None, Tag='my_tag')
>>> new_wall.ObjectType = ''
>>> new_wall.ObjectPlacement = new_wall.Representation = None
>>> f[92]
#92=IfcWallStandardCase('2O2Fr$t4X7Zf8NOew3FLIE',#1,'Basic Wall:Interior - Partition (92mm Stud):143921',$,'Basic Wall:Interior - Partition (92mm Stud):128360',#5206,#18805,'143921')
>>> f['2O2Fr$t4X7Zf8NOew3FLIE']
#92=IfcWallStandardCase('2O2Fr$t4X7Zf8NOew3FLIE',#1,'Basic Wall:Interior - Partition (92mm Stud):143921',$,'Basic Wall:Interior - Partition (92mm Stud):128360',#5206,#18805,'143921')
>>> f.write("out.ifc")
Compiling on Windows
====================
Users are advised to use the Visual Studio .sln file in the win/ folder.
For Windows users a prebuilt Open CASCADE version is available from the
http://opencascade.org website. Download and install this version and
provide the paths to the Open CASCADE header and library files to MS
Visual Studio C++.
For building the Autodesk 3ds Max plugin, the 3ds Max SDK needs to be
installed as well as 3ds Max itself. Please provide the include and
library paths to Visual Studio.
For building the IfcPython wrapper, SWIG needs to be installed. Please
download the latest swigwin version from http://www.swig.org/download.html.
After extracting the .zip file, please add the extracted folder to the PATH
environment variable. Python needs to be installed, please provide the
include and library paths to Visual Studio.
Compiling on *nix
====================
Users are advised to build IfcOpenShell using the cmake file provided in
the cmake/ folder. There might be an Open CASCADE package in your operating
system's software repository. If not, you will need to compile Open
CASCADE yourself. See http://opencascade.org.
For building the IfcPython wrapper, SWIG and Python development are
required.
To build IfcOpenShell please take the following steps:
$ cd /path/to/IfcOpenShell/cmake
$ mkdir build
$ cd build
Optionally:
$ OCC_INCLUDE_PATH="/path/to/OpenCASCADE/include"
$ OCC_LIBRARY_PATH="/path/to/OpenCASCADE/lib"
$ export OCC_INCLUDE_PATH
$ export OCC_LIBRARY_PATH
$ cmake ../
$ make
Ubuntu Notes
============
The following sequence of commands has been tested successfully on Ubuntu 14.04.
OCE installation. This step worked OK with cmake 2.8.12.2, gcc 4.8.2, g++ 4.8.2. Also, it might take up to an hour to complete.
apt-get install git cmake gcc g++ libftgl-dev libtbb2 libtbb-dev libboost-all-dev
cd /
mkdir git && cd git
git clone https://github.com/tpaviot/oce.git
mkdir oceBuild && cd oceBuild
cmake ../oce
make -j4
sudo make install
IfcOpenShell installation. This step worked OK with cmake 2.8.12.2, gcc 4.8.2, g++ 4.8.2.
apt-get install swig
cd /git/
git clone https://github.com/aothms/IfcOpenShell.git
cd IfcOpenShell/cmake
mkdir build && cd build
cmake ../
make -j4
Once done, IfcConvert is to be found in the build folder.
+21 -2
View File
@@ -125,6 +125,7 @@ INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCL
ADD_LIBRARY(IfcParse STATIC
../src/ifcparse/Ifc2x3.cpp
../src/ifcparse/Ifc4.cpp
../src/ifcparse/IfcUtil.cpp
../src/ifcparse/IfcParse.cpp
../src/ifcparse/IfcCharacterDecoder.cpp
@@ -132,7 +133,11 @@ ADD_LIBRARY(IfcParse STATIC
../src/ifcparse/IfcWrite.cpp
../src/ifcparse/IfcGuidHelper.cpp
../src/ifcparse/IfcHierarchyHelper.cpp
../src/ifcparse/IfcHierarchyHelper.cpp
../src/ifcparse/Ifc2x3-rt.cpp
../src/ifcparse/Ifc4-rt.cpp
../src/ifcparse/IfcUntypedEntity.cpp
)
ADD_LIBRARY(IfcGeom STATIC
@@ -162,7 +167,13 @@ ADD_EXECUTABLE(IfcConvert
../src/ifcconvert/WavefrontObjSerializer.cpp
)
TARGET_LINK_LIBRARIES (IfcConvert IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES})
TARGET_LINK_LIBRARIES (IfcConvert IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES TKOffset ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES})
ADD_EXECUTABLE(IfcGeomServer
../src/ifcgeomserver/IfcGeomServer.cpp
)
TARGET_LINK_LIBRARIES (IfcGeomServer IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKSTEP TKSTEPBase TKSTEPAttr TKXSBase TKSTEP209 TKIGES TKOffset)
# Build python wrapper using separate CMakeLists.txt
ADD_SUBDIRECTORY(../src/ifcwrap ifcwrap)
@@ -189,11 +200,14 @@ SET(include_files_geom
../src/ifcgeom/IfcRegisterIsShapeCollection.h
../src/ifcgeom/IfcRegisterPurgeCache.h
../src/ifcgeom/IfcRegisterUndef.h
../src/ifcgeom/IfcGeomRenderStyles.h
../src/ifcgeom/IfcRepresentationShapeItem.h
)
SET(include_files_parse
../src/ifcparse/Ifc2x3.h
../src/ifcparse/Ifc2x3enum.h
../src/ifcparse/Ifc4.h
../src/ifcparse/Ifc4enum.h
../src/ifcparse/IfcCharacterDecoder.h
../src/ifcparse/IfcException.h
../src/ifcparse/IfcFile.h
@@ -204,6 +218,11 @@ SET(include_files_parse
../src/ifcparse/IfcWrite.h
../src/ifcparse/IfcWritableEntity.h
../src/ifcparse/Ifc2x3-rt.h
../src/ifcparse/Ifc4-rt.h
../src/ifcparse/IfcUntypedEntity.h
../src/ifcparse/IfcEntityDescriptor.h
)
INSTALL(FILES ${include_files_geom} DESTINATION include/ifcgeom)
INSTALL(FILES ${include_files_parse} DESTINATION include/ifcparse)
+1 -1
View File
@@ -2,4 +2,4 @@ ADD_EXECUTABLE(IfcParseExamples IfcParseExamples.cpp)
TARGET_LINK_LIBRARIES (IfcParseExamples IfcParse)
ADD_EXECUTABLE(IfcOpenHouse IfcOpenHouse.cpp)
TARGET_LINK_LIBRARIES (IfcOpenHouse IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet)
TARGET_LINK_LIBRARIES (IfcOpenHouse IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKOffset)
+170 -76
View File
@@ -31,7 +31,12 @@
#include <Standard_Version.hxx>
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
#include "../ifcparse/Ifc2x3.h"
#endif
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
#include "../ifcgeom/IfcGeom.h"
@@ -53,7 +58,7 @@ int main(int argc, char** argv) {
file.filename("IfcOpenHouse.ifc");
// Start by adding a wall to the file, initially leaving most attributes blank.
Ifc2x3::IfcWallStandardCase* south_wall = new Ifc2x3::IfcWallStandardCase(
IfcSchema::IfcWallStandardCase* south_wall = new IfcSchema::IfcWallStandardCase(
guid(), // GlobalId
0, // OwnerHistory
S("South wall"), // Name
@@ -62,6 +67,9 @@ int main(int argc, char** argv) {
0, // ObjectPlacement
0, // Representation
null // Tag
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(south_wall);
@@ -70,13 +78,13 @@ int main(int argc, char** argv) {
// Lateron changing the name of the IfcProject can be done by obtaining a reference to the
// project, which has been created automatically.
file.getSingle<Ifc2x3::IfcProject>()->setName("IfcOpenHouse");
file.getSingle<IfcSchema::IfcProject>()->setName("IfcOpenHouse");
// An IfcOwnerHistory has been initialized as well, which should be assigned to the wall.
south_wall->setOwnerHistory(file.getSingle<Ifc2x3::IfcOwnerHistory>());
south_wall->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
// The wall will be shaped as a box, with the dimensions specified in millimeters.
Ifc2x3::IfcProductDefinitionShape* south_wall_shape = file.addBox(10000, 360, 3000);
IfcSchema::IfcProductDefinitionShape* south_wall_shape = file.addBox(10000, 360, 3000);
// The shape has to be assigned to the representation of the wall and is placed at the origin
// of the coordinate system.
@@ -84,59 +92,67 @@ int main(int argc, char** argv) {
south_wall->setObjectPlacement(file.addLocalPlacement());
// A pale white colour is assigned to the wall.
Ifc2x3::IfcPresentationStyleAssignment* wall_colour = file.setSurfaceColour(
IfcSchema::IfcPresentationStyleAssignment* wall_colour = file.setSurfaceColour(
south_wall->Representation(), 0.75, 0.73, 0.68);
// Now create a footing for the wall to rest on.
Ifc2x3::IfcFooting* footing = new Ifc2x3::IfcFooting(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
S("Footing"), null, null, 0, 0, null, Ifc2x3::IfcFootingTypeEnum::IfcFootingType_STRIP_FOOTING);
IfcSchema::IfcFooting* footing = new IfcSchema::IfcFooting(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
S("Footing"), null, null, 0, 0, null, IfcSchema::IfcFootingTypeEnum::IfcFootingType_STRIP_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, 0, 0, 0, file.getSingle<Ifc2x3::IfcRepresentationContext>()));
footing->setRepresentation(file.addBox(10100, 5460, 2000, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()));
footing->setObjectPlacement(file.addLocalPlacement(0, 2500, -2000));
// The footing will have a dark gray colour
Ifc2x3::IfcPresentationStyleAssignment* footing_colour = file.setSurfaceColour(footing->Representation(), 0.26, 0.22, 0.18);
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
Ifc2x3::IfcOpeningElement* west_opening = new Ifc2x3::IfcOpeningElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
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<Ifc2x3::IfcRepresentationContext>()), null);
file.addBox(6000, 3630, 1600, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
file.AddEntity(west_opening);
// Relate the opening element to the wall.
Ifc2x3::IfcRelVoidsElement* void_element = new Ifc2x3::IfcRelVoidsElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
IfcSchema::IfcRelVoidsElement* void_element = new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, south_wall, west_opening);
file.AddEntity(void_element);
// Now create an additional opening
Ifc2x3::IfcOpeningElement* south_opening = new Ifc2x3::IfcOpeningElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
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<Ifc2x3::IfcRepresentationContext>()), null);
file.addBox(1860, 3000, 1600, 0, 0, 0, file.getSingle<IfcSchema::IfcRepresentationContext>()), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
file.AddEntity(south_opening);
file.AddEntity(new Ifc2x3::IfcRelVoidsElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null, south_wall, south_opening));
file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null, null, south_wall, south_opening));
// Create a roof element
Ifc2x3::IfcRoof* south_roof = new Ifc2x3::IfcRoof(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), S("South roof"), null, null,
0, 0, null, Ifc2x3::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
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<Ifc2x3::IfcDirection>(0, -sqrt(0.5), sqrt(0.5)), file.getSingle<Ifc2x3::IfcRepresentationContext>()));
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);
// 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
Ifc2x3::IfcRoof* north_roof = new Ifc2x3::IfcRoof(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), S("North roof"),
null, null, 0, 0, null, Ifc2x3::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
north_roof->setOwnerHistory(file.getSingle<Ifc2x3::IfcOwnerHistory>());
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);
@@ -146,12 +162,20 @@ int main(int argc, char** argv) {
file.setSurfaceColour(south_roof->Representation(), 0.24, 0.08, 0.04);
// Copy the south wall to the north
file.addBuildingProduct(new Ifc2x3::IfcWallStandardCase(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), S("North wall"),
null, null, file.addLocalPlacement(0, 5000, 0), south_wall->Representation(), null));
file.addBuildingProduct(new IfcSchema::IfcWallStandardCase(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), S("North wall"),
null, null, file.addLocalPlacement(0, 5000, 0), south_wall->Representation(), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
));
// Now create a wall on the east of the building, again starting with just a box shape
Ifc2x3::IfcWallStandardCase* east_wall = new Ifc2x3::IfcWallStandardCase(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
S("East wall"), null, null, file.addLocalPlacement(4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addBox(5000, 360, 6000), null);
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
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(east_wall);
// The east wall geometry is clipped using two IfcHalfSpaceSolids, created from an
@@ -162,8 +186,12 @@ int main(int argc, char** argv) {
file.setSurfaceColour(east_wall->Representation(), wall_colour);
// The east wall is copied to the west location of the house
Ifc2x3::IfcWallStandardCase* west_wall = new Ifc2x3::IfcWallStandardCase(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
S("West wall"), null, null, file.addLocalPlacement(-4820, 2500, 0, 0, 0, 1, 0, -1, 0), east_wall->Representation(), null);
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
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(west_wall);
// The west wall is assigned an opening element we created for the south wall, opening elements are
@@ -171,10 +199,14 @@ int main(int argc, char** argv) {
// 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
Ifc2x3::IfcOpeningElement* west_opening_copy = new Ifc2x3::IfcOpeningElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
null, null, null, west_opening->ObjectPlacement(), west_opening->Representation(), null);
IfcSchema::IfcOpeningElement* west_opening_copy = new IfcSchema::IfcOpeningElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, west_opening->ObjectPlacement(), west_opening->Representation(), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
file.AddEntity(west_opening_copy);
file.AddEntity(new Ifc2x3::IfcRelVoidsElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null, west_wall, west_opening_copy));
file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null, null, west_wall, 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
@@ -182,12 +214,12 @@ int main(int argc, char** argv) {
TopoDS_Shape shape;
createGroundShape(shape);
IfcEntities geometrical_entities(new IfcEntityList());
Ifc2x3::IfcProductDefinitionShape* ground_representation = IfcGeom::tesselate(shape, 100., geometrical_entities);
file.getSingle<Ifc2x3::IfcSite>()->setRepresentation(ground_representation);
IfcSchema::IfcProductDefinitionShape* ground_representation = IfcGeom::tesselate(shape, 100., geometrical_entities);
file.getSingle<IfcSchema::IfcSite>()->setRepresentation(ground_representation);
file.AddEntities(geometrical_entities);
Ifc2x3::IfcShapeRepresentation::list ground_reps = geometrical_entities->as<Ifc2x3::IfcShapeRepresentation>();
for (Ifc2x3::IfcShapeRepresentation::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
(*it)->setContextOfItems(file.getSingle<Ifc2x3::IfcRepresentationContext>());
IfcSchema::IfcShapeRepresentation::list ground_reps = geometrical_entities->as<IfcSchema::IfcShapeRepresentation>();
for (IfcSchema::IfcShapeRepresentation::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
(*it)->setContextOfItems(file.getSingle<IfcSchema::IfcRepresentationContext>());
}
file.setSurfaceColour(ground_representation, 0.15, 0.25, 0.05);
@@ -198,18 +230,52 @@ int main(int argc, char** argv) {
// 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.
Ifc2x3::IfcMaterial* material = new Ifc2x3::IfcMaterial("Brick");
Ifc2x3::IfcMaterialLayer* layer = new Ifc2x3::IfcMaterialLayer(material, 360, null);
Ifc2x3::IfcMaterialLayer::list layers (new IfcTemplatedEntityList<Ifc2x3::IfcMaterialLayer>());
#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 layers (new IfcTemplatedEntityList<IfcSchema::IfcMaterialLayer>());
layers->push(layer);
Ifc2x3::IfcMaterialLayerSet* layer_set = new Ifc2x3::IfcMaterialLayerSet(layers, S("Wall"));
Ifc2x3::IfcMaterialLayerSetUsage* layer_usage = new Ifc2x3::IfcMaterialLayerSetUsage(layer_set,
Ifc2x3::IfcLayerSetDirectionEnum::IfcLayerSetDirection_AXIS2,
Ifc2x3::IfcDirectionSenseEnum::IfcDirectionSense_POSITIVE, -180);
IfcSchema::IfcMaterialLayerSet* layer_set = new IfcSchema::IfcMaterialLayerSet(
layers,
S("Wall")
#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
);
Ifc2x3::IfcRelAssociatesMaterial* associates_material = new Ifc2x3::IfcRelAssociatesMaterial(guid(),
file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null,
file.EntitiesByType<Ifc2x3::IfcWallStandardCase>()->as<Ifc2x3::IfcRoot>(), layer_usage);
IfcSchema::IfcRelAssociatesMaterial* associates_material = new IfcSchema::IfcRelAssociatesMaterial(
guid(),
file.getSingle<IfcSchema::IfcOwnerHistory>(),
null,
null,
#ifdef USE_IFC4
file.EntitiesByType<IfcSchema::IfcWallStandardCase>()->generalize(),
#else
file.EntitiesByType<IfcSchema::IfcWallStandardCase>()->as<IfcSchema::IfcRoot>(),
#endif
layer_usage);
file.AddEntity(material);
file.AddEntity(layer);
@@ -226,30 +292,44 @@ int main(int argc, char** argv) {
stair_points.push_back(XY(500, 200));
stair_points.push_back(XY(500, 400));
stair_points.push_back(XY( 0, 400));
Ifc2x3::IfcStairFlight* stair = new Ifc2x3::IfcStairFlight(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
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),
file.addExtrudedPolyline(stair_points, 1200), null, 2, 2, 0.2, 0.25);
file.addExtrudedPolyline(stair_points, 1200), null, 2, 2, 0.2, 0.25
#ifdef USE_IFC4
, IfcSchema::IfcStairFlightTypeEnum::IfcStairFlightType_STRAIGHT
#endif
);
file.addBuildingProduct(stair);
file.setSurfaceColour(stair->Representation(), footing_colour);
Ifc2x3::IfcOpeningElement* door_opening = new Ifc2x3::IfcOpeningElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
null, null, null, file.addLocalPlacement(5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null);
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
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
file.AddEntity(door_opening);
file.AddEntity(new Ifc2x3::IfcRelVoidsElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null, east_wall, door_opening));
file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null, null, east_wall, 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.
Ifc2x3::IfcDoor* door = new Ifc2x3::IfcDoor(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null, null,
file.addLocalPlacement(4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000);
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
#ifdef USE_IFC4
, IfcSchema::IfcDoorTypeEnum::IfcDoorType_DOOR
, IfcSchema::IfcDoorTypeOperationEnum::IfcDoorTypeOperation_SINGLE_SWING_LEFT
, null
#endif
);
door->setRepresentation(file.addBox(80, 80, 2120, 0, file.addPlacement3d(460, 0, 0)));
Ifc2x3::IfcRepresentation::list door_representations = door->Representation()->Representations();
Ifc2x3::IfcShapeRepresentation* door_body = 0;
for (Ifc2x3::IfcRepresentation::it i = door_representations->begin(); i != door_representations->end(); ++i) {
Ifc2x3::IfcRepresentation* rep = *i;
if (rep->is(Ifc2x3::Type::IfcShapeRepresentation) && rep->RepresentationIdentifier() == "Body") {
door_body = (Ifc2x3::IfcShapeRepresentation*) rep;
IfcSchema::IfcRepresentation::list door_representations = door->Representation()->Representations();
IfcSchema::IfcShapeRepresentation* door_body = 0;
for (IfcSchema::IfcRepresentation::it i = door_representations->begin(); i != door_representations->end(); ++i) {
IfcSchema::IfcRepresentation* rep = *i;
if (rep->is(IfcSchema::Type::IfcShapeRepresentation) && rep->RepresentationIdentifier() == "Body") {
door_body = (IfcSchema::IfcShapeRepresentation*) rep;
}
}
file.addBox(door_body, 80, 80, 2120, 0, file.addPlacement3d(-460, 0, 0));
@@ -257,7 +337,7 @@ int main(int argc, char** argv) {
file.addBox(door_body, 860, 30, 2120);
file.addBuildingProduct(door);
file.setSurfaceColour(door->Representation(), 0.9, 0.9, 0.9);
file.AddEntity(new Ifc2x3::IfcRelFillsElement(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null, null, door_opening, door));
file.AddEntity(new IfcSchema::IfcRelFillsElement(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(), null, null, door_opening, door));
// Surface styles are assigned to representation items, hence there is no real limitation to
// assign different colours within the same representation. However, some viewers have
@@ -270,15 +350,15 @@ 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.
Ifc2x3::IfcProductDefinitionShape::list frame_representations (new IfcTemplatedEntityList<Ifc2x3::IfcProductDefinitionShape>());
IfcSchema::IfcProductDefinitionShape::list 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
// The beams all have the same surface style assigned
Ifc2x3::IfcPresentationStyleAssignment* frame_style = 0;
for (Ifc2x3::IfcProductDefinitionShape::it i = frame_representations->begin(); i != frame_representations->end(); ++i) {
IfcSchema::IfcPresentationStyleAssignment* frame_style = 0;
for (IfcSchema::IfcProductDefinitionShape::it i = frame_representations->begin(); i != frame_representations->end(); ++i) {
if (frame_style) {
file.setSurfaceColour(*i, frame_style);
} else {
@@ -288,49 +368,63 @@ int main(int argc, char** argv) {
// 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.
Ifc2x3::IfcLocalPlacement::list window_placements (new IfcTemplatedEntityList<Ifc2x3::IfcLocalPlacement>());
IfcSchema::IfcLocalPlacement::list 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));
for (Ifc2x3::IfcLocalPlacement::it it = window_placements->begin(); it != window_placements->end(); ++it) {
for (IfcSchema::IfcLocalPlacement::it it = window_placements->begin(); it != window_placements->end(); ++it) {
// Create the window at the current location
Ifc2x3::IfcLocalPlacement* place = *it;
Ifc2x3::IfcWindow* window = new Ifc2x3::IfcWindow(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
null, null, null, place, 0, null, 1600, 1860);
IfcSchema::IfcLocalPlacement* place = *it;
IfcSchema::IfcWindow* window = new IfcSchema::IfcWindow(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, place, 0, null, 1600, 1860
#ifdef USE_IFC4
, IfcSchema::IfcWindowTypeEnum::IfcWindowType_WINDOW
, IfcSchema::IfcWindowTypePartitioningEnum::IfcWindowTypePartitioning_SINGLE_PANEL
, null
#endif
);
file.addBuildingProduct(window);
// Initalize a list of parts for the window to be composed of
Ifc2x3::IfcObjectDefinition::list window_parts(new IfcTemplatedEntityList<Ifc2x3::IfcObjectDefinition>());
IfcSchema::IfcObjectDefinition::list window_parts(new IfcTemplatedEntityList<IfcSchema::IfcObjectDefinition>());
// The placements for the beams are not shared accross the different windows because every
// beam is placed relative to its parent window entity.
Ifc2x3::IfcLocalPlacement::list frame_placements (new IfcTemplatedEntityList<Ifc2x3::IfcLocalPlacement>());
IfcSchema::IfcLocalPlacement::list 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));
// Now iterate over the placements and representations of the beam and add them to list of parts
Ifc2x3::IfcLocalPlacement::it frame_placement;
Ifc2x3::IfcProductDefinitionShape::it frame_representation;
IfcSchema::IfcLocalPlacement::it frame_placement;
IfcSchema::IfcProductDefinitionShape::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)
{
Ifc2x3::IfcMember* frame_part = new Ifc2x3::IfcMember(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
null, null, null, *frame_placement, *frame_representation, null);
IfcSchema::IfcMember* frame_part = new IfcSchema::IfcMember(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, null, *frame_placement, *frame_representation, null
#ifdef USE_IFC4
, IfcSchema::IfcMemberTypeEnum::IfcMemberType_MULLION
#endif
);
file.AddEntity(frame_part);
window_parts->push(frame_part);
file.relatePlacements(window, frame_part);
}
// Add the glass plate to the list of parts
Ifc2x3::IfcPlate* glass_part = new Ifc2x3::IfcPlate(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(), null,
null, null, file.addLocalPlacement(930, 45, 90), file.addBox(1680, 10, 1420), null);
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
#ifdef USE_IFC4
, IfcSchema::IfcPlateTypeEnum::IfcPlateType_SHEET
#endif
);
file.AddEntity(glass_part);
window_parts->push(glass_part);
file.relatePlacements(window, glass_part);
@@ -338,7 +432,7 @@ int main(int argc, char** argv) {
// 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.
Ifc2x3::IfcRelDecomposes* decomposition = new Ifc2x3::IfcRelAggregates(guid(), file.getSingle<Ifc2x3::IfcOwnerHistory>(),
IfcSchema::IfcRelDecomposes* decomposition = new IfcSchema::IfcRelAggregates(guid(), file.getSingle<IfcSchema::IfcOwnerHistory>(),
null, null, window, window_parts);
file.AddEntity(decomposition);
}
+2 -1
View File
@@ -18,8 +18,9 @@
********************************************************************************/
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcFile.h"
using namespace Ifc2x3;
using namespace IfcSchema;
int main(int argc, char** argv) {
+140
View File
@@ -0,0 +1,140 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Example that generates various representations from *
* IfcArbitraryOpenProfileDefs and its subclass IfcCenterLineProfileDef *
* *
********************************************************************************/
#include <string>
#include <iostream>
#include <fstream>
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast<boost::none_t>(0));
static int i = 0;
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_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");
}
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(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;
}
+119
View File
@@ -0,0 +1,119 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Example that generates extrusions of parameterized profiles. *
* *
********************************************************************************/
#include <string>
#include <iostream>
#include <fstream>
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast<boost::none_t>(0));
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;
}
+193
View File
@@ -0,0 +1,193 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Example that generates a Constructive Solid Geometry example *
* *
********************************************************************************/
#include <string>
#include <iostream>
#include <fstream>
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast<boost::none_t>(0));
class Node {
private:
typedef enum {
OP_ADD, OP_SUBTRACT, OP_INTERSECT, OP_TERMINAL
} Op;
typedef enum {
PRIM_BOX, PRIM_CONE, PRIM_CYLINDER, PRIM_PYRAMID, PRIM_SPHERE
} Prim;
double x,y,z, zx,zy,zz, xx,xy,xz, a,b,c;
const Node *left, *right;
Op op;
Prim prim;
Node& operate(Op op, const Node& p) {
left = new Node(*this);
right = new Node(p);
this->op = op;
return *this;
}
Node(Prim p, double la, double lb=0., double lc=0.)
: prim(p), op(OP_TERMINAL),
x(0.), y(0.), z(0.),
zx(0.), zy(0.), zz(1.),
xx(1.), xy(0.), xz(0.),
a(la), b(lb), c(lc) {}
public:
static Node Sphere(double r) {
return Node(PRIM_SPHERE, r);
}
static Node Box(double dx, double dy, double dz) {
return Node(PRIM_BOX, dx, dy, dz);
}
static Node Pyramid(double dx, double dy, double dz) {
return Node(PRIM_PYRAMID, dx, dy, dz);
}
static Node Cylinder(double r, double h) {
return Node(PRIM_CYLINDER, r, h);
}
static Node Cone(double r, double h) {
return Node(PRIM_CONE, r, h);
}
Node& move(
double px = 0., double py = 0., double pz = 0.,
double zx = 0., double zy = 0., double zz = 1.,
double xx = 1., double xy = 0., double xz = 0.)
{
this->x = px; this->y = py; this->z = pz;
this->zx = zx; this->zy = zy; this->zz = zz;
this->xx = xx; this->xy = xy; this->xz = xz;
return *this;
}
Node& add(const Node& p) {
return operate(OP_ADD, p);
}
Node& subtract(const Node& p) {
return operate(OP_SUBTRACT, p);
}
Node& intersect(const Node& p) {
return operate(OP_INTERSECT, p);
}
IfcSchema::IfcRepresentationItem* serialize(IfcHierarchyHelper& file) const {
IfcSchema::IfcRepresentationItem* my;
if (op == OP_TERMINAL) {
IfcSchema::IfcAxis2Placement3D* place = file.addPlacement3d(x,y,z,zx,zy,zz,xx,xy,xz);
if (prim == PRIM_SPHERE) {
my = new IfcSchema::IfcSphere(place, a);
} else if (prim == PRIM_BOX) {
my = new IfcSchema::IfcBlock(place, a, b, c);
} else if (prim == PRIM_PYRAMID) {
my = new IfcSchema::IfcRectangularPyramid(place, a, b, c);
} else if (prim == PRIM_CYLINDER) {
my = new IfcSchema::IfcRightCircularCylinder(place, b, a);
} else if (prim == PRIM_CONE) {
my = new IfcSchema::IfcRightCircularCone(place, b, a);
}
} else {
IfcSchema::IfcBooleanOperator::IfcBooleanOperator o;
if (op == OP_ADD) {
o = IfcSchema::IfcBooleanOperator::IfcBooleanOperator_UNION;
} else if (op == OP_SUBTRACT) {
o = IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE;
} else if (op == OP_INTERSECT) {
o = IfcSchema::IfcBooleanOperator::IfcBooleanOperator_INTERSECTION;
}
my = new IfcSchema::IfcBooleanResult(o, left->serialize(file), right->serialize(file));
}
file.AddEntity(my);
return my;
}
};
int main(int argc, char** argv) {
const char filename[] = "IfcCsgPrimitive.ifc";
IfcHierarchyHelper file;
file.filename(filename);
IfcSchema::IfcRepresentationItem* csg1 = Node::Box(8000.,6000.,3000.).subtract(
Node::Box(7600.,5600.,2800.).move(200.,200.,200.)
).add(
Node::Pyramid(8000.,6000.,3000.).move(0,0,3000.).add(
Node::Cylinder(1000.,4000.).move(4000.,1000.,4000., 0.,1.,0.)
).subtract(
Node::Pyramid(7600.,5600.,2800.).move(200.,200.,3000.)
).subtract(
Node::Cylinder(900.,4000.).move(4000.,1000.,4000., 0.,1.,0.).intersect(
Node::Box(2000.,4000.,1000.).move(3000.,1000.,4000.)
)
)
).serialize(file);
const double x = 1000.; const double y = -4000.;
IfcSchema::IfcRepresentationItem* csg2 = Node::Sphere(5000.).move(x,y,-4500.).intersect(
Node::Box(6000., 6000., 6000.).move(x-3000., y-3000., 0.)
).add(
Node::Cone(500., 3000.).move(x,y).add(
Node::Cone(1500., 1000.).move(x,y, 900.).add(
Node::Cone(1100., 1000.).move(x,y, 1800.).add(
Node::Cone(750., 600.).move(x,y, 2700.)
)))).serialize(file);
IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
guid(), 0, S("IfcCsgPrimitive"), null, null, 0, 0, null, null);
file.addBuildingProduct(product);
product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
product->setObjectPlacement(file.addLocalPlacement());
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
items->push(csg1);
items->push(csg2);
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
file.getSingle<IfcSchema::IfcRepresentationContext>(), S("Body"), S("CSG"), 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;
}
+148
View File
@@ -0,0 +1,148 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Example that generates profiles of trimmed ellipses. *
* *
********************************************************************************/
#include <string>
#include <iostream>
#include <fstream>
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast<boost::none_t>(0));
typedef struct {
double r1;
double r2;
double t1;
double t2;
} EllipsePie;
static int i = 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);
}
int main(int argc, char** argv) {
const std::string filename = "ellipse_pies.ifc";
IfcHierarchyHelper file;
{ EllipsePie pie = {80., 50., 0., 150.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
{ EllipsePie pie = {80, 50., 30., 300.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
{ EllipsePie pie = {80, 50., 300., 30.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
{ EllipsePie pie = {50., 80., 0., 150.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
{ EllipsePie pie = {50, 80., 30., 300.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
{ EllipsePie pie = {50, 80., 300., 30.};
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER);
create_testcase_for(file, pie, Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN);}
std::ofstream f(filename.c_str());
f << file;
}
+203
View File
@@ -0,0 +1,203 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Example that generates extrusions of parameterized profiles. *
* *
********************************************************************************/
#include <string>
#include <iostream>
#include <fstream>
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcHierarchyHelper.h"
typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast<boost::none_t>(0));
void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
IfcSchema::IfcProfileDef* profile = *profiles->begin();
const std::string profile_type = IfcSchema::Type::ToString(profile->type());
const std::string filename = profile_type + ".ifc";
IfcHierarchyHelper file;
file.filename(filename);
int i = 0;
for (IfcSchema::IfcProfileDef::it it = profiles->begin(); it != profiles->end(); ++it, ++i) {
IfcSchema::IfcProfileDef* profile = *it;
IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
guid(), 0, S("profile"), null, null, 0, 0, null, null);
file.addBuildingProduct(product);
file.getSingle<IfcSchema::IfcProject>()->setName(profile_type);
product->setOwnerHistory(file.getSingle<IfcSchema::IfcOwnerHistory>());
product->setObjectPlacement(file.addLocalPlacement(100 * i));
if (profile->is(IfcSchema::Type::IfcParameterizedProfileDef)) {
((IfcSchema::IfcParameterizedProfileDef*) profile)->setPosition(file.addPlacement2d());
}
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(profile,
file.addPlacement3d(), file.addTriplet<IfcSchema::IfcDirection>(0, 0, 1), 20.0);
file.AddEntity(profile);
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);
}
std::ofstream f(filename.c_str());
f << file;
}
int main(int argc, char** argv) {
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcUShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null, null, null));
profiles->push(new Ifc2x3::IfcUShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, 2.0, 2.0, null, null));
profiles->push(new Ifc2x3::IfcUShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null, 4.0, null));
profiles->push(new Ifc2x3::IfcUShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, 1.0, 3.0, 6.0, null));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcTShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null, null, null, null, null));
profiles->push(new Ifc2x3::IfcTShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, 2.0, 2.0, 2.0, null, null, null));
profiles->push(new Ifc2x3::IfcTShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null, null, 2.0, 2.0, null));
profiles->push(new Ifc2x3::IfcTShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, 3.0, 2.0, 1.0, 2.0, 2.0, null));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcZShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null));
profiles->push(new Ifc2x3::IfcZShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, 2.0, 2.0));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcEllipseProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0, 15.0));
profiles->push(new Ifc2x3::IfcEllipseProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 15.0, 25.0));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcIShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0, 50.0, 5.0, 5.0, null));
profiles->push(new Ifc2x3::IfcIShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0, 50.0, 5.0, 5.0, 2.0));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcLShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, null, null, null, null, null));
profiles->push(new Ifc2x3::IfcLShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 2.0, 2.0, null, null, null));
profiles->push(new Ifc2x3::IfcLShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, null, null, 2.0, null, null));
profiles->push(new Ifc2x3::IfcLShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 1.0, 2.0, 2.0, null, null));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcCShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 10.0, null, null));
profiles->push(new Ifc2x3::IfcCShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 10.0, 2.0, null));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcCircleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0));
profiles->push(new Ifc2x3::IfcCircleHollowProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0, 5.0));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcRectangleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0));
profiles->push(new Ifc2x3::IfcRoundedRectangleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0));
profiles->push(new Ifc2x3::IfcRectangleHollowProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, null, null));
profiles->push(new Ifc2x3::IfcRectangleHollowProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 2.0, 4.0));
create_testcase_for(profiles); }
{ IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList<IfcSchema::IfcProfileDef>());
profiles->push(new Ifc2x3::IfcTrapeziumProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 30.0, 25.0, 0.0));
profiles->push(new Ifc2x3::IfcTrapeziumProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 60.0, 25.0, -20.0));
profiles->push(new Ifc2x3::IfcTrapeziumProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 10.0, 25.0, 30.0));
create_testcase_for(profiles); }
}
+64 -46
View File
@@ -30,12 +30,23 @@ bl_info = {
"description": "Import files in the "\
"Industry Foundation Classes (.ifc) file format",
"author": "Thomas Krijnen, IfcOpenShell",
"blender": (2, 73, 0),
"blender": (2, 5, 8),
"api": 37702,
"location": "File > Import",
"tracker_url": "https://sourceforge.net/p/ifcopenshell/"\
"_list/tickets?source=navbar",
"warning": "",
"wiki_url": "http://sourceforge.net/apps/"\
"mediawiki/ifcopenshell/index.php",
"tracker_url": "http://sourceforge.net/tracker/?group_id=543113",
"category": "Import-Export"}
import sys
max_unicode = 0x110000-1 if sys.platform[0:5] == 'linux' else 0x10000-1
wrong_unicode = max_unicode != sys.maxunicode
if wrong_unicode:
print("\nWarning: wrong unicode representation detected, switching to "\
"compatibility layer for text transferral, may result in undefined "\
"behaviour, please use offical release from http://blender.org\n")
if "bpy" in locals():
import imp
if "IfcImport" in locals():
@@ -60,9 +71,15 @@ bpy.types.Object.ifc_type = StringProperty(name="IFC Entity Type",
def import_ifc(filename, use_names, process_relations):
global wrong_unicode
from . import IfcImport
print("Reading %s..."%bpy.path.basename(filename))
valid_file = IfcImport.Init(filename)
if wrong_unicode:
valid_file = IfcImport.InitUCS2(
''.join(['\0']+['\0%s'%s for s in filename]+['\0\0'])
)
else:
valid_file = IfcImport.Init(filename)
if not valid_file:
IfcImport.CleanUp()
return False
@@ -74,14 +91,19 @@ def import_ifc(filename, use_names, process_relations):
print("Creating geometry...")
while True:
ob = IfcImport.Get()
if wrong_unicode:
ob_name = ''.join([chr(c) for c in ob.name_as_intvector()])
ob_type = ''.join([chr(c) for c in ob.type_as_intvector()])
ob_guid = ''.join([chr(c) for c in ob.guid_as_intvector()])
else:
ob_name, ob_type, ob_guid = ob.name, ob.type, ob.guid
f = ob.mesh.faces
v = ob.mesh.verts
mats = ob.mesh.materials
matids = ob.mesh.material_ids
m = ob.matrix
t = ob.type[0:21]
nm = ob.name if len(ob.name) and use_names else ob.guid
m = ob.matrix
t = ob_type[0:21]
nm = ob_name if len(ob_name) and use_names else ob_guid
verts = [[v[i], v[i + 1], v[i + 2]] \
for i in range(0, len(v), 3)]
@@ -90,29 +112,12 @@ def import_ifc(filename, use_names, process_relations):
me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
me.from_pydata(verts, [], faces)
def add_material(mname, props):
if mname in bpy.data.materials:
mat = bpy.data.materials[mname]
mat.use_fake_user = True
else:
mat = bpy.data.materials.new(mname)
for k,v in props.items():
setattr(mat, k, v)
me.materials.append(mat)
needs_default = -1 in matids
if needs_default: add_material(t, {})
for mat in mats:
props = {}
if mat.has_diffuse: props['diffuse_color'] = mat.diffuse
if mat.has_specular: props['specular_color'] = mat.specular
if mat.has_transparency and mat.transparency > 0:
props['alpha'] = 1.0 - mat.transparency
props['use_transparency'] = True
if mat.has_specularity: props['specular_hardness'] = mat.specularity
add_material(mat.name, props)
if t in bpy.data.materials:
mat = bpy.data.materials[t]
mat.use_fake_user = True
else:
mat = bpy.data.materials.new(t)
me.materials.append(mat)
bob = bpy.data.objects.new(nm, me)
mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
@@ -133,9 +138,9 @@ def import_ifc(filename, use_names, process_relations):
bpy.ops.object.mode_set(mode='OBJECT')
bob.ifc_id, bob.ifc_guid, bob.ifc_name, bob.ifc_type = \
ob.id, ob.guid, ob.name, ob.type
ob.id, ob_guid, ob_name, ob_type
bob.hide = ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement'
bob.hide = ob_type == 'IfcSpace' or ob_type == 'IfcOpeningElement'
bob.hide_render = bob.hide
if ob.id not in id_to_object: id_to_object[ob.id] = []
@@ -144,11 +149,6 @@ def import_ifc(filename, use_names, process_relations):
if ob.parent_id > 0:
id_to_parent[ob.id] = ob.parent_id
faces = me.polygons if hasattr(me, 'polygons') else me.faces
if len(faces) == len(matids):
for face, matid in zip(faces, matids):
face.material_index = matid + (1 if needs_default else 0)
progress = IfcImport.Progress() // 2
if progress > old_progress:
print("\r[" + "#" * progress + " " * (50 - progress) + "]", end="")
@@ -173,9 +173,20 @@ def import_ifc(filename, use_names, process_relations):
if parent_ob.id == -1:
bob = None
else:
if wrong_unicode:
parent_ob_name = ''.join(
[chr(c) for c in parent_ob.name_as_intvector()])
parent_ob_type = ''.join(
[chr(c) for c in parent_ob.type_as_intvector()])
parent_ob_guid = ''.join(
[chr(c) for c in parent_ob.guid_as_intvector()])
else:
parent_ob_name, parent_ob_type, parent_ob_guid = \
parent_ob.name, parent_ob.type, parent_ob.guid
m = parent_ob.matrix
nm = parent_ob.name if len(parent_ob.name) and use_names \
else parent_ob.guid
nm = parent_ob_name if len(parent_ob_name) and use_names \
else parent_ob_guid
bob = bpy.data.objects.new(nm, None)
mat = mathutils.Matrix((
@@ -190,7 +201,7 @@ def import_ifc(filename, use_names, process_relations):
bob.ifc_id = parent_ob.id
bob.ifc_name, bob.ifc_type, bob.ifc_guid = \
parent_ob.name, parent_ob.type, parent_ob.guid
parent_ob_name, parent_ob_type, parent_ob_guid
if parent_ob.parent_id > 0:
id_to_parent[parent_id] = parent_ob.parent_id
@@ -216,8 +227,9 @@ def import_ifc(filename, use_names, process_relations):
if process_relations:
print("Done processing relations")
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
txt.from_string(IfcImport.GetLog())
if not wrong_unicode:
txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
txt.from_string(IfcImport.GetLog())
IfcImport.CleanUp()
@@ -241,7 +253,13 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
default=False)
def execute(self, context):
if not import_ifc(self.filepath, self.use_names, self.process_relations):
global wrong_unicode
if wrong_unicode and sys.platform[0:5] != 'linux':
self.report({'ERROR'},
'Your version of Blender is incompatible with IfcBlender\n' \
'Please use the offical release from http://blender.org instead'
)
elif not import_ifc(self.filepath, self.use_names, self.process_relations):
self.report({'ERROR'},
'Unable to parse .ifc file or no geometrical entities found'
)
-2
View File
@@ -128,8 +128,6 @@ int main(int argc, char** argv) {
} catch (const boost::program_options::unknown_option& e) {
std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'" << std::endl << std::endl;
// Usage information will be emitted below
} catch (...) {
// Catch other errors such as invalid command line syntax
}
boost::program_options::notify(vmap);
+7 -14
View File
@@ -24,8 +24,6 @@
#include <BRepBuilderAPI_GTransform.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <Standard_Version.hxx>
#include "OpenCascadeBasedSerializer.h"
bool OpenCascadeBasedSerializer::ready() {
@@ -40,19 +38,14 @@ void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomSh
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->mesh().begin(); it != o->mesh().end(); ++ it) {
gp_GTrsf gtrsf = it->Placement();
// Convert the matrix back into a transformation object. The tolerance values
// are taken into consideration to reconstruct the form of the transformation.
gp_Trsf o_trsf;
o_trsf.SetValues(
o->matrix()[0], o->matrix()[3], o->matrix()[6], o->matrix()[ 9],
o->matrix()[1], o->matrix()[4], o->matrix()[7], o->matrix()[10],
o->matrix()[2], o->matrix()[5], o->matrix()[8], o->matrix()[11]
#if OCC_VERSION_HEX < 0x60800
, Precision::Angular(), Precision::Confusion()
#endif
);
gtrsf.PreMultiply(o_trsf);
// TODO:
gp_GTrsf o_trsf;
int k = 0;
for( int i = 1; i < 5; ++ i )
for ( int j = 1; j < 4; ++ j )
o_trsf.SetValue(j, i, o->matrix()[k++]);
gtrsf.PreMultiply(o_trsf);
const TopoDS_Shape& s = it->Shape();
bool trsf_valid = false;
+153 -33
View File
@@ -348,22 +348,22 @@ class InverseList:
return s
class Classdef:
def __init__(self,l):
self.class_name, self.parent_class, self.arguments, derive, self.inverse = l
self.class_name, self.parent_class, self.arguments, self.inverse = l
self.arguments.class_name = self.class_name
self.arguments.parent_class = self.parent_class
entity_names.add(self.class_name)
parent_relations[self.class_name] = self.parent_class
argument_count[self.class_name] = len(self.arguments)
entity_map[self.class_name] = self
# For derived attributes only a reference is kepts to overridden attributes in parent classes
self.derive = [x[0].split('.')[-1] for x in derive[1] if x[0].startswith("SELF\\")] if derive else []
def list_constructor_args(self):
s = entity_map[self.parent_class].list_constructor_args() if self.parent_class else []
i = len(s) + 1
s += [(a.type_str(),b+i,a.name) for a,b in zip(self.arguments.l,range(len(self.arguments)))]
def get_attributes(self, get_parent=True):
s = entity_map[self.parent_class].get_attributes() if get_parent and self.parent_class else []
s += [(a.name,not not a.optional,a.type.type_enum(),a.type.type if a.is_enum() else None) for a in self.arguments.l]
return s
def get_constructor_args(self):
return ["%s v%d_%s"%x for x in self.list_constructor_args() if x[2] not in self.get_derived()]
s = entity_map[self.parent_class].get_constructor_args() if self.parent_class else []
i = len(s) + 1
s += ["%s v%d_%s"%(a.type_str(),b+i,a.name) for a,b in zip(self.arguments.l,range(len(self.arguments)))]
return s
def get_constructor_implementation(self):
s = entity_map[self.parent_class].get_constructor_implementation() if self.parent_class else []
i = len(s) + 1
@@ -382,13 +382,10 @@ class Classdef:
else:
impl = "e->setArgument(%d,(%sv%d_%s)%s)"%(b+i-1,dereference,b+i,a.name,generalize)
if use_boost_optional:
s.append(["if (v%d_%s) { %s; } else { e->setArgument(%d); } "%(b+i,a.name,impl,b+i-1),a.name,i-1])
else: s.append([impl,a.name,i-1])
s.append("if (v%d_%s) { %s; } else { e->setArgument(%d); } "%(b+i,a.name,impl,b+i-1))
else: s.append(impl)
b += 1
return s
def get_derived(self):
s = entity_map[self.parent_class].get_derived() if self.parent_class else []
return s + self.derive
return s#"; ".join(s)
def __str__(self):
self.constructor_args_list = self.get_constructor_args()
self.constructor_args = ", ".join(self.constructor_args_list)
@@ -410,7 +407,7 @@ class Classdef:
)
elif generator_mode == 'SOURCE':
self.arguments.argstart = argument_start(self.class_name)
self.constructor_implementation = "; ".join([x[0] if x[1] not in self.get_derived() else "e->setArgumentDerived(%d)"%x[2] for x in self.get_constructor_implementation()])
self.constructor_implementation = "; ".join(self.get_constructor_implementation())
return (("\n// Function implementations for %(class_name)s"+str(self.arguments)+str(self.inverse)+
("\nbool %(class_name)s::is(Type::Enum v) const { return v == Type::%(class_name)s; }" if self.parent_class is None else
"\nbool %(class_name)s::is(Type::Enum v) const { return v == Type::%(class_name)s || %(parent_class)s::is(v); }")+
@@ -469,9 +466,9 @@ unique_value = s + x(':') + s + many(a(',')+s) + a(';')
unique = skip(a('UNIQUE') + many(unique_value))
inverse_def = s + x(':') + (array|single) + x('FOR') + s + x(';') >> inverse_type
inverse = maybe(x('INVERSE') + many( inverse_def )) >> inverse_list
derive = a('DERIVE') + many(clause)
derive = skip(a('DERIVE') + many(clause))
entity = entity_start + arguments + skip(maybe(unique)) + maybe(derive) + inverse + skip(maybe(where)) + entity_end >> Classdef
entity = entity_start + arguments + skip(maybe(unique)) + skip(maybe(derive)) + inverse + skip(maybe(where)) + entity_end >> Classdef
schema = skip(a('SCHEMA')) + s + x(';')
@@ -483,8 +480,10 @@ schema_version = schema_version.capitalize()
# Writing of the three generated files starts here
#
h_file = open("%s.h"%schema_version,'w')
h2_file = open("%s-rt.h"%schema_version,'w')
enumh_file = open("%senum.h"%schema_version,'w')
cpp_file = open("%s.cpp"%schema_version,'w')
cpp2_file = open("%s-rt.cpp"%schema_version,'w')
header += """
@@ -499,19 +498,23 @@ header += """
generator_mode = 'HEADER'
print >>h_file, header
print >>h2_file, header
print >>enumh_file, header
print >>cpp_file, header
print >>cpp2_file, header
print >>h_file, """#ifndef %(schema_upper)s_H
#define %(schema_upper)s_H
#include <string>
#include <vector>
#include <map>
#include <set>
#include <boost/optional.hpp>
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/ArgumentType.h"
#include "../ifcparse/%(schema)senum.h"
using namespace IfcUtil;
@@ -540,13 +543,15 @@ using boost::optional;
namespace %(schema)s {
"""%{'schema_upper':schema_version.upper(),'schema':schema_version}
simple_enumerations = sorted(selectable_simple_types)
simple_enumerations = sorted(simple_types)
entity_enumerations = sorted(entity_names)
all_enumerations = simple_enumerations + entity_enumerations
print >>enumh_file, """#ifndef IFC2X3ENUM_H
#define IFC2X3ENUM_H
#include "../ifcparse/ArgumentType.h"
namespace Ifc2x3 {
namespace Type {
@@ -563,6 +568,24 @@ namespace Type {
#endif
"""%{'schema_upper':schema_version.upper(),'schema':schema_version,'enum':", ".join(all_enumerations + ["ALL"])}
print >>h2_file, """#ifndef IFC2X3RT_H
#define IFC2X3RT_H
#include "../ifcparse/ArgumentType.h"
namespace Ifc2x3 {
namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
}}
#endif
"""
defined_types = set(express_to_cpp.values())
deferred_types = []
@@ -597,11 +620,21 @@ print >>h_file, "IfcSchemaEntity SchemaEntity(IfcAbstractEntityPtr e = 0);"
print >>h_file, "}\n\n#endif"
generator_mode = 'SOURCE'
print >>cpp2_file, """#include "../ifcparse/%(schema)s.h"
#include "../ifcparse/%(schema)s-rt.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/ArgumentType.h"
print >>cpp_file, """#include "%(schema)s.h"
#include "IfcException.h"
#include "IfcWrite.h"
#include "IfcWritableEntity.h"
using namespace %(schema)s;
using namespace IfcParse;
using namespace IfcWrite;"""%{'schema':schema_version}
print >>cpp_file, """#include "../ifcparse/%(schema)s.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/ArgumentType.h"
using namespace %(schema)s;
using namespace IfcParse;
@@ -623,20 +656,52 @@ print >>cpp_file, ' const char* names[] = { "%s" };'%'","'.join(all_enumerati
print >>cpp_file, ' return names[v];'
print >>cpp_file, "}"
print >>cpp_file
#print >>cpp_file, "Type::Enum Type::FromStringOld(const std::string& s){"
#elseif = "if"
#maxlen = max([len(e) for e in all_enumerations])
#for e in all_enumerations:
# print >>cpp_file, ' %s(s=="%s"%s) { return %s; }'%(elseif,e.upper()," "*(maxlen-len(e)),e)
#print >>cpp_file, " throw;"
#print >>cpp_file, "}"
print >>cpp_file, "std::map<std::string,Type::Enum> string_map;"
print >>cpp_file, "void Ifc2x3::InitStringMap() {"
print >>cpp2_file, "std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;"
print >>cpp2_file, "std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;"
maxlen = max([len(e) for e in all_enumerations])
string_map,attribute_count_map,attribute_index_map,attribute_name_map,attribute_optional_map,attribute_type_map = [""]*6
print >>cpp2_file, "void InitDescriptorMap() {"
print >>cpp2_file, " IfcEntityDescriptor* current;"
for k,v in simple_types.items():
if k in enumerations or k in selections: continue
print >>cpp2_file, " current = entity_descriptor_map[Type::%s] = new IfcEntityDescriptor(Type::%s,0);"%(k,k)
print >>cpp2_file, " current->add(\"wrappedValue\",false,%s);"%(v.type_enum())
rt_entities = set()
while True:
todo = [e for e in entities if e.class_name not in rt_entities]
if len(todo) == 0: break
for e in todo:
if e.parent_class and e.parent_class not in rt_entities: continue
rt_entities.add(e.class_name)
args = e.get_attributes(False)
parent_descriptor = ("entity_descriptor_map.find(Type::%s)->second"%e.parent_class) if e.parent_class else "0"
print >>cpp2_file, " current = entity_descriptor_map[Type::%s] = new IfcEntityDescriptor(Type::%s,%s);"%(e.class_name,e.class_name,parent_descriptor)
for a,i in zip(args,range(len(args))):
name,optional,type,enum_class = a
if enum_class:
print >>cpp2_file, " current->add(\"%s\",%s,%s,Type::%s);"%(name,"true" if optional else "false",type,enum_class)
else:
print >>cpp2_file, " current->add(\"%s\",%s,%s);"%(name,"true" if optional else "false",type)
print >>cpp2_file, " // Enumerations"
print >>cpp2_file, " IfcEnumerationDescriptor* current_enum;"
print >>cpp2_file, " std::vector<std::string> values;"
for e, name in [(e, name) for name, e in simple_types.items() if name in enumerations]:
print >>cpp2_file, " values.clear(); values.reserve(128);"
for value in e.type.v:
print >>cpp2_file, " values.push_back(\"%s\");"%value[0]
print >>cpp2_file, " current_enum = enumeration_descriptor_map[Type::%s] = new IfcEnumerationDescriptor(Type::%s, values);"%(name,name)
print >>cpp2_file, "}"
for e in all_enumerations:
print >>cpp_file, ' string_map["%s"%s] = Type::%s;'%(e.upper()," "*(maxlen-len(e)),e)
print >>cpp_file, """}
Type::Enum Type::FromString(const std::string& s) {
string_map += ' string_map["%s"%s] = Type::%s;\n'%(e.upper()," "*(maxlen-len(e)),e)
print >>cpp_file, """void Ifc2x3::InitStringMap() {
%(string_map)s
}"""%locals()
print >>cpp_file, """Type::Enum Type::FromString(const std::string& s) {
if (string_map.empty()) ::Ifc2x3::InitStringMap();
std::map<std::string,Type::Enum>::const_iterator it = string_map.find(s);
if ( it == string_map.end() ) throw IfcException("Unable to find find keyword in schema");
else return it->second;
@@ -657,3 +722,58 @@ print >>cpp_file, "}"
for t in [T for T in types if isinstance(T.type,EnumType)]:
print >>cpp_file, t
for e in entities: print >>cpp_file, e,
print >>cpp_file, ""
print >>cpp2_file, """int Type::GetAttributeIndex(Enum t, const std::string& a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentIndex(a);
}
int Type::GetAttributeCount(Enum t) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentCount();
}
ArgumentType Type::GetAttributeType(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentType(a);
}
const std::string& Type::GetAttributeName(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentName(a);
}
bool Type::GetAttributeOptional(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentOptional(a);
}
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
if ( i == enumeration_descriptor_map.end() ) throw IfcException("Value not found");
else return i->second->getIndex(a);
}
Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else {
Type::Enum t = i->second->getArgumentEnumerationClass(a);
if ( t == Type::ALL ) throw IfcException("Not an enumeration");
else return t;
}
}
"""
+9
View File
@@ -0,0 +1,9 @@
This folder contains Python code to generate C++ type information based on an
Express schema. In particular is has only been tested using recent version of
the IFC schema and will most likely fail on any other Express schema.
The code can be invoked in the following way and results in two header files
and a single implementation file named according to the schema name in the
Express file. A python 3 interpreter with the pyparsing library is required.
$ python bootstrap.py express.bnf > express_parser.py && python express_parser.py IFC2X3_TC1.exp
+193
View File
@@ -0,0 +1,193 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import sys
import string
from pyparsing import *
class Expression:
def __init__(self, contents):
self.contents = contents[0]
def __repr__(self):
if self.op is None: return repr(self.contents)
c = [isinstance(c,str) and c or str(c) for c in self.contents]
if "%s" in self.op: return self.op % (" ".join(c))
else: return "(%s)" % (" %s "%self.op).join(c)
def __iter__(self):
return self.contents.__iter__()
class Union(Expression):
op = "|"
class Concat(Expression):
op = "+"
class Optional(Expression):
op = "Optional(%s)"
class Repeated(Expression):
op = "ZeroOrMore(%s)"
class Term(Expression):
op = None
class Keyword:
def __init__(self, contents):
self.contents = contents[0]
def __repr__(self):
return self.contents
class Terminal:
def __init__(self, contents):
self.contents = contents[0]
def __repr__(self):
s = self.contents
is_keyword = len(s) >= 4 and s[0::len(s)-1] == '""' and \
all(c in alphanums+"_" for c in s[1:-1])
ty = "CaselessKeyword" if is_keyword else "CaselessLiteral"
return "%s(%s)" % (ty, s)
LPAREN = Suppress("(")
RPAREN = Suppress(")")
LBRACK = Suppress("[")
RBRACK = Suppress("]")
LBRACE = Suppress("{")
RBRACE = Suppress("}")
EQUALS = Suppress("=")
VBAR = Suppress("|")
PERIOD = Suppress(".")
HASH = Suppress("#")
identifier = Word(alphanums+"_")
keyword = Word(alphanums+"_").setParseAction(Keyword)
expression = Forward()
optional = Group(LBRACK + expression + RBRACK).setParseAction(Optional)
repeated = Group(LBRACE + expression + RBRACE).setParseAction(Repeated)
terminal = quotedString.setParseAction(Terminal)
term = (keyword | terminal | optional | repeated | (LPAREN + expression + RPAREN)).setParseAction(Term)
concat = Group(term + OneOrMore(term)).setParseAction(Concat)
factor = concat | term
union = Group(factor + OneOrMore(VBAR + factor)).setParseAction(Union)
rule = identifier + EQUALS + expression + PERIOD
expression << (union | factor)
grammar = OneOrMore(Group(rule))
grammar.ignore(HASH + restOfLine)
express = grammar.parseFile(sys.argv[1])
def find_keywords(expr, li = None):
if li is None: li = []
if isinstance(expr, Term):
expr = expr.contents
if isinstance(expr, Keyword):
li.append(repr(expr))
return li
elif isinstance(expr, Expression):
for term in expr:
find_keywords(term, li)
return set(li)
actions = {
'type_decl' : "lambda t: TypeDeclaration(t)",
'entity_decl' : "lambda t: EntityDeclaration(t)",
'underlying_type' : "lambda t: UnderlyingType(t)",
'enumeration_type' : "lambda t: EnumerationType(t)",
'aggregation_types' : "lambda t: AggregationType(t)",
'general_aggregation_types' : "lambda t: AggregationType(t)",
'select_type' : "lambda t: SelectType(t)",
'binary_type' : "lambda t: BinaryType(t)",
'subtype_declaration' : "lambda t: SubtypeExpression(t)",
'derive_clause' : "lambda t: AttributeList('derive', t)",
'derived_attr' : "lambda t: DerivedAttribute(t)",
'inverse_clause' : "lambda t: AttributeList('inverse', t)",
'inverse_attr' : "lambda t: InverseAttribute(t)",
'bound_spec' : "lambda t: BoundSpecification(t)",
'explicit_attr' : "lambda t: ExplicitAttribute(t)",
}
to_emit = set(id for id, expr in express)
emitted = set()
to_combine = set(["simple_id"])
to_ignore = set(["where_clause", "supertype_constraint", "unique_clause"])
statements = []
while True:
emitted_in_loop = set()
for id, expr in express:
kws = find_keywords(expr)
found = [k in emitted for k in kws]
if id in to_emit and all(found):
emitted_in_loop.add(id)
emitted.add(id)
stmt = "(%s)" % expr
if id in to_combine:
stmt = "originalTextFor(Combine%s)" % stmt
if id in actions:
stmt = "%s.setParseAction(%s)" % (stmt, actions[id])
statements.append("%s = %s" % (id, stmt))
to_emit -= emitted_in_loop
if not emitted_in_loop: break
for id in to_emit:
action = ".setParseAction(%s)" % actions[id] if id in actions else ""
statements.append("%s = Forward()%s" % (id, action))
for id in to_emit:
expr = [e for k, e in express if k == id][0]
stmt = "(%s)" % expr
if id in to_combine:
stmt = "Suppress%s" % stmt
statements.append("%s << %s" % (id, stmt))
print ("""import sys
from pyparsing import *
from nodes import *
%s
import schema
import mapping
import header
import enum_header
import implementation
import rt_header
import rt_implementation
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
ast = syntax.parseFile(sys.argv[1])
schema = schema.Schema(ast)
mapping = mapping.Mapping(schema)
header.Header(mapping).emit()
enum_header.EnumHeader(mapping).emit()
implementation.Implementation(mapping).emit()
rt_header.RuntimeTypingHeader(mapping).emit()
rt_implementation.RuntimeTypingImplementation(mapping).emit()
def retry():
import imp
imp.reload(rt_header)
imp.reload(rt_implementation)
rt_header.RuntimeTypingHeader(mapping).emit()
rt_implementation.RuntimeTypingImplementation(mapping).emit()
"""%('\n'.join(statements)))
+70
View File
@@ -0,0 +1,70 @@
###############################################################################
# #
# 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 files uses the documentation files from buildingSMART to generate #
# descriptions from EXPRESS names that are suitable for comments in the C++ #
# code. The .csv files used by this file are generated from the MS Office #
# Access database, which in turn has been generated from the IFC baseline #
# documentation by the IFCDOC utility provided by buildingSMART. #
# #
###############################################################################
import re,csv
import csv
try: from html.entities import entitydefs
except: from htmlentitydefs import entitydefs
name_to_oid = {}
oid_to_desc = {}
oid_to_name = {}
oid_to_pid = {}
regices = list(zip([re.compile(s,re.M) for s in [r'<[\w\n=" \-/\.;_\t:%#,\?\(\)]+>',r'(\n[\t ]*){2,}',r'^[\t ]+']],['','\n\n',' ']))
definition_files = ['DocEntity.csv', 'DocEnumeration.csv', 'DocDefined.csv', 'DocSelect.csv']
for fn in definition_files:
with open(fn) as f:
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
name_to_oid[name] = oid
oid_to_name[oid] = name
oid_to_desc[oid] = desc
with open('DocEntityAttributes.csv') as f:
for pid, x, oid in csv.reader(f, delimiter=';', quotechar='"'):
oid_to_pid[oid] = pid
with open('DocAttribute.csv') as f:
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
pid = oid_to_pid[oid]
pname = oid_to_name[pid]
name_to_oid[(pname, name)] = oid
oid_to_desc[oid] = desc
def description(item):
global name_to_oid, oid_to_desc, oid_to_name, oid_to_pid
oid = name_to_oid.get(item,0)
desc = oid_to_desc.get(oid, None)
if desc:
for a,b in entitydefs.items(): desc = desc.replace("&%s;"%a,b)
desc = desc.replace("\r","")
for r,s in regices: desc = r.sub(s,desc)
desc = desc.strip()
return desc.split("\n")
else: return []
+38
View File
@@ -0,0 +1,38 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import templates
class EnumHeader:
def __init__(self, mapping):
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
self.str = templates.enum_header % {
'schema_name_upper' : mapping.schema.name.upper(),
'schema_name' : mapping.schema.name.capitalize(),
'types' : ', '.join(enumerable_types)
}
self.schema_name = mapping.schema.name.capitalize()
def __repr__(self):
return self.str
def emit(self):
f = open('%senum.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+344
View File
@@ -0,0 +1,344 @@
# Taken from http://sourceforge.net/p/exp-engine/expresso/ci/master/tree/docs/iso-10303-11--2004.bnf
ABS = "abs" .
ABSTRACT = "abstract" .
ACOS = "acos" .
AGGREGATE = "aggregate" .
ALIAS = "alias" .
AND = "and" .
ANDOR = "andor" .
ARRAY = "array" .
AS = "as" .
ASIN = "asin" .
ATAN = "atan" .
BAG = "bag" .
BASED_ON = "based_on" .
BEGIN = "begin" .
BINARY = "binary" .
BLENGTH = "blength" .
BOOLEAN = "boolean" .
BY = "by" .
CASE = "case" .
CONSTANT = "constant" .
CONST_E = "const_e" .
COS = "cos" .
DERIVE = "derive" .
DIV = "div" .
ELSE = "else" .
END = "end" .
END_ALIAS = "end_alias" .
END_CASE = "end_case" .
END_CONSTANT = "end_constant" .
END_ENTITY = "end_entity" .
END_FUNCTION = "end_function" .
END_IF = "end_if" .
END_LOCAL = "end_local" .
END_PROCEDURE = "end_procedure" .
END_REPEAT = "end_repeat" .
END_RULE = "end_rule" .
END_SCHEMA = "end_schema" .
END_SUBTYPE_CONSTRAINT = "end_subtype_constraint" .
END_TYPE = "end_type" .
ENTITY = "entity" .
ENUMERATION = "enumeration" .
ESCAPE = "escape" .
EXISTS = "exists" .
EXTENSIBLE = "extensible" .
EXP = "exp" .
FALSE = "false" .
FIXED = "fixed" .
FOR = "for" .
FORMAT = "format" .
FROM = "from" .
FUNCTION = "function" .
GENERIC = "generic" .
GENERIC_ENTITY = "generic_entity" .
HIBOUND = "hibound" .
HIINDEX = "hiindex" .
IF = "if" .
IN = "in" .
INSERT = "insert" .
INTEGER = "integer" .
INVERSE = "inverse" .
LENGTH = "length" .
LIKE = "like" .
LIST = "list" .
LOBOUND = "lobound" .
LOCAL = "local" .
LOG = "log" .
LOG10 = "log10" .
LOG2 = "log2" .
LOGICAL = "logical" .
LOINDEX = "loindex" .
MOD = "mod" .
NOT = "not" .
NUMBER = "number" .
NVL = "nvl" .
ODD = "odd" .
OF = "of" .
ONEOF = "oneof" .
OPTIONAL = "optional" .
OR = "or" .
OTHERWISE = "otherwise" .
PI = "pi" .
PROCEDURE = "procedure" .
QUERY = "query" .
REAL = "real" .
REFERENCE = "reference" .
REMOVE = "remove" .
RENAMED = "renamed" .
REPEAT = "repeat" .
RETURN = "return" .
ROLESOF = "rolesof" .
RULE = "rule" .
SCHEMA = "schema" .
SELECT = "select" .
SELF = "self" .
SET = "set" .
SIN = "sin" .
SIZEOF = "sizeof" .
SKIP = "skip" .
SQRT = "sqrt" .
STRING = "string" .
SUBTYPE = "subtype" .
SUBTYPE_CONSTRAINT = "subtype_constraint" .
SUPERTYPE = "supertype" .
TAN = "tan" .
THEN = "then" .
TO = "to" .
TOTAL_OVER = "total_over" .
TRUE = "true" .
TYPE = "type" .
TYPEOF = "typeof" .
UNIQUE = "unique" .
UNKNOWN = "unknown" .
UNTIL = "until" .
USE = "use" .
USEDIN = "usedin" .
VALUE = "value" .
VALUE_IN = "value_in" .
VALUE_UNIQUE = "value_unique" .
VAR = "var" .
WHERE = "where" .
WHILE = "while" .
WITH = "with" .
XOR = "xor" .
bit = "0" | "1" .
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
digits = digit { digit } .
encoded_character = octet octet octet octet .
hex_digit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" .
lparen_then_not_lparen_star = "(" { "(" } not_lparen_star { not_lparen_star } .
not_lparen_star = not_paren_star | ")" .
not_paren_star = letter | digit | not_paren_star_special .
not_paren_star_quote_special = "!" | "#" | "$" | "%" | "&" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<" | "=" | ">" | "?" | "@" | "[" | "\\" | "]" | "^" | "_" | "{" | "|" | "}" | "~" .
not_paren_star_special = not_paren_star_quote_special | "\"\"" .
not_quote = not_paren_star_quote_special | letter | digit | "(" | ")" | "*" .
not_rparen_star = not_paren_star | "(" .
octet = hex_digit hex_digit .
special = not_paren_star_quote_special | "(" | ")" | "*" | "\"\"" .
not_rparen_star_then_rparen = not_rparen_star { not_rparen_star } ")" { ")" } .
binary_literal = "%" bit { bit } .
encoded_string_literal = "\"" encoded_character { encoded_character } "\"" .
integer_literal = digits .
real_literal = ( digits "." [ digits ] [ "e" [ sign ] digits ] ) | integer_literal .
simple_id = letter { letter | digit | "_" } .
simple_string_literal = "'" { ( "'" "'" ) | not_quote } "'" .
embedded_remark = "(*" [ remark_tag ] { ( not_paren_star { not_paren_star } ) | lparen_then_not_lparen_star | ( "*" { "*" } ) | not_rparen_star_then_rparen | embedded_remark } "*)" .
remark = embedded_remark | tail_remark .
remark_tag = "\"" remark_ref { "." remark_ref } "\"" .
remark_ref = attribute_ref | constant_ref | entity_ref | enumeration_ref | function_ref | parameter_ref | procedure_ref | rule_label_ref | rule_ref | schema_ref | subtype_constraint_ref | type_label_ref | type_ref | variable_ref .
tail_remark = "--" [ remark_tag ] .
attribute_ref = attribute_id .
constant_ref = constant_id .
entity_ref = entity_id .
enumeration_ref = enumeration_id .
function_ref = function_id .
parameter_ref = parameter_id .
procedure_ref = procedure_id .
rule_label_ref = rule_label_id .
rule_ref = rule_id .
schema_ref = schema_id .
subtype_constraint_ref = subtype_constraint_id .
type_label_ref = type_label_id .
type_ref = type_id .
variable_ref = variable_id .
abstract_entity_declaration = ABSTRACT .
abstract_supertype = ABSTRACT SUPERTYPE ";" .
abstract_supertype_declaration = ABSTRACT SUPERTYPE [ subtype_constraint ] .
actual_parameter_list = "(" [ parameter ] { "," parameter } ")" .
add_like_op = "+" | "-" | OR | XOR .
aggregate_initializer = "[" [ element { "," element } ] "]" .
aggregate_source = simple_expression .
aggregate_type = AGGREGATE [ ":" type_label ] OF parameter_type .
aggregation_types = array_type | bag_type | list_type | set_type .
algorithm_head = { declaration } [ constant_decl ] [ local_decl ] .
alias_stmt = ALIAS variable_id FOR general_ref { qualifier } ";" stmt { stmt } END_ALIAS ";" .
array_type = ARRAY bound_spec OF [ OPTIONAL ] [ UNIQUE ] instantiable_type .
assignment_stmt = general_ref { qualifier } ":=" expression ";" .
attribute_decl = redeclared_attribute | attribute_id .
attribute_id = simple_id .
attribute_qualifier = "." attribute_ref .
bag_type = BAG [ bound_spec ] OF instantiable_type .
binary_type = BINARY [ width_spec ] .
boolean_type = BOOLEAN .
bound_1 = numeric_expression .
bound_2 = numeric_expression .
bound_spec = "[" bound_1 ":" bound_2 "]" .
built_in_constant = CONST_E | PI | SELF | "?" .
built_in_function = ABS | ACOS | ASIN | ATAN | BLENGTH | COS | EXISTS | EXP | FORMAT | HIBOUND | HIINDEX | LENGTH | LOBOUND | LOINDEX | LOG | LOG2 | LOG10 | NVL | ODD | ROLESOF | SIN | SIZEOF | SQRT | TAN | TYPEOF | USEDIN | VALUE | VALUE_IN | VALUE_UNIQUE .
built_in_procedure = INSERT | REMOVE .
case_action = case_label { "," case_label } ":" stmt .
case_label = expression .
case_stmt = CASE selector OF { case_action } [ OTHERWISE ":" stmt ] END_CASE ";" .
compound_stmt = BEGIN stmt { stmt } END ";" .
concrete_types = aggregation_types | simple_types | type_ref .
constant_body = constant_id ":" instantiable_type ":=" expression ";" .
constant_decl = CONSTANT constant_body { constant_body } END_CONSTANT ";" .
constant_factor = built_in_constant | constant_ref .
constant_id = simple_id .
constructed_types = enumeration_type | select_type .
declaration = entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl .
derived_attr = attribute_decl ":" parameter_type ":=" expression ";" .
derive_clause = DERIVE derived_attr { derived_attr } .
domain_rule = rule_label_id ":" expression .
element = expression [ ":" repetition ] .
entity_body = { explicit_attr } [ derive_clause ] [ inverse_clause ] [ unique_clause ] [ where_clause ] .
entity_constructor = entity_ref "(" [ expression { "," expression } ] ")" .
entity_decl = entity_head entity_body END_ENTITY ";" .
entity_head = ENTITY entity_id subsuper ";" .
entity_id = simple_id .
enumeration_extension = BASED_ON type_ref [ WITH enumeration_items ] .
enumeration_id = simple_id .
enumeration_items = "(" enumeration_id { "," enumeration_id } ")" .
enumeration_reference = [ type_ref "." ] enumeration_ref .
enumeration_type = [ EXTENSIBLE ] ENUMERATION [ ( OF enumeration_items ) | enumeration_extension ] .
escape_stmt = ESCAPE ";" .
explicit_attr = attribute_decl { "," attribute_decl } ":" [ OPTIONAL ] parameter_type ";" .
expression = simple_expression [ rel_op_extended simple_expression ] .
factor = simple_factor [ "**" simple_factor ] .
formal_parameter = parameter_id { "," parameter_id } ":" parameter_type .
function_call = ( built_in_function | function_ref ) actual_parameter_list .
function_decl = function_head algorithm_head stmt { stmt } END_FUNCTION ";" .
function_head = FUNCTION function_id [ "(" formal_parameter { ";" formal_parameter } ")" ] ":" parameter_type ";" .
function_id = simple_id .
generalized_types = aggregate_type | general_aggregation_types | generic_entity_type | generic_type .
general_aggregation_types = general_array_type | general_bag_type | general_list_type | general_set_type .
general_array_type = ARRAY [ bound_spec ] OF [ OPTIONAL ] [ UNIQUE ] parameter_type .
general_bag_type = BAG [ bound_spec ] OF parameter_type .
general_list_type = LIST [ bound_spec ] OF [ UNIQUE ] parameter_type .
general_ref = parameter_ref | variable_ref .
general_set_type = SET [ bound_spec ] OF parameter_type .
generic_entity_type = GENERIC_ENTITY [ ":" type_label ] .
generic_type = GENERIC [ ":" type_label ] .
group_qualifier = "\\" entity_ref .
if_stmt = IF logical_expression THEN stmt { stmt } [ ELSE stmt { stmt } ] END_IF ";" .
increment = numeric_expression .
increment_control = variable_id ":=" bound_1 TO bound_2 [ BY increment ] .
index = numeric_expression .
index_1 = index .
index_2 = index .
index_qualifier = "[" index_1 [ ":" index_2 ] "]" .
instantiable_type = concrete_types | entity_ref .
integer_type = INTEGER .
interface_specification = reference_clause | use_clause .
interval = "{" interval_low interval_op interval_item interval_op interval_high "}" .
interval_high = simple_expression .
interval_item = simple_expression .
interval_low = simple_expression .
interval_op = "<=" | "<" .
inverse_attr = attribute_decl ":" [ ( SET | BAG ) [ bound_spec ] OF ] entity_ref FOR [ entity_ref "." ] attribute_ref ";" .
inverse_clause = INVERSE inverse_attr { inverse_attr } .
list_type = LIST [ bound_spec ] OF [ UNIQUE ] instantiable_type .
literal = binary_literal | logical_literal | real_literal | string_literal .
local_decl = LOCAL local_variable { local_variable } END_LOCAL ";" .
local_variable = variable_id { "," variable_id } ":" parameter_type [ ":=" expression ] ";" .
logical_expression = expression .
logical_literal = FALSE | TRUE | UNKNOWN .
logical_type = LOGICAL .
multiplication_like_op = "*" | "/" | DIV | MOD | AND | "||" .
named_types = entity_ref | type_ref .
named_type_or_rename = named_types [ AS ( entity_id | type_id ) ] .
null_stmt = ";" .
number_type = NUMBER .
numeric_expression = simple_expression .
one_of = ONEOF "(" supertype_expression { "," supertype_expression } ")" .
parameter = expression .
parameter_id = simple_id .
parameter_type = generalized_types | simple_types | named_types .
population = entity_ref .
precision_spec = numeric_expression .
primary = literal | ( qualifiable_factor { qualifier } ) .
procedure_call_stmt = ( built_in_procedure | procedure_ref ) actual_parameter_list ";" .
procedure_decl = procedure_head algorithm_head { stmt } END_PROCEDURE ";" .
procedure_head = PROCEDURE procedure_id [ "(" [ VAR ] formal_parameter { ";" [ VAR ] formal_parameter } ")" ] ";" .
procedure_id = simple_id .
qualifiable_factor = function_call | attribute_ref | constant_factor | general_ref | population .
qualified_attribute = SELF group_qualifier attribute_qualifier .
qualifier = attribute_qualifier | group_qualifier | index_qualifier .
query_expression = QUERY "(" variable_id "<*" aggregate_source "|" logical_expression ")" .
real_type = REAL [ "(" precision_spec ")" ] .
redeclared_attribute = qualified_attribute [ RENAMED attribute_id ] .
referenced_attribute = attribute_ref | qualified_attribute .
reference_clause = REFERENCE FROM schema_ref [ "(" resource_or_rename { "," resource_or_rename } ")" ] ";" .
rel_op = "<=" | ">=" | "<>" | "=" | ":<>:" | ":=:" | "<" | ">" .
rel_op_extended = rel_op | IN | LIKE .
rename_id = constant_id | entity_id | function_id | procedure_id | type_id .
repeat_control = [ increment_control ] [ while_control ] [ until_control ] .
repeat_stmt = REPEAT repeat_control ";" stmt { stmt } END_REPEAT ";" .
repetition = numeric_expression .
resource_or_rename = resource_ref [ AS rename_id ] .
resource_ref = constant_ref | entity_ref | function_ref | procedure_ref | type_ref .
return_stmt = RETURN [ "(" expression ")" ] ";" .
rule_decl = rule_head algorithm_head { stmt } where_clause END_RULE ";" .
rule_head = RULE rule_id FOR "(" entity_ref { "," entity_ref } ")" ";" .
rule_id = simple_id .
rule_label_id = simple_id .
schema_body = { interface_specification } [ constant_decl ] { declaration | rule_decl } .
schema_decl = SCHEMA schema_id [ schema_version_id ] ";" schema_body END_SCHEMA ";" .
schema_id = simple_id .
schema_version_id = string_literal .
selector = expression .
select_extension = BASED_ON type_ref [ WITH select_list ] .
select_list = "(" named_types { "," named_types } ")" .
select_type = [ EXTENSIBLE [ GENERIC_ENTITY ] ] SELECT [ select_list | select_extension ] .
set_type = SET [ bound_spec ] OF instantiable_type .
sign = "+" | "-" .
simple_expression = term { add_like_op term } .
simple_factor = aggregate_initializer | interval | query_expression | ( [ unary_op ] ( "(" expression ")" | primary ) ) | entity_constructor | enumeration_reference .
simple_types = binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type .
skip_stmt = SKIP ";" .
stmt = alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt .
string_literal = simple_string_literal | encoded_string_literal .
string_type = STRING [ width_spec ] .
subsuper = [ supertype_constraint ] [ subtype_declaration ] .
subtype_constraint = OF "(" supertype_expression ")" .
subtype_constraint_body = [ abstract_supertype ] [ total_over ] [ supertype_expression ";" ] .
subtype_constraint_decl = subtype_constraint_head subtype_constraint_body END_SUBTYPE_CONSTRAINT ";" .
subtype_constraint_head = SUBTYPE_CONSTRAINT subtype_constraint_id FOR entity_ref ";" .
subtype_constraint_id = simple_id .
subtype_declaration = SUBTYPE OF "(" entity_ref { "," entity_ref } ")" .
supertype_constraint = abstract_supertype_declaration | abstract_entity_declaration | supertype_rule .
supertype_expression = supertype_factor { ANDOR supertype_factor } .
supertype_factor = supertype_term { AND supertype_term } .
supertype_rule = SUPERTYPE subtype_constraint .
supertype_term = one_of | "(" supertype_expression ")" | entity_ref .
syntax = schema_decl { schema_decl } .
term = factor { multiplication_like_op factor } .
total_over = TOTAL_OVER "(" entity_ref { "," entity_ref } ")" ";" .
type_decl = TYPE type_id "=" underlying_type ";" [ where_clause ] END_TYPE ";" .
type_id = simple_id .
type_label = type_label_id | type_label_ref .
type_label_id = simple_id .
unary_op = "+" | "-" | NOT .
underlying_type = constructed_types | concrete_types .
unique_clause = UNIQUE unique_rule ";" { unique_rule ";" } .
unique_rule = rule_label_id ":" referenced_attribute { "," referenced_attribute } .
until_control = UNTIL logical_expression .
use_clause = USE FROM schema_ref [ "(" named_type_or_rename { "," named_type_or_rename } ")" ] ";" .
variable_id = simple_id .
where_clause = WHERE domain_rule ";" { domain_rule ";" } .
while_control = WHILE logical_expression .
width = numeric_expression .
width_spec = "(" width ")" [ FIXED ] .
+127
View File
@@ -0,0 +1,127 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import templates
import documentation
class Header:
def __init__(self, mapping):
emitted_types = set(mapping.express_to_cpp_typemapping.values())
declarations = []
write = lambda str, **kwargs: declarations.append(str%dict({
'documentation': templates.multi_line_comment(documentation.description(kwargs['name']))}, **kwargs))
for name, type in mapping.schema.simpletypes.items():
type_str = mapping.make_type_string(type)
type_dep = mapping.get_type_dep(type)
if type_dep in emitted_types:
write(templates.simpletype, name=name, type=type_str)
emitted_types.add(name)
for name, type in mapping.schema.selects.items():
write(templates.select, name=name)
emitted_types.add(name)
for name, type in mapping.schema.simpletypes.items():
if name not in emitted_types:
type_str = mapping.make_type_string(type)
write(templates.simpletype, name=name, type=type_str)
emitted_types.add(name)
for name, type in mapping.schema.enumerations.items():
short_name = name[:-4] if name.endswith("Enum") else name
write(templates.enumeration, name=name, values=", ".join(["%s_%s"%(short_name, v) for v in type.values]))
forward_definitions = "".join(["class %s; "%n for n in mapping.schema.entities.keys()])
class_definitions = []
write = lambda str, **kwargs: class_definitions.append(str%dict({
'documentation': templates.multi_line_comment(documentation.description(kwargs['name']))}, **kwargs))
emitted_entities = set()
while len(emitted_entities) < len(mapping.schema.entities):
for name, type in mapping.schema.entities.items():
if name in emitted_entities: continue
if len(type.supertypes) == 0 or set(type.supertypes) < emitted_entities:
attr_lines = []
def write_method(attr):
if attr.optional:
attr_lines.append(templates.optional_attribute_description % (attr.name, name))
attr_lines.append("bool has%s();"%(attr.name))
attr_lines.extend(["/// %s"%d for d in documentation.description((name, attr.name))])
type_str = mapping.get_parameter_type(attr, allow_optional=False, allow_entities=False)
if mapping.make_argument_type(attr) != "IfcUtil::Argument_UNKNOWN":
attr_lines.append("%s %s();"%(type_str, attr.name))
attr_lines.append("void set%s(%s v);"%(attr.name, type_str))
[write_method(attr) for attr in type.attributes]
inv_lines = []
def write_inverse(attr):
inv_lines.append(templates.inverse_attr%{'name':attr.name, 'entity':attr.entity, 'attribute':attr.attribute})
if type.inverse:
[write_inverse(attr) for attr in type.inverse.elements]
attributes = "\n".join(["%s%s"%(' '*4, a) for a in attr_lines])
if len(attributes): attributes += '\n'
inverse = "\n".join(["%s%s"%(' '*4, a) for a in inv_lines])
if len(inverse): inverse += '\n'
supertypes = type.supertypes if len(type.supertypes) else ['IfcUtil::IfcBaseEntity']
superclass = ": %s "%(", ".join(["public %s"%c for c in supertypes]))
argument_count = mapping.argument_count(type)
argument_start = argument_count - len(type.attributes)
argument_name_function_body_switch_stmt = " switch (i) {%s}"%("".join(['case %d: return "%s"; '%(i+argument_start, attr.name) for i, attr in enumerate(type.attributes)])) if len(type.attributes) else ""
argument_name_function_body_tail = (" return %s::getArgumentName(i); "%type.supertypes[0]) if len(type.supertypes) == 1 else ' throw IfcParse::IfcException("argument out of range"); '
argument_name_function_body = argument_name_function_body_switch_stmt + argument_name_function_body_tail
argument_type_function_body_switch_stmt = " switch (i) {%s}"%("".join(['case %d: return %s; '%(i+argument_start, mapping.make_argument_type(attr)) for i, attr in enumerate(type.attributes)])) if len(type.attributes) else ""
argument_type_function_body_tail = (" return %s::getArgumentType(i); "%type.supertypes[0]) if len(type.supertypes) == 1 else ' throw IfcParse::IfcException("argument out of range"); '
argument_type_function_body = argument_type_function_body_switch_stmt + argument_type_function_body_tail
constructor_arguments = ", ".join("%(full_type)s v%(index)d_%(name)s"%a for a in mapping.get_assignable_arguments(type))
write(templates.entity, **locals())
emitted_entities.add(name)
self.str = templates.header % {
'schema_name_upper' : mapping.schema.name.upper(),
'schema_name' : mapping.schema.name.capitalize(),
'declarations' : ''.join(declarations),
'forward_definitions' : forward_definitions,
'class_definitions' : ''.join(class_definitions)
}
self.schema_name = mapping.schema.name.capitalize()
def __repr__(self):
return self.str
def emit(self):
f = open('%s.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+178
View File
@@ -0,0 +1,178 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import templates
class Implementation:
def __init__(self, mapping):
enumeration_functions = []
entity_implementations = []
schema_entity_statements = []
schema_name = mapping.schema.name.capitalize()
stringify = lambda s: '"%s"'%s
cat = lambda vs: "".join(vs)
catc = lambda vs: ", ".join(vs)
catnl = lambda vs: "\n".join(vs)
cator = lambda vs: " || ".join(vs)
nl = lambda s: "%s\n"%s if len(s) else s
write = lambda str, **kwargs: enumeration_functions.append(str%kwargs)
for name, enum in mapping.schema.enumerations.items():
short_name = name[:-4] if name.endswith("Enum") else name
context = locals()
write(
templates.enumeration_function,
max_id = len(enum.values),
name = name,
values = catc(map(stringify, enum.values)),
from_string_statements = catnl(templates.enum_from_string_stmt%dict(context,**locals()) for value in enum.values)
)
write = lambda str, **kwargs: entity_implementations.append(str%kwargs)
for name, type in mapping.schema.entities.items():
parent_type_test = "" if not type.supertypes or len(type.supertypes) != 1 \
else templates.parent_type_test%(type.supertypes[0])
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
constructor_arguments_str = catc("%(full_type)s v%(index)d_%(name)s"%a for a in constructor_arguments if not a['is_derived'])
attributes = []
constructor_implementations = []
write_attr = lambda str, **kwargs: attributes.append(str%kwargs)
for arg in constructor_arguments:
if not arg['is_inherited'] and not arg['is_derived']:
if arg['is_optional']:
write_attr(
templates.function,
class_name = name,
name = 'has%s'%arg['name'],
arguments = '',
return_type = 'bool',
body = templates.optional_attr_stmt % {'index':arg['index']-1}
)
tmpl = templates.get_attr_stmt_enum if arg['is_enum'] else templates.get_attr_stmt_array if arg['is_array'] and not mapping.schema.is_simpletype(arg['list_instance_type']) and arg['list_instance_type'] not in mapping.express_to_cpp_typemapping else templates.get_attr_stmt_entity if arg['non_optional_type'].endswith('*') else templates.get_attr_stmt
write_attr(
templates.function,
class_name = name,
name = arg['name'],
arguments = '',
return_type = arg['non_optional_type'],
body = tmpl % {'index': arg['index']-1,
'type' : arg['non_optional_type'].split('::')[0],
'list_instance_type' : arg['list_instance_type']}
)
tmpl = templates.set_attr_stmt_enum if arg['is_enum'] else templates.set_attr_stmt_array if arg['is_array'] and not mapping.schema.is_simpletype(arg['list_instance_type']) and arg['list_instance_type'] not in mapping.express_to_cpp_typemapping else templates.set_attr_stmt
write_attr(
templates.function,
class_name = name,
name = 'set%s'%arg['name'],
arguments = '%s v'%arg['non_optional_type'],
return_type = 'void',
body = tmpl % {'index': arg['index']-1,
'type' : arg['non_optional_type'].split('::')[0]}
)
if arg['is_derived']:
constructor_implementations.append(templates.constructor_stmt_derived % {'index' : arg['index']-1})
else:
is_optional_non_naked_ptr = arg['is_optional'] and not arg['non_optional_type'].endswith('*')
arg_name = "v%(index)d_%(name)s"%arg
deref_name = ("*%s"%arg_name) if is_optional_non_naked_ptr else arg_name
tmpl = templates.constructor_stmt_array if arg['is_templated_list'] \
else templates.constructor_stmt_enum if arg['is_enum'] \
else templates.constructor_stmt
impl = tmpl % {'name' : deref_name,
'index' : arg['index']-1,
'type' : arg['non_optional_type'].split('::')[0]}
if is_optional_non_naked_ptr:
impl = templates.constructor_stmt_optional%{'name' : arg_name,
'index' : arg['index']-1,
'stmt' : impl}
constructor_implementations.append(impl)
inverse = [templates.function % {
'class_name' : name,
'name' : i.name,
'arguments' : '',
'return_type' : '%s::list' % i.entity,
'body' : templates.get_inverse % {'type': i.entity}
} for i in (type.inverse.elements if type.inverse else [])]
superclass = "%s((IfcAbstractEntityPtr)0)" % type.supertypes[0] if len(type.supertypes) == 1 else 'IfcUtil::IfcBaseEntity()'
write(
templates.entity_implementation,
name = name,
parent_type_test = parent_type_test,
constructor_arguments = constructor_arguments_str,
constructor_implementation = cat(constructor_implementations),
attributes = nl(catnl(attributes)),
inverse = nl(catnl(inverse)),
superclass = superclass
)
selectable_simple_types = sorted(set(sum([b.values for a,b in mapping.schema.selects.items()], [])) & set(mapping.schema.types.keys()))
schema_entity_statements += [templates.schema_simple_stmt%locals() for name in selectable_simple_types]
schema_entity_statements += [templates.schema_entity_stmt%locals() for name, type in mapping.schema.entities.items()]
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
max_len = max(map(len, enumerable_types))
type_name_strings = catc(map(stringify, enumerable_types))
string_map_statements = [templates.string_map_statement % {
'uppercase_name' : name.upper(),
'name' : name,
'padding' : ' ' * (max_len - len(name))
} for name in enumerable_types]
parent_type_statements = [templates.parent_type_stmt % {
'name' : name,
'parent' : type.supertypes[0],
'padding' : ' ' * (max_len - len(name))
} for name, type in mapping.schema.entities.items() if type.supertypes and len(type.supertypes) == 1]
max_id = len(enumerable_types)
simple_type_statements = cator("v == Type::%s"%name for name in selectable_simple_types)
self.str = templates.implementation % {
'schema_name_upper' : mapping.schema.name.upper(),
'schema_name' : mapping.schema.name.capitalize(),
'max_id' : max_id,
'enumeration_functions' : cat(enumeration_functions),
'schema_entity_statements' : catnl(schema_entity_statements),
'type_name_strings' : type_name_strings,
'string_map_statements' : catnl(string_map_statements),
'simple_type_statement' : simple_type_statements,
'parent_type_statements' : catnl(parent_type_statements),
'entity_implementations' : catnl(entity_implementations)
}
self.schema_name = mapping.schema.name.capitalize()
def __repr__(self):
return self.str
def emit(self):
f = open('%s.cpp'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+171
View File
@@ -0,0 +1,171 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import nodes
import templates
class Mapping:
express_to_cpp_typemapping = {
'boolean' : 'bool',
'logical' : 'bool',
'integer' : 'int',
'real' : 'double',
'number' : 'double',
'string' : 'std::string'
}
def __init__(self, schema):
self.schema = schema
def make_type_string(self, type):
if isinstance(type, str):
return self.express_to_cpp_typemapping.get(type, type)
else:
is_list = self.schema.is_entity(type.type)
tmpl = templates.list_type if is_list else templates.array_type
return tmpl % {
'instance_type' : self.make_type_string(type.type),
'lower' : type.bounds.lower,
'upper' : type.bounds.upper,
}
def is_array(self, type):
if isinstance(type, nodes.AggregationType):
return True
elif isinstance(type, str) and self.schema.is_type(type):
return self.is_array(self.schema.types[type].type.type)
else:
return False
def make_argument_type(self, attr):
def _make_argument_type(type):
if type in self.express_to_cpp_typemapping:
return self.express_to_cpp_typemapping.get(type, type).split('::')[-1].upper()
elif self.schema.is_entity(type):
return "ENTITY"
elif self.schema.is_type(type):
return _make_argument_type(self.schema.types[type].type.type)
elif isinstance(type, nodes.BinaryType):
return "UNKNOWN"
elif isinstance(type, nodes.EnumerationType):
return "ENUMERATION"
elif isinstance(type, nodes.SelectType):
return "ENTITY"
elif isinstance(type, nodes.AggregationType):
ty = _make_argument_type(type.type)
if ty == "UNKNOWN": return "UNKNOWN"
return "ENTITY_LIST" if ty == "ENTITY" else ("VECTOR_%s"%ty)
else: raise ValueError
supported = {'INT', 'BOOL', 'DOUBLE', 'STRING', 'VECTOR_INT', 'VECTOR_DOUBLE', 'VECTOR_STRING', 'ENTITY', 'ENTITY_LIST', 'ENUMERATION'}
ty = _make_argument_type(attr.type)
if ty not in supported: ty = 'UNKNOWN'
return "IfcUtil::Argument_%s" % ty
def get_type_dep(self, type):
if isinstance(type, str):
return self.express_to_cpp_typemapping.get(type, type)
else:
return self.get_type_dep(type.type)
def get_parameter_type(self, attr, allow_optional, allow_entities, allow_pointer = True):
type_str = self.express_to_cpp_typemapping.get(str(attr.type), attr.type)
is_ptr = False
if self.schema.is_enumeration(attr.type):
type_str = '%s::%s'%(attr.type, attr.type)
elif isinstance(type_str, nodes.AggregationType):
ty = self.get_parameter_type(attr.type, False, allow_entities, allow_pointer=False)
if allow_entities and self.schema.is_select(attr.type.type):
type_str = templates.untyped_list
elif self.schema.is_simpletype(ty) or ty in self.express_to_cpp_typemapping.values():
type_str = templates.array_type % {
'instance_type' : ty,
'lower' : attr.type.bounds.lower,
'upper' : attr.type.bounds.upper
}
else:
type_str = templates.list_type % {
'instance_type': ty
}
elif allow_pointer and self.schema.is_entity(type_str):
type_str += '*'
is_ptr = True
elif not allow_pointer and self.schema.is_select(type_str):
type_str = "IfcUtil::IfcAbstractSelect"
is_ptr = True
if allow_optional and attr.optional and not is_ptr:
type_str = "boost::optional< %s >"%type_str
return type_str
def argument_count(self, t):
c = sum([self.argument_count(self.schema.entities[s]) for s in t.supertypes])
return c + len(t.attributes)
def arguments(self, t):
c = sum([self.arguments(self.schema.entities[s]) for s in t.supertypes], [])
return c + t.attributes
def derived_in_supertype(self, t):
c = sum([self.derived_in_supertype(self.schema.entities[s]) for s in t.supertypes], [])
return c + ([str(s) for s in t.derive.elements] if t.derive else [])
def list_instance_type(self, attr):
f = lambda v : 'IfcUtil::IfcAbstractSelect' if self.schema.is_select(v) else v
if self.is_array(attr.type) and not isinstance(attr.type, str):
return f(attr.type.type)
elif self.is_array(attr.type) and isinstance(attr.type, str):
return f(attr.type)
else: return None
def is_templated_list(self, attr):
ty = self.list_instance_type(attr)
arr = self.is_array(attr.type)
simple = self.schema.is_simpletype(ty)
express = ty in self.express_to_cpp_typemapping
select = ty == 'IfcUtil::IfcAbstractSelect'
return arr and not simple and not express and not select
def get_assignable_arguments(self, t, include_derived = False):
count = self.argument_count(t)
num_inherited = count - len(t.attributes)
derived = set(self.derived_in_supertype(t))
attrs = enumerate(self.arguments(t))
def include(attr):
not_derived = include_derived or (attr.name not in derived)
supported = self.make_argument_type(attr) != "IfcUtil::Argument_UNKNOWN"
return not_derived and supported
return [{
'index' : i+1,
'name' : attr.name,
'full_type' : self.get_parameter_type(attr, allow_optional=True, allow_entities=True),
'specialized_type' : self.get_parameter_type(attr, allow_optional=True, allow_entities=False),
'non_optional_type' : self.get_parameter_type(attr, allow_optional=False, allow_entities=False),
'list_instance_type' : self.list_instance_type(attr),
'is_optional' : attr.optional,
'is_inherited' : i < num_inherited,
'is_enum' : attr.type in self.schema.enumerations,
'is_array' : self.is_array(attr.type),
'is_derived' : attr.name in derived,
'is_templated_list' : self.is_templated_list(attr),
'argument_type_enum' : self.make_argument_type(attr),
'argument_type' : attr.type
} for i, attr in attrs if include(attr)]
+175
View File
@@ -0,0 +1,175 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import string
import collections
class Node:
def __init__(self, tokens):
self.tokens = tokens
self.init()
def tokens_of_type(self, cls):
return [t for t in self.tokens if isinstance(t, cls)]
def single_token_of_type(self, cls, k = None, v = None):
ts = [t for t in self.tokens if isinstance(t, cls) and (k is None or getattr(t, k) == v)]
return ts[0] if len(ts) == 1 else None
class TypeDeclaration(Node):
name = property(lambda self: self.tokens[1])
type = property(lambda self: self.tokens[3])
def init(self):
assert self.tokens[0] == 'type'
assert isinstance(self.type, UnderlyingType)
def __repr__(self):
return "%s = TypeDeclaration(%s)" % (self.name, self.type)
class EntityDeclaration(Node):
name = property(lambda self: self.tokens[1])
attributes = property(lambda self: self.tokens_of_type(ExplicitAttribute))
def init(self):
assert self.tokens[0] == 'entity'
s = self.single_token_of_type(SubtypeExpression)
self.inverse = self.single_token_of_type(AttributeList, 'type', 'inverse')
self.derive = self.single_token_of_type(AttributeList, 'type', 'derive')
self.supertypes = s.types if s else []
def __repr__(self):
builder = ""
builder += "Entity(%s)" % (self.name)
if len(self.supertypes):
builder += "\n Supertypes: %s"%(",".join(self.supertypes))
if len(self.attributes):
builder += "\n Attributes: %s"%("".join(["\n %s"%a for a in self.attributes]))
if self.derive:
builder += "\n Derive:"
builder += str(self.derive)
if self.inverse:
builder += "\n Inverse:"
builder += str(self.inverse)
builder += "\n"
return builder
class UnderlyingType(Node):
type = property(lambda self: self.tokens[0])
def init(self):
pass
def __repr__(self):
return repr(self.type)
class EnumerationType(Node):
type = property(lambda self: self.tokens[0])
values = property(lambda self: self.tokens[3::2])
def init(self):
assert self.type == 'enumeration'
def __repr__(self):
return ",".join(self.values)
class AggregationType(Node):
aggregate_type = property(lambda self: self.tokens[0])
bounds = property(lambda self: None if self.tokens[1] == 'of' else self.tokens[1])
type = property(lambda self: self.tokens[-1])
def init(self):
assert self.bounds is None or isinstance(self.bounds, BoundSpecification)
def __repr__(self):
return "%s%s of %s"%(self.aggregate_type, self.bounds, self.type)
class SelectType(Node):
type = property(lambda self: self.tokens[0])
values = property(lambda self: self.tokens[2::2])
def init(self):
assert self.type == 'select'
def __repr__(self):
return ",".join(self.values)
class SubSuperTypeExpression(Node):
type = property(lambda self: self.tokens[0])
types = property(lambda self: self.tokens[3::2])
def init(self):
assert self.type == self.class_type
class SubtypeExpression(SubSuperTypeExpression):
class_type = 'subtype'
class AttributeList(Node):
elements = property(lambda self: self.tokens[1:])
def __init__(self, ty, toks):
self.type = ty
Node.__init__(self, toks)
def init(self):
assert self.type == self.tokens[0]
def __repr__(self):
return "".join(["\n %s"%s for s in self.elements])
class InverseAttribute(Node):
name = property(lambda self: self.tokens[0])
type = property(lambda self: self.tokens[2])
bounds = property(lambda self: None if len(self.tokens) == 6 else self.tokens[3])
entity = property(lambda self: self.tokens[-4])
attribute = property(lambda self: self.tokens[-2])
def init(self):
assert self.bounds is None or isinstance(self.bounds, BoundSpecification)
def __repr__(self):
return "%s = %s.%s (%s%s)"%(self.name, self.entity, self.attribute, self.type, self.bounds or "")
class DerivedAttribute(Node):
def init(self):
name_index = list(self.tokens).index(':') - 1
self.name = self.tokens[name_index]
def __repr__(self):
return str(self.name)
class BinaryType(Node):
def init(self):
pass
def __repr__(self):
return "BINARY"
class BoundSpecification(Node):
lower = property(lambda self: self.tokens[1])
upper = property(lambda self: self.tokens[3])
def init(self):
# assert self.lower in string.digits or self.lower == '?'
# assert self.upper in string.digits or self.upper == '?'
pass
def __repr__(self):
return "[%s:%s]"%(self.lower, self.upper)
class ExplicitAttribute(Node):
name = property(lambda self: self.tokens[0])
type = property(lambda self: self.tokens[-2])
optional = property(lambda self: len(self.tokens) == 5 and self.tokens[-3] == 'optional')
def init(self):
# NB: This assumes a single name per attribute
# definition, which is not necessarily the case.
assert self.tokens[1] == ':'
def __repr__(self):
return "%s : %s%s" % (self.name, self.type, " ?" if self.optional else "")
+35
View File
@@ -0,0 +1,35 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import templates
class RuntimeTypingHeader:
def __init__(self, mapping):
self.str = templates.rt_header % {
'schema_name_upper' : mapping.schema.name.upper(),
'schema_name' : mapping.schema.name.capitalize()
}
self.schema_name = mapping.schema.name.capitalize()
def __repr__(self):
return self.str
def emit(self):
f = open('%s-rt.h'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+117
View File
@@ -0,0 +1,117 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import templates
class RuntimeTypingImplementation:
def __init__(self, mapping):
schema_name = mapping.schema.name.capitalize()
entity_descriptors = []
enumeration_descriptors = []
derived_field_statements = []
inverse_implementations = []
for name, type in mapping.schema.simpletypes.items():
entity_descriptors.append(templates.entity_descriptor % {
'type' : name,
'parent_statement' : '0',
'entity_descriptor_attributes' : templates.entity_descriptor_attribute % {
'name' : 'wrappedValue',
'optional' : 'false',
'type' : mapping.make_argument_type(mapping.schema.types[name].type)
}
})
emitted_entities = set()
entities_to_emit = mapping.schema.entities.keys()
while len(emitted_entities) < len(mapping.schema.entities):
for name, type in mapping.schema.entities.items():
if name in emitted_entities: continue
if len(type.supertypes) == 0 or set(type.supertypes) < emitted_entities:
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
entity_descriptor_attributes = []
for arg in constructor_arguments:
if not arg['is_inherited']:
tmpl = templates.entity_descriptor_attribute_enum if arg['argument_type_enum'] == 'IfcUtil::Argument_ENUMERATION' else templates.entity_descriptor_attribute
entity_descriptor_attributes.append(tmpl % {
'name' : arg['name'],
'optional' : 'true' if arg['is_optional'] else 'false',
'type' : arg['argument_type_enum'],
'enum_type' : arg['argument_type']
})
emitted_entities.add(name)
parent_statement = '0' if len(type.supertypes) != 1 else templates.entity_descriptor_parent % {
'type' : type.supertypes[0]
}
entity_descriptors.append(templates.entity_descriptor % {
'type' : name,
'parent_statement' : parent_statement,
'entity_descriptor_attributes' : '\n'.join(entity_descriptor_attributes)
})
for name, enum in mapping.schema.enumerations.items():
enumeration_descriptor_values = '\n'.join([templates.enumeration_descriptor_value % {
'name' : v
} for v in enum.values])
enumeration_descriptors.append(templates.enumeration_descriptor % {
'type' : name,
'enumeration_descriptor_values' : enumeration_descriptor_values
})
for name, type in mapping.schema.entities.items():
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
statements = ''.join(templates.derived_field_statement_attrs % (a['index']-1) for a in constructor_arguments if a['is_derived'])
if len(statements):
derived_field_statements.append(templates.derived_field_statement % {
'type' : name,
'statements' : statements
})
for name, type in mapping.schema.entities.items():
if type.inverse:
for attr in type.inverse.elements:
related_entity = mapping.schema.entities[attr.entity]
related_attrs = [a['name'] for a in mapping.get_assignable_arguments(related_entity, include_derived=True)]
inverse_implementations.append(templates.inverse_implementation % {
'type' : name,
'name' : attr.name,
'related_type' : attr.entity,
'index' : related_attrs.index(attr.attribute)
})
self.str = templates.rt_implementation % {
'schema_name_upper' : mapping.schema.name.upper(),
'schema_name' : mapping.schema.name.capitalize(),
'entity_descriptors' : '\n'.join(entity_descriptors),
'enumeration_descriptors' : '\n'.join(enumeration_descriptors),
'derived_field_statements' : '\n'.join(derived_field_statements),
'inverse_implementations' : '\n'.join(inverse_implementations)
}
self.schema_name = mapping.schema.name.capitalize()
def __repr__(self):
return self.str
def emit(self):
f = open('%s-rt.cpp'%self.schema_name, 'w', encoding='utf-8')
f.write(str(self))
f.close()
+46
View File
@@ -0,0 +1,46 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
import nodes
import collections
class Schema:
def is_enumeration(self, v):
return v in self.enumerations
def is_select(self, v):
return v in self.selects
def is_simpletype(self, v):
return v in self.simpletypes
def is_type(self, v):
return v in self.types
def is_entity(self, v):
return v in self.entities
def __init__(self, parsetree):
self.name = parsetree[1]
sort = lambda d: collections.OrderedDict(sorted(d.items()))
self.types = sort({t.name:t for t in parsetree if isinstance(t, nodes.TypeDeclaration)})
self.entities = sort({t.name:t for t in parsetree if isinstance(t, nodes.EntityDeclaration)})
of_type = lambda *types: sort({a: b.type.type for a,b in self.types.items() if any(isinstance(b.type.type, ty) for ty in types)})
self.enumerations = of_type(nodes.EnumerationType)
self.selects = of_type(nodes.SelectType)
self.simpletypes = of_type(str, nodes.AggregationType)
+401
View File
@@ -0,0 +1,401 @@
###############################################################################
# #
# 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/>. #
# #
###############################################################################
header = """
#ifndef %(schema_name_upper)s_H
#define %(schema_name_upper)s_H
#include <string>
#include <vector>
#include <map>
#include <boost/optional.hpp>
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/%(schema_name)senum.h"
#define IfcSchema %(schema_name)s
namespace %(schema_name)s {
// Forward definitions
%(forward_definitions)s
%(declarations)s
%(class_definitions)s
void InitStringMap();
IfcUtil::IfcSchemaEntity SchemaEntity(IfcAbstractEntityPtr e = 0);
}
#endif
"""
enum_header = """
#ifndef %(schema_name_upper)sENUM_H
#define %(schema_name_upper)sENUM_H
#define IfcSchema %(schema_name)s
namespace %(schema_name)s {
namespace Type {
typedef enum {
%(types)s, ALL
} Enum;
Enum Parent(Enum v);
Enum FromString(const std::string& s);
std::string ToString(Enum v);
bool IsSimple(Enum v);
}
}
#endif
"""
rt_header = """
#ifndef %(schema_name_upper)sRT_H
#define %(schema_name_upper)sRT_H
#define IfcSchema %(schema_name)s
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcEntityDescriptor.h"
#include "../ifcparse/IfcWritableEntity.h"
namespace %(schema_name)s {
namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
#endif
"""
implementation= """
#include "../ifcparse/%(schema_name)s.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
using namespace %(schema_name)s;
using namespace IfcParse;
using namespace IfcWrite;
IfcUtil::IfcSchemaEntity %(schema_name)s::SchemaEntity(IfcAbstractEntityPtr e) {
switch(e->type()) {
%(schema_entity_statements)s
default: throw IfcException("Unable to find find keyword in schema"); break;
}
}
std::string Type::ToString(Enum v) {
if (v < 0 || v >= %(max_id)d) throw IfcException("Unable to find find keyword in schema");
const char* names[] = { %(type_name_strings)s };
return names[v];
}
static std::map<std::string,Type::Enum> string_map;
void %(schema_name)s::InitStringMap() {
%(string_map_statements)s
}
Type::Enum Type::FromString(const std::string& s) {
if (string_map.empty()) InitStringMap();
std::map<std::string,Type::Enum>::const_iterator it = string_map.find(s);
if ( it == string_map.end() ) throw IfcException("Unable to find find keyword in schema");
else return it->second;
}
Type::Enum Type::Parent(Enum v){
if (v < 0 || v >= %(max_id)d) return (Enum)-1;
%(parent_type_statements)s
return (Enum)-1;
}
bool Type::IsSimple(Enum v) {
return %(simple_type_statement)s;
}
%(enumeration_functions)s
#define RETURN_INVERSE(T) \
IfcEntities e = entity->getInverse(T::Class()); \
SHARED_PTR< IfcTemplatedEntityList<T> > l ( new IfcTemplatedEntityList<T>() ); \
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \
l->push(reinterpret_pointer_cast<IfcBaseClass,T>(*it)); \
} \
return l;
#define RETURN_AS_SINGLE(T,a) \
return reinterpret_pointer_cast<IfcBaseClass,T>(*entity->getArgument(a));
#define RETURN_AS_LIST(T,a) \
IfcEntities e = *entity->getArgument(a); \
SHARED_PTR< IfcTemplatedEntityList<T> > l ( new IfcTemplatedEntityList<T>() ); \
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) { \
l->push(reinterpret_pointer_cast<IfcBaseClass,T>(*it)); \
} \
return l;
%(entity_implementations)s
"""
rt_implementation = """
#include <set>
#include "../ifcparse/%(schema_name)s.h"
#include "../ifcparse/%(schema_name)s-rt.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcEntityDescriptor.h"
using namespace %(schema_name)s;
using namespace IfcParse;
using namespace IfcWrite;
using namespace IfcUtil;
std::map<Type::Enum,IfcEntityDescriptor*> entity_descriptor_map;
std::map<Type::Enum,IfcEnumerationDescriptor*> enumeration_descriptor_map;
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> > inverse_map;
std::map<Type::Enum,std::set<int> > derived_map;
void InitDescriptorMap() {
IfcEntityDescriptor* current;
%(entity_descriptors)s
// Enumerations
IfcEnumerationDescriptor* current_enum;
std::vector<std::string> values;
%(enumeration_descriptors)s
}
void InitInverseMap() {
%(inverse_implementations)s
}
void InitDerivedMap() {
%(derived_field_statements)s
}
int Type::GetAttributeIndex(Enum t, const std::string& a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentIndex(a);
}
int Type::GetAttributeCount(Enum t) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentCount();
}
ArgumentType Type::GetAttributeType(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentType(a);
}
const std::string& Type::GetAttributeName(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentName(a);
}
bool Type::GetAttributeOptional(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else return i->second->getArgumentOptional(a);
}
bool Type::GetAttributeDerived(Enum t, unsigned char a) {
if (derived_map.empty()) ::InitDerivedMap();
std::map<Type::Enum,std::set<int> >::const_iterator i = derived_map.find(t);
return i != derived_map.end() && i->second.find(a) != i->second.end();
}
std::pair<const char*, int> Type::GetEnumerationIndex(Enum t, const std::string& a) {
if (enumeration_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEnumerationDescriptor*>::const_iterator i = enumeration_descriptor_map.find(t);
if ( i == enumeration_descriptor_map.end() ) throw IfcException("Value not found");
else return i->second->getIndex(a);
}
std::pair<Type::Enum, unsigned> Type::GetInverseAttribute(Enum t, const std::string& a) {
if (inverse_map.empty()) ::InitInverseMap();
std::map<std::pair<Type::Enum, std::string>, std::pair<Type::Enum, int> >::const_iterator it;
std::pair<Type::Enum, std::string> key = std::make_pair(t, a);
while (true) {
it = inverse_map.find(key);
if (it != inverse_map.end()) return it->second;
if ((key.first = Parent(key.first)) == -1) break;
}
throw IfcException("Attribute not found");
}
Type::Enum Type::GetAttributeEnumerationClass(Enum t, unsigned char a) {
if (entity_descriptor_map.empty()) ::InitDescriptorMap();
std::map<Type::Enum,IfcEntityDescriptor*>::const_iterator i = entity_descriptor_map.find(t);
if ( i == entity_descriptor_map.end() ) throw IfcException("Type not found");
else {
Type::Enum t = i->second->getArgumentEnumerationClass(a);
if ( t == Type::ALL ) throw IfcException("Not an enumeration");
else return t;
}
}
void Type::PopulateDerivedFields(IfcWrite::IfcWritableEntity* e) {
std::map<Type::Enum, std::set<int> >::const_iterator i = derived_map.find(e->type());
if (i != derived_map.end()) {
for (std::set<int>::const_iterator it = i->second.begin(); it != i->second.end(); ++it) {
e->setArgumentDerived(*it);
}
}
}
"""
entity_descriptor = """ current = entity_descriptor_map[Type::%(type)s] = new IfcEntityDescriptor(Type::%(type)s,%(parent_statement)s);
%(entity_descriptor_attributes)s"""
entity_descriptor_parent = "entity_descriptor_map.find(Type::%(type)s)->second"
entity_descriptor_attribute = ' current->add("%(name)s",%(optional)s,%(type)s);'
entity_descriptor_attribute_enum = ' current->add("%(name)s",%(optional)s,%(type)s,Type::%(enum_type)s);'
enumeration_descriptor = """ values.clear(); values.reserve(128);
%(enumeration_descriptor_values)s
current_enum = enumeration_descriptor_map[Type::%(type)s] = new IfcEnumerationDescriptor(Type::%(type)s, values);"""
enumeration_descriptor_value = ' values.push_back("%(name)s");'
derived_field_statement = ' {std::set<int> idxs; %(statements)sderived_map[Type::%(type)s] = idxs;}';
derived_field_statement_attrs = 'idxs.insert(%d); '
simpletype = """%(documentation)s
typedef %(type)s %(name)s;
"""
select = """%(documentation)s
typedef IfcUtil::IfcSchemaEntity %(name)s;
"""
enumeration = """namespace %(name)s {
%(documentation)s
typedef enum {%(values)s} %(name)s;
const char* ToString(%(name)s v);
%(name)s FromString(const std::string& s);
}
"""
entity = """%(documentation)s
class %(name)s %(superclass)s{
public:
%(attributes)s virtual unsigned int getArgumentCount() const { return %(argument_count)d; }
virtual IfcUtil::ArgumentType getArgumentType(unsigned int i) const {%(argument_type_function_body)s}
virtual const char* getArgumentName(unsigned int i) const {%(argument_name_function_body)s}
virtual ArgumentPtr getArgument(unsigned int i) const { return entity->getArgument(i); }
%(inverse)s bool is(Type::Enum v) const;
Type::Enum type() const;
static Type::Enum Class();
%(name)s (IfcAbstractEntityPtr e);
%(name)s (%(constructor_arguments)s);
typedef %(name)s* ptr;
typedef SHARED_PTR< IfcTemplatedEntityList< %(name)s > > list;
typedef IfcTemplatedEntityList< %(name)s >::it it;
};
"""
enumeration_function="""
const char* %(name)s::ToString(%(name)s v) {
if ( v < 0 || v >= %(max_id)d ) throw IfcException("Unable to find find keyword in schema");
const char* names[] = { %(values)s };
return names[v];
}
%(name)s::%(name)s %(name)s::FromString(const std::string& s) {
%(from_string_statements)s
throw IfcException("Unable to find find keyword in schema");
}
"""
entity_implementation = """// Function implementations for %(name)s
%(attributes)s%(inverse)sbool %(name)s::is(Type::Enum v) const { return v == Type::%(name)s%(parent_type_test)s; }
Type::Enum %(name)s::type() const { return Type::%(name)s; }
Type::Enum %(name)s::Class() { return Type::%(name)s; }
%(name)s::%(name)s(IfcAbstractEntityPtr e) : %(superclass)s { if (!e) return; if (!e->is(Type::%(name)s)) throw IfcException("Unable to find find keyword in schema"); entity = e; }
%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass)s { IfcWritableEntity* e = new IfcWritableEntity(Class());%(constructor_implementation)s entity = e; EntityBuffer::Add(this); }
"""
optional_attribute_description = "/// Whether the optional attribute %s is defined for this %s"
function = "%(return_type)s %(class_name)s::%(name)s(%(arguments)s) { %(body)s }"
array_type = "std::vector< %(instance_type)s > /*[%(lower)s:%(upper)s]*/"
list_type = "SHARED_PTR< IfcTemplatedEntityList< %(instance_type)s > >"
untyped_list = "IfcEntities"
inverse_attr = "SHARED_PTR< IfcTemplatedEntityList< %(entity)s > > %(name)s(); // INVERSE %(entity)s::%(attribute)s"
enum_from_string_stmt = ' if (s == "%(value)s") return ::%(schema_name)s::%(name)s::%(short_name)s_%(value)s;'
schema_entity_stmt = ' case Type::%(name)s: return new %(name)s(e); break;'
schema_simple_stmt = ' case Type::%(name)s: return new IfcUtil::IfcEntitySelect(e); break;'
string_map_statement = ' string_map["%(uppercase_name)s"%(padding)s] = Type::%(name)s;'
parent_type_stmt = ' if(v==%(name)s%(padding)s) { return %(parent)s; }'
parent_type_test = " || %s::is(v)"
optional_attr_stmt = "return !entity->getArgument(%(index)d)->isNull();"
get_attr_stmt = "return *entity->getArgument(%(index)d);"
get_attr_stmt_enum = "return %(type)s::FromString(*entity->getArgument(%(index)d));"
get_attr_stmt_entity = "return (%(type)s)((IfcUtil::IfcSchemaEntity)(*entity->getArgument(%(index)d)));"
get_attr_stmt_array = "RETURN_AS_LIST(%(list_instance_type)s,%(index)d)"
get_inverse = "RETURN_INVERSE(%(type)s)"
set_attr_stmt = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v);"
set_attr_stmt_enum = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v,%(type)s::ToString(v));"
set_attr_stmt_array = "if ( ! entity->isWritable() ) { entity = new IfcWritableEntity(entity); } ((IfcWritableEntity*)entity)->setArgument(%(index)d,v->generalize());"
constructor_stmt = " e->setArgument(%(index)d,(%(name)s));"
constructor_stmt_enum = " e->setArgument(%(index)d,%(name)s,%(type)s::ToString(%(name)s));"
constructor_stmt_array = " e->setArgument(%(index)d,(%(name)s)->generalize());"
constructor_stmt_optional = " if (%(name)s) {%(stmt)s } else { e->setArgument(%(index)d); }"
constructor_stmt_derived = " e->setArgumentDerived(%(index)d);"
inverse_implementation = " inverse_map.insert(std::make_pair(std::make_pair(Type::%(type)s, \"%(name)s\"), std::make_pair(Type::%(related_type)s, %(index)d)));"
def multi_line_comment(li):
return ("/// %s"%("\n/// ".join(li))) if len(li) else ""
+16 -8
View File
@@ -36,7 +36,6 @@
#include <TopoDS_Face.hxx>
#include <Geom_Curve.hxx>
#include <gp_Pln.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcUtil.h"
@@ -80,16 +79,22 @@ namespace IfcGeom {
GV_PRECISION
};
const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0;
const int DISABLE_OBJECT_PLACEMENT = 1 << 1;
const int SEW_SHELLS = 1 << 2;
const int CONVERT_TO_METERS = 1 << 3;
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);
bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result);
bool is_shape_collection(const IfcUtil::IfcBaseClass* L);
bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result);
bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result);
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result);
bool convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
bool convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
Ifc2x3::IfcSurfaceStyleShading* get_surface_style(Ifc2x3::IfcRepresentationItem* item);
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
bool convert_openings(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
bool convert_openings_fast(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
IfcSchema::IfcSurfaceStyleShading* get_surface_style(IfcSchema::IfcRepresentationItem* item);
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid);
bool is_compound(const TopoDS_Shape& shape);
bool is_convex(const TopoDS_Wire& wire);
@@ -97,14 +102,17 @@ namespace IfcGeom {
gp_Pln plane_from_face(const TopoDS_Face& face);
gp_Pnt point_above_plane(const gp_Pln& pln, bool agree=true);
const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid);
bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face);
double shape_volume(const TopoDS_Shape& s);
double face_area(const TopoDS_Face& f);
void apply_tolerance(TopoDS_Shape& s, double t);
void SetValue(GeomValue var, double value);
double GetValue(GeomValue var);
Ifc2x3::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es);
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
std::string create_brep_data(IfcSchema::IfcProduct* s, unsigned int settings);
void initialize_units_and_precision(IfcSchema::IfcProject* proj, double& unit_magnitude, std::string& unit_name);
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape);
IfcSchema::IfcProductDefinitionShape* tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es);
namespace Cache {
+23 -15
View File
@@ -23,6 +23,8 @@
* *
********************************************************************************/
#include <algorithm>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
@@ -77,16 +79,16 @@
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert(const Ifc2x3::IfcCircle::ptr l, Handle(Geom_Curve)& curve) {
bool IfcGeom::convert(const IfcSchema::IfcCircle::ptr l, Handle(Geom_Curve)& curve) {
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( r < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
return false;
}
gp_Trsf trsf;
Ifc2x3::IfcAxis2Placement placement = l->Position();
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)placement,trsf);
IfcSchema::IfcAxis2Placement placement = l->Position();
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
} else {
gp_Trsf2d trsf2d;
IfcGeom::convert((IfcAxis2Placement2D*)placement,trsf2d);
@@ -96,31 +98,37 @@ bool IfcGeom::convert(const Ifc2x3::IfcCircle::ptr l, Handle(Geom_Curve)& curve)
curve = new Geom_Circle(ax, r);
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcEllipse::ptr l, Handle(Geom_Curve)& curve) {
bool IfcGeom::convert(const IfcSchema::IfcEllipse::ptr l, Handle(Geom_Curve)& curve) {
double x = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
double y = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
if (x < ALMOST_ZERO || y < ALMOST_ZERO) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity);
return false;
}
if (y > x) {
Logger::Message(Logger::LOG_ERROR, "Ellipse with SemiAxis2 larger than SemiAxis1 not supported for:", l->entity);
return false;
}
// Open Cascade does not allow ellipses of which the minor radius
// is greater than the major radius. Hence, in this case, the
// ellipse is rotated. Note that special care needs to be taken
// when creating a trimmed curve off of an ellipse like this.
const bool rotated = y > x;
gp_Trsf trsf;
Ifc2x3::IfcAxis2Placement placement = l->Position();
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)placement,trsf);
IfcSchema::IfcAxis2Placement placement = l->Position();
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
} else {
gp_Trsf2d trsf2d;
IfcGeom::convert((Ifc2x3::IfcAxis2Placement2D*)placement,trsf2d);
IfcGeom::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d);
trsf = trsf2d;
}
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
gp_Ax2 ax = gp_Ax2();
if (rotated) {
ax.Rotate(ax.Axis(), M_PI / 2.);
std::swap(x, y);
}
ax.Transform(trsf);
curve = new Geom_Ellipse(ax, x, y);
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcLine::ptr l, Handle(Geom_Curve)& curve) {
bool IfcGeom::convert(const IfcSchema::IfcLine::ptr l, Handle(Geom_Curve)& curve) {
gp_Pnt pnt;gp_Vec vec;
IfcGeom::convert(l->Pnt(),pnt);
IfcGeom::convert(l->Dir(),vec);
+466 -40
View File
@@ -50,23 +50,27 @@
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_OffsetCurve.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
#include <BRepOffsetAPI_Sewing.hxx>
#include <BRepOffsetAPI_MakeOffset.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <ShapeFix_Shape.hxx>
@@ -76,12 +80,17 @@
#include <TopLoc_Location.hxx>
#include <BRepGProp_Face.hxx>
#include <Standard_Failure.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
Ifc2x3::IfcFaceBound::list bounds = l->Bounds();
Ifc2x3::IfcFaceBound::it it = bounds->begin();
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Shape& face) {
IfcSchema::IfcFaceBound::list bounds = l->Bounds();
IfcSchema::IfcFaceBound::it it = bounds->begin();
IfcSchema::IfcLoop::ptr loop = (*it)->Bound();
TopoDS_Wire outer_wire;
if ( ! IfcGeom::convert_wire(loop,outer_wire) ) return false;
BRepBuilderAPI_MakeFace mf (outer_wire);
@@ -98,7 +107,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
face = mf.Face();
} else {
for( ++it; it != bounds->end(); ++ it) {
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
IfcSchema::IfcLoop::ptr loop = (*it)->Bound();
TopoDS_Wire wire;
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
mf.Add(wire);
@@ -125,7 +134,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
// as a simple edge cross product can give opposite results
// for a concave face boundary.
// Reference: Graphics Gems III p. 231
BRepGProp_Face prop(face);
BRepGProp_Face prop(TopoDS::Face(face));
gp_Vec normal_direction;
gp_Pnt center;
double u1,u2,v1,v2;
@@ -170,12 +179,9 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
// as the topological face normal the face orientation is
// reversed
gp_Vec face_normal2(x,y,z);
if (face_normal2.Magnitude() > ALMOST_ZERO) {
if ( face_normal1.Dot(face_normal2) < 0 ) {
TopAbs_Orientation o = face.Orientation();
face.Orientation(o == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
}
if ( face_normal1.Dot(face_normal2) < 0 ) {
TopAbs_Orientation o = face.Orientation();
face.Orientation(o == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
}
}
@@ -186,17 +192,23 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
// return face_area(face) > 0.0001;
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Shape& face) {
TopoDS_Wire wire;
if ( ! IfcGeom::convert_wire(l->OuterCurve(),wire) ) return false;
return IfcGeom::convert_wire_to_face(wire,face);
TopoDS_Face f;
bool success = IfcGeom::convert_wire_to_face(wire, f);
if (success) face = f;
return success;
}
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Shape& face) {
TopoDS_Wire profile;
if ( ! IfcGeom::convert_wire(l->OuterCurve(),profile) ) return false;
BRepBuilderAPI_MakeFace mf(profile);
Ifc2x3::IfcCurve::list voids = l->InnerCurves();
for( Ifc2x3::IfcCurve::it it = voids->begin(); it != voids->end(); ++ it ) {
IfcSchema::IfcCurve::list voids = l->InnerCurves();
for( IfcSchema::IfcCurve::it it = voids->begin(); it != voids->end(); ++ it ) {
TopoDS_Wire hole;
if ( IfcGeom::convert_wire(*it,hole) ) {
mf.Add(hole);
@@ -207,11 +219,12 @@ bool IfcGeom::convert(const Ifc2x3::IfcArbitraryProfileDefWithVoids::ptr l, Topo
face = TopoDS::Face(sfs.Shape());
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcRectangleProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Shape& face) {
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( x == 0.0f || y == 0.0f ) {
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
@@ -221,13 +234,96 @@ bool IfcGeom::convert(const Ifc2x3::IfcRectangleProfileDef::ptr l, TopoDS_Face&
double coords[8] = {-x,-y,x,-y,x,y,-x,y};
return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face);
}
bool IfcGeom::convert(const Ifc2x3::IfcIShapeProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, TopoDS_Shape& face) {
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double r = l->RoundingRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || r < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[8] = {-x,-y, x,-y, x,y, -x,y};
int fillets[4] = {0,1,2,3};
double radii[4] = {r,r,r,r};
return IfcGeom::profile_helper(4,coords,4,fillets,radii,trsf2d,face);
}
bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, TopoDS_Shape& face) {
const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const bool fr1 = l->hasInnerFilletRadius();
const bool fr2 = l->hasInnerFilletRadius();
const double r1 = fr2 ? l->OuterFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT) : 0.;
const double r2 = fr1 ? l->InnerFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT) : 0.;
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
TopoDS_Face f1;
TopoDS_Face f2;
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords1[8] = {-x ,-y, x ,-y, x, y, -x, y };
double coords2[8] = {-x+d,-y+d, x-d,-y+d, x-d,y-d, -x+d,y-d};
double radii1[4] = {r1,r1,r1,r1};
double radii2[4] = {r2,r2,r2,r2};
int fillets[4] = {0,1,2,3};
bool s1 = IfcGeom::profile_helper(4,coords1,fr1 ? 4 : 0,fillets,radii1,trsf2d,f1);
bool s2 = IfcGeom::profile_helper(4,coords2,fr2 ? 4 : 0,fillets,radii2,trsf2d,f2);
if (!s1 || !s2) return false;
TopExp_Explorer exp1(f1, TopAbs_WIRE);
TopExp_Explorer exp2(f2, TopAbs_WIRE);
TopoDS_Wire w1 = TopoDS::Wire(exp1.Current());
TopoDS_Wire w2 = TopoDS::Wire(exp2.Current());
BRepBuilderAPI_MakeFace mf(w1, false);
mf.Add(w2);
ShapeFix_Shape sfs(mf.Face());
sfs.Perform();
face = TopoDS::Face(sfs.Shape());
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Shape& face) {
const double x1 = l->BottomXDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double w = l->TopXDim() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dx = l->TopXOffset() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->YDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( x1 < ALMOST_ZERO || w < ALMOST_ZERO || y < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[8] = {-x1,-y, x1,-y, dx+w-x1,y, dx-x1,y};
return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face);
}
bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Shape& face) {
const double x = l->OverallWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->OverallDepth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d1 = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d2 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
bool doFillet = l->hasFilletRadius();
double f;
double f = 0.;
if ( doFillet ) {
f = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
@@ -245,19 +341,54 @@ bool IfcGeom::convert(const Ifc2x3::IfcIShapeProfileDef::ptr l, TopoDS_Face& fac
double radii[4] = {f,f,f,f};
return IfcGeom::profile_helper(12,coords,doFillet ? 4 : 0,fillets,radii,trsf2d,face);
}
bool IfcGeom::convert(const Ifc2x3::IfcCShapeProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Shape& face) {
const double x = l->FlangeWidth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dx = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dy = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
bool doFillet = l->hasFilletRadius();
bool doEdgeFillet = l->hasEdgeRadius();
double f1 = 0.;
double f2 = 0.;
if ( doFillet ) {
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if ( doEdgeFillet ) {
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if ( x == 0.0f || y == 0.0f || dx == 0.0f || dy == 0.0f ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[16] = {-dx,-y, x,-y, x,-y+dy, dx,-y+dy, dx,y, -x,y, -x,y-dy, -dx,y-dy};
int fillets[4] = {2,3,6,7};
double radii[4] = {f2,f1,f2,f1};
return IfcGeom::profile_helper(8,coords,(doFillet || doEdgeFillet) ? 4 : 0,fillets,radii,trsf2d,face);
}
bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Shape& face) {
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double x = l->Width() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d1 = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d2 = l->Girth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
bool doFillet = l->hasInternalFilletRadius();
double f1,f2;
double f1 = 0;
double f2 = 0;
if ( doFillet ) {
f1 = l->InternalFilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
f2 = f1 + d1;
}
if ( x == 0.0f || y == 0.0f || d1 == 0.0f || d2 == 0.0f ) {
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
@@ -270,12 +401,17 @@ bool IfcGeom::convert(const Ifc2x3::IfcCShapeProfileDef::ptr l, TopoDS_Face& fac
double radii[8] = {f2,f2,f1,f1,f1,f1,f2,f2};
return IfcGeom::profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face);
}
bool IfcGeom::convert(const Ifc2x3::IfcLShapeProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Shape& face) {
const bool hasSlope = l->hasLegSlope();
const bool doEdgeFillet = l->hasEdgeRadius();
const bool doFillet = l->hasFilletRadius();
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double x = (l->hasWidth() ? l->Width() : l->Depth()) / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
bool doEdgeFillet = l->hasEdgeRadius();
bool doFillet = l->hasFilletRadius();
const double slope = hasSlope ? (l->LegSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
double f1 = 0.0f;
double f2 = 0.0f;
if (doFillet) {
@@ -284,7 +420,86 @@ bool IfcGeom::convert(const Ifc2x3::IfcLShapeProfileDef::ptr l, TopoDS_Face& fac
if ( doEdgeFillet) {
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if ( x == 0.0f || y == 0.0f || d == 0.0f ) {
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
double xx = -x+d;
double xy = -y+d;
double dy1 = 0.;
double dy2 = 0.;
double dx1 = 0.;
double dx2 = 0.;
if (hasSlope) {
dy1 = tan(slope) * x;
dy2 = tan(slope) * (x - d);
dx1 = tan(slope) * y;
dx2 = tan(slope) * (y - d);
const double x1s = x; const double y1s = -y + d - dy1;
const double x1e = -x + d; const double y1e = -y + d + dy2;
const double x2s = -x + d - dx1; const double y2s = y;
const double x2e = -x + d + dx2; const double y2e = -y + d;
const double a1 = y1e - y1s;
const double b1 = x1s - x1e;
const double c1 = a1*x1s + b1*y1s;
const double a2 = y2e - y2s;
const double b2 = x2s - x2e;
const double c2 = a2*x2s + b2*y2s;
const double det = a1*b2 - a2*b1;
if (ALMOST_THE_SAME(det, 0.)) {
Logger::Message(Logger::LOG_NOTICE, "Legs do not intersect for:",l->entity);
return false;
}
xx = (b2*c1 - b1*c2) / det;
xy = (a1*c2 - a2*c1) / det;
}
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[12] = {-x,-y, x,-y, x,-y+d-dy1, xx, xy, -x+d-dx1,y, -x,y};
int fillets[3] = {2,3,4};
double radii[3] = {f2,f1,f2};
return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face);
}
bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Shape& face) {
const bool doEdgeFillet = l->hasEdgeRadius();
const bool doFillet = l->hasFilletRadius();
const bool hasSlope = l->hasFlangeSlope();
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double x = l->FlangeWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d1 = l->WebThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d2 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double slope = hasSlope ? (l->FlangeSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
double dy1 = 0.0f;
double dy2 = 0.0f;
double f1 = 0.0f;
double f2 = 0.0f;
if (doFillet) {
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if (doEdgeFillet) {
f2 = l->EdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if (hasSlope) {
dy1 = (x - d1) * tan(slope);
dy2 = x * tan(slope);
}
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
@@ -292,12 +507,96 @@ bool IfcGeom::convert(const Ifc2x3::IfcLShapeProfileDef::ptr l, TopoDS_Face& fac
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[12] = {-x,-y,x,-y,x,-y+d,-x+d,-y+d,-x+d,y,-x,y};
int fillets[3] = {2,3,4};
double radii[3] = {f2,f1,f2};
return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face);
double coords[16] = {-x,-y, x,-y, x,-y+d2-dy2, -x+d1,-y+d2+dy1, -x+d1,y-d2-dy1, x,y-d2+dy2, x,y, -x,y};
int fillets[4] = {2,3,4,5};
double radii[4] = {f2,f1,f1,f2};
return IfcGeom::profile_helper(8, coords, (doFillet || doEdgeFillet) ? 4 : 0, fillets, radii, trsf2d, face);
}
bool IfcGeom::convert(const Ifc2x3::IfcCircleProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Shape& face) {
const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius();
const bool doWebEdgeFillet = l->hasWebEdgeRadius();
const bool doFillet = l->hasFilletRadius();
const bool hasFlangeSlope = l->hasFlangeSlope();
const bool hasWebSlope = l->hasWebSlope();
const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double x = l->FlangeWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d1 = l->WebThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double d2 = l->FlangeThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double flangeSlope = hasFlangeSlope ? (l->FlangeSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
const double webSlope = hasWebSlope ? (l->WebSlope() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT)) : 0.;
if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
double dy1 = 0.0f;
double dy2 = 0.0f;
double dx1 = 0.0f;
double dx2 = 0.0f;
double f1 = 0.0f;
double f2 = 0.0f;
double f3 = 0.0f;
if (doFillet) {
f1 = l->FilletRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if (doWebEdgeFillet) {
f2 = l->WebEdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
if (doFlangeEdgeFillet) {
f3 = l->FlangeEdgeRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
}
double xx, xy;
if (hasFlangeSlope) {
dy1 = (x / 2. - d1) * tan(flangeSlope);
dy2 = x / 2. * tan(flangeSlope);
}
if (hasWebSlope) {
dx1 = (y - d2) * tan(webSlope);
dx2 = y * tan(webSlope);
}
if (hasWebSlope || hasFlangeSlope) {
const double x1s = d1/2. - dx2; const double y1s = -y;
const double x1e = d1/2. + dx1; const double y1e = y - d2;
const double x2s = x; const double y2s = y - d2 + dy2;
const double x2e = d1/2.; const double y2e = y - d2 - dy1;
const double a1 = y1e - y1s;
const double b1 = x1s - x1e;
const double c1 = a1*x1s + b1*y1s;
const double a2 = y2e - y2s;
const double b2 = x2s - x2e;
const double c2 = a2*x2s + b2*y2s;
const double det = a1*b2 - a2*b1;
if (ALMOST_THE_SAME(det, 0.)) {
Logger::Message(Logger::LOG_NOTICE, "Web and flange do not intersect for:",l->entity);
return false;
}
xx = (b2*c1 - b1*c2) / det;
xy = (a1*c2 - a2*c1) / det;
} else {
xx = d1 / 2;
xy = y - d2;
}
gp_Trsf2d trsf2d;
IfcGeom::convert(l->Position(),trsf2d);
double coords[16] = {d1/2.-dx2,-y, xx,xy, x,y-d2+dy2, x,y, -x,y, -x,y-d2+dy2, -xx,xy, -d1/2.+dx2,-y};
int fillets[6] = {0,1,2,5,6,7};
double radii[6] = {f2,f1,f3,f3,f1,f2};
return IfcGeom::profile_helper(8, coords, (doFillet || doWebEdgeFillet || doFlangeEdgeFillet) ? 6 : 0, fillets, radii, trsf2d, face);
}
bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Shape& face) {
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( r == 0.0f ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
@@ -312,9 +611,14 @@ bool IfcGeom::convert(const Ifc2x3::IfcCircleProfileDef::ptr l, TopoDS_Face& fac
Handle(Geom_Circle) circle = new Geom_Circle(ax, r);
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle);
w.Add(edge);
return IfcGeom::convert_wire_to_face(w,face);
TopoDS_Face f;
bool success = IfcGeom::convert_wire_to_face(w, f);
if (success) face = f;
return success;
}
bool IfcGeom::convert(const Ifc2x3::IfcCircleHollowProfileDef::ptr l, TopoDS_Face& face) {
bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_Shape& face) {
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double t = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT);
@@ -341,4 +645,126 @@ bool IfcGeom::convert(const Ifc2x3::IfcCircleHollowProfileDef::ptr l, TopoDS_Fac
sfs.Perform();
face = TopoDS::Face(sfs.Shape());
return true;
}
}
bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Shape& face) {
double rx = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
double ry = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
if ( rx < ALMOST_ZERO || ry < ALMOST_ZERO ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
return false;
}
const bool rotated = ry > rx;
gp_Trsf2d trsf;
IfcGeom::convert(l->Position(),trsf);
gp_Ax2 ax = gp_Ax2();
if (rotated) {
ax.Rotate(ax.Axis(), M_PI / 2.);
std::swap(rx, ry);
}
ax.Transform(trsf);
BRepBuilderAPI_MakeWire w;
Handle(Geom_Ellipse) ellipse = new Geom_Ellipse(ax, rx, ry);
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ellipse);
w.Add(edge);
TopoDS_Face f;
bool success = IfcGeom::convert_wire_to_face(w, f);
if (success) face = f;
return success;
}
bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Shape& face) {
const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT) / 2.;
TopoDS_Wire wire;
if (!IfcGeom::convert_wire(l->Curve(), wire)) return false;
// BRepOffsetAPI_MakeOffset insists on creating circular arc
// segments for joining the curves that constitute the center
// line. This is probably not in accordance with the IFC spec.
// Although it does not specify a method to join segments
// explicitly, it does dictate 'a constant thickness along the
// curve'. Therefore for simple singular wires a quick
// alternative is provided that uses a straight join.
TopExp_Explorer exp(wire, TopAbs_EDGE);
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
exp.Next();
if (!exp.More()) {
double u1, u2;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2);
Handle(Geom_TrimmedCurve) trim = new Geom_TrimmedCurve(curve, u1, u2);
Handle(Geom_OffsetCurve) c1 = new Geom_OffsetCurve(trim, d, gp::DZ());
Handle(Geom_OffsetCurve) c2 = new Geom_OffsetCurve(trim, -d, gp::DZ());
gp_Pnt c1a, c1b, c2a, c2b;
c1->D0(c1->FirstParameter(), c1a);
c1->D0(c1->LastParameter(), c1b);
c2->D0(c2->FirstParameter(), c2a);
c2->D0(c2->LastParameter(), c2b);
BRepBuilderAPI_MakeWire mw;
mw.Add(BRepBuilderAPI_MakeEdge(c1));
mw.Add(BRepBuilderAPI_MakeEdge(c1a, c2a));
mw.Add(BRepBuilderAPI_MakeEdge(c2));
mw.Add(BRepBuilderAPI_MakeEdge(c2b, c1b));
face = BRepBuilderAPI_MakeFace(mw.Wire());
} else {
BRepOffsetAPI_MakeOffset offset(BRepBuilderAPI_MakeFace(gp_Pln(gp::Origin(), gp::DZ())));
offset.AddWire(wire);
offset.Perform(d);
face = BRepBuilderAPI_MakeFace(TopoDS::Wire(offset));
}
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcCompositeProfileDef::ptr l, TopoDS_Shape& face) {
// BRepBuilderAPI_MakeFace mf;
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
IfcSchema::IfcProfileDef::list profiles = l->Profiles();
bool first = true;
for (IfcSchema::IfcProfileDef::it it = profiles->begin(); it != profiles->end(); ++it) {
TopoDS_Face f;
if (IfcGeom::convert_face(*it, f)) {
builder.Add(compound, f);
/* TopExp_Explorer exp(f, TopAbs_WIRE);
for (; exp.More(); exp.Next()) {
const TopoDS_Wire& wire = TopoDS::Wire(exp.Current());
if (first) {
mf.Init(BRepBuilderAPI_MakeFace(wire));
} else {
mf.Add(wire);
}
first = false;
} */
}
}
face = compound;
return !face.IsNull();
}
bool IfcGeom::convert(const IfcSchema::IfcDerivedProfileDef::ptr l, TopoDS_Shape& face) {
TopoDS_Face f;
gp_Trsf2d trsf2d;
if (IfcGeom::convert_face(l->ParentProfile(), f) && IfcGeom::convert(l->Operator(), trsf2d)) {
gp_Trsf trsf = trsf2d;
face = TopoDS::Face(BRepBuilderAPI_Transform(f, trsf));
return true;
} else {
return false;
}
}
+387 -70
View File
@@ -23,8 +23,9 @@
* *
********************************************************************************/
#include <set>
#include <cassert>
#include <algorithm>
#include <limits>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
@@ -87,12 +88,19 @@
#include <BRepGProp_Face.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepMesh.hxx>
#include <BRepTools.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <BRepTools.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
@@ -126,28 +134,20 @@ bool IfcGeom::is_compound(const TopoDS_Shape& shape) {
const TopoDS_Shape& IfcGeom::ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid) {
const bool is_comp = IfcGeom::is_compound(shape);
if (!is_comp) {
return solid = shape;
}
IfcGeom::create_solid_from_compound(shape, solid);
// If the SEW_SHELLS option had been set this precision had been applied
// at the end of the generic IfcGeom::convert_shape() call.
const double precision = IfcGeom::GetValue(GV_PRECISION);
IfcGeom::apply_tolerance(solid, precision);
if ( ! is_comp ) return shape;
IfcGeom::create_solid_from_compound(shape,solid);
return solid;
}
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
bool IfcGeom::convert_openings(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings,
const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
// Iterate over IfcOpeningElements
IfcGeom::IfcRepresentationShapeItems opening_shapes;
unsigned int last_size = 0;
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {
for ( IfcSchema::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
IfcSchema::IfcRelVoidsElement::ptr v = *it;
IfcSchema::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
@@ -156,10 +156,10 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
IfcSchema::IfcProductRepresentation::ptr prodrep = fes->Representation();
IfcSchema::IfcRepresentation::list reps = prodrep->Representations();
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
for ( IfcSchema::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
IfcGeom::convert_shapes(*it2,opening_shapes);
}
@@ -233,7 +233,7 @@ bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x
return true;
}
bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
bool IfcGeom::convert_openings_fast(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings,
const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) {
// Create a compound of all opening shapes in order to speed up the boolean operations
@@ -241,10 +241,10 @@ bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const
BRep_Builder builder;
builder.MakeCompound(opening_compound);
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {
for ( IfcSchema::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
IfcSchema::IfcRelVoidsElement::ptr v = *it;
IfcSchema::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
@@ -253,12 +253,12 @@ bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
IfcSchema::IfcProductRepresentation::ptr prodrep = fes->Representation();
IfcSchema::IfcRepresentation::list reps = prodrep->Representations();
IfcGeom::IfcRepresentationShapeItems opening_shapes;
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
for ( IfcSchema::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
IfcGeom::convert_shapes(*it2,opening_shapes);
}
@@ -324,7 +324,13 @@ bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
face = mf.Face();
return true;
}
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) {
bool IfcGeom::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) {
wire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(curve));
return true;
}
bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) {
TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
for ( int i = 0; i < numVerts; i ++ ) {
@@ -337,23 +343,22 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
for ( int i = 0; i < numVerts; i ++ )
w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts]));
TopoDS_Face face;
IfcGeom::convert_wire_to_face(w.Wire(),face);
if ( numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > 1e-7 ) {
if ( numFillets ) {
BRepFilletAPI_MakeFillet2d fillet (face);
for ( int i = 0; i < numFillets; i ++ ) {
const double radius = filletRadii[i];
if ( radius <= 1e-7 ) continue;
if ( radius < ALMOST_ZERO ) continue;
fillet.AddFillet(vertices[filletIndices[i]],radius);
}
fillet.Build();
if (fillet.IsDone()) {
face = TopoDS::Face(fillet.Shape());
} else {
Logger::Message(Logger::LOG_WARNING, "Failed to process profile fillets");
}
face = TopoDS::Face(fillet.Shape());
}
face_shape = face;
delete[] vertices;
return true;
}
@@ -514,10 +519,10 @@ double IfcGeom::GetValue(GeomValue var) {
return 0;
}
Ifc2x3::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es) {
BRepMesh_IncrementalMesh(shape, deflection);
IfcSchema::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, double deflection, IfcEntities es) {
BRepMesh::Mesh(shape, deflection);
Ifc2x3::IfcFace::list faces (new IfcTemplatedEntityList<Ifc2x3::IfcFace>());
IfcSchema::IfcFace::list faces (new IfcTemplatedEntityList<IfcSchema::IfcFace>());
for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) {
const TopoDS_Face& face = TopoDS::Face(exp.Current());
@@ -526,11 +531,11 @@ Ifc2x3::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, doubl
if (! tri.IsNull()) {
const TColgp_Array1OfPnt& nodes = tri->Nodes();
std::vector<Ifc2x3::IfcCartesianPoint*> vertices;
std::vector<IfcSchema::IfcCartesianPoint*> vertices;
for (int i = 1; i <= nodes.Length(); ++i) {
gp_Pnt pnt = nodes(i).Transformed(loc);
std::vector<double> xyz; xyz.push_back(pnt.X()); xyz.push_back(pnt.Y()); xyz.push_back(pnt.Z());
Ifc2x3::IfcCartesianPoint* cpnt = new Ifc2x3::IfcCartesianPoint(xyz);
IfcSchema::IfcCartesianPoint* cpnt = new IfcSchema::IfcCartesianPoint(xyz);
vertices.push_back(cpnt);
es->push(cpnt);
}
@@ -538,15 +543,15 @@ Ifc2x3::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, doubl
for (int i = 1; i <= triangles.Length(); ++ i) {
int n1, n2, n3;
triangles(i).Get(n1, n2, n3);
Ifc2x3::IfcCartesianPoint::list points (new IfcTemplatedEntityList<Ifc2x3::IfcCartesianPoint>());
IfcSchema::IfcCartesianPoint::list points (new IfcTemplatedEntityList<IfcSchema::IfcCartesianPoint>());
points->push(vertices[n1-1]);
points->push(vertices[n2-1]);
points->push(vertices[n3-1]);
Ifc2x3::IfcPolyLoop* loop = new Ifc2x3::IfcPolyLoop(points);
Ifc2x3::IfcFaceOuterBound* bound = new Ifc2x3::IfcFaceOuterBound(loop, face.Orientation() != TopAbs_REVERSED);
Ifc2x3::IfcFaceBound::list bounds (new IfcTemplatedEntityList<Ifc2x3::IfcFaceBound>());
IfcSchema::IfcPolyLoop* loop = new IfcSchema::IfcPolyLoop(points);
IfcSchema::IfcFaceOuterBound* bound = new IfcSchema::IfcFaceOuterBound(loop, face.Orientation() != TopAbs_REVERSED);
IfcSchema::IfcFaceBound::list bounds (new IfcTemplatedEntityList<IfcSchema::IfcFaceBound>());
bounds->push(bound);
Ifc2x3::IfcFace* face = new Ifc2x3::IfcFace(bounds);
IfcSchema::IfcFace* face = new IfcSchema::IfcFace(bounds);
es->push(loop);
es->push(bound);
es->push(face);
@@ -554,21 +559,21 @@ Ifc2x3::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, doubl
}
}
}
Ifc2x3::IfcOpenShell* shell = new Ifc2x3::IfcOpenShell(faces);
Ifc2x3::IfcConnectedFaceSet::list shells (new IfcTemplatedEntityList<Ifc2x3::IfcConnectedFaceSet>());
IfcSchema::IfcOpenShell* shell = new IfcSchema::IfcOpenShell(faces);
IfcSchema::IfcConnectedFaceSet::list shells (new IfcTemplatedEntityList<IfcSchema::IfcConnectedFaceSet>());
shells->push(shell);
Ifc2x3::IfcFaceBasedSurfaceModel* surface_model = new Ifc2x3::IfcFaceBasedSurfaceModel(shells);
IfcSchema::IfcFaceBasedSurfaceModel* surface_model = new IfcSchema::IfcFaceBasedSurfaceModel(shells);
Ifc2x3::IfcRepresentation::list reps (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentation>());
Ifc2x3::IfcRepresentationItem::list items (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentationItem>());
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
items->push(surface_model);
Ifc2x3::IfcShapeRepresentation* rep = new Ifc2x3::IfcShapeRepresentation(
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
0, std::string("Facetation"), std::string("SurfaceModel"), items);
reps->push(rep);
Ifc2x3::IfcProductDefinitionShape* shapedef = new Ifc2x3::IfcProductDefinitionShape(0, 0, reps);
IfcSchema::IfcProductDefinitionShape* shapedef = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
es->push(shell);
es->push(surface_model);
@@ -578,26 +583,338 @@ Ifc2x3::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, doubl
return shapedef;
}
void IfcGeom::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
if (tol <= 0.) tol = GetValue(GV_POINT_EQUALITY_TOLERANCE);
tol *= tol;
// Returns the vertex part of an TopoDS_Edge edge that is not TopoDS_Vertex vertex
TopoDS_Vertex find_other(const TopoDS_Edge& edge, const TopoDS_Vertex& vertex) {
TopExp_Explorer exp(edge, TopAbs_VERTEX);
while (exp.More()) {
if (!exp.Current().IsSame(vertex)) {
return TopoDS::Vertex(exp.Current());
}
exp.Next();
}
return TopoDS_Vertex();
}
while (true) {
bool removed = false;
int n = polygon.Length() - (closed ? 0 : 1);
for (int i = 1; i <= n; ++i) {
// wrap around to the first point in case of a closed loop
int j = (i % polygon.Length()) + 1;
double dist = polygon.Value(i).SquareDistance(polygon.Value(j));
if (dist < tol) {
// do not remove the first or last point to
// maintain connectivity with other wires
if ((closed && j == 1) || (!closed && j == n)) polygon.Remove(i);
else polygon.Remove(j);
removed = true;
TopoDS_Edge find_next(const TopTools_IndexedMapOfShape& edge_set, const TopTools_IndexedDataMapOfShapeListOfShape& vertex_to_edges, const TopoDS_Vertex& current, const TopoDS_Edge& previous_edge) {
const TopTools_ListOfShape& edges = vertex_to_edges.FindFromKey(current);
TopTools_ListIteratorOfListOfShape eit;
for (eit.Initialize(edges); eit.More(); eit.Next()) {
const TopoDS_Edge& edge = TopoDS::Edge(eit.Value());
if (edge.IsSame(previous_edge)) continue;
if (edge_set.Contains(edge)) {
return edge;
}
}
return TopoDS_Edge();
}
bool IfcGeom::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing sew;
sew.Add(shape);
TopTools_IndexedDataMapOfShapeListOfShape edge_to_faces;
TopTools_IndexedDataMapOfShapeListOfShape vertex_to_edges;
std::set<int> visited;
TopTools_IndexedMapOfShape edge_set;
TopExp::MapShapesAndAncestors (shape, TopAbs_EDGE, TopAbs_FACE, edge_to_faces);
const int num_edges = edge_to_faces.Extent();
for (int i = 1; i <= num_edges; ++i) {
const TopTools_ListOfShape& faces = edge_to_faces.FindFromIndex(i);
const int count = faces.Extent();
// Find only the non-manifold edges: Edges that are only part of a
// single face and therefore part of the wire(s) we want to fill.
if (count == 1) {
const TopoDS_Shape& edge = edge_to_faces.FindKey(i);
TopExp::MapShapesAndAncestors (edge, TopAbs_VERTEX, TopAbs_EDGE, vertex_to_edges);
edge_set.Add(edge);
}
}
const int num_verts = vertex_to_edges.Extent();
TopoDS_Vertex first, current;
TopoDS_Edge previous_edge;
// Now loop over all the vertices that are part of the wire(s) to be filled
for (int i = 1; i <= num_verts; ++i) {
first = current = TopoDS::Vertex(vertex_to_edges.FindKey(i));
const bool isSame = first.IsSame(current);
// We keep track of the vertices we already used
if (visited.find(vertex_to_edges.FindIndex(current)) != visited.end()) {
continue;
}
// Given these vertices, try to find closed loops and create new
// wires out of them.
BRepBuilderAPI_MakeWire w;
while (true) {
visited.insert(vertex_to_edges.FindIndex(current));
// Find the edge that the current vertex is part of and points
// away from the previous vertex (null for the first vertex).
TopoDS_Edge edge = find_next(edge_set, vertex_to_edges, current, previous_edge);
if (edge.IsNull()) {
return false;
}
TopoDS_Vertex other = find_other(edge, current);
if (other.IsNull()) {
// Dealing with a conical edge probably, for some reason
// this works better than adding the edge directly.
double u1, u2;
Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u1, u2);
w.Add(BRepBuilderAPI_MakeEdge(crv, u1, u2));
break;
} else {
w.Add(edge);
}
// See if the starting point of this loop has been reached. Note that
// additional wires after this one potentially will be created.
if (other.IsSame(first)) {
break;
}
previous_edge = edge;
current = other;
}
sew.Add(BRepBuilderAPI_MakeFace(w));
previous_edge.Nullify();
}
sew.Perform();
shape = sew.SewedShape();
try {
ShapeFix_Solid solid;
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
return true;
}
std::string IfcGeom::create_brep_data(IfcSchema::IfcProduct* ifc_product, unsigned int settings) {
const bool no_openings = !!(settings & DISABLE_OPENING_SUBTRACTIONS);
const bool no_placement = !!(settings & DISABLE_OBJECT_PLACEMENT);
const bool sew_shells = !!(settings & SEW_SHELLS);
const bool convert_to_meters = !!(settings & CONVERT_TO_METERS);
const double old_max_faces_to_sew = GetValue(GV_MAX_FACES_TO_SEW);
const double inf = std::numeric_limits<double>::infinity();
SetValue(GV_MAX_FACES_TO_SEW, sew_shells ? inf : -inf);
std::string brep_data = "";
if (ifc_product->hasRepresentation()) {
IfcSchema::IfcProductRepresentation* prod_rep = ifc_product->Representation();
IfcSchema::IfcRepresentation::list li = prod_rep->Representations();
IfcSchema::IfcShapeRepresentation* shape_rep = 0;
for (IfcSchema::IfcRepresentation::it i = li->begin(); i != li->end(); ++i) {
const std::string representation_identifier = (*i)->RepresentationIdentifier();
if ((*i)->is(IfcSchema::Type::IfcShapeRepresentation) && (representation_identifier == "Body" || representation_identifier == "Facetation")) {
shape_rep = (IfcSchema::IfcShapeRepresentation*) *i;
break;
}
}
if (!removed) break;
if (!!shape_rep) {
IfcGeom::IfcRepresentationShapeItems shapes;
if (IfcGeom::convert_shapes(shape_rep,shapes)) {
gp_Trsf trsf;
try {
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
} catch (...) {}
// Does the IfcElement have any IfcOpenings?
// Note that openings for IfcOpeningElements are not processed
IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list();
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcElement>(ifc_product);
openings = element->HasOpenings();
}
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcBuildingElementPart>(ifc_product);
#ifdef USE_IFC4
IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes();
for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
#else
IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes();
for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
#endif
IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcObjectDefinition,IfcSchema::IfcElement>(obdef);
openings->push(element->HasOpenings());
}
}
}
if (openings && openings->Size() && !no_openings) {
IfcGeom::IfcRepresentationShapeItems opened_shapes;
try {
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
} catch(...) {
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
}
shapes = opened_shapes;
}
if (!no_placement) {
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
it->prepend(trsf);
}
}
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
const TopoDS_Shape& s = it->Shape();
const gp_GTrsf& trsf = it->Placement();
bool trsf_valid = false;
gp_Trsf _trsf;
try {
_trsf = trsf.Trsf();
trsf_valid = true;
} catch (...) {}
const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) :
BRepBuilderAPI_GTransform(s,trsf,true).Shape();
builder.Add(compound,moved_shape);
}
if (GetValue(GV_LENGTH_UNIT) != 1. && !convert_to_meters) {
gp_Trsf length_unit_scale;
length_unit_scale.SetScaleFactor(1. / GetValue(GV_LENGTH_UNIT));
compound.Move(length_unit_scale);
}
std::stringstream sstream;
BRepTools::Write(compound,sstream);
brep_data = sstream.str();
}
}
}
SetValue(GV_MAX_FACES_TO_SEW, old_max_faces_to_sew);
return brep_data;
}
double UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v ) {
if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_EXA ) return (double) 1e18;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PETA ) return (double) 1e15;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_TERA ) return (double) 1e12;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_GIGA ) return (double) 1e9;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MEGA ) return (double) 1e6;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_KILO ) return (double) 1e3;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_HECTO ) return (double) 1e2;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECA ) return (double) 1;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_DECI ) return (double) 1e-1;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_CENTI ) return (double) 1e-2;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MILLI ) return (double) 1e-3;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_MICRO ) return (double) 1e-6;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_NANO ) return (double) 1e-9;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_PICO ) return (double) 1e-12;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_FEMTO ) return (double) 1e-15;
else if ( v == IfcSchema::IfcSIPrefix::IfcSIPrefix_ATTO ) return (double) 1e-18;
else return 1.0f;
}
void IfcGeom::initialize_units_and_precision(IfcSchema::IfcProject* proj, double& unit_magnitude, std::string& unit_name) {
// IfcOpenShell measures internally in meters, therefore a conversion factor
// is obtained based on the length unit in the file.
// Set default units, set length to meters, angles to undefined
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,1.0);
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,-1.0);
IfcUtil::IfcAbstractSelect::list units = IfcUtil::IfcAbstractSelect::list();
try {
IfcSchema::IfcUnitAssignment* unit_assignment = proj->UnitsInContext();
units = unit_assignment->Units();
} catch (const IfcParse::IfcException&) {}
try {
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
std::string current_unit_name = "";
const IfcUtil::IfcAbstractSelect::ptr base = *it;
IfcSchema::IfcSIUnit::ptr unit = IfcSchema::IfcSIUnit::ptr();
double value = 1.0f;
if ( base->is(IfcSchema::Type::IfcConversionBasedUnit) ) {
const IfcSchema::IfcConversionBasedUnit::ptr u = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcSchema::IfcConversionBasedUnit>(base);
current_unit_name = u->Name();
const IfcSchema::IfcMeasureWithUnit::ptr u2 = u->ConversionFactor();
IfcSchema::IfcUnit u3 = u2->UnitComponent();
if ( u3->is(IfcSchema::Type::IfcSIUnit) ) {
unit = (IfcSchema::IfcSIUnit*) u3;
}
IfcSchema::IfcValue v = u2->ValueComponent();
const double f = *((IfcUtil::IfcBaseEntity*)v)->entity->getArgument(0);
value *= f;
} else if ( base->is(IfcSchema::Type::IfcSIUnit) ) {
unit = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcSchema::IfcSIUnit>(base);
}
if ( unit ) {
if ( unit->hasPrefix() ) {
value *= UnitPrefixToValue(unit->Prefix());
}
IfcSchema::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
if ( type == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,value);
if (current_unit_name.empty()) {
if (unit->hasPrefix()) {
current_unit_name = IfcSchema::IfcSIPrefix::ToString(unit->Prefix());
}
current_unit_name += IfcSchema::IfcSIUnitName::ToString(unit->Name());
}
unit_magnitude = value;
unit_name = current_unit_name;
} else if ( type == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,value);
}
}
}
} catch (const IfcParse::IfcException& ex) {
std::stringstream ss;
ss << "Failed to determine unit information '" << ex.what() << "'";
Logger::Message(Logger::LOG_ERROR, ss.str());
}
// Boolean operations rely on a precision value for vertex and face coincedence. This
// value is obtained from the IfcGeometricRepresentationContexts in the file.
// Set an initial guess in case reading from file fails.
IfcGeom::SetValue(IfcGeom::GV_PRECISION, 0.00001);
try {
IfcSchema::IfcRepresentationContext::list rep_contexts = proj->RepresentationContexts();
// Currently, IfcGeometricRepresentationContext aren't used as much as they should be
// in the evaluation of shape representations, hence, we try to find the one with the
// lowest precision. Typically, a value of 1e-5 is encountered. This value is applied
// to all TopoDS_Shapes generated by one of the IfcGeom::convert() functions.
// TODO: Many of the empirically found tolerances should probably be substituted by
// one that is defined in the model file.
double lowest_precision_encountered = std::numeric_limits<double>::infinity();
bool any_precision_encountered = false;
for (IfcSchema::IfcRepresentationContext::it it = rep_contexts->begin(); it != rep_contexts->end(); ++it) {
if ((*it)->is(IfcSchema::Type::IfcGeometricRepresentationContext)) {
IfcSchema::IfcGeometricRepresentationContext* rep_context = (IfcSchema::IfcGeometricRepresentationContext*)*it;
if (rep_context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) continue;
if (rep_context->hasPrecision()) {
const double precision = rep_context->Precision();
if (precision < lowest_precision_encountered) {
any_precision_encountered = true;
lowest_precision_encountered = precision;
}
}
}
}
if (any_precision_encountered) {
IfcGeom::SetValue(IfcGeom::GV_PRECISION, lowest_precision_encountered);
}
} catch (const IfcParse::IfcException& ex) {
std::stringstream ss;
ss << "Failed to determine precision value '" << ex.what() << "'";
Logger::Message(Logger::LOG_ERROR, ss.str());
}
}
+85 -26
View File
@@ -87,7 +87,7 @@ namespace IfcGeom {
if ( it != Cache::T.end() ) { e = it->second; return true; }
#define CACHE(T,E,e) Cache::T[E->entity->id()] = e;
bool IfcGeom::convert(const Ifc2x3::IfcCartesianPoint::ptr l, gp_Pnt& point) {
bool IfcGeom::convert(const IfcSchema::IfcCartesianPoint::ptr l, gp_Pnt& point) {
IN_CACHE(IfcCartesianPoint,l,gp_Pnt,point)
std::vector<double> xyz = l->Coordinates();
point = gp_Pnt(
@@ -98,7 +98,8 @@ bool IfcGeom::convert(const Ifc2x3::IfcCartesianPoint::ptr l, gp_Pnt& point) {
CACHE(IfcCartesianPoint,l,point)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcDirection::ptr l, gp_Dir& dir) {
bool IfcGeom::convert(const IfcSchema::IfcDirection::ptr l, gp_Dir& dir) {
IN_CACHE(IfcDirection,l,gp_Dir,dir)
std::vector<double> xyz = l->DirectionRatios();
dir = gp_Dir(
@@ -109,7 +110,8 @@ bool IfcGeom::convert(const Ifc2x3::IfcDirection::ptr l, gp_Dir& dir) {
CACHE(IfcDirection,l,dir)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcVector::ptr l, gp_Vec& v) {
bool IfcGeom::convert(const IfcSchema::IfcVector::ptr l, gp_Vec& v) {
IN_CACHE(IfcVector,l,gp_Vec,v)
gp_Dir d;
IfcGeom::convert(l->Orientation(),d);
@@ -117,7 +119,8 @@ bool IfcGeom::convert(const Ifc2x3::IfcVector::ptr l, gp_Vec& v) {
CACHE(IfcVector,l,v)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement3D::ptr l, gp_Trsf& trsf) {
bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement3D::ptr l, gp_Trsf& trsf) {
IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf)
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
IfcGeom::convert(l->Location(),o);
@@ -131,16 +134,28 @@ bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement3D::ptr l, gp_Trsf& trsf) {
CACHE(IfcAxis2Placement3D,l,trsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3D::ptr l, gp_Trsf& trsf) {
bool IfcGeom::convert(const IfcSchema::IfcAxis1Placement::ptr l, gp_Ax1& ax) {
IN_CACHE(IfcAxis1Placement,l,gp_Ax1,ax)
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);
IfcGeom::convert(l->Location(),o);
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(), axis);
ax = gp_Ax1(o, axis);
CACHE(IfcAxis1Placement,l,ax)
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3D::ptr l, gp_Trsf& trsf) {
IN_CACHE(IfcCartesianTransformationOperator3D,l,gp_Trsf,trsf)
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
gp_Dir axis2 (0.,1.,0.);
gp_Dir axis3 (0.,0.,1.);
gp_Dir axis3;
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
else axis3 = axis1.Crossed(axis2);
gp_Ax3 ax3 (origin,axis3,axis1);
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
trsf.SetTransformation(ax3);
@@ -149,30 +164,53 @@ bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3D::ptr l,
CACHE(IfcCartesianTransformationOperator3D,l,trsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2D::ptr l, gp_Trsf2d& trsf) {
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2D::ptr l, gp_Trsf2d& trsf) {
IN_CACHE(IfcCartesianTransformationOperator2D,l,gp_Trsf2d,trsf)
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
gp_Dir axis2 (0.,1.,0.);
IfcGeom::convert(l->LocalOrigin(),origin);
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
const gp_Pnt2d origin2d(origin.X(), origin.Y());
const gp_Dir2d axis12d(axis1.X(), axis1.Y());
const gp_Dir2d axis22d(axis2.X(), axis2.Y());
// A better match to represent the IfcCartesianTransformationOperator2D would
// be the gp_Ax22d, but to my knowledge no easy way exists to convert it into
// a gp_Trsf2d. Easiest would probably be to simply update the underlying
// gp_Mat2d directly.
const gp_Ax2d ax2d (origin2d, axis12d);
trsf.SetTransformation(ax2d);
if ( ax2d.Direction().Rotated(M_PI / 2.).Dot(axis22d) < 0. ) {
gp_Trsf2d mirror; mirror.SetMirror(ax2d);
trsf.Multiply(mirror);
}
trsf.Invert();
if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
CACHE(IfcCartesianTransformationOperator2D,l,trsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3DnonUniform::ptr l, gp_GTrsf& gtrsf) {
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUniform::ptr l, gp_GTrsf& gtrsf) {
IN_CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gp_GTrsf,gtrsf)
gp_Trsf trsf;
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
gp_Dir axis2 (0.,1.,0.);
gp_Dir axis3 (0.,0.,1.);
gp_Dir axis3;
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
else axis3 = axis1.Crossed(axis2);
gp_Ax3 ax3 (origin,axis3,axis1);
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
trsf.SetTransformation(ax3);
@@ -188,16 +226,33 @@ bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3DnonUnifo
CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gtrsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2DnonUniform::ptr l, gp_GTrsf2d& gtrsf) {
bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUniform::ptr l, gp_GTrsf2d& gtrsf) {
IN_CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gp_GTrsf2d,gtrsf)
gp_Trsf2d trsf;
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
gp_Dir axis2 (0.,1.,0.);
IfcGeom::convert(l->LocalOrigin(),origin);
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
const gp_Pnt2d origin2d(origin.X(), origin.Y());
const gp_Dir2d axis12d(axis1.X(), axis1.Y());
const gp_Dir2d axis22d(axis2.X(), axis2.Y());
const gp_Ax2d ax2d (origin2d, axis12d);
trsf.SetTransformation(ax2d);
if ( ax2d.Direction().Rotated(M_PI / 2.).Dot(axis22d) < 0. ) {
gp_Trsf2d mirror; mirror.SetMirror(ax2d);
trsf.Multiply(mirror);
}
trsf.Invert();
const double scale1 = l->hasScale() ? l->Scale() : 1.0f;
const double scale2 = l->hasScale2() ? l->Scale2() : scale1;
gtrsf = gp_GTrsf2d();
@@ -207,9 +262,10 @@ bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2DnonUnifo
CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcPlane::ptr pln, gp_Pln& plane) {
bool IfcGeom::convert(const IfcSchema::IfcPlane::ptr pln, gp_Pln& plane) {
IN_CACHE(IfcPlane,pln,gp_Pln,plane)
Ifc2x3::IfcAxis2Placement3D::ptr l = pln->Position();
IfcSchema::IfcAxis2Placement3D::ptr l = pln->Position();
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
IfcGeom::convert(l->Location(),o);
bool hasRef = l->hasRefDirection();
@@ -222,7 +278,8 @@ bool IfcGeom::convert(const Ifc2x3::IfcPlane::ptr pln, gp_Pln& plane) {
CACHE(IfcPlane,pln,plane)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement2D::ptr l, gp_Trsf2d& trsf) {
bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement2D::ptr l, gp_Trsf2d& trsf) {
IN_CACHE(IfcAxis2Placement2D,l,gp_Trsf2d,trsf)
gp_Pnt P; gp_Dir V (1,0,0);
IfcGeom::convert(l->Location(),P);
@@ -234,30 +291,32 @@ bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement2D::ptr l, gp_Trsf2d& trsf)
CACHE(IfcAxis2Placement2D,l,trsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcObjectPlacement::ptr l, gp_Trsf& trsf) {
bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement::ptr l, gp_Trsf& trsf) {
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
if ( ! l->is(Ifc2x3::Type::IfcLocalPlacement) ) {
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l->entity);
return false;
}
Ifc2x3::IfcLocalPlacement::ptr current = reinterpret_pointer_cast<Ifc2x3::IfcObjectPlacement,Ifc2x3::IfcLocalPlacement>(l);
IfcSchema::IfcLocalPlacement::ptr current = reinterpret_pointer_cast<IfcSchema::IfcObjectPlacement,IfcSchema::IfcLocalPlacement>(l);
while (1) {
gp_Trsf trsf2;
Ifc2x3::IfcAxis2Placement relplacement = current->RelativePlacement();
if ( relplacement->is(Ifc2x3::Type::IfcAxis2Placement3D) ) {
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)relplacement,trsf2);
IfcSchema::IfcAxis2Placement relplacement = current->RelativePlacement();
if ( relplacement->is(IfcSchema::Type::IfcAxis2Placement3D) ) {
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)relplacement,trsf2);
trsf.PreMultiply(trsf2);
}
if ( current->hasPlacementRelTo() ) {
Ifc2x3::IfcObjectPlacement::ptr relto = current->PlacementRelTo();
if ( relto->is(Ifc2x3::Type::IfcLocalPlacement) )
current = reinterpret_pointer_cast<Ifc2x3::IfcObjectPlacement,Ifc2x3::IfcLocalPlacement>(current->PlacementRelTo());
IfcSchema::IfcObjectPlacement::ptr relto = current->PlacementRelTo();
if ( relto->is(IfcSchema::Type::IfcLocalPlacement) )
current = reinterpret_pointer_cast<IfcSchema::IfcObjectPlacement,IfcSchema::IfcLocalPlacement>(current->PlacementRelTo());
else break;
} else break;
}
CACHE(IfcObjectPlacement,l,trsf)
return true;
}
void IfcGeom::Cache::Purge() {
#include "IfcRegisterPurgeCache.h"
IfcGeom::Cache::PurgeShapeCache();
+72 -191
View File
@@ -32,7 +32,7 @@
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepMesh.hxx>
#include <Poly_Triangulation.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <TColgp_Array1OfPnt.hxx>
@@ -44,6 +44,7 @@
#include <BRepBuilderAPI_GTransform.hxx>
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcgeom/IfcGeomObjects.h"
#include "../ifcgeom/IfcGeom.h"
@@ -133,7 +134,8 @@ IfcGeomObjects::IfcRepresentationTriangulation::IfcRepresentationTriangulation(c
// Triangulate the shape
try {
BRepMesh_IncrementalMesh(s, IfcGeom::GetValue(IfcGeom::GV_DEFLECTION_TOLERANCE));
// BRepTools::Clean(s);
BRepMesh::Mesh(s, IfcGeom::GetValue(IfcGeom::GV_DEFLECTION_TOLERANCE));
} catch(...) {
Logger::Message(Logger::LOG_ERROR,"Failed to triangulate shape:",ifc_file->EntityById(_id)->entity);
continue;
@@ -278,8 +280,8 @@ IfcGeomObjects::IfcGeomObject::IfcGeomObject(
{}
// A container and iterator for IfcShapeRepresentations
static Ifc2x3::IfcShapeRepresentation::list shapereps;
static Ifc2x3::IfcShapeRepresentation::it shaperep_iterator;
static IfcSchema::IfcShapeRepresentation::list shapereps;
static IfcSchema::IfcShapeRepresentation::it shaperep_iterator;
// The object is fetched beforehand to be positive an entity actually exists
static IfcGeomObjects::IfcGeomObject* current_geom_obj = 0;
@@ -287,8 +289,8 @@ static IfcGeomObjects::IfcGeomShapeModelObject* current_shape_model_obj = 0;
static IfcGeomObjects::IfcGeomBrepDataObject* current_brep_data_obj = 0;
// A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *shaperep_iterator
static Ifc2x3::IfcProduct::list entities;
static Ifc2x3::IfcProduct::it ifcproduct_iterator;
static IfcSchema::IfcProduct::list entities;
static IfcSchema::IfcProduct::it ifcproduct_iterator;
static int done;
static int total;
@@ -300,44 +302,53 @@ void _nextShape() {
++ done;
}
int _getParentId(const Ifc2x3::IfcProduct::ptr ifc_product) {
int _getParentId(const IfcSchema::IfcProduct::ptr ifc_product) {
int parent_id = -1;
// In case of an opening element, parent to the RelatingBuildingElement
if ( ifc_product->is(Ifc2x3::Type::IfcOpeningElement ) ) {
Ifc2x3::IfcOpeningElement::ptr opening = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcOpeningElement>(ifc_product);
Ifc2x3::IfcRelVoidsElement::list voids = opening->VoidsElements();
if ( ifc_product->is(IfcSchema::Type::IfcOpeningElement ) ) {
IfcSchema::IfcOpeningElement::ptr opening = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcOpeningElement>(ifc_product);
IfcSchema::IfcRelVoidsElement::list voids = opening->VoidsElements();
if ( voids->Size() ) {
Ifc2x3::IfcRelVoidsElement::ptr ifc_void = *voids->begin();
IfcSchema::IfcRelVoidsElement::ptr ifc_void = *voids->begin();
parent_id = ifc_void->RelatingBuildingElement()->entity->id();
}
} else if ( ifc_product->is(Ifc2x3::Type::IfcElement ) ) {
Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcElement>(ifc_product);
Ifc2x3::IfcRelFillsElement::list fills = element->FillsVoids();
} else if ( ifc_product->is(IfcSchema::Type::IfcElement ) ) {
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcElement>(ifc_product);
IfcSchema::IfcRelFillsElement::list fills = element->FillsVoids();
// Incase of a RelatedBuildingElement parent to the opening element
if ( fills->Size() ) {
for ( Ifc2x3::IfcRelFillsElement::it it = fills->begin(); it != fills->end(); ++ it ) {
Ifc2x3::IfcRelFillsElement::ptr fill = *it;
Ifc2x3::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
for ( IfcSchema::IfcRelFillsElement::it it = fills->begin(); it != fills->end(); ++ it ) {
IfcSchema::IfcRelFillsElement::ptr fill = *it;
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
if ( ifc_product == ifc_objectdef ) continue;
parent_id = ifc_objectdef->entity->id();
}
}
// Else simply parent to the containing structure
if ( parent_id == -1 ) {
Ifc2x3::IfcRelContainedInSpatialStructure::list parents = element->ContainedInStructure();
IfcSchema::IfcRelContainedInSpatialStructure::list parents = element->ContainedInStructure();
if ( parents->Size() ) {
Ifc2x3::IfcRelContainedInSpatialStructure::ptr parent = *parents->begin();
IfcSchema::IfcRelContainedInSpatialStructure::ptr parent = *parents->begin();
parent_id = parent->RelatingStructure()->entity->id();
}
}
}
// Parent decompositions to the RelatingObject
if ( parent_id == -1 ) {
IfcEntities parents = ifc_product->entity->getInverse(Ifc2x3::Type::IfcRelAggregates);
parents->push(ifc_product->entity->getInverse(Ifc2x3::Type::IfcRelNests));
IfcEntities parents = ifc_product->entity->getInverse(IfcSchema::Type::IfcRelAggregates);
parents->push(ifc_product->entity->getInverse(IfcSchema::Type::IfcRelNests));
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
Ifc2x3::IfcRelDecomposes::ptr decompose = reinterpret_pointer_cast<IfcBaseClass,Ifc2x3::IfcRelDecomposes>(*it);
Ifc2x3::IfcObjectDefinition* ifc_objectdef = decompose->RelatingObject();
IfcSchema::IfcRelDecomposes::ptr decompose = reinterpret_pointer_cast<IfcUtil::IfcBaseClass,IfcSchema::IfcRelDecomposes>(*it);
IfcSchema::IfcObjectDefinition* ifc_objectdef;
#ifdef USE_IFC4
if (decompose->is(IfcSchema::Type::IfcRelAggregates)) {
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
} else {
continue;
}
#else
ifc_objectdef = decompose->RelatingObject();
#endif
if ( ifc_product == ifc_objectdef ) continue;
parent_id = ifc_objectdef->entity->id();
}
@@ -347,7 +358,7 @@ int _getParentId(const Ifc2x3::IfcProduct::ptr ifc_product) {
IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
while ( true ) {
Ifc2x3::IfcShapeRepresentation::ptr shaperep;
IfcSchema::IfcShapeRepresentation::ptr shaperep;
// Have we reached the end of our list of representations?
if ( shaperep_iterator == shapereps->end() ) {
@@ -368,11 +379,11 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
continue;
}
}
Ifc2x3::IfcProductRepresentation::list prodreps = shaperep->OfProductRepresentation();
entities = Ifc2x3::IfcProduct::list( new IfcTemplatedEntityList<Ifc2x3::IfcProduct>() );
for ( Ifc2x3::IfcProductRepresentation::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
if ( (*it)->is(Ifc2x3::Type::IfcProductDefinitionShape) ) {
Ifc2x3::IfcProductDefinitionShape::ptr pds = reinterpret_pointer_cast<Ifc2x3::IfcProductRepresentation,Ifc2x3::IfcProductDefinitionShape>(*it);
IfcSchema::IfcProductRepresentation::list prodreps = shaperep->OfProductRepresentation();
entities = IfcSchema::IfcProduct::list( new IfcTemplatedEntityList<IfcSchema::IfcProduct>() );
for ( IfcSchema::IfcProductRepresentation::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
IfcSchema::IfcProductDefinitionShape::ptr pds = reinterpret_pointer_cast<IfcSchema::IfcProductRepresentation,IfcSchema::IfcProductDefinitionShape>(*it);
entities->push(pds->ShapeOfProduct());
} else {
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
@@ -381,9 +392,9 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
IfcEntities products = (*it)->entity->getInverse(Ifc2x3::Type::IfcProduct);
IfcEntities products = (*it)->entity->getInverse(IfcSchema::Type::IfcProduct);
for ( IfcEntityList::it it = products->begin(); it != products->end(); ++ it ) {
entities->push(reinterpret_pointer_cast<IfcBaseClass,Ifc2x3::IfcProduct>(*it));
entities->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,IfcSchema::IfcProduct>(*it));
}
}
}
@@ -408,7 +419,7 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
continue;
}
Ifc2x3::IfcProduct::ptr ifc_product = *ifcproduct_iterator;
IfcSchema::IfcProduct::ptr ifc_product = *ifcproduct_iterator;
int parent_id = -1;
try {
@@ -425,19 +436,24 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
// Does the IfcElement have any IfcOpenings?
// Note that openings for IfcOpeningElements are not processed
Ifc2x3::IfcRelVoidsElement::list openings = Ifc2x3::IfcRelVoidsElement::list();
if ( ifc_product->is(Ifc2x3::Type::IfcElement) && !ifc_product->is(Ifc2x3::Type::IfcOpeningElement) ) {
Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcElement>(ifc_product);
IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list();
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcElement>(ifc_product);
openings = element->HasOpenings();
}
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
if ( ifc_product->is(Ifc2x3::Type::IfcBuildingElementPart ) ) {
Ifc2x3::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcBuildingElementPart>(ifc_product);
Ifc2x3::IfcRelDecomposes::list decomposes = part->Decomposes();
for ( Ifc2x3::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
Ifc2x3::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
if ( obdef->is(Ifc2x3::Type::IfcElement) ) {
Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast<Ifc2x3::IfcObjectDefinition,Ifc2x3::IfcElement>(obdef);
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcBuildingElementPart>(ifc_product);
#ifdef USE_IFC4
IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes();
for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
#else
IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes();
for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
#endif
IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcObjectDefinition,IfcSchema::IfcElement>(obdef);
openings->push(element->HasOpenings());
}
}
@@ -476,7 +492,7 @@ IfcGeomObjects::IfcGeomShapeModelObject* create_shape_model_for_next_entity() {
}
return new IfcGeomObjects::IfcGeomShapeModelObject(ifc_product->entity->id(), parent_id, name,
Ifc2x3::Type::ToString(ifc_product->type()), guid, trsf, shape);
IfcSchema::Type::ToString(ifc_product->type()), guid, trsf, shape);
}
}
@@ -537,8 +553,8 @@ const IfcGeomObjects::IfcObject* IfcGeomObjects::GetObject(int id) {
IfcObject* ifc_object = 0;
try {
const IfcParse::IfcEntity& ifc_entity = ifc_file->EntityById(id);
if ( ifc_entity->is(Ifc2x3::Type::IfcProduct) ) {
Ifc2x3::IfcProduct::ptr ifc_product = reinterpret_pointer_cast<IfcUtil::IfcBaseClass,Ifc2x3::IfcProduct>(ifc_entity);
if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) {
IfcSchema::IfcProduct::ptr ifc_product = reinterpret_pointer_cast<IfcUtil::IfcBaseClass,IfcSchema::IfcProduct>(ifc_entity);
int parent_id = -1;
try {
parent_id = _getParentId(ifc_product);
@@ -549,7 +565,7 @@ const IfcGeomObjects::IfcObject* IfcGeomObjects::GetObject(int id) {
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
} catch (...) {}
ifc_object = new IfcObject(ifc_product->entity->id(),parent_id,name,
Ifc2x3::Type::ToString(ifc_product->type()),ifc_product->GlobalId(),trsf);
IfcSchema::Type::ToString(ifc_product->type()),ifc_product->GlobalId(),trsf);
}
} catch(...) {}
if ( !ifc_object ) ifc_object = new IfcObject(-1,-1,"","","",gp_Trsf());
@@ -571,150 +587,16 @@ const IfcGeomObjects::IfcGeomBrepDataObject* IfcGeomObjects::GetBrepData() {
}
return current_brep_data_obj;
}
double UnitPrefixToValue( Ifc2x3::IfcSIPrefix::IfcSIPrefix v ) {
if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_EXA ) return (double) 1e18;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_PETA ) return (double) 1e15;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_TERA ) return (double) 1e12;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_GIGA ) return (double) 1e9;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_MEGA ) return (double) 1e6;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_KILO ) return (double) 1e3;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_HECTO ) return (double) 1e2;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_DECA ) return (double) 1;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_DECI ) return (double) 1e-1;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_CENTI ) return (double) 1e-2;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_MILLI ) return (double) 1e-3;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_MICRO ) return (double) 1e-6;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_NANO ) return (double) 1e-9;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_PICO ) return (double) 1e-12;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_FEMTO ) return (double) 1e-15;
else if ( v == Ifc2x3::IfcSIPrefix::IfcSIPrefix_ATTO ) return (double) 1e-18;
else return 1.0f;
}
static std::string unit_name = "METER";
static float unit_magnitude = 1.0f;
void IfcGeomObjects::InitPrecision() {
IfcGeom::SetValue(IfcGeom::GV_PRECISION, 0.00001);
try {
Ifc2x3::IfcGeometricRepresentationContext::list rep_contexts = ifc_file->EntitiesByType<Ifc2x3::IfcGeometricRepresentationContext>();
// Currently, IfcGeometricRepresentationContext aren't used as much as they should be
// in the evaluation of shape representations, hence, we try to find the one with the
// lowest precision. Typically, a value of 1e-5 is encountered. This value is applied
// to all TopoDS_Shapes generated by one of the IfcGeom::convert() functions.
// TODO: Many of the empirically found tolerances should probably be substituted by
// one that is defined in the model file.
double lowest_precision_encountered = std::numeric_limits<double>::infinity();
bool any_precision_encountered = false;
for (Ifc2x3::IfcGeometricRepresentationContext::it it = rep_contexts->begin(); it != rep_contexts->end(); ++it) {
Ifc2x3::IfcGeometricRepresentationContext* rep_context = *it;
if (rep_context->is(Ifc2x3::Type::IfcGeometricRepresentationSubContext)) continue;
if (rep_context->hasPrecision()) {
const double precision = rep_context->Precision();
if (precision < lowest_precision_encountered) {
any_precision_encountered = true;
lowest_precision_encountered = precision;
}
}
}
if (any_precision_encountered) {
// Some arbitrary factor that has proven to work better for the models in the set of test files.
lowest_precision_encountered *= 10.;
lowest_precision_encountered *= unit_magnitude;
if (lowest_precision_encountered < 1.e-7) {
Logger::Message(Logger::LOG_WARNING, "Precision lower than 0.0000001 meter not enforced");
IfcGeom::SetValue(IfcGeom::GV_PRECISION, 1.e-7);
} else {
IfcGeom::SetValue(IfcGeom::GV_PRECISION, lowest_precision_encountered);
}
}
} catch (const IfcParse::IfcException& ex) {
std::stringstream ss;
ss << "Failed to determine precision value '" << ex.what() << "'";
Logger::Message(Logger::LOG_ERROR, ss.str());
}
}
void IfcGeomObjects::InitUnits() {
// Set default units, set length to meters, angles to undefined
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,1.0);
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,-1.0);
Ifc2x3::IfcUnitAssignment::list unit_assignments = ifc_file->EntitiesByType<Ifc2x3::IfcUnitAssignment>();
IfcUtil::IfcAbstractSelect::list units = IfcUtil::IfcAbstractSelect::list();
try {
if ( unit_assignments->Size() ) {
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *unit_assignments->begin();
units = unit_assignment->Units();
}
} catch (const IfcParse::IfcException&) {}
if (!units) {
// No units eh... Since tolerances and deflection are specified internally in meters
// we will try to find another indication of the model size.
Ifc2x3::IfcExtrudedAreaSolid::list extrusions = ifc_file->EntitiesByType<Ifc2x3::IfcExtrudedAreaSolid>();
if ( ! extrusions->Size() ) return;
double max_height = -1.0f;
for ( Ifc2x3::IfcExtrudedAreaSolid::it it = extrusions->begin(); it != extrusions->end(); ++ it ) {
try {
const double depth = (*it)->Depth();
if ( depth > max_height ) max_height = depth;
} catch (const IfcParse::IfcException&) {}
}
if ( max_height > 100.0f ) {
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,0.001);
Logger::Message(Logger::LOG_NOTICE, "Guessed length unit to be in millimeters based on extrusion depth");
}
return;
}
try {
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
std::string current_unit_name = "";
const IfcUtil::IfcAbstractSelect::ptr base = *it;
Ifc2x3::IfcSIUnit::ptr unit = Ifc2x3::IfcSIUnit::ptr();
double value = 1.0f;
if ( base->is(Ifc2x3::Type::IfcConversionBasedUnit) ) {
const Ifc2x3::IfcConversionBasedUnit::ptr u = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcConversionBasedUnit>(base);
current_unit_name = u->Name();
const Ifc2x3::IfcMeasureWithUnit::ptr u2 = u->ConversionFactor();
Ifc2x3::IfcUnit u3 = u2->UnitComponent();
if ( u3->is(Ifc2x3::Type::IfcSIUnit) ) {
unit = (Ifc2x3::IfcSIUnit*) u3;
}
Ifc2x3::IfcValue v = u2->ValueComponent();
IfcUtil::IfcArgumentSelect* v2 = (IfcUtil::IfcArgumentSelect*) v;
const double f = *v2->wrappedValue();
value *= f;
} else if ( base->is(Ifc2x3::Type::IfcSIUnit) ) {
unit = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcSIUnit>(base);
}
if ( unit ) {
if ( unit->hasPrefix() ) {
value *= UnitPrefixToValue(unit->Prefix());
}
Ifc2x3::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,value);
if (current_unit_name.empty()) {
if (unit->hasPrefix()) {
current_unit_name = Ifc2x3::IfcSIPrefix::ToString(unit->Prefix());
}
current_unit_name += Ifc2x3::IfcSIUnitName::ToString(unit->Name());
}
unit_magnitude = value;
unit_name = current_unit_name;
} else if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,value);
}
}
}
} catch (const IfcParse::IfcException& ex) {
std::stringstream ss;
ss << "Failed to determine unit information '" << ex.what() << "'";
Logger::Message(Logger::LOG_ERROR, ss.str());
IfcSchema::IfcProject::list projects = ifc_file->EntitiesByType<IfcSchema::IfcProject>();
if (projects->Size() == 1) {
double unit_magnitude_double;
IfcGeom::initialize_units_and_precision(*projects->begin(), unit_magnitude_double, unit_name);
unit_magnitude = static_cast<float>(unit_magnitude_double);
}
}
@@ -723,9 +605,8 @@ bool IfcGeomObjects::Init(const std::string fn) {
}
bool _Init() {
IfcGeomObjects::InitUnits();
IfcGeomObjects::InitPrecision();
shapereps = ifc_file->EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
shapereps = ifc_file->EntitiesByType<IfcSchema::IfcShapeRepresentation>();
if ( ! shapereps ) return false;
shaperep_iterator = shapereps->begin();
@@ -811,10 +692,10 @@ IfcParse::IfcFile* IfcGeomObjects::GetFile() {
static double black[3] = {0,0,0};
IfcGeomObjects::Material::Material(const IfcGeom::SurfaceStyle* style) : style(style) {}
bool IfcGeomObjects::Material::hasDiffuse() const { return style->Diffuse() ? true : false; }
bool IfcGeomObjects::Material::hasSpecular() const { return style->Specular() ? true : false; }
bool IfcGeomObjects::Material::hasTransparency() const { return style->Transparency() ? true : false; }
bool IfcGeomObjects::Material::hasSpecularity() const { return style->Specularity() ? true : false; }
bool IfcGeomObjects::Material::hasDiffuse() const { return style->Diffuse(); }
bool IfcGeomObjects::Material::hasSpecular() const { return style->Specular(); }
bool IfcGeomObjects::Material::hasTransparency() const { return style->Transparency(); }
bool IfcGeomObjects::Material::hasSpecularity() const { return style->Specularity(); }
const double* IfcGeomObjects::Material::diffuse() const { if (hasDiffuse()) return &((*style->Diffuse()).R()); else return black; }
const double* IfcGeomObjects::Material::specular() const { if (hasSpecular()) return &((*style->Specular()).R()); else return black; }
double IfcGeomObjects::Material::transparency() const { if (hasTransparency()) return *style->Transparency(); else return 0; }
+13 -21
View File
@@ -30,7 +30,7 @@ namespace IfcGeom {
}
}
bool process_colour(Ifc2x3::IfcColourRgb* colour, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcSchema::IfcColourRgb* colour, std::tr1::array<double, 3>& rgb) {
if (colour != 0) {
rgb[0] = colour->Red();
rgb[1] = colour->Green();
@@ -39,28 +39,28 @@ bool process_colour(Ifc2x3::IfcColourRgb* colour, std::tr1::array<double, 3>& rg
return colour != 0;
}
bool process_colour(IfcUtil::IfcArgumentSelect* factor, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcUtil::IfcBaseEntity* factor, std::tr1::array<double, 3>& rgb) {
if (factor != 0) {
const double f = *factor->wrappedValue();
const double f = *factor->entity->getArgument(0);
rgb[0] = rgb[1] = rgb[2] = f;
}
return factor != 0;
}
bool process_colour(Ifc2x3::IfcColourOrFactor colour_or_factor, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcSchema::IfcColourOrFactor colour_or_factor, std::tr1::array<double, 3>& rgb) {
if (colour_or_factor == 0) {
return false;
} else if (colour_or_factor->is(Ifc2x3::Type::IfcColourRgb)) {
return process_colour(static_cast<Ifc2x3::IfcColourRgb*>(colour_or_factor), rgb);
} else if (colour_or_factor->is(Ifc2x3::Type::IfcNormalisedRatioMeasure)) {
return process_colour(static_cast<IfcUtil::IfcArgumentSelect*>(colour_or_factor), rgb);
} else if (colour_or_factor->is(IfcSchema::Type::IfcColourRgb)) {
return process_colour(static_cast<IfcSchema::IfcColourRgb*>(colour_or_factor), rgb);
} else if (colour_or_factor->is(IfcSchema::Type::IfcNormalisedRatioMeasure)) {
return process_colour(static_cast<IfcUtil::IfcBaseEntity*>(colour_or_factor), rgb);
} else {
return false;
}
}
const IfcGeom::SurfaceStyle* IfcGeom::get_style(Ifc2x3::IfcRepresentationItem* item) {
std::pair<Ifc2x3::IfcSurfaceStyle*, Ifc2x3::IfcSurfaceStyleShading*> shading_styles = get_surface_style<Ifc2x3::IfcSurfaceStyleShading>(item);
const IfcGeom::SurfaceStyle* IfcGeom::get_style(IfcSchema::IfcRepresentationItem* item) {
std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*> shading_styles = get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item);
if (shading_styles.second == 0) {
return 0;
}
@@ -79,8 +79,8 @@ const IfcGeom::SurfaceStyle* IfcGeom::get_style(Ifc2x3::IfcRepresentationItem* i
if (process_colour(shading_styles.second->SurfaceColour(), rgb)) {
surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
if (shading_styles.second->is(Ifc2x3::Type::IfcSurfaceStyleRendering)) {
Ifc2x3::IfcSurfaceStyleRendering* rendering_style = static_cast<Ifc2x3::IfcSurfaceStyleRendering*>(shading_styles.second);
if (shading_styles.second->is(IfcSchema::Type::IfcSurfaceStyleRendering)) {
IfcSchema::IfcSurfaceStyleRendering* rendering_style = static_cast<IfcSchema::IfcSurfaceStyleRendering*>(shading_styles.second);
if (rendering_style->hasDiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) {
SurfaceStyle::ColorComponent diffuse = surface_style.Diffuse().get_value_or(SurfaceStyle::ColorComponent(1,1,1));
surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(diffuse.R() * rgb[0], diffuse.G() * rgb[1], diffuse.B() * rgb[2]));
@@ -95,15 +95,7 @@ const IfcGeom::SurfaceStyle* IfcGeom::get_style(Ifc2x3::IfcRepresentationItem* i
surface_style.Specular().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
if (rendering_style->hasSpecularHighlight()) {
IfcUtil::IfcArgumentSelect* highlight = static_cast<IfcUtil::IfcArgumentSelect*>(rendering_style->SpecularHighlight());
if (highlight->is(Ifc2x3::Type::IfcSpecularRoughness)) {
double roughness = *highlight->wrappedValue();
if (roughness >= 1e-9) {
surface_style.Specularity().reset(1.0 / roughness);
}
} else if (highlight->is(Ifc2x3::Type::IfcSpecularExponent)) {
surface_style.Specularity().reset(*highlight->wrappedValue());
}
// Not supported
}
if (rendering_style->hasTransmissionColour()) {
// Not supported
+29 -15
View File
@@ -26,7 +26,11 @@
#include <array>
#endif
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
#include "../ifcparse/Ifc2x3.h"
#endif
namespace IfcGeom {
class SurfaceStyle {
@@ -97,19 +101,29 @@ namespace IfcGeom {
boost::optional<double>& Specularity() { return specularity; }
};
template <typename T> std::pair<Ifc2x3::IfcSurfaceStyle*, T*> get_surface_style(Ifc2x3::IfcRepresentationItem* representation_item) {
Ifc2x3::IfcStyledItem::list styled_items = representation_item->StyledByItem();
for (Ifc2x3::IfcStyledItem::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
Ifc2x3::IfcPresentationStyleAssignment::list style_assignments = (*jt)->Styles();
for (Ifc2x3::IfcPresentationStyleAssignment::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
IfcAbstractSelect::list styles = (*kt)->Styles();
for (IfcAbstractSelect::it lt = styles->begin(); lt != styles->end(); ++lt) {
IfcAbstractSelect::ptr style = *lt;
if (style->is(Ifc2x3::Type::IfcSurfaceStyle)) {
Ifc2x3::IfcSurfaceStyle* surface_style = (Ifc2x3::IfcSurfaceStyle*) style;
if (surface_style->Side() != Ifc2x3::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
IfcAbstractSelect::list styles_elements = surface_style->Styles();
for (IfcAbstractSelect::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(IfcSchema::IfcRepresentationItem* representation_item) {
IfcSchema::IfcStyledItem::list styled_items = representation_item->StyledByItem();
for (IfcSchema::IfcStyledItem::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
#ifdef USE_IFC4
IfcUtil::IfcAbstractSelect::list style_assignments = (*jt)->Styles();
for (IfcUtil::IfcAbstractSelect::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
if (!(*kt)->is(IfcSchema::Type::IfcPresentationStyleAssignment)) {
continue;
}
IfcSchema::IfcPresentationStyleAssignment::ptr style_assignment = (IfcSchema::IfcPresentationStyleAssignment::ptr) *kt;
#else
IfcSchema::IfcPresentationStyleAssignment::list style_assignments = (*jt)->Styles();
for (IfcSchema::IfcPresentationStyleAssignment::it kt = style_assignments->begin(); kt != style_assignments->end(); ++kt) {
IfcSchema::IfcPresentationStyleAssignment::ptr style_assignment = *kt;
#endif
IfcUtil::IfcAbstractSelect::list styles = style_assignment->Styles();
for (IfcUtil::IfcAbstractSelect::it lt = styles->begin(); lt != styles->end(); ++lt) {
IfcUtil::IfcAbstractSelect::ptr style = *lt;
if (style->is(IfcSchema::Type::IfcSurfaceStyle)) {
IfcSchema::IfcSurfaceStyle* surface_style = (IfcSchema::IfcSurfaceStyle*) style;
if (surface_style->Side() != IfcSchema::IfcSurfaceSide::IfcSurfaceSide_NEGATIVE) {
IfcUtil::IfcAbstractSelect::list styles_elements = surface_style->Styles();
for (IfcUtil::IfcAbstractSelect::it mt = styles_elements->begin(); mt != styles_elements->end(); ++mt) {
if ((*mt)->is(T::Class())) {
return std::make_pair(surface_style, (T*) *mt);
}
@@ -124,10 +138,10 @@ namespace IfcGeom {
break;
}
return std::make_pair<Ifc2x3::IfcSurfaceStyle*, T*>(0,0);
return std::make_pair<IfcSchema::IfcSurfaceStyle*, T*>(0,0);
}
const SurfaceStyle* get_style(Ifc2x3::IfcRepresentationItem* representation_item);
const SurfaceStyle* get_style(IfcSchema::IfcRepresentationItem* representation_item);
const SurfaceStyle* get_default_style(const std::string& ifc_type);
namespace Cache {
+499 -110
View File
@@ -35,6 +35,7 @@
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
@@ -44,12 +45,17 @@
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Geom_Line.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <BRepOffsetAPI_Sewing.hxx>
#include <BRepOffsetAPI_MakePipe.hxx>
#include <BRepOffsetAPI_MakePipeShell.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
@@ -62,10 +68,21 @@
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeWedge.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <ShapeFix_Shape.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
@@ -74,13 +91,10 @@
#include <TopLoc_Location.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert(const Ifc2x3::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape& shape) {
TopoDS_Face face;
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
@@ -94,7 +108,71 @@ bool IfcGeom::convert(const Ifc2x3::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape& s
shape.Move(trsf);
return ! shape.IsNull();
}
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, IfcRepresentationShapeItems& shape) {
bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion::ptr l, TopoDS_Shape& shape) {
TopoDS_Wire wire;
if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) {
TopoDS_Face face;
if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false;
TopExp_Explorer exp(face, TopAbs_WIRE);
wire = TopoDS::Wire(exp.Current());
}
const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
gp_Dir dir;
convert(l->ExtrudedDirection(),dir);
shape = BRepPrimAPI_MakePrism(wire, height*dir);
shape.Move(trsf);
return !shape.IsNull();
}
bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfRevolution::ptr l, TopoDS_Shape& shape) {
TopoDS_Wire wire;
if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) {
TopoDS_Face face;
if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false;
TopExp_Explorer exp(face, TopAbs_WIRE);
wire = TopoDS::Wire(exp.Current());
}
gp_Ax1 ax1;
IfcGeom::convert(l->AxisPosition(), ax1);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
shape = BRepPrimAPI_MakeRevol(wire, ax1);
shape.Move(trsf);
return !shape.IsNull();
}
bool IfcGeom::convert(const IfcSchema::IfcRevolvedAreaSolid::ptr l, TopoDS_Shape& shape) {
const double ang = l->Angle() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT);
TopoDS_Face face;
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
gp_Ax1 ax1;
IfcGeom::convert(l->Axis(), ax1);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
if (ang >= M_PI * 2. - ALMOST_ZERO) {
shape = BRepPrimAPI_MakeRevol(face, ax1);
} else {
shape = BRepPrimAPI_MakeRevol(face, ax1, ang);
}
shape.Move(trsf);
return !shape.IsNull();
}
bool IfcGeom::convert(const IfcSchema::IfcFacetedBrep::ptr l, IfcRepresentationShapeItems& shape) {
TopoDS_Shape s;
const SurfaceStyle* collective_style = get_style(l);
if (IfcGeom::convert_shape(l->Outer(),s) ) {
@@ -104,10 +182,11 @@ bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, IfcRepresentationShap
}
return false;
}
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
Ifc2x3::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
bool IfcGeom::convert(const IfcSchema::IfcFaceBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
IfcSchema::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
const SurfaceStyle* collective_style = get_style(l);
for( Ifc2x3::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
for( IfcSchema::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
TopoDS_Shape s;
const SurfaceStyle* shell_style = get_style(*it);
if (IfcGeom::convert_shape(*it,s)) {
@@ -116,21 +195,23 @@ bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, IfcRepresen
}
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcHalfSpaceSolid::ptr l, TopoDS_Shape& shape) {
Ifc2x3::IfcSurface::ptr surface = l->BaseSurface();
if ( ! surface->is(Ifc2x3::Type::IfcPlane) ) {
bool IfcGeom::convert(const IfcSchema::IfcHalfSpaceSolid::ptr l, TopoDS_Shape& shape) {
IfcSchema::IfcSurface::ptr surface = l->BaseSurface();
if ( ! surface->is(IfcSchema::Type::IfcPlane) ) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface->entity);
return false;
}
gp_Pln pln;
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcSurface,Ifc2x3::IfcPlane>(surface),pln);
IfcGeom::convert(reinterpret_pointer_cast<IfcSchema::IfcSurface,IfcSchema::IfcPlane>(surface),pln);
const gp_Pnt pnt = pln.Location().Translated( l->AgreementFlag() ? -pln.Axis().Direction() : pln.Axis().Direction());
shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_Shape& shape) {
TopoDS_Shape halfspace;
if ( ! IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcPolygonalBoundedHalfSpace,Ifc2x3::IfcHalfSpaceSolid>(l),halfspace) ) return false;
if ( ! IfcGeom::convert(reinterpret_pointer_cast<IfcSchema::IfcPolygonalBoundedHalfSpace,IfcSchema::IfcHalfSpaceSolid>(l),halfspace) ) return false;
TopoDS_Wire wire;
if ( ! IfcGeom::convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
gp_Trsf trsf;
@@ -141,14 +222,15 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_
shape = BRepAlgoAPI_Common(halfspace,prism);
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
bool IfcGeom::convert(const IfcSchema::IfcShellBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) {
IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary();
const SurfaceStyle* collective_style = get_style(l);
for( IfcUtil::IfcAbstractSelect::it it = shells->begin(); it != shells->end(); ++ it ) {
TopoDS_Shape s;
const SurfaceStyle* shell_style = 0;
if ((*it)->is(Ifc2x3::Type::IfcRepresentationItem)) {
shell_style = get_style((Ifc2x3::IfcRepresentationItem*)*it);
if ((*it)->is(IfcSchema::Type::IfcRepresentationItem)) {
shell_style = get_style((IfcSchema::IfcRepresentationItem*)*it);
}
if (IfcGeom::convert_shape(*it,s)) {
shapes.push_back(IfcRepresentationShapeItem(s, shell_style ? shell_style : collective_style));
@@ -156,12 +238,13 @@ bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, IfcReprese
}
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const IfcSchema::IfcBooleanResult::ptr l, TopoDS_Shape& shape) {
TopoDS_Shape s1, s2;
TopoDS_Wire boundary_wire;
Ifc2x3::IfcBooleanOperand operand1 = l->FirstOperand();
Ifc2x3::IfcBooleanOperand operand2 = l->SecondOperand();
bool is_halfspace = operand2->is(Ifc2x3::Type::IfcHalfSpaceSolid);
IfcSchema::IfcBooleanOperand operand1 = l->FirstOperand();
IfcSchema::IfcBooleanOperand operand2 = l->SecondOperand();
bool is_halfspace = operand2->is(IfcSchema::Type::IfcHalfSpaceSolid);
if ( ! IfcGeom::convert_shape(operand1,s1) )
return false;
@@ -182,50 +265,90 @@ bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr l, TopoDS_Shap
Logger::Message(Logger::LOG_WARNING,"Empty solid for:",operand2->entity);
}
bool valid_cut = false;
BRepAlgoAPI_Cut brep_cut(s1,s2);
if ( brep_cut.IsDone() ) {
TopoDS_Shape result = brep_cut;
const IfcSchema::IfcBooleanOperator::IfcBooleanOperator op = l->Operator();
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE) {
bool valid_cut = false;
BRepAlgoAPI_Cut brep_cut(s1,s2);
if ( brep_cut.IsDone() ) {
TopoDS_Shape result = brep_cut;
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if ( is_valid ) {
shape = result;
valid_cut = true;
}
}
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if ( is_valid ) {
shape = result;
valid_cut = true;
}
}
if ( valid_cut ) {
const double volume_after_subtraction = shape_volume(shape);
if ( ALMOST_THE_SAME(first_operand_volume,volume_after_subtraction) )
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",l->entity);
} else {
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",l->entity);
shape = s1;
}
return true;
} else if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_UNION) {
BRepAlgoAPI_Fuse brep_fuse(s1,s2);
if ( brep_fuse.IsDone() ) {
TopoDS_Shape result = brep_fuse;
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if ( is_valid ) {
shape = result;
}
}
return true;
} else if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_INTERSECTION) {
BRepAlgoAPI_Common brep_common(s1,s2);
if ( brep_common.IsDone() ) {
TopoDS_Shape result = brep_common;
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
bool is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if ( is_valid ) {
shape = result;
}
}
return true;
if ( valid_cut ) {
const double volume_after_subtraction = shape_volume(shape);
if ( ALMOST_THE_SAME(first_operand_volume,volume_after_subtraction) )
Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",l->entity);
} else {
Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",l->entity);
shape = s1;
return false;
}
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& shape) {
Ifc2x3::IfcFace::list faces = l->CfsFaces();
bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet::ptr l, TopoDS_Shape& shape) {
IfcSchema::IfcFace::list faces = l->CfsFaces();
bool facesAdded = false;
const unsigned int num_faces = faces->Size();
bool valid_shell = false;
if ( num_faces < GetValue(GV_MAX_FACES_TO_SEW) ) {
BRepOffsetAPI_Sewing builder;
builder.SetTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMaxTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMinTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
for( IfcSchema::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
TopoDS_Face face;
bool converted_face = false;
try {
converted_face = IfcGeom::convert_face(*it,face);
} catch (...) {}
if ( converted_face && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
if ( IfcGeom::convert_face(*it,face) && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
builder.Add(face);
facesAdded = true;
} else {
@@ -233,38 +356,20 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
}
}
if ( ! facesAdded ) return false;
builder.Perform();
shape = builder.SewedShape();
try {
builder.Perform();
shape = builder.SewedShape();
valid_shell = BRepCheck_Analyzer(shape).IsValid();
ShapeFix_Solid solid;
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
if (valid_shell) {
try {
ShapeFix_Solid solid;
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
TopoDS_Solid solid_shape = solid.SolidFromShell(TopoDS::Shell(shape));
if (!solid_shape.IsNull()) {
try {
BRepClass3d_SolidClassifier classifier(solid_shape);
shape = solid_shape;
} catch (...) {}
}
} catch(...) {}
} else {
Logger::Message(Logger::LOG_WARNING,"Failed to sew faceset:",l->entity);
}
}
if (!valid_shell) {
} else {
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
for( IfcSchema::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
TopoDS_Face face;
bool converted_face = false;
try {
converted_face = IfcGeom::convert_face(*it,face);
} catch (...) {}
if ( converted_face && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
if ( IfcGeom::convert_face(*it,face) && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
builder.Add(compound,face);
facesAdded = true;
} else {
@@ -276,34 +381,35 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
}
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, IfcRepresentationShapeItems& shapes) {
bool IfcGeom::convert(const IfcSchema::IfcMappedItem::ptr l, IfcRepresentationShapeItems& shapes) {
gp_GTrsf gtrsf;
Ifc2x3::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator3DnonUniform>(transform),gtrsf);
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
IfcSchema::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
IfcGeom::convert(reinterpret_pointer_cast<IfcSchema::IfcCartesianTransformationOperator,
IfcSchema::IfcCartesianTransformationOperator3DnonUniform>(transform),gtrsf);
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity);
return false;
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3D) ) {
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) {
gp_Trsf trsf;
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator3D>(transform),trsf);
IfcGeom::convert(reinterpret_pointer_cast<IfcSchema::IfcCartesianTransformationOperator,
IfcSchema::IfcCartesianTransformationOperator3D>(transform),trsf);
gtrsf = trsf;
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2D) ) {
} else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) {
gp_Trsf2d trsf_2d;
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator2D>(transform),trsf_2d);
IfcGeom::convert(reinterpret_pointer_cast<IfcSchema::IfcCartesianTransformationOperator,
IfcSchema::IfcCartesianTransformationOperator2D>(transform),trsf_2d);
gtrsf = (gp_Trsf) trsf_2d;
}
Ifc2x3::IfcRepresentationMap::ptr map = l->MappingSource();
Ifc2x3::IfcAxis2Placement placement = map->MappingOrigin();
IfcSchema::IfcRepresentationMap::ptr map = l->MappingSource();
IfcSchema::IfcAxis2Placement placement = map->MappingOrigin();
gp_Trsf trsf;
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)placement,trsf);
if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf);
} else {
gp_Trsf2d trsf_2d;
IfcGeom::convert((Ifc2x3::IfcAxis2Placement2D*)placement,trsf_2d);
IfcGeom::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf_2d);
trsf = trsf_2d;
}
gtrsf.Multiply(trsf);
@@ -315,22 +421,305 @@ bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, IfcRepresentationShape
return b;
}
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr l, IfcRepresentationShapeItems& shapes) {
Ifc2x3::IfcRepresentationItem::list items = l->Items();
bool part_succes = false;
if ( items->Size() ) {
for ( Ifc2x3::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
Ifc2x3::IfcRepresentationItem* representation_item = *it;
if ( IfcGeom::is_shape_collection(representation_item) ) {
part_succes |= IfcGeom::convert_shapes(*it, shapes);
} else {
TopoDS_Shape s;
if (IfcGeom::convert_shape(representation_item,s)) {
shapes.push_back(IfcRepresentationShapeItem(s, get_style(representation_item)));
part_succes |= true;
}
bool IfcGeom::convert(const IfcSchema::IfcShapeRepresentation::ptr l, IfcRepresentationShapeItems& shapes) {
IfcSchema::IfcRepresentationItem::list items = l->Items();
if ( ! items->Size() ) return false;
for ( IfcSchema::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
IfcSchema::IfcRepresentationItem* representation_item = *it;
if ( IfcGeom::is_shape_collection(representation_item) ) IfcGeom::convert_shapes(*it,shapes);
else {
TopoDS_Shape s;
if (IfcGeom::convert_shape(representation_item,s)) {
shapes.push_back(IfcRepresentationShapeItem(s, get_style(representation_item)));
}
}
}
return part_succes;
}
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcGeometricSet::ptr l, IfcRepresentationShapeItems& shapes) {
IfcUtil::IfcAbstractSelect::list elements = l->Elements();
if ( !elements->Size() ) return false;
const IfcGeom::SurfaceStyle* parent_style = get_style(l);
for ( IfcUtil::IfcAbstractSelect::it it = elements->begin(); it != elements->end(); ++ it ) {
IfcSchema::IfcGeometricSetSelect element = *it;
if (element->is(IfcSchema::Type::IfcSurface)) {
IfcSchema::IfcSurface* surface = (IfcSchema::IfcSurface*) element;
TopoDS_Shape s;
if (IfcGeom::convert_shape(surface, s)) {
const IfcGeom::SurfaceStyle* style = get_style(surface);
shapes.push_back(IfcRepresentationShapeItem(s, style ? style : parent_style));
}
}
}
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcBlock::ptr l, TopoDS_Shape& shape) {
const double dx = l->XLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dy = l->YLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dz = l->ZLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
BRepPrimAPI_MakeBox builder(dx, dy, dz);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
shape = builder.Solid().Moved(trsf);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcRectangularPyramid::ptr l, TopoDS_Shape& shape) {
const double dx = l->XLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dy = l->YLength() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double dz = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
BRepPrimAPI_MakeWedge builder(dx, dz, dy, dx / 2., dy / 2., dx / 2., dy / 2.);
gp_Trsf trsf1, trsf2;
trsf2.SetValues(1, 0, 0, 0,
0, 0, 1, 0,
0, 1, 0, 0, Precision::Confusion(), Precision::Confusion());
IfcGeom::convert(l->Position(), trsf1);
shape = BRepBuilderAPI_Transform(builder.Solid(), trsf1 * trsf2);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcRightCircularCylinder::ptr l, TopoDS_Shape& shape) {
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double h = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
BRepPrimAPI_MakeCylinder builder(r, h);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
shape = builder.Solid().Moved(trsf);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcRightCircularCone::ptr l, TopoDS_Shape& shape) {
const double r = l->BottomRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const double h = l->Height() * IfcGeom::GetValue(GV_LENGTH_UNIT);
BRepPrimAPI_MakeCone builder(r, 0., h);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
shape = builder.Solid().Moved(trsf);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcSphere::ptr l, TopoDS_Shape& shape) {
const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
BRepPrimAPI_MakeSphere builder(r);
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
shape = builder.Solid().Moved(trsf);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcCsgSolid::ptr l, TopoDS_Shape& shape) {
return IfcGeom::convert_shape(l->TreeRootExpression(), shape);
}
bool IfcGeom::convert(const IfcSchema::IfcCurveBoundedPlane::ptr l, TopoDS_Shape& face) {
gp_Pln pln;
IfcGeom::convert(l->BasisSurface(), pln);
gp_Trsf trsf;
trsf.SetTransformation(pln.Position());
TopoDS_Wire outer;
IfcGeom::convert_wire(l->OuterBoundary(), outer);
BRepBuilderAPI_MakeFace mf (outer);
mf.Add(outer);
IfcSchema::IfcCurve::list inner = l->InnerBoundaries();
for (IfcSchema::IfcCurve::it it = inner->begin(); it != inner->end(); ++it) {
TopoDS_Wire inner;
IfcGeom::convert_wire(*it, inner);
mf.Add(inner);
}
ShapeFix_Shape sfs(mf.Face());
sfs.Perform();
face = TopoDS::Face(sfs.Shape()).Moved(trsf);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcRectangularTrimmedSurface::ptr l, TopoDS_Shape& face) {
if (!l->BasisSurface()->is(IfcSchema::Type::IfcPlane)) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", l->BasisSurface()->entity);
return false;
}
gp_Pln pln;
IfcGeom::convert((IfcSchema::IfcPlane*) l->BasisSurface(), pln);
BRepBuilderAPI_MakeFace mf(pln, l->U1(), l->U2(), l->V1(), l->V2());
face = mf.Face();
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid::ptr l, TopoDS_Shape& shape) {
gp_Trsf directrix, position;
TopoDS_Shape face;
TopoDS_Wire wire, section;
if (!l->ReferenceSurface()->is(IfcSchema::Type::IfcPlane)) {
Logger::Message(Logger::LOG_WARNING, "Reference surface not supported", l->ReferenceSurface()->entity);
return false;
}
if (!IfcGeom::convert(l->Position(), position) ||
!IfcGeom::convert_face(l->SweptArea(), face) ||
!IfcGeom::convert_wire(l->Directrix(), wire) ) {
return false;
}
gp_Pln pln;
gp_Pnt directrix_origin;
gp_Vec directrix_tangent;
bool directrix_on_plane = true;
IfcGeom::convert((IfcSchema::IfcPlane*) l->ReferenceSurface(), pln);
// As per Informal propositions 2: The Directrix shall lie on the ReferenceSurface.
// This is not always the case with the test files in the repository. I am not sure
// how to deal with this and whether my interpretation of the propositions is
// correct. However, if it has been asserted that the vertices of the directrix do
// not conform to the ReferenceSurface, the ReferenceSurface is ignored.
{
for (TopExp_Explorer exp(wire, TopAbs_VERTEX); exp.More(); exp.Next()) {
if (pln.Distance(BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))) > ALMOST_ZERO) {
directrix_on_plane = false;
Logger::Message(Logger::LOG_WARNING, "The Directrix does not lie on the ReferenceSurface", l->entity);
break;
}
}
}
{
TopExp_Explorer exp(wire, TopAbs_EDGE);
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
double u0, u1;
Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u0, u1);
crv->D1(u0, directrix_origin, directrix_tangent);
}
if (pln.Axis().Direction().IsNormal(directrix_tangent, Precision::Approximation()) && directrix_on_plane) {
directrix.SetTransformation(gp_Ax3(directrix_origin, directrix_tangent, pln.Axis().Direction()), gp::XOY());
} else {
directrix.SetTransformation(gp_Ax3(directrix_origin, directrix_tangent), gp::XOY());
}
face = BRepBuilderAPI_Transform(face, directrix);
// NB: Note that StartParam and EndParam param are ignored and the assumption is
// made that the parametric range over which to be swept matches the IfcCurve in
// its entirety.
BRepOffsetAPI_MakePipeShell builder(wire);
{ TopExp_Explorer exp(face, TopAbs_WIRE);
section = TopoDS::Wire(exp.Current()); }
builder.Add(section);
builder.SetTransitionMode(BRepBuilderAPI_RightCorner);
if (directrix_on_plane) {
builder.SetMode(pln.Axis().Direction());
}
builder.Build();
builder.MakeSolid();
shape = builder.Shape();
shape.Move(position);
return true;
}
bool IfcGeom::convert(const IfcSchema::IfcSweptDiskSolid::ptr l, TopoDS_Shape& shape) {
TopoDS_Wire wire, section1, section2;
const bool hasInnerRadius = l->hasInnerRadius();
if (!IfcGeom::convert_wire(l->Directrix(), wire)) {
return false;
}
gp_Ax2 directrix;
{
gp_Pnt directrix_origin;
gp_Vec directrix_tangent;
TopExp_Explorer exp(wire, TopAbs_EDGE);
TopoDS_Edge edge = TopoDS::Edge(exp.Current());
double u0, u1;
Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u0, u1);
crv->D1(u0, directrix_origin, directrix_tangent);
directrix = gp_Ax2(directrix_origin, directrix_tangent);
}
const double r1 = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r1);
section1 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
if (hasInnerRadius) {
const double r2 = l->InnerRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT);
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r2);
section2 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
}
// NB: Note that StartParam and EndParam param are ignored and the assumption is
// made that the parametric range over which to be swept matches the IfcCurve in
// its entirety.
// NB2: Contrary to IfcSurfaceCurveSweptAreaSolid the transition mode has been
// set to create round corners as this has proven to work better with the types
// of directrices encountered, which do not necessarily conform to a surface.
{ BRepOffsetAPI_MakePipeShell builder(wire);
builder.Add(section1);
builder.SetTransitionMode(BRepBuilderAPI_RoundCorner);
builder.Build();
builder.MakeSolid();
shape = builder.Shape(); }
if (hasInnerRadius) {
BRepOffsetAPI_MakePipeShell builder(wire);
builder.Add(section2);
builder.SetTransitionMode(BRepBuilderAPI_RoundCorner);
builder.Build();
builder.MakeSolid();
TopoDS_Shape inner = builder.Shape();
BRepAlgoAPI_Cut brep_cut(shape, inner);
bool is_valid = false;
if (brep_cut.IsDone()) {
TopoDS_Shape result = brep_cut;
ShapeFix_Shape fix(result);
fix.Perform();
result = fix.Shape();
is_valid = BRepCheck_Analyzer(result).IsValid() != 0;
if (is_valid) {
shape = result;
}
}
if (!is_valid) {
Logger::Message(Logger::LOG_WARNING, "Failed to subtract inner radius void for:", l->entity);
}
}
return true;
}
#ifdef USE_IFC4
bool IfcGeom::convert(const IfcSchema::IfcCylindricalSurface::ptr l, TopoDS_Shape& face) {
gp_Trsf trsf;
IfcGeom::convert(l->Position(),trsf);
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius()), GetValue(GV_PRECISION)).Face().Moved(trsf);
return true;
}
#endif
+58 -70
View File
@@ -82,7 +82,7 @@
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire) {
bool IfcGeom::convert(const IfcSchema::IfcCompositeCurve::ptr l, TopoDS_Wire& wire) {
if ( IfcGeom::GetValue(GV_PLANEANGLE_UNIT)<0 ) {
Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity);
@@ -138,11 +138,11 @@ bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire)
return use_radians || use_degrees;
}
Ifc2x3::IfcCompositeCurveSegment::list segments = l->Segments();
IfcSchema::IfcCompositeCurveSegment::list segments = l->Segments();
BRepBuilderAPI_MakeWire w;
//TopoDS_Vertex last_vertex;
for( Ifc2x3::IfcCompositeCurveSegment::it it = segments->begin(); it != segments->end(); ++ it ) {
const Ifc2x3::IfcCurve::ptr curve = (*it)->ParentCurve();
for( IfcSchema::IfcCompositeCurveSegment::it it = segments->begin(); it != segments->end(); ++ it ) {
const IfcSchema::IfcCurve::ptr curve = (*it)->ParentCurve();
TopoDS_Wire wire2;
if ( ! IfcGeom::convert_wire(curve,wire2) ) {
Logger::Message(Logger::LOG_ERROR,"Failed to convert curve:",curve->entity);
@@ -171,13 +171,13 @@ bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire)
wire = w.Wire();
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
Ifc2x3::IfcCurve::ptr basis_curve = l->BasisCurve();
bool isConic = basis_curve->is(Ifc2x3::Type::IfcConic);
bool IfcGeom::convert(const IfcSchema::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
IfcSchema::IfcCurve::ptr basis_curve = l->BasisCurve();
bool isConic = basis_curve->is(IfcSchema::Type::IfcConic);
double parameterFactor = isConic ? IfcGeom::GetValue(GV_PLANEANGLE_UNIT) : IfcGeom::GetValue(GV_LENGTH_UNIT);
Handle(Geom_Curve) curve;
if ( ! IfcGeom::convert_curve(basis_curve,curve) ) return false;
bool trim_cartesian = l->MasterRepresentation() == Ifc2x3::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
IfcUtil::IfcAbstractSelect::list trims1 = l->Trim1();
IfcUtil::IfcAbstractSelect::list trims2 = l->Trim2();
bool trimmed1 = false;
@@ -190,22 +190,22 @@ bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
BRepBuilderAPI_MakeWire w;
for ( IfcUtil::IfcAbstractSelect::it it = trims1->begin(); it != trims1->end(); it ++ ) {
const IfcUtil::IfcAbstractSelect::ptr i = *it;
if ( i->is(Ifc2x3::Type::IfcCartesianPoint) ) {
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnts[sense_agreement] );
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcSchema::IfcCartesianPoint>(i), pnts[sense_agreement] );
has_pnts[sense_agreement] = true;
} else if ( i->is(Ifc2x3::Type::IfcParameterValue) ) {
const double value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
const double value = *((IfcUtil::IfcBaseEntity*)i)->entity->getArgument(0);
flts[sense_agreement] = value * parameterFactor;
has_flts[sense_agreement] = true;
}
}
for ( IfcUtil::IfcAbstractSelect::it it = trims2->begin(); it != trims2->end(); it ++ ) {
const IfcUtil::IfcAbstractSelect::ptr i = *it;
if ( i->is(Ifc2x3::Type::IfcCartesianPoint) ) {
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnts[1-sense_agreement] );
if ( i->is(IfcSchema::Type::IfcCartesianPoint) ) {
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcSchema::IfcCartesianPoint>(i), pnts[1-sense_agreement] );
has_pnts[1-sense_agreement] = true;
} else if ( i->is(Ifc2x3::Type::IfcParameterValue) ) {
const double value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
} else if ( i->is(IfcSchema::Type::IfcParameterValue) ) {
const double value = *((IfcUtil::IfcBaseEntity*)i)->entity->getArgument(0);
flts[1-sense_agreement] = value * parameterFactor;
has_flts[1-sense_agreement] = true;
}
@@ -238,11 +238,21 @@ bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
// is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because
// the vector is normalised when passed to Geom_Line constructor the magnitude
// needs to be factored in with the IfcParameterValue here.
if ( basis_curve->is(Ifc2x3::Type::IfcLine) ) {
Ifc2x3::IfcLine* line = static_cast<Ifc2x3::IfcLine*>(basis_curve);
if ( basis_curve->is(IfcSchema::Type::IfcLine) ) {
IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve);
const double magnitude = line->Dir()->Magnitude();
flts[0] *= magnitude; flts[1] *= magnitude;
}
if ( basis_curve->is(IfcSchema::Type::IfcEllipse) ) {
IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
double x = ellipse->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT);
double y = ellipse->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT);
const bool rotated = y > x;
if (rotated) {
flts[0] -= M_PI / 2.;
flts[1] -= M_PI / 2.;
}
}
if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
w.Add(BRepBuilderAPI_MakeEdge(curve));
} else {
@@ -259,66 +269,44 @@ bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr l, TopoDS_Wire& wire) {
return false;
}
}
bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr l, TopoDS_Wire& result) {
Ifc2x3::IfcCartesianPoint::list points = l->Points();
bool IfcGeom::convert(const IfcSchema::IfcPolyline::ptr l, TopoDS_Wire& result) {
IfcSchema::IfcCartesianPoint::list points = l->Points();
// Parse and store the points in a sequence
TColgp_SequenceOfPnt polygon;
for(Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it) {
gp_Pnt pnt;
IfcGeom::convert(*it, pnt);
polygon.Append(pnt);
}
// Remove points that are too close to one another
remove_redundant_points_from_loop(polygon, false);
BRepBuilderAPI_MakePolygon w;
for (int i = 1; i <= polygon.Length(); ++i) {
w.Add(polygon.Value(i));
BRepBuilderAPI_MakeWire w;
gp_Pnt P1;gp_Pnt P2;
for( IfcSchema::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
IfcGeom::convert(*it,P2);
if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) )
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
P1 = P2;
}
result = w.Wire();
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr l, TopoDS_Wire& result) {
Ifc2x3::IfcCartesianPoint::list points = l->Polygon();
bool IfcGeom::convert(const IfcSchema::IfcPolyLoop::ptr l, TopoDS_Wire& result) {
IfcSchema::IfcCartesianPoint::list points = l->Polygon();
// Parse and store the points in a sequence
TColgp_SequenceOfPnt polygon;
for(Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it) {
gp_Pnt pnt;
IfcGeom::convert(*it, pnt);
polygon.Append(pnt);
BRepBuilderAPI_MakeWire w;
gp_Pnt P1;gp_Pnt P2;gp_Pnt F;
int count = 0;
for( IfcSchema::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
IfcGeom::convert(*it,P2);
if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) {
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
count ++;
} else if ( ! count ) F = P2;
P1 = P2;
}
// A loop should consist of at least three vertices
int original_count = polygon.Length();
if (original_count < 3) {
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity);
return false;
if ( !P1.IsEqual(F,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) {
w.Add(BRepBuilderAPI_MakeEdge(P1,F));
count ++;
}
if ( count < 3 ) return false;
// Remove points that are too close to one another
remove_redundant_points_from_loop(polygon, true);
int count = polygon.Length();
if (original_count - count != 0) {
std::stringstream ss; ss << (original_count - count) << " edges removed for:";
Logger::Message(Logger::LOG_WARNING, ss.str(), l->entity);
}
if (count < 3) {
Logger::Message(Logger::LOG_ERROR, "Not enough edges for:", l->entity);
return false;
}
BRepBuilderAPI_MakePolygon w;
for (int i = 1; i <= polygon.Length(); ++i) {
w.Add(polygon.Value(i));
}
w.Close();
result = w.Wire();
result = w.Wire();
return true;
}
}
bool IfcGeom::convert(const IfcSchema::IfcArbitraryOpenProfileDef::ptr l, TopoDS_Wire& result) {
return IfcGeom::convert_wire(l->Curve(), result);
}
+6 -2
View File
@@ -28,7 +28,7 @@ namespace IfcGeom {
}
}
using namespace Ifc2x3;
using namespace IfcSchema;
using namespace IfcUtil;
bool IfcGeom::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
@@ -58,10 +58,14 @@ bool IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
}
bool IfcGeom::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) {
#include "IfcRegisterConvertWire.h"
Handle(Geom_Curve) curve;
if (IfcGeom::convert_curve(l, curve)) {
return IfcGeom::convert_curve_to_wire(curve, r);
}
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
return false;
}
bool IfcGeom::convert_face(const IfcBaseClass* l, TopoDS_Face& r) {
bool IfcGeom::convert_face(const IfcBaseClass* l, TopoDS_Shape& r) {
#include "IfcRegisterConvertFace.h"
Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity);
return false;
+32 -3
View File
@@ -41,34 +41,62 @@
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcParse.h"
using namespace Ifc2x3;
using namespace IfcSchema;
SHAPES(IfcShellBasedSurfaceModel);
SHAPES(IfcFaceBasedSurfaceModel);
SHAPES(IfcShapeRepresentation);
SHAPES(IfcMappedItem);
SHAPES(IfcFacetedBrep);
SHAPES(IfcGeometricSet);
SHAPE(IfcExtrudedAreaSolid);
SHAPE(IfcRevolvedAreaSolid);
SHAPE(IfcConnectedFaceSet);
SHAPE(IfcBooleanClippingResult);
SHAPE(IfcBooleanResult);
SHAPE(IfcPolygonalBoundedHalfSpace);
SHAPE(IfcHalfSpaceSolid);
SHAPE(IfcSurfaceOfLinearExtrusion);
SHAPE(IfcSurfaceOfRevolution);
SHAPE(IfcBlock);
SHAPE(IfcRectangularPyramid);
SHAPE(IfcRightCircularCylinder);
SHAPE(IfcRightCircularCone);
SHAPE(IfcSphere);
SHAPE(IfcCsgSolid);
SHAPE(IfcCurveBoundedPlane);
SHAPE(IfcRectangularTrimmedSurface);
SHAPE(IfcSurfaceCurveSweptAreaSolid);
SHAPE(IfcSweptDiskSolid);
#ifdef USE_IFC4
SHAPE(IfcCylindricalSurface);
#endif
FACE(IfcArbitraryProfileDefWithVoids);
FACE(IfcArbitraryClosedProfileDef);
FACE(IfcRoundedRectangleProfileDef);
FACE(IfcRectangleHollowProfileDef);
FACE(IfcRectangleProfileDef);
FACE(IfcIShapeProfileDef);
FACE(IfcTrapeziumProfileDef)
FACE(IfcCShapeProfileDef);
FACE(IfcIShapeProfileDef);
FACE(IfcLShapeProfileDef);
FACE(IfcTShapeProfileDef);
FACE(IfcUShapeProfileDef);
FACE(IfcZShapeProfileDef);
FACE(IfcCircleHollowProfileDef);
FACE(IfcCircleProfileDef);
FACE(IfcEllipseProfileDef);
FACE(IfcCenterLineProfileDef);
FACE(IfcCompositeProfileDef);
FACE(IfcDerivedProfileDef);
FACE(IfcFace);
WIRE(IfcPolyline);
WIRE(IfcPolyLoop);
WIRE(IfcCompositeCurve);
WIRE(IfcTrimmedCurve);
WIRE(IfcArbitraryOpenProfileDef);
CURVE(IfcCircle);
CURVE(IfcEllipse);
@@ -78,6 +106,7 @@ CLASS(IfcCartesianPoint,gp_Pnt);
CLASS(IfcDirection,gp_Dir);
CLASS(IfcAxis2Placement2D,gp_Trsf2d);
CLASS(IfcAxis2Placement3D,gp_Trsf);
CLASS(IfcAxis1Placement,gp_Ax1);
CLASS(IfcCartesianTransformationOperator2DnonUniform,gp_GTrsf2d);
CLASS(IfcCartesianTransformationOperator3DnonUniform,gp_GTrsf);
CLASS(IfcCartesianTransformationOperator2D,gp_Trsf2d);
+1 -1
View File
@@ -3,7 +3,7 @@
#define SHAPES(T) CLASS(T,IfcRepresentationShapeItems)
#define SHAPE(T) CLASS(T,TopoDS_Shape)
#define WIRE(T) CLASS(T,TopoDS_Wire)
#define FACE(T) CLASS(T,TopoDS_Face)
#define FACE(T) CLASS(T,TopoDS_Shape)
#define CURVE(T) CLASS(T,Handle(Geom_Curve))
#include "IfcRegisterDef.h"
+30
View File
@@ -0,0 +1,30 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
#ifndef IFCSHAPELIST_H
#define IFCSHAPELIST_H
#include <gp_GTrsf.hxx>
#include <TopoDS_Shape.hxx>
namespace IfcGeom {
typedef std::pair<gp_GTrsf*,const TopoDS_Shape*> LocationShape;
typedef std::vector<LocationShape> ShapeList;
}
#endif
+339
View File
@@ -0,0 +1,339 @@
/********************************************************************************
* *
* 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 examples exposes the IfcOpenShell API through a command-based stdin *
* interface *
* *
********************************************************************************/
#include <iostream>
#include <boost/cstdint.hpp>
#if defined(_WIN32) && !defined(__CYGWIN__)
#define SET_BINARY_STREAMS
#endif
#ifdef SET_BINARY_STREAMS
#include <io.h>
#include <fcntl.h>
#endif
#include "../ifcgeom/IfcGeomObjects.h"
using namespace boost;
template <typename T>
T sread(std::istream& s) {
char buf[sizeof(T)];
s.read(buf, sizeof(T));
return *((T*)buf);
}
template <>
std::string sread(std::istream& s) {
int32_t len = sread<int32_t>(s);
char* buf = new char[len + 1];
s.read(buf, len);
buf[len] = 0;
while (len++ % 4) s.get();
std::string str(buf);
delete buf;
return str;
}
static std::streambuf *stdout_orig, *stdout_redir;
template <typename T>
void swrite(std::ostream& s, T t) {
char buf[sizeof(T)];
memcpy(buf, &t, sizeof(T));
s.write(buf, sizeof(T));
}
template <>
void swrite(std::ostream& s, std::string t) {
int32_t len = t.size();
swrite(s, len);
s.write(t.c_str(), len);
while (len++ % 4) s.put(0);
}
class Command {
protected:
virtual void read_content(std::istream& s) = 0;
virtual void write_content(std::ostream& s) = 0;
int32_t iden;
int32_t len;
public:
void read(std::istream& s) {
len = sread<int32_t>(s);
read_content(s);
}
void write(std::ostream& s) {
std::cout.rdbuf(stdout_orig);
swrite(s, iden);
std::ostringstream oss;
write_content(oss);
swrite(s, oss.str());
s.flush();
std::cout.rdbuf(stdout_redir);
}
Command(int32_t iden) : iden(iden) {}
};
const int32_t HELLO = 0xff00;
const int32_t IFC_MODEL = HELLO + 1;
const int32_t GET = IFC_MODEL + 1;
const int32_t ENTITY = GET + 1;
const int32_t MORE = ENTITY + 1;
const int32_t NEXT = MORE + 1;
const int32_t BYE = NEXT + 1;
const int32_t GET_LOG = BYE + 1;
const int32_t LOG = GET_LOG + 1;
class Hello : public Command {
private:
std::string str;
protected:
void read_content(std::istream& s) {
str = sread<std::string>(s);
}
void write_content(std::ostream& s) {
swrite(s, str);
}
public:
const std::string& string() { return str; }
Hello() : Command(HELLO), str("IfcOpenShell-" IFCOPENSHELL_VERSION) {}
};
class More : public Command {
private:
bool more;
protected:
void read_content(std::istream& s) {
more = sread<int32_t>(s) == 1;
}
void write_content(std::ostream& s) {
swrite<int32_t>(s, more ? 1 : 0);
}
public:
More(bool more) : Command(MORE), more(more) {}
};
class IfcModel : public Command {
private:
std::string str;
protected:
void read_content(std::istream& s) {
str = sread<std::string>(s);
}
void write_content(std::ostream& s) {
swrite(s, str);
}
public:
const std::string& string() { return str; }
IfcModel() : Command(IFC_MODEL) {};
};
class Get : public Command {
protected:
void read_content(std::istream& s) {}
void write_content(std::ostream& s) {}
public:
Get() : Command(GET) {};
};
class GetLog : public Command {
protected:
void read_content(std::istream& s) {}
void write_content(std::ostream& s) {}
public:
GetLog() : Command(GET_LOG) {};
};
class WriteLog : public Command {
private:
std::string str;
protected:
void read_content(std::istream& s) {
str = sread<std::string>(s);
}
void write_content(std::ostream& s) {
swrite(s, str);
}
public:
WriteLog(const std::string& str) : Command(LOG), str(str) {};
};
class Entity : public Command {
private:
const IfcGeomObjects::IfcGeomObject* geom;
protected:
void read_content(std::istream& s) {}
void write_content(std::ostream& s) {
swrite<int32_t>(s, geom->id());
swrite(s, geom->guid());
swrite(s, geom->name());
swrite(s, geom->type());
swrite<int32_t>(s, geom->parent_id());
const std::vector<float>& m = geom->matrix();
const float matrix_array[16] = {
m[0], m[3], m[6], m[ 9],
m[1], m[4], m[7], m[10],
m[2], m[5], m[8], m[11],
0, 0, 0, 1
};
swrite(s, std::string((char*)matrix_array, 16 * sizeof(float)));
swrite<int32_t>(s, geom->mesh().id());
swrite(s, std::string((char*)geom->mesh().verts().data(), geom->mesh().verts().size() * sizeof(float)));
swrite(s, std::string((char*)geom->mesh().normals().data(), geom->mesh().normals().size() * sizeof(float)));
{ std::vector<int32_t> indices;
for (std::vector<int>::const_iterator it = geom->mesh().faces().begin(); it != geom->mesh().faces().end(); ++it) {
indices.push_back(*it);
}
swrite(s, std::string((char*) indices.data(), indices.size() * sizeof(int32_t))); }
{ std::vector<float> diffuse_color_array;
for (std::vector<IfcGeomObjects::Material>::const_iterator it = geom->mesh().materials().begin(); it != geom->mesh().materials().end(); ++it) {
const IfcGeomObjects::Material& m = *it;
if (m.hasDiffuse()) {
const double* color = m.diffuse();
diffuse_color_array.push_back(static_cast<float>(color[0]));
diffuse_color_array.push_back(static_cast<float>(color[1]));
diffuse_color_array.push_back(static_cast<float>(color[2]));
} else {
diffuse_color_array.push_back(0.f);
diffuse_color_array.push_back(0.f);
diffuse_color_array.push_back(0.f);
}
if (m.hasTransparency()) {
diffuse_color_array.push_back(static_cast<float>(1. - m.transparency()));
} else {
diffuse_color_array.push_back(1.f);
}
}
swrite(s, std::string((char*) diffuse_color_array.data(), diffuse_color_array.size() * sizeof(float))); }
{ std::vector<int32_t> material_indices;
for (std::vector<int>::const_iterator it = geom->mesh().material_ids().begin(); it != geom->mesh().material_ids().end(); ++it) {
material_indices.push_back(*it);
}
swrite(s, std::string((char*) material_indices.data(), material_indices.size() * sizeof(int32_t))); }
}
public:
Entity(const IfcGeomObjects::IfcGeomObject* geom) : Command(ENTITY), geom(geom) {};
};
class Next : public Command {
protected:
void read_content(std::istream& s) {}
void write_content(std::ostream& s) {}
public:
Next() : Command(NEXT) {};
};
class Bye : public Command {
protected:
void read_content(std::istream& s) {}
void write_content(std::ostream& s) {}
public:
Bye() : Command(BYE) {};
};
int main (int argc, char** argv) {
if (sizeof(float) != 4 || sizeof(int32_t) != 4) {
return 1;
}
// Redirect stdout to this stream, so that involuntary
// writes to stdout do not interfere with our protocol.
std::ostringstream oss;
stdout_redir = oss.rdbuf();
stdout_orig = std::cout.rdbuf();
std::cout.rdbuf(stdout_redir);
#ifdef SET_BINARY_STREAMS
_setmode(_fileno(stdout), _O_BINARY);
std::cout.setf(std::ios_base::binary);
_setmode(_fileno(stdin), _O_BINARY);
std::cin.setf(std::ios_base::binary);
#endif
bool has_more = false;
Hello().write(std::cout);
int exit_code = 0;
while (1) {
const int32_t msg_type = sread<int32_t>(std::cin);
switch (msg_type) {
case IFC_MODEL: {
IfcModel m; m.read(std::cin);
std::string::size_type len = m.string().size();
char* data = new char[len];
memcpy(data, m.string().c_str(), len);
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, false);
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES, false);
IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS, true);
IfcGeomObjects::Settings(IfcGeomObjects::FORCE_CCW_FACE_ORIENTATION, true);
has_more = IfcGeomObjects::Init(data, len);
More(has_more).write(std::cout);
continue;
}
case GET: {
Get g; g.read(std::cin);
if (!has_more) {
exit_code = 1;
break;
}
const IfcGeomObjects::IfcGeomObject* geom = IfcGeomObjects::Get();
Entity(geom).write(std::cout);
continue;
}
case NEXT: {
Next n; n.read(std::cin);
has_more = IfcGeomObjects::Next();
if (!has_more) {
IfcGeomObjects::CleanUp();
}
More(has_more).write(std::cout);
continue;
}
case GET_LOG: {
GetLog gl; gl.read(std::cin);
WriteLog(IfcGeomObjects::GetLog()).write(std::cout);
continue;
}
case BYE: {
Bye().write(std::cout);
exit_code = 0;
break;
}
default:
exit_code = 1;
break;
}
break;
}
std::cout.rdbuf(stdout_orig);
return exit_code;
}
+48
View File
@@ -0,0 +1,48 @@
/********************************************************************************
* *
* 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 file defines materials for use in 3ds Max for several IFC datatypes *
* *
********************************************************************************/
#include <string>
#include "Max.h"
#include "stdmat.h"
StdMat2* GetMaterial(const std::string& s) {
StdMat2* mat = NewDefaultStdMat();
TimeValue t (-1);
mat->SetSpecular(Color(0.2f,0.2f,0.2f),t);
mat->SetAmbient(Color(0.1f,0.1f,0.1f),t);
mat->SetWire( s == "IfcSpace" || s == "IfcOpeningElement" );
if ( s == "IfcSite" ) { mat->SetDiffuse(Color(0.75f,0.8f,0.65f),t); }
if ( s == "IfcSlab" ) { mat->SetDiffuse(Color(0.4f,0.4f,0.4f),t); }
if ( s == "IfcWallStandardCase" ) { mat->SetDiffuse(Color(0.9f,0.9f,0.9f),t); }
if ( s == "IfcWall" ) { mat->SetDiffuse(Color(0.9f,0.9f,0.9f),t); }
if ( s == "IfcWindow" ) { mat->SetDiffuse(Color(0.75f,0.8f,0.75f),t); mat->SetSpecular(Color(1.0f,1.0f,1.0f),t);
mat->SetAmbient(Color(0.0f,0.0f,0.0f),t); mat->SetShininess(500.0f,t); mat->SetOpacity(0.3f,t); }
if ( s == "IfcDoor" ) { mat->SetDiffuse(Color(0.55f,0.3f,0.15f),t); }
if ( s == "IfcBeam" ) { mat->SetDiffuse(Color(0.75f,0.7f,0.7f),t); }
if ( s == "IfcRailing" ) { mat->SetDiffuse(Color(0.75f,0.7f,0.7f),t); }
if ( s == "IfcMember" ) { mat->SetDiffuse(Color(0.75f,0.7f,0.7f),t); }
return mat;
}
+127
View File
@@ -0,0 +1,127 @@
/********************************************************************************
* *
* 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 is a brief example of how IfcOpenShell can be interfaced from within *
* a C++ context. The application reads an .ifc file and outputs geometry in *
* the Wavefront .obj file format. *
* *
********************************************************************************/
#include <fstream>
#include <sstream>
#include <set>
#include <time.h>
#include "../ifcgeom/IfcGeomObjects.h"
#include "../ifcobj/ObjMaterials.h"
int main ( int argc, char** argv ) {
if ( argc != 2 ) {
std::cout << "usage: IfcObj <filename.ifc>" << std::endl;
return 1;
}
const std::string fnObj = std::string(argv[1]) + ".obj";
const std::string fnMtl = std::string(argv[1]) + ".mtl";
ofstream fObj(fnObj.c_str());
ofstream fMtl(fnMtl.c_str());
if ( ! ( fObj.is_open() && fMtl.is_open() ) ) {
std::cout << "[Error] unable to open output file for writing" << std::endl;
return 1;
}
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,true);
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,false);
IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS,true);
// Stream for log messages, we don't want to interupt our new progress bar...
std::stringstream ss;
// Parse the file supplied in argv[1]. Returns true on succes.
if ( ! IfcGeomObjects::Init(argv[1],&std::cout,&ss) ) {
std::cout << "[Error] unable to parse .ifc file or no geometrical entities found" << std::endl;
return 1;
}
fObj << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << std::endl;
fObj << "mtllib " << fnMtl << std::endl;
std::set<std::string> materials;
time_t start,end;
time(&start);
int old_progress = -1;
std::cout << "Creating geometry..." << std::endl;
// The functions IfcGeomObjects::Get() and IfcGeomObjects::Next() wrap an iterator of all geometrical entities in the Ifc file.
// IfcGeomObjects::Get() returns an IfcGeomObjects::IfcGeomObject (see IfcObjects.h for definition)
// IfcGeomObjects::Next() is used to poll whether more geometrical entities are available
int vcount_total = 1;
do {
const IfcGeomObjects::IfcGeomObject* o = IfcGeomObjects::Get();
if ( o->type == "IfcSpace" || o->type == "IfcOpeningElement" ) continue;
const std::string name = o->name.empty() ? o->guid : o->name;
fObj << "g " << name << std::endl;
fObj << "s 1" << std::endl;
fObj << "usemtl " << o->type << std::endl;
materials.insert(o->type);
const int vcount = o->mesh->verts.size() / 3;
for ( IfcGeomObjects::FltIt it = o->mesh->verts.begin(); it != o->mesh->verts.end(); ) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
fObj << "v " << x << " " << y << " " << z << std::endl;
}
for ( IfcGeomObjects::FltIt it = o->mesh->normals.begin(); it != o->mesh->normals.end(); ) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
fObj << "vn " << x << " " << y << " " << z << std::endl;
}
for ( IfcGeomObjects::IntIt it = o->mesh->faces.begin(); it != o->mesh->faces.end(); ) {
const int v1 = *(it++)+vcount_total;
const int v2 = *(it++)+vcount_total;
const int v3 = *(it++)+vcount_total;
fObj << "f " << v1 << "//" << v1 << " " << v2 << "//" << v2 << " " << v3 << "//" << v3 << std::endl;
}
vcount_total += vcount;
const int progress = IfcGeomObjects::Progress() / 2;
if ( old_progress!= progress ) std::cout << "\r[" << std::string(progress,'#') << std::string(50 - progress,' ') << "]" << std::flush;
old_progress = progress;
} while ( IfcGeomObjects::Next() );
std::cout << "\rDone creating geometry " << std::endl;
// Writes the material settings, defined in Materials.h
fMtl << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << std::endl;
for( std::set<std::string>::iterator it = materials.begin(); it != materials.end(); ++ it ) {
fMtl << GetMaterial(*it);
}
std::string log = ss.str();
if ( log.size() ) {
std::cout << std::endl << "Log:" << std::endl;
std::cout << ss.str();
}
time(&end);
int dif = (int) difftime (end,start);
printf ("\nConversion took %d seconds\n", dif );
}
+5
View File
@@ -0,0 +1,5 @@
#include "../IfcObj/Materials.h"
void InitMaterials() {
materials["IFCSITE"] = ObjMaterial("IFCSITE",0.7f,0.8f,0.5f);
}
+64
View File
@@ -0,0 +1,64 @@
/********************************************************************************
* *
* 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 file defines materials in .mtl format for several IFC datatypes *
* *
********************************************************************************/
#include <string>
#include <sstream>
class ObjMaterial {
private:
std::string data;
public:
ObjMaterial(const std::string& name,
double Kd_r = 0.7f,double Kd_g = 0.7f,double Kd_b = 0.7f,
double Ks_r = 0.2f,double Ks_g = 0.2f,double Ks_b = 0.2f,
double Ka_r = 0.1f,double Ka_g = 0.1f,double Ka_b = 0.1f,
double Ns = 10.0f, double Tr = 1.0f) {
std::stringstream ss;
ss << "newmtl " << name << std::endl;
ss << "Kd " << Kd_r << " " << Kd_g << " " << Kd_b << std::endl;
ss << "Ks " << Ks_r << " " << Ks_g << " " << Ks_b << std::endl;
ss << "Ka " << Ka_r << " " << Ka_g << " " << Ka_b << std::endl;
ss << "Ns " << Ns << std::endl;
ss << "Tr " << Tr << std::endl;
ss << "d " << Tr << std::endl;
ss << "D " << Tr << std::endl;
data = ss.str();
}
friend ostream& operator<<(ostream& o, const ObjMaterial& m) {o << m.data; return o;}
};
ObjMaterial GetMaterial(const std::string& s) {
if ( s == "IfcSite" ) { return ObjMaterial("IfcSite",0.75f,0.8f,0.65f); }
if ( s == "IfcSlab" ) { return ObjMaterial("IfcSlab",0.4f,0.4f,0.4f); }
if ( s == "IfcWallStandardCase" ) { return ObjMaterial("IfcWallStandardCase",0.9f,0.9f,0.9f); }
if ( s == "IfcWall" ) { return ObjMaterial("IfcWall",0.9f,0.9f,0.9f); }
if ( s == "IfcWindow" ) { return ObjMaterial("IfcWindow",0.75f,0.8f,0.75f,1.0f,1.0f,1.0f,0.0f,0.0f,0.0f,500.0f,0.3f); }
if ( s == "IfcDoor" ) { return ObjMaterial("IfcDoor",0.55f,0.3f,0.15f); }
if ( s == "IfcBeam" ) { return ObjMaterial("IfcBeam",0.75f,0.7f,0.7f); }
if ( s == "IfcRailing" ) { return ObjMaterial("IfcRailing",0.65f,0.6f,0.6f); }
if ( s == "IfcMember" ) { return ObjMaterial("IfcMember",0.65f,0.6f,0.6f); }
if ( s == "IfcPlate" ) { return ObjMaterial("IfcPlate",0.8f,0.8f,0.8f); }
return ObjMaterial(s);
}
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
/********************************************************************************
* *
* 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 file has been generated from IFC2X3_TC1.exp. Do not make modifications *
* but instead modify the python script that has been used to generate this. *
* *
********************************************************************************/
#ifndef IFC2X3RT_H
#define IFC2X3RT_H
#define IfcSchema Ifc2x3
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcEntityDescriptor.h"
#include "../ifcparse/IfcWritableEntity.h"
namespace Ifc2x3 {
namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
#endif
+4527 -3296
View File
File diff suppressed because one or more lines are too long
+5450 -5295
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
/********************************************************************************
* *
* 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 file has been generated from IFC4.exp. Do not make modifications *
* but instead modify the python script that has been used to generate this. *
* *
********************************************************************************/
#ifndef IFC4RT_H
#define IFC4RT_H
#define IfcSchema Ifc4
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcEntityDescriptor.h"
#include "../ifcparse/IfcWritableEntity.h"
namespace Ifc4 {
namespace Type {
int GetAttributeCount(Enum t);
int GetAttributeIndex(Enum t, const std::string& a);
IfcUtil::ArgumentType GetAttributeType(Enum t, unsigned char a);
const std::string& GetAttributeName(Enum t, unsigned char a);
bool GetAttributeOptional(Enum t, unsigned char a);
bool GetAttributeDerived(Enum t, unsigned char a);
std::pair<const char*, int> GetEnumerationIndex(Enum t, const std::string& a);
std::pair<Enum, unsigned> GetInverseAttribute(Enum t, const std::string& a);
Enum GetAttributeEnumerationClass(Enum t, unsigned char a);
void PopulateDerivedFields(IfcWrite::IfcWritableEntity* e);
}}
#endif
+15753
View File
File diff suppressed because one or more lines are too long
+54630
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -30,7 +30,7 @@
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSpfStream.h"
#define FIRST_SOLIDUS (1 << 1)
#define PAGE (1 << 2)
+1 -1
View File
@@ -36,7 +36,7 @@
typedef unsigned int UChar32;
#endif
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSpfStream.h"
namespace IfcParse {
+127
View File
@@ -0,0 +1,127 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
#ifndef IFCENTITYDESCRIPTOR_H
#define IFCENTITYDESCRIPTOR_H
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include "../ifcparse/SharedPointer.h"
#include "../ifcparse/Ifc2x3enum.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcException.h"
namespace IfcUtil {
class IfcEnumerationDescriptor {
private:
IfcSchema::Type::Enum type;
std::vector<std::string> values;
public:
IfcEnumerationDescriptor(IfcSchema::Type::Enum type, const std::vector<std::string>& values)
: type(type), values(values) {}
std::pair<const char*, int> getIndex(const std::string& value) const {
std::vector<std::string>::const_iterator it = std::find(values.begin(), values.end(), value);
if (it != values.end()) {
return std::make_pair(it->c_str(), std::distance(it, values.begin()));
} else {
throw IfcParse::IfcException("Invalid enumeration value");
}
}
const std::vector<std::string>& getValues() {
return values;
}
IfcSchema::Type::Enum getType() {
return type;
}
};
class IfcEntityDescriptor {
public:
class IfcArgumentDescriptor
{
public:
std::string name;
bool optional;
ArgumentType argument_type;
IfcSchema::Type::Enum data_type;
IfcArgumentDescriptor(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type)
: name(name), optional(optional), argument_type(argument_type), data_type(data_type) {}
};
private:
IfcSchema::Type::Enum type;
IfcEntityDescriptor* parent;
std::vector<IfcArgumentDescriptor> arguments;
unsigned argument_start() const {
return parent ? parent->getArgumentCount() : 0;
}
const IfcArgumentDescriptor& get_argument(unsigned i) const {
if (i < arguments.size()) return arguments[i];
else throw IfcParse::IfcException("Argument out of range");
}
public:
IfcEntityDescriptor(IfcSchema::Type::Enum type, IfcEntityDescriptor* parent)
: type(type), parent(parent) {}
void add(const std::string& name, bool optional, ArgumentType argument_type, IfcSchema::Type::Enum data_type = IfcSchema::Type::ALL) {
arguments.push_back(IfcArgumentDescriptor(name, optional, argument_type, data_type));
}
unsigned getArgumentCount() const {
return (parent ? parent->getArgumentCount() : 0) + arguments.size();
}
const std::string& getArgumentName(unsigned i) const {
const unsigned a = argument_start();
return i < a
? parent->getArgumentName(i)
: get_argument(i-a).name;
}
ArgumentType getArgumentType(unsigned i) const {
const unsigned a = argument_start();
return i < a
? parent->getArgumentType(i)
: get_argument(i-a).argument_type;
}
bool getArgumentOptional(unsigned i) const {
const unsigned a = argument_start();
return i < a
? parent->getArgumentOptional(i)
: get_argument(i-a).optional;
}
IfcSchema::Type::Enum getArgumentEnumerationClass(unsigned i) const {
const unsigned a = argument_start();
return i < a
? parent->getArgumentEnumerationClass(i)
: get_argument(i-a).data_type;
}
unsigned getArgumentIndex(const std::string& s) const {
unsigned a = argument_start();
for(std::vector<IfcArgumentDescriptor>::const_iterator i = arguments.begin(); i != arguments.end(); ++i) {
if (i->name == s) return a;
a++;
}
if (parent) return parent->getArgumentIndex(s);
throw IfcParse::IfcException(std::string("Argument ") + s + " not found on " + IfcSchema::Type::ToString(type));
}
};
}
#endif
+99 -70
View File
@@ -1,81 +1,110 @@
/********************************************************************************
/********************************************************************************
* *
* 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 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 file provides functions for loading an IFC file into memory and access *
* its entities either by ID, by an IfcSchema::Type or by reference *
* *
********************************************************************************/
/********************************************************************************
* *
* Reads a file in chunks of BUF_SIZE and provides functions to access its *
* contents randomly and character by character *
* *
********************************************************************************/
#ifndef IFCFILE_H
#define IFCFILE_H
#include <fstream>
#include <string>
// As of IfcOpenShell version 0.3.0 the paging functionality, which
// loads a file on disk into multiple chunks, has been disabled.
// It proved to be an inefficient way of working with large files,
// as often these did not facilitate to be parsed in a sequential
// manner efficiently. To enable the paging functionality uncomment
// the following statement.
// #define BUF_SIZE (8 * 1024 * 1024)
#include "../ifcparse/IfcParse.h"
namespace IfcParse {
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
/// The file is interpreted as a sequence of tokens which are lazily
/// interpreted only when requested. If the size of the file is
/// larger than BUF_SIZE, the file is split into seperate pages, of
/// which only one is simultaneously kept in memory, for files
/// that define their entities not in a sequential nature, this is
/// detrimental for the performance of the parser.
class IfcSpfStream {
private:
FILE* stream;
char* buffer;
unsigned int ptr;
unsigned int len;
void ReadBuffer(bool inc=true);
#ifdef BUF_SIZE
unsigned int offset;
bool paging;
#endif
public:
bool valid;
bool eof;
unsigned int size;
IfcSpfStream(const std::string& fn);
IfcSpfStream(std::istream& f, int len);
IfcSpfStream(void* data, int len);
/// Returns the character at the cursor
char Peek();
/// Returns the character at specified offset
char Read(unsigned int offset);
/// Increment the file cursor and reads new page if necessary
void Inc();
void Close();
/// Moves the file cursor to an arbitrary offset in the file
void Seek(unsigned int offset);
/// Returns the cursor position
unsigned int Tell();
};
/// This class provides several static convenience functions and variables
/// and provide access to the entities in an IFC file
class IfcFile {
private:
MapEntityById byid;
MapEntitiesByType bytype;
MapEntitiesByRef byref;
MapEntityByGuid byguid;
MapOffsetById offsets;
unsigned int lastId;
unsigned int MaxId;
std::string _filename;
std::string _timestamp;
std::string _author;
std::string _author_email;
std::string _author_organisation;
void initTimestamp();
public:
typedef MapEntityById::const_iterator const_iterator;
IfcFile();
~IfcFile();
/// Returns the first entity in the file, this probably is the entity with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator begin() const;
/// Returns the last entity in the file, this probably is the entity with the highes id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator end() const;
IfcParse::IfcSpfStream* file;
IfcParse::Tokens* tokens;
/// Returns all entities in the file that match the template argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
template <class T>
typename T::list EntitiesByType() {
IfcEntities e = EntitiesByType(T::Class());
typename T::list l ( new IfcTemplatedEntityList<T>() );
if ( e && e->Size() )
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));
}
return l;
}
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
IfcEntities EntitiesByType(IfcSchema::Type::Enum t);
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
IfcEntities EntitiesByType(const std::string& t);
/// Returns all entities in the file that reference the id
IfcEntities EntitiesByReference(int id);
/// Returns the entity with the specified id
IfcEntity EntityById(int id);
/// Returns the entity with the specified GlobalId
IfcSchema::IfcRoot::ptr EntityByGuid(const std::string& guid);
bool Init(const std::string& fn);
bool Init(std::istream& fn, int len);
bool Init(void* data, int len);
bool Init(IfcParse::IfcSpfStream* f);
unsigned int FreshId() { MaxId ++; return MaxId; }
void AddEntity(IfcUtil::IfcSchemaEntity e);
void AddEntities(IfcEntities es);
void filename(const std::string& s);
std::string filename() const;
void timestamp(const std::string& s);
std::string timestamp() const;
void author(const std::string& name, const std::string& email, const std::string& organisation);
std::string authorName() const;
std::string authorEmail() const;
std::string authorOrganisation() const;
};
}
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);
#endif
+3 -19
View File
@@ -26,23 +26,17 @@
#include <time.h>
#include <stdlib.h>
#define HAS_BOOST_UUID
#ifdef HAS_BOOST_UUID
#include <algorithm>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#endif
#include "IfcWrite.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcException.h"
static const char* chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
#ifdef HAS_BOOST_UUID
// Converts an unsigned integer into a base64 string of length l
std::string base64(unsigned v, int l) {
std::string r;
@@ -64,7 +58,7 @@ unsigned from_base64(const std::string& s) {
for ( std::string::const_iterator i = s.begin()+zeros; i != s.end(); ++ i ) {
r *= 64;
const char* c = strchr(chars,*i);
if ( !c ) throw IfcException("Failed to decode GlobalId");
if ( !c ) throw IfcParse::IfcException("Failed to decode GlobalId");
r += (c-chars);
}
return r;
@@ -95,10 +89,7 @@ void expand(const std::string& s, std::vector<unsigned char>& v) {
// A random number generator for the UUID
static boost::uuids::basic_random_generator<boost::mt19937> gen;
#endif
IfcWrite::IfcGuidHelper::IfcGuidHelper() {
#ifdef HAS_BOOST_UUID
boost::uuids::uuid u = gen();
std::vector<unsigned char> v(u.size());
std::copy(u.begin(), u.end(), v.begin());
@@ -108,13 +99,6 @@ IfcWrite::IfcGuidHelper::IfcGuidHelper() {
expand(data,v2);
boost::uuids::uuid u2;
std::copy(v2.begin(), v2.end(), u2.begin());
#else
if ( ! seeded ) { srand((unsigned int)time(0)); seeded = true; }
data.resize(length);
for ( unsigned int i = 0; i < length; ++ i ) {
data[i] = chars[rand()%strlen(chars)];
}
#endif
}
IfcWrite::IfcGuidHelper::operator std::string() const {
return data;
+135 -131
View File
@@ -29,56 +29,56 @@
#include "../ifcparse/IfcHierarchyHelper.h"
Ifc2x3::IfcAxis2Placement3D* IfcHierarchyHelper::addPlacement3d(
IfcSchema::IfcAxis2Placement3D* IfcHierarchyHelper::addPlacement3d(
double ox, double oy, double oz,
double zx, double zy, double zz,
double xx, double xy, double xz)
{
Ifc2x3::IfcDirection* x = addTriplet<Ifc2x3::IfcDirection>(xx, xy, xz);
Ifc2x3::IfcDirection* z = addTriplet<Ifc2x3::IfcDirection>(zx, zy, zz);
Ifc2x3::IfcCartesianPoint* o = addTriplet<Ifc2x3::IfcCartesianPoint>(ox, oy, oz);
Ifc2x3::IfcAxis2Placement3D* p3d = new Ifc2x3::IfcAxis2Placement3D(o, z, x);
IfcSchema::IfcDirection* x = addTriplet<IfcSchema::IfcDirection>(xx, xy, xz);
IfcSchema::IfcDirection* z = addTriplet<IfcSchema::IfcDirection>(zx, zy, zz);
IfcSchema::IfcCartesianPoint* o = addTriplet<IfcSchema::IfcCartesianPoint>(ox, oy, oz);
IfcSchema::IfcAxis2Placement3D* p3d = new IfcSchema::IfcAxis2Placement3D(o, z, x);
AddEntity(p3d);
return p3d;
}
Ifc2x3::IfcAxis2Placement2D* IfcHierarchyHelper::addPlacement2d(
IfcSchema::IfcAxis2Placement2D* IfcHierarchyHelper::addPlacement2d(
double ox, double oy,
double xx, double xy)
{
Ifc2x3::IfcDirection* x = addDoublet<Ifc2x3::IfcDirection>(xx, xy);
Ifc2x3::IfcCartesianPoint* o = addDoublet<Ifc2x3::IfcCartesianPoint>(ox, oy);
Ifc2x3::IfcAxis2Placement2D* p2d = new Ifc2x3::IfcAxis2Placement2D(o, x);
IfcSchema::IfcDirection* x = addDoublet<IfcSchema::IfcDirection>(xx, xy);
IfcSchema::IfcCartesianPoint* o = addDoublet<IfcSchema::IfcCartesianPoint>(ox, oy);
IfcSchema::IfcAxis2Placement2D* p2d = new IfcSchema::IfcAxis2Placement2D(o, x);
AddEntity(p2d);
return p2d;
}
Ifc2x3::IfcLocalPlacement* IfcHierarchyHelper::addLocalPlacement(
IfcSchema::IfcLocalPlacement* IfcHierarchyHelper::addLocalPlacement(
double ox, double oy, double oz,
double zx, double zy, double zz,
double xx, double xy, double xz)
{
Ifc2x3::IfcLocalPlacement* lp = new Ifc2x3::IfcLocalPlacement(0,
IfcSchema::IfcLocalPlacement* lp = new IfcSchema::IfcLocalPlacement(0,
addPlacement3d(ox, oy, oz, zx, zy, zz, xx, xy, xz));
AddEntity(lp);
return lp;
}
Ifc2x3::IfcOwnerHistory* IfcHierarchyHelper::addOwnerHistory() {
Ifc2x3::IfcPerson* person = new Ifc2x3::IfcPerson(boost::none, boost::none, std::string(""),
IfcSchema::IfcOwnerHistory* IfcHierarchyHelper::addOwnerHistory() {
IfcSchema::IfcPerson* person = new IfcSchema::IfcPerson(boost::none, boost::none, std::string(""),
boost::none, boost::none, boost::none, boost::none, boost::none);
Ifc2x3::IfcOrganization* organization = new Ifc2x3::IfcOrganization(boost::none,
IfcSchema::IfcOrganization* organization = new IfcSchema::IfcOrganization(boost::none,
"IfcOpenShell", boost::none, boost::none, boost::none);
Ifc2x3::IfcPersonAndOrganization* person_and_org = new Ifc2x3::IfcPersonAndOrganization(person, organization, boost::none);
Ifc2x3::IfcApplication* application = new Ifc2x3::IfcApplication(organization,
IfcSchema::IfcPersonAndOrganization* person_and_org = new IfcSchema::IfcPersonAndOrganization(person, organization, boost::none);
IfcSchema::IfcApplication* application = new IfcSchema::IfcApplication(organization,
IFCOPENSHELL_VERSION, "IfcOpenShell", "IfcOpenShell");
int timestamp = (int) time(0);
Ifc2x3::IfcOwnerHistory* owner_hist = new Ifc2x3::IfcOwnerHistory(person_and_org, application,
boost::none, Ifc2x3::IfcChangeActionEnum::IfcChangeAction_ADDED, boost::none, person_and_org, application, timestamp);
IfcSchema::IfcOwnerHistory* owner_hist = new IfcSchema::IfcOwnerHistory(person_and_org, application,
boost::none, IfcSchema::IfcChangeActionEnum::IfcChangeAction_ADDED, boost::none, person_and_org, application, timestamp);
AddEntity(person);
AddEntity(organization);
@@ -89,30 +89,30 @@ Ifc2x3::IfcOwnerHistory* IfcHierarchyHelper::addOwnerHistory() {
return owner_hist;
}
Ifc2x3::IfcProject* IfcHierarchyHelper::addProject(Ifc2x3::IfcOwnerHistory* owner_hist) {
Ifc2x3::IfcRepresentationContext::list rep_contexts (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentationContext>());
Ifc2x3::IfcGeometricRepresentationContext* rep_context = new Ifc2x3::IfcGeometricRepresentationContext(
std::string("Plan"), std::string("Model"), 3, 1e-5, addPlacement3d(), addTriplet<Ifc2x3::IfcDirection>(0, 1, 0));
IfcSchema::IfcProject* IfcHierarchyHelper::addProject(IfcSchema::IfcOwnerHistory* owner_hist) {
IfcSchema::IfcRepresentationContext::list rep_contexts (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationContext>());
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);
IfcEntities units (new IfcEntityList());
Ifc2x3::IfcDimensionalExponents* dimexp = new Ifc2x3::IfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0);
Ifc2x3::IfcSIUnit* unit1 = new Ifc2x3::IfcSIUnit(Ifc2x3::IfcUnitEnum::IfcUnit_LENGTHUNIT,
Ifc2x3::IfcSIPrefix::IfcSIPrefix_MILLI, Ifc2x3::IfcSIUnitName::IfcSIUnitName_METRE);
Ifc2x3::IfcSIUnit* unit2a = new Ifc2x3::IfcSIUnit(Ifc2x3::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT,
boost::none, Ifc2x3::IfcSIUnitName::IfcSIUnitName_RADIAN);
Ifc2x3::IfcMeasureWithUnit* unit2b = new Ifc2x3::IfcMeasureWithUnit(
new IfcWrite::IfcSelectHelper(0.017453293, Ifc2x3::Type::IfcPlaneAngleMeasure), unit2a);
Ifc2x3::IfcConversionBasedUnit* unit2 = new Ifc2x3::IfcConversionBasedUnit(dimexp,
Ifc2x3::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT, "Degrees", unit2b);
IfcSchema::IfcDimensionalExponents* dimexp = new IfcSchema::IfcDimensionalExponents(0, 0, 0, 0, 0, 0, 0);
IfcSchema::IfcSIUnit* unit1 = new IfcSchema::IfcSIUnit(IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT,
IfcSchema::IfcSIPrefix::IfcSIPrefix_MILLI, IfcSchema::IfcSIUnitName::IfcSIUnitName_METRE);
IfcSchema::IfcSIUnit* unit2a = new IfcSchema::IfcSIUnit(IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT,
boost::none, IfcSchema::IfcSIUnitName::IfcSIUnitName_RADIAN);
IfcSchema::IfcMeasureWithUnit* unit2b = new IfcSchema::IfcMeasureWithUnit(
new IfcWrite::IfcSelectHelper(0.017453293, IfcSchema::Type::IfcPlaneAngleMeasure), unit2a);
IfcSchema::IfcConversionBasedUnit* unit2 = new IfcSchema::IfcConversionBasedUnit(dimexp,
IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT, "Degrees", unit2b);
units->push(unit1);
units->push(unit2);
Ifc2x3::IfcUnitAssignment* unit_assignment = new Ifc2x3::IfcUnitAssignment(units);
IfcSchema::IfcUnitAssignment* unit_assignment = new IfcSchema::IfcUnitAssignment(units);
Ifc2x3::IfcProject* project = new Ifc2x3::IfcProject(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none,
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);
@@ -127,128 +127,128 @@ Ifc2x3::IfcProject* IfcHierarchyHelper::addProject(Ifc2x3::IfcOwnerHistory* owne
return project;
}
void IfcHierarchyHelper::relatePlacements(Ifc2x3::IfcProduct* parent, Ifc2x3::IfcProduct* product) {
Ifc2x3::IfcObjectPlacement* place = product->hasObjectPlacement() ? product->ObjectPlacement() : 0;
if (place && place->is(Ifc2x3::Type::IfcLocalPlacement)) {
Ifc2x3::IfcLocalPlacement* local_place = (Ifc2x3::IfcLocalPlacement*) place;
void IfcHierarchyHelper::relatePlacements(IfcSchema::IfcProduct* parent, IfcSchema::IfcProduct* product) {
IfcSchema::IfcObjectPlacement* place = product->hasObjectPlacement() ? product->ObjectPlacement() : 0;
if (place && place->is(IfcSchema::Type::IfcLocalPlacement)) {
IfcSchema::IfcLocalPlacement* local_place = (IfcSchema::IfcLocalPlacement*) place;
if (parent->hasObjectPlacement()) {
local_place->setPlacementRelTo(parent->ObjectPlacement());
}
}
}
Ifc2x3::IfcSite* IfcHierarchyHelper::addSite(Ifc2x3::IfcProject* proj, Ifc2x3::IfcOwnerHistory* owner_hist) {
IfcSchema::IfcSite* IfcHierarchyHelper::addSite(IfcSchema::IfcProject* proj, IfcSchema::IfcOwnerHistory* owner_hist) {
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
if (! proj) {
proj = getSingle<Ifc2x3::IfcProject>();
proj = getSingle<IfcSchema::IfcProject>();
}
if (! proj) {
proj = addProject(owner_hist);
}
Ifc2x3::IfcSite* site = new Ifc2x3::IfcSite(IfcWrite::IfcGuidHelper(), owner_hist, boost::none,
IfcSchema::IfcSite* site = new IfcSchema::IfcSite(IfcWrite::IfcGuidHelper(), owner_hist, boost::none,
boost::none, boost::none, addLocalPlacement(), 0, boost::none,
Ifc2x3::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
boost::none, boost::none, boost::none, boost::none, 0);
AddEntity(site);
addRelatedObject<Ifc2x3::IfcRelAggregates>(proj, site);
addRelatedObject<IfcSchema::IfcRelAggregates>(proj, site);
return site;
}
Ifc2x3::IfcBuilding* IfcHierarchyHelper::addBuilding(Ifc2x3::IfcSite* site, Ifc2x3::IfcOwnerHistory* owner_hist) {
IfcSchema::IfcBuilding* IfcHierarchyHelper::addBuilding(IfcSchema::IfcSite* site, IfcSchema::IfcOwnerHistory* owner_hist) {
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
if (! site) {
site = getSingle<Ifc2x3::IfcSite>();
site = getSingle<IfcSchema::IfcSite>();
}
if (! site) {
site = addSite(0, owner_hist);
}
Ifc2x3::IfcBuilding* building = new Ifc2x3::IfcBuilding(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none, boost::none,
addLocalPlacement(), 0, boost::none, Ifc2x3::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
IfcSchema::IfcBuilding* building = new IfcSchema::IfcBuilding(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none, boost::none,
addLocalPlacement(), 0, boost::none, IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT,
boost::none, boost::none, 0);
AddEntity(building);
addRelatedObject<Ifc2x3::IfcRelAggregates>(site, building);
addRelatedObject<IfcSchema::IfcRelAggregates>(site, building);
relatePlacements(site, building);
return building;
}
Ifc2x3::IfcBuildingStorey* IfcHierarchyHelper::addBuildingStorey(Ifc2x3::IfcBuilding* building,
Ifc2x3::IfcOwnerHistory* owner_hist)
IfcSchema::IfcBuildingStorey* IfcHierarchyHelper::addBuildingStorey(IfcSchema::IfcBuilding* building,
IfcSchema::IfcOwnerHistory* owner_hist)
{
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
if (! building) {
building = getSingle<Ifc2x3::IfcBuilding>();
building = getSingle<IfcSchema::IfcBuilding>();
}
if (! building) {
building = addBuilding(0, owner_hist);
}
Ifc2x3::IfcBuildingStorey* storey = new Ifc2x3::IfcBuildingStorey(IfcWrite::IfcGuidHelper(),
IfcSchema::IfcBuildingStorey* storey = new IfcSchema::IfcBuildingStorey(IfcWrite::IfcGuidHelper(),
owner_hist, boost::none, boost::none, boost::none, addLocalPlacement(), 0, boost::none,
Ifc2x3::IfcElementCompositionEnum::IfcElementComposition_ELEMENT, boost::none);
IfcSchema::IfcElementCompositionEnum::IfcElementComposition_ELEMENT, boost::none);
AddEntity(storey);
addRelatedObject<Ifc2x3::IfcRelAggregates>(building, storey);
addRelatedObject<IfcSchema::IfcRelAggregates>(building, storey);
relatePlacements(building, storey);
return storey;
}
Ifc2x3::IfcBuildingStorey* IfcHierarchyHelper::addBuildingProduct(Ifc2x3::IfcProduct* product,
Ifc2x3::IfcBuildingStorey* storey, Ifc2x3::IfcOwnerHistory* owner_hist)
IfcSchema::IfcBuildingStorey* IfcHierarchyHelper::addBuildingProduct(IfcSchema::IfcProduct* product,
IfcSchema::IfcBuildingStorey* storey, IfcSchema::IfcOwnerHistory* owner_hist)
{
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
if (! storey) {
storey = getSingle<Ifc2x3::IfcBuildingStorey>();
storey = getSingle<IfcSchema::IfcBuildingStorey>();
}
if (! storey) {
storey = addBuildingStorey(0, owner_hist);
}
AddEntity(product);
addRelatedObject<Ifc2x3::IfcRelContainedInSpatialStructure>(storey, product);
addRelatedObject<IfcSchema::IfcRelContainedInSpatialStructure>(storey, product);
relatePlacements(storey, product);
return storey;
}
void IfcHierarchyHelper::addExtrudedPolyline(Ifc2x3::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double> >& points, double h,
Ifc2x3::IfcAxis2Placement2D* place, Ifc2x3::IfcAxis2Placement3D* place2,
Ifc2x3::IfcDirection* dir, Ifc2x3::IfcRepresentationContext* context)
void IfcHierarchyHelper::addExtrudedPolyline(IfcSchema::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double> >& points, double h,
IfcSchema::IfcAxis2Placement2D* place, IfcSchema::IfcAxis2Placement3D* place2,
IfcSchema::IfcDirection* dir, IfcSchema::IfcRepresentationContext* context)
{
Ifc2x3::IfcCartesianPoint::list cartesian_points (new IfcTemplatedEntityList<Ifc2x3::IfcCartesianPoint>());
IfcSchema::IfcCartesianPoint::list cartesian_points (new IfcTemplatedEntityList<IfcSchema::IfcCartesianPoint>());
for (std::vector<std::pair<double, double> >::const_iterator i = points.begin(); i != points.end(); ++i) {
cartesian_points->push(addDoublet<Ifc2x3::IfcCartesianPoint>(i->first, i->second));
cartesian_points->push(addDoublet<IfcSchema::IfcCartesianPoint>(i->first, i->second));
}
if (cartesian_points->Size()) cartesian_points->push(*cartesian_points->begin());
Ifc2x3::IfcPolyline* line = new Ifc2x3::IfcPolyline(cartesian_points);
Ifc2x3::IfcArbitraryClosedProfileDef* profile = new Ifc2x3::IfcArbitraryClosedProfileDef(
Ifc2x3::IfcProfileTypeEnum::IfcProfileType_AREA, boost::none, line);
IfcSchema::IfcPolyline* line = new IfcSchema::IfcPolyline(cartesian_points);
IfcSchema::IfcArbitraryClosedProfileDef* profile = new IfcSchema::IfcArbitraryClosedProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, boost::none, line);
Ifc2x3::IfcExtrudedAreaSolid* solid = new Ifc2x3::IfcExtrudedAreaSolid(
profile, place2 ? place2 : addPlacement3d(), dir ? dir : addTriplet<Ifc2x3::IfcDirection>(0, 0, 1), h);
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(
profile, place2 ? place2 : addPlacement3d(), dir ? dir : addTriplet<IfcSchema::IfcDirection>(0, 0, 1), h);
Ifc2x3::IfcRepresentationItem::list items = rep->Items();
IfcSchema::IfcRepresentationItem::list items = rep->Items();
items->push(solid);
rep->setItems(items);
@@ -257,17 +257,17 @@ void IfcHierarchyHelper::addExtrudedPolyline(Ifc2x3::IfcShapeRepresentation* rep
AddEntity(solid);
}
Ifc2x3::IfcProductDefinitionShape* IfcHierarchyHelper::addExtrudedPolyline(const std::vector<std::pair<double, double> >& points, double h,
Ifc2x3::IfcAxis2Placement2D* place, Ifc2x3::IfcAxis2Placement3D* place2, Ifc2x3::IfcDirection* dir,
Ifc2x3::IfcRepresentationContext* context)
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addExtrudedPolyline(const std::vector<std::pair<double, double> >& points, double h,
IfcSchema::IfcAxis2Placement2D* place, IfcSchema::IfcAxis2Placement3D* place2, IfcSchema::IfcDirection* dir,
IfcSchema::IfcRepresentationContext* context)
{
Ifc2x3::IfcRepresentation::list reps (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentation>());
Ifc2x3::IfcRepresentationItem::list items (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentationItem>());
Ifc2x3::IfcShapeRepresentation* rep = new Ifc2x3::IfcShapeRepresentation(context
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(context
? context
: getSingle<Ifc2x3::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
: getSingle<IfcSchema::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
reps->push(rep);
Ifc2x3::IfcProductDefinitionShape* shape = new Ifc2x3::IfcProductDefinitionShape(0, 0, reps);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
AddEntity(rep);
AddEntity(shape);
addExtrudedPolyline(rep, points, h, place, place2, dir, context);
@@ -275,19 +275,19 @@ Ifc2x3::IfcProductDefinitionShape* IfcHierarchyHelper::addExtrudedPolyline(const
return shape;
}
void IfcHierarchyHelper::addBox(Ifc2x3::IfcShapeRepresentation* rep, double w, double d, double h,
Ifc2x3::IfcAxis2Placement2D* place, Ifc2x3::IfcAxis2Placement3D* place2,
Ifc2x3::IfcDirection* dir, Ifc2x3::IfcRepresentationContext* context)
void IfcHierarchyHelper::addBox(IfcSchema::IfcShapeRepresentation* rep, double w, double d, double h,
IfcSchema::IfcAxis2Placement2D* place, IfcSchema::IfcAxis2Placement3D* place2,
IfcSchema::IfcDirection* dir, IfcSchema::IfcRepresentationContext* context)
{
if (false) {
Ifc2x3::IfcRectangleProfileDef* profile = new Ifc2x3::IfcRectangleProfileDef(
Ifc2x3::IfcProfileTypeEnum::IfcProfileType_AREA, 0, place ? place : addPlacement2d(), w, d);
Ifc2x3::IfcExtrudedAreaSolid* solid = new Ifc2x3::IfcExtrudedAreaSolid(profile,
place2 ? place2 : addPlacement3d(), dir ? dir : addTriplet<Ifc2x3::IfcDirection>(0, 0, 1), h);
IfcSchema::IfcRectangleProfileDef* profile = new IfcSchema::IfcRectangleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, 0, place ? place : addPlacement2d(), w, d);
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(profile,
place2 ? place2 : addPlacement3d(), dir ? dir : addTriplet<IfcSchema::IfcDirection>(0, 0, 1), h);
AddEntity(profile);
AddEntity(solid);
Ifc2x3::IfcRepresentationItem::list items = rep->Items();
IfcSchema::IfcRepresentationItem::list items = rep->Items();
items->push(solid);
rep->setItems(items);
} else {
@@ -296,44 +296,44 @@ void IfcHierarchyHelper::addBox(Ifc2x3::IfcShapeRepresentation* rep, double w, d
points.push_back(std::pair<double, double>(w/2, -d/2));
points.push_back(std::pair<double, double>(w/2, d/2));
points.push_back(std::pair<double, double>(-w/2, d/2));
// The call to addExtrudedPolyline() closes the polyline
points.push_back(*points.begin());
addExtrudedPolyline(rep, points, h, place, place2, dir, context);
}
}
Ifc2x3::IfcProductDefinitionShape* IfcHierarchyHelper::addBox(double w, double d, double h, Ifc2x3::IfcAxis2Placement2D* place,
Ifc2x3::IfcAxis2Placement3D* place2, Ifc2x3::IfcDirection* dir, Ifc2x3::IfcRepresentationContext* context)
IfcSchema::IfcProductDefinitionShape* IfcHierarchyHelper::addBox(double w, double d, double h, IfcSchema::IfcAxis2Placement2D* place,
IfcSchema::IfcAxis2Placement3D* place2, IfcSchema::IfcDirection* dir, IfcSchema::IfcRepresentationContext* context)
{
Ifc2x3::IfcRepresentation::list reps (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentation>());
Ifc2x3::IfcRepresentationItem::list items (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentationItem>());
Ifc2x3::IfcShapeRepresentation* rep = new Ifc2x3::IfcShapeRepresentation(
context ? context : getSingle<Ifc2x3::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList<IfcSchema::IfcRepresentation>());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
context ? context : getSingle<IfcSchema::IfcRepresentationContext>(), std::string("Body"), std::string("SweptSolid"), items);
reps->push(rep);
Ifc2x3::IfcProductDefinitionShape* shape = new Ifc2x3::IfcProductDefinitionShape(0, 0, reps);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
AddEntity(rep);
AddEntity(shape);
addBox(rep, w, d, h, place, place2, dir, context);
return shape;
}
void IfcHierarchyHelper::clipRepresentation(Ifc2x3::IfcProductRepresentation* shape,
Ifc2x3::IfcAxis2Placement3D* place, bool agree)
void IfcHierarchyHelper::clipRepresentation(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcAxis2Placement3D* place, bool agree)
{
Ifc2x3::IfcPlane* plane = new Ifc2x3::IfcPlane(place);
Ifc2x3::IfcHalfSpaceSolid* half_space = new Ifc2x3::IfcHalfSpaceSolid(plane, agree);
Ifc2x3::IfcRepresentation::list reps = shape->Representations();
for (Ifc2x3::IfcRepresentation::it j = reps->begin(); j != reps->end(); ++j) {
Ifc2x3::IfcRepresentation* rep = *j;
IfcSchema::IfcPlane* plane = new IfcSchema::IfcPlane(place);
IfcSchema::IfcHalfSpaceSolid* half_space = new IfcSchema::IfcHalfSpaceSolid(plane, agree);
IfcSchema::IfcRepresentation::list reps = shape->Representations();
for (IfcSchema::IfcRepresentation::it j = reps->begin(); j != reps->end(); ++j) {
IfcSchema::IfcRepresentation* rep = *j;
if (rep->RepresentationIdentifier() != "Body") continue;
rep->setRepresentationType("Clipping");
Ifc2x3::IfcRepresentationItem::list items = rep->Items();
Ifc2x3::IfcRepresentationItem::list new_items (new IfcTemplatedEntityList<Ifc2x3::IfcRepresentationItem>());
IfcSchema::IfcRepresentationItem::list items = rep->Items();
IfcSchema::IfcRepresentationItem::list new_items (new IfcTemplatedEntityList<IfcSchema::IfcRepresentationItem>());
AddEntity(plane);
AddEntity(half_space);
for (Ifc2x3::IfcRepresentationItem::it i = items->begin(); i != items->end(); ++i) {
Ifc2x3::IfcRepresentationItem* item = *i;
Ifc2x3::IfcBooleanClippingResult* clip = new Ifc2x3::IfcBooleanClippingResult(
Ifc2x3::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE, item, half_space);
for (IfcSchema::IfcRepresentationItem::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);
}
@@ -341,24 +341,24 @@ void IfcHierarchyHelper::clipRepresentation(Ifc2x3::IfcProductRepresentation* sh
}
}
Ifc2x3::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
Ifc2x3::IfcProductRepresentation* shape, double r, double g, double b, double a)
IfcSchema::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
IfcSchema::IfcProductRepresentation* shape, double r, double g, double b, double a)
{
Ifc2x3::IfcColourRgb* colour = new Ifc2x3::IfcColourRgb(boost::none, r, g, b);
Ifc2x3::IfcSurfaceStyleRendering* rendering = a == 1.0
? new Ifc2x3::IfcSurfaceStyleRendering(colour, boost::none, boost::none, boost::none, boost::none, boost::none,
boost::none, boost::none, Ifc2x3::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT)
: new Ifc2x3::IfcSurfaceStyleRendering(colour, 1.0-a, boost::none, boost::none, boost::none, boost::none,
boost::none, boost::none, Ifc2x3::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT);
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,
boost::none, boost::none, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT)
: new IfcSchema::IfcSurfaceStyleRendering(colour, 1.0-a, boost::none, boost::none, boost::none, boost::none,
boost::none, boost::none, IfcSchema::IfcReflectanceMethodEnum::IfcReflectanceMethod_FLAT);
IfcEntities styles(new IfcEntityList());
styles->push(rendering);
Ifc2x3::IfcSurfaceStyle* surface_style = new Ifc2x3::IfcSurfaceStyle(
boost::none, Ifc2x3::IfcSurfaceSide::IfcSurfaceSide_BOTH, styles);
IfcSchema::IfcSurfaceStyle* surface_style = new IfcSchema::IfcSurfaceStyle(
boost::none, IfcSchema::IfcSurfaceSide::IfcSurfaceSide_BOTH, styles);
IfcEntities surface_styles(new IfcEntityList());
surface_styles->push(surface_style);
Ifc2x3::IfcPresentationStyleAssignment* style_assignment =
new Ifc2x3::IfcPresentationStyleAssignment(surface_styles);
IfcSchema::IfcPresentationStyleAssignment* style_assignment =
new IfcSchema::IfcPresentationStyleAssignment(surface_styles);
AddEntity(colour);
AddEntity(rendering);
AddEntity(surface_style);
@@ -367,19 +367,23 @@ Ifc2x3::IfcPresentationStyleAssignment* IfcHierarchyHelper::setSurfaceColour(
return style_assignment;
}
void IfcHierarchyHelper::setSurfaceColour(Ifc2x3::IfcProductRepresentation* shape,
Ifc2x3::IfcPresentationStyleAssignment* style_assignment)
void IfcHierarchyHelper::setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* style_assignment)
{
Ifc2x3::IfcPresentationStyleAssignment::list style_assignments (new IfcTemplatedEntityList<Ifc2x3::IfcPresentationStyleAssignment>());
#ifdef USE_IFC4
IfcEntities style_assignments (new IfcEntityList());
#else
IfcSchema::IfcPresentationStyleAssignment::list style_assignments (new IfcTemplatedEntityList<IfcSchema::IfcPresentationStyleAssignment>());
#endif
style_assignments->push(style_assignment);
Ifc2x3::IfcRepresentation::list reps = shape->Representations();
for (Ifc2x3::IfcRepresentation::it j = reps->begin(); j != reps->end(); ++j) {
Ifc2x3::IfcRepresentation* rep = *j;
IfcSchema::IfcRepresentation::list reps = shape->Representations();
for (IfcSchema::IfcRepresentation::it j = reps->begin(); j != reps->end(); ++j) {
IfcSchema::IfcRepresentation* rep = *j;
if (rep->RepresentationIdentifier() != "Body" && rep->RepresentationIdentifier() != "Facetation") continue;
Ifc2x3::IfcRepresentationItem::list items = rep->Items();
for (Ifc2x3::IfcRepresentationItem::it i = items->begin(); i != items->end(); ++i) {
Ifc2x3::IfcRepresentationItem* item = *i;
Ifc2x3::IfcStyledItem* styled_item = new Ifc2x3::IfcStyledItem(item, style_assignments, boost::none);
IfcSchema::IfcRepresentationItem::list items = rep->Items();
for (IfcSchema::IfcRepresentationItem::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);
}
}
+50 -45
View File
@@ -28,8 +28,13 @@
#ifndef IFCHIERARCHYHELPER_H
#define IFCHIERARCHYHELPER_H
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
#include "../ifcparse/Ifc2x3.h"
#endif
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSpfStream.h"
#include "../ifcparse/IfcWrite.h"
class IfcHierarchyHelper : public IfcParse::IfcFile {
@@ -57,27 +62,27 @@ public:
return *ts->begin();
}
Ifc2x3::IfcAxis2Placement3D* addPlacement3d(double ox=0.0, double oy=0.0, double oz=0.0,
IfcSchema::IfcAxis2Placement3D* addPlacement3d(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);
Ifc2x3::IfcAxis2Placement2D* addPlacement2d(double ox=0.0, double oy=0.0,
IfcSchema::IfcAxis2Placement2D* addPlacement2d(double ox=0.0, double oy=0.0,
double xx=1.0, double xy=0.0);
Ifc2x3::IfcLocalPlacement* addLocalPlacement(double ox=0.0, double oy=0.0, double oz=0.0,
IfcSchema::IfcLocalPlacement* addLocalPlacement(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);
template <class T>
void addRelatedObject(Ifc2x3::IfcObjectDefinition* related_object,
Ifc2x3::IfcObjectDefinition* relating_object, Ifc2x3::IfcOwnerHistory* owner_hist = 0)
void addRelatedObject(IfcSchema::IfcObjectDefinition* related_object,
IfcSchema::IfcObjectDefinition* relating_object, IfcSchema::IfcOwnerHistory* owner_hist = 0)
{
typename T::list li = EntitiesByType<T>();
bool found = false;
for (typename T::it i = li->begin(); i != li->end(); ++i) {
T* rel = *i;
if (rel->RelatingObject() == relating_object) {
Ifc2x3::IfcObjectDefinition::list products = rel->RelatedObjects();
IfcSchema::IfcObjectDefinition::list products = rel->RelatedObjects();
products->push(related_object);
rel->setRelatedObjects(products);
found = true;
@@ -86,67 +91,67 @@ public:
}
if (! found) {
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
Ifc2x3::IfcObjectDefinition::list relating_objects (new IfcTemplatedEntityList<Ifc2x3::IfcObjectDefinition>());
IfcSchema::IfcObjectDefinition::list relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcObjectDefinition>());
relating_objects->push(relating_object);
T* t = new T(IfcWrite::IfcGuidHelper(), owner_hist, boost::none, boost::none, related_object, relating_objects);
AddEntity(t);
}
}
Ifc2x3::IfcOwnerHistory* addOwnerHistory();
Ifc2x3::IfcProject* addProject(Ifc2x3::IfcOwnerHistory* owner_hist = 0);
void relatePlacements(Ifc2x3::IfcProduct* parent, Ifc2x3::IfcProduct* product);
Ifc2x3::IfcSite* addSite(Ifc2x3::IfcProject* proj = 0, Ifc2x3::IfcOwnerHistory* owner_hist = 0);
Ifc2x3::IfcBuilding* addBuilding(Ifc2x3::IfcSite* site = 0, Ifc2x3::IfcOwnerHistory* owner_hist = 0);
IfcSchema::IfcOwnerHistory* addOwnerHistory();
IfcSchema::IfcProject* addProject(IfcSchema::IfcOwnerHistory* owner_hist = 0);
void relatePlacements(IfcSchema::IfcProduct* parent, IfcSchema::IfcProduct* product);
IfcSchema::IfcSite* addSite(IfcSchema::IfcProject* proj = 0, IfcSchema::IfcOwnerHistory* owner_hist = 0);
IfcSchema::IfcBuilding* addBuilding(IfcSchema::IfcSite* site = 0, IfcSchema::IfcOwnerHistory* owner_hist = 0);
Ifc2x3::IfcBuildingStorey* addBuildingStorey(Ifc2x3::IfcBuilding* building = 0,
Ifc2x3::IfcOwnerHistory* owner_hist = 0);
IfcSchema::IfcBuildingStorey* addBuildingStorey(IfcSchema::IfcBuilding* building = 0,
IfcSchema::IfcOwnerHistory* owner_hist = 0);
Ifc2x3::IfcBuildingStorey* addBuildingProduct(Ifc2x3::IfcProduct* product,
Ifc2x3::IfcBuildingStorey* storey = 0, Ifc2x3::IfcOwnerHistory* owner_hist = 0);
IfcSchema::IfcBuildingStorey* addBuildingProduct(IfcSchema::IfcProduct* product,
IfcSchema::IfcBuildingStorey* storey = 0, IfcSchema::IfcOwnerHistory* owner_hist = 0);
void addExtrudedPolyline(Ifc2x3::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double> >& points, double h,
Ifc2x3::IfcAxis2Placement2D* place=0, Ifc2x3::IfcAxis2Placement3D* place2=0,
Ifc2x3::IfcDirection* dir=0, Ifc2x3::IfcRepresentationContext* context=0);
void addExtrudedPolyline(IfcSchema::IfcShapeRepresentation* rep, const std::vector<std::pair<double, double> >& points, double h,
IfcSchema::IfcAxis2Placement2D* place=0, IfcSchema::IfcAxis2Placement3D* place2=0,
IfcSchema::IfcDirection* dir=0, IfcSchema::IfcRepresentationContext* context=0);
Ifc2x3::IfcProductDefinitionShape* addExtrudedPolyline(const std::vector<std::pair<double, double> >& points, double h,
Ifc2x3::IfcAxis2Placement2D* place=0, Ifc2x3::IfcAxis2Placement3D* place2=0, Ifc2x3::IfcDirection* dir=0,
Ifc2x3::IfcRepresentationContext* context=0);
IfcSchema::IfcProductDefinitionShape* addExtrudedPolyline(const std::vector<std::pair<double, double> >& points, double h,
IfcSchema::IfcAxis2Placement2D* place=0, IfcSchema::IfcAxis2Placement3D* place2=0, IfcSchema::IfcDirection* dir=0,
IfcSchema::IfcRepresentationContext* context=0);
void addBox(Ifc2x3::IfcShapeRepresentation* rep, double w, double d, double h,
Ifc2x3::IfcAxis2Placement2D* place=0, Ifc2x3::IfcAxis2Placement3D* place2=0,
Ifc2x3::IfcDirection* dir=0, Ifc2x3::IfcRepresentationContext* context=0);
void addBox(IfcSchema::IfcShapeRepresentation* rep, double w, double d, double h,
IfcSchema::IfcAxis2Placement2D* place=0, IfcSchema::IfcAxis2Placement3D* place2=0,
IfcSchema::IfcDirection* dir=0, IfcSchema::IfcRepresentationContext* context=0);
Ifc2x3::IfcProductDefinitionShape* addBox(double w, double d, double h, Ifc2x3::IfcAxis2Placement2D* place=0,
Ifc2x3::IfcAxis2Placement3D* place2=0, Ifc2x3::IfcDirection* dir=0, Ifc2x3::IfcRepresentationContext* context=0);
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 clipRepresentation(Ifc2x3::IfcProductRepresentation* shape,
Ifc2x3::IfcAxis2Placement3D* place, bool agree);
void clipRepresentation(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcAxis2Placement3D* place, bool agree);
Ifc2x3::IfcPresentationStyleAssignment* setSurfaceColour(Ifc2x3::IfcProductRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
double r, double g, double b, double a=1.0);
void setSurfaceColour(Ifc2x3::IfcProductRepresentation* shape,
Ifc2x3::IfcPresentationStyleAssignment* style_assignment);
void setSurfaceColour(IfcSchema::IfcProductRepresentation* shape,
IfcSchema::IfcPresentationStyleAssignment* style_assignment);
};
template <>
inline void IfcHierarchyHelper::addRelatedObject <Ifc2x3::IfcRelContainedInSpatialStructure> (Ifc2x3::IfcObjectDefinition* related_object,
Ifc2x3::IfcObjectDefinition* relating_object, Ifc2x3::IfcOwnerHistory* owner_hist)
inline void IfcHierarchyHelper::addRelatedObject <IfcSchema::IfcRelContainedInSpatialStructure> (IfcSchema::IfcObjectDefinition* related_object,
IfcSchema::IfcObjectDefinition* relating_object, IfcSchema::IfcOwnerHistory* owner_hist)
{
Ifc2x3::IfcRelContainedInSpatialStructure::list li = EntitiesByType<Ifc2x3::IfcRelContainedInSpatialStructure>();
IfcSchema::IfcRelContainedInSpatialStructure::list li = EntitiesByType<IfcSchema::IfcRelContainedInSpatialStructure>();
bool found = false;
for (Ifc2x3::IfcRelContainedInSpatialStructure::it i = li->begin(); i != li->end(); ++i) {
Ifc2x3::IfcRelContainedInSpatialStructure* rel = *i;
for (IfcSchema::IfcRelContainedInSpatialStructure::it i = li->begin(); i != li->end(); ++i) {
IfcSchema::IfcRelContainedInSpatialStructure* rel = *i;
if (rel->RelatingStructure() == relating_object) {
Ifc2x3::IfcProduct::list products = rel->RelatedElements();
products->push((Ifc2x3::IfcProduct*)related_object);
IfcSchema::IfcProduct::list products = rel->RelatedElements();
products->push((IfcSchema::IfcProduct*)related_object);
rel->setRelatedElements(products);
found = true;
break;
@@ -154,15 +159,15 @@ inline void IfcHierarchyHelper::addRelatedObject <Ifc2x3::IfcRelContainedInSpati
}
if (! found) {
if (! owner_hist) {
owner_hist = getSingle<Ifc2x3::IfcOwnerHistory>();
owner_hist = getSingle<IfcSchema::IfcOwnerHistory>();
}
if (! owner_hist) {
owner_hist = addOwnerHistory();
}
Ifc2x3::IfcProduct::list relating_objects (new IfcTemplatedEntityList<Ifc2x3::IfcProduct>());
relating_objects->push((Ifc2x3::IfcProduct*)relating_object);
Ifc2x3::IfcRelContainedInSpatialStructure* t = new Ifc2x3::IfcRelContainedInSpatialStructure(IfcWrite::IfcGuidHelper(), owner_hist,
boost::none, boost::none, relating_objects, (Ifc2x3::IfcSpatialStructureElement*)related_object);
IfcSchema::IfcProduct::list relating_objects (new IfcTemplatedEntityList<IfcSchema::IfcProduct>());
relating_objects->push((IfcSchema::IfcProduct*)relating_object);
IfcSchema::IfcRelContainedInSpatialStructure* t = new IfcSchema::IfcRelContainedInSpatialStructure(IfcWrite::IfcGuidHelper(), owner_hist,
boost::none, boost::none, relating_objects, (IfcSchema::IfcSpatialStructureElement*)related_object);
AddEntity(t);
}
+58 -103
View File
@@ -31,41 +31,20 @@
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcSpfStream.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcWritableEntity.h"
using namespace IfcParse;
#include "../ifcparse/IfcUntypedEntity.h"
// A static locale for the real number parser. strtod() is locale-dependent, causing issues
// in locales that have ',' as a decimal separator. Therefore the non standard _strtod_l() /
// strtod_l() is used and a reference to the "C" locale is obtained here. The alternative is
// to use std::istringstream::imbue(std::locale::classic()), but there are subtleties in
// parsing in MSVC2010 and it appears to be much slower.
#ifdef _MSC_VER
static _locale_t locale = (_locale_t) 0;
void init_locale() {
if (locale == (_locale_t) 0) {
locale = _create_locale(LC_NUMERIC, "C");
}
}
#else
#ifdef __APPLE__
#include <xlocale.h>
#endif
static locale_t locale = (locale_t) 0;
void init_locale() {
if (locale == (locale_t) 0) {
locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
}
}
#endif
using namespace IfcParse;
//
// Opens the file, gets the filesize and reads a chunk in memory
//
IfcSpfStream::IfcSpfStream(const std::string& fn) {
eof = false;
#ifdef _MSC_VER
#ifdef _MSC_VER_NO
int fn_buffer_size = MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, 0, 0);
wchar_t* fn_wide = new wchar_t[fn_buffer_size];
MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, fn_wide, fn_buffer_size);
@@ -387,11 +366,7 @@ double TokenFunc::asFloat(const Token& t) {
const std::string str = asString(t);
const char* start = str.c_str();
char* end;
#ifdef _MSC_VER
double result = _strtod_l(start,&end,locale);
#else
double result = strtod_l(start,&end,locale);
#endif
double result = strtod(start,&end);
if ( start == end ) throw IfcException("Token is not a real");
return result;
}
@@ -411,8 +386,8 @@ TokenArgument::TokenArgument(const Token& t) {
token = t;
}
EntityArgument::EntityArgument(Ifc2x3::Type::Enum ty, const Token& t) {
entity = new IfcUtil::IfcArgumentSelect(ty,new TokenArgument(t));
EntityArgument::EntityArgument(IfcSchema::Type::Enum ty, const Token& t) {
entity = new IfcUntypedEntity(new Entity(0,t.first->file,t.second));
}
//
@@ -430,11 +405,10 @@ ArgumentList::ArgumentList(Tokens* t, std::vector<unsigned int>& ids) {
if ( TokenFunc::isDatatype(next) ) {
t->Next();
try {
Push ( new EntityArgument(Ifc2x3::Type::FromString(TokenFunc::asString(next)),t->Next()) );
Push ( new EntityArgument(Ifc2x3::Type::ALL,next) ); //Ifc2x3::Type::FromString(TokenFunc::asString(next)),t->Next()) );
} catch ( IfcException& e ) {
Logger::Message(Logger::LOG_ERROR,e.what());
}
t->Next();
} else {
Push ( new TokenArgument(next) );
}
@@ -552,22 +526,7 @@ EntityArgument::operator IfcEntities() const { throw IfcException("Argument is n
unsigned int EntityArgument::Size() const { return 1; }
ArgumentPtr EntityArgument::operator [] (unsigned int i) const { throw IfcException("Argument is not a list of arguments"); }
std::string EntityArgument::toString(bool upper) const {
ArgumentPtr arg = entity->wrappedValue();
IfcParse::TokenArgument* token_arg = dynamic_cast<IfcParse::TokenArgument*>(arg);
const bool is_string = TokenFunc::isString(token_arg->token);
std::string token_string = token_arg ? (is_string
? TokenFunc::asString(token_arg->token)
: TokenFunc::toString(token_arg->token))
: std::string();
std::string dt = Ifc2x3::Type::ToString(entity->type());
if ( upper ) {
for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
if (is_string) token_string = IfcWrite::IfcCharacterEncoder(token_string);
} else {
token_string.insert(token_string.begin(),'\'');
token_string.push_back('\'');
}
return dt + "(" + token_string + ")";
return entity->entity->toString(upper);
}
//return entity->entity->toString(); }
bool EntityArgument::isNull() const { return false; }
@@ -580,7 +539,7 @@ Entity::Entity(unsigned int i, IfcFile* f) { //: file(f) {
file = f;
Token datatype = f->tokens->Next();
if ( ! TokenFunc::isDatatype(datatype)) throw IfcException("Unexpected token while parsing entity");
_type = Ifc2x3::Type::FromString(TokenFunc::asString(datatype));
_type = IfcSchema::Type::FromString(TokenFunc::asString(datatype));
_id = i;
args = ArgumentPtr();
offset = datatype.second;
@@ -624,7 +583,7 @@ void Entity::Load(std::vector<unsigned int>& ids, bool seek) {
file->tokens->stream->Seek(offset);
Token datatype = file->tokens->Next();
if ( ! TokenFunc::isDatatype(datatype)) throw IfcException("Unexpected token while parsing entity");
_type = Ifc2x3::Type::FromString(TokenFunc::asString(datatype));
_type = IfcSchema::Type::FromString(TokenFunc::asString(datatype));
}
Token open = file->tokens->Next();
args = new ArgumentList(file->tokens, ids);
@@ -633,7 +592,7 @@ void Entity::Load(std::vector<unsigned int>& ids, bool seek) {
if ( ! TokenFunc::isOperator(semilocon,';') ) file->tokens->stream->Seek(old_offset);
}
Ifc2x3::Type::Enum Entity::type() const {
IfcSchema::Type::Enum Entity::type() const {
return _type;
}
@@ -641,7 +600,7 @@ Ifc2x3::Type::Enum Entity::type() const {
// Returns the CamelCase string representation of the datatype as it is defined in the schema
//
std::string Entity::datatype() {
return Ifc2x3::Type::ToString(_type);
return IfcSchema::Type::ToString(_type);
}
//
@@ -654,13 +613,14 @@ std::string Entity::toString(bool upper) {
Load(ids, true);
}
std::stringstream ss;
ss.imbue(std::locale::classic());
std::string dt = datatype();
if ( upper ) {
for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
}
ss << "#" << _id << "=" << dt << args->toString(upper);
if (_id) {
ss << "#" << _id << "=";
}
ss << dt << args->toString(upper);
return ss.str();
}
@@ -671,18 +631,18 @@ Entity::~Entity() {
//
// Returns the entities of type c that have this entity in their ArgumentList
//
IfcEntities Entity::getInverse(Ifc2x3::Type::Enum c) {
IfcEntities Entity::getInverse(IfcSchema::Type::Enum c) {
IfcEntities l = IfcEntities(new IfcEntityList());
IfcEntities all = file->EntitiesByReference(_id);
if ( ! all ) return l;
for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
if ( c == Ifc2x3::Type::ALL || (*it)->is(c) ) {
if ( c == IfcSchema::Type::ALL || (*it)->is(c) ) {
l->push(*it);
}
}
return l;
}
IfcEntities Entity::getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a) {
IfcEntities Entity::getInverse(IfcSchema::Type::Enum c, int i, const std::string& a) {
IfcEntities l = IfcEntities(new IfcEntityList());
IfcEntities all = getInverse(c);
for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
@@ -693,7 +653,7 @@ IfcEntities Entity::getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a
}
return l;
}
bool Entity::is(Ifc2x3::Type::Enum v) const { return _type == v; }
bool Entity::is(IfcSchema::Type::Enum v) const { return _type == v; }
unsigned int Entity::id() { return _id; }
bool Entity::isWritable() {
@@ -723,11 +683,7 @@ bool IfcFile::Init(void* data, int len) {
return IfcFile::Init(new IfcSpfStream(data,len));
}
bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
// Initialize a "C" locale for locale-independent
// number parsing. See comment above on line 41.
init_locale();
Ifc2x3::InitStringMap();
IfcSchema::InitStringMap();
file = f;
if ( ! file->valid ) return false;
tokens = new Tokens (file,this);
@@ -743,7 +699,7 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
if ( currentId ) {
try {
e = new Entity(currentId,this);
entity = Ifc2x3::SchemaEntity(e);
entity = new IfcUntypedEntity(e);
} catch (IfcException ex) {
currentId = 0;
Logger::Message(Logger::LOG_ERROR,ex.what());
@@ -754,8 +710,8 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
std::stringstream ss; ss << "\r#" << currentId;
Logger::Status(ss.str(), false);
}
if ( entity->is(Ifc2x3::Type::IfcRoot) ) {
Ifc2x3::IfcRoot::ptr ifc_root = (Ifc2x3::IfcRoot::ptr) entity;
if ( entity->is(IfcSchema::Type::IfcRoot) ) {
IfcSchema::IfcRoot::ptr ifc_root = (IfcSchema::IfcRoot::ptr) entity;
try {
const std::string guid = ifc_root->GlobalId();
if ( byguid.find(guid) != byguid.end() ) {
@@ -768,45 +724,40 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* f) {
Logger::Message(Logger::LOG_ERROR,ex.what());
}
}
Ifc2x3::Type::Enum ty = entity->type();
IfcSchema::Type::Enum ty = entity->type();
do {
IfcEntities instances_by_type = EntitiesByType(ty);
if (!instances_by_type) {
instances_by_type = IfcEntities(new IfcEntityList());
bytype[ty] = instances_by_type;
IfcEntities L = EntitiesByType(ty);
if ( L == 0 ) {
L = IfcEntities(new IfcEntityList());
bytype[ty] = L;
}
instances_by_type->push(entity);
ty = Ifc2x3::Type::Parent(ty);
L->push(entity);
ty = IfcSchema::Type::Parent(ty);
} while ( ty > -1 );
if ( byid.find(currentId) != byid.end() ) {
std::stringstream ss;
ss << "Overwriting entity with id " << currentId;
Logger::Message(Logger::LOG_WARNING,ss.str());
}
byid[currentId] = entity;
MaxId = (std::max)(MaxId,currentId);
currentId = 0;
} else {
try { token = tokens->Next(); }
catch (... ) { token = TokenPtr(); }
}
if ( ! (token.second || token.first) ) break;
if ( (previous.second || previous.first) && TokenFunc::isIdentifier(previous) ) {
int id = TokenFunc::asInt(previous);
if ( TokenFunc::isOperator(token,'=') ) {
currentId = id;
} else if (entity) {
IfcEntities instances_by_ref = EntitiesByReference(id);
if (!instances_by_ref) {
instances_by_ref = IfcEntities(new IfcEntityList());
byref[id] = instances_by_ref;
IfcEntities L = EntitiesByReference(id);
if ( L == 0 ) {
L = IfcEntities(new IfcEntityList());
byref[id] = L;
}
instances_by_ref->push(entity);
L->push(entity);
}
}
previous = token;
@@ -820,8 +771,8 @@ void IfcFile::AddEntities(IfcEntities es) {
}
}
void IfcFile::AddEntity(IfcUtil::IfcSchemaEntity entity) {
if ( entity->is(Ifc2x3::Type::IfcRoot) ) {
Ifc2x3::IfcRoot::ptr ifc_root = (Ifc2x3::IfcRoot::ptr) entity;
if ( entity->is(IfcSchema::Type::IfcRoot) ) {
IfcSchema::IfcRoot::ptr ifc_root = (IfcSchema::IfcRoot::ptr) entity;
try {
const std::string guid = ifc_root->GlobalId();
if ( byguid.find(guid) != byguid.end() ) {
@@ -834,18 +785,16 @@ void IfcFile::AddEntity(IfcUtil::IfcSchemaEntity entity) {
Logger::Message(Logger::LOG_ERROR,ex.what());
}
}
Ifc2x3::Type::Enum ty = entity->type();
IfcSchema::Type::Enum ty = entity->type();
do {
IfcEntities instances_by_type = EntitiesByType(ty);
if (!instances_by_type) {
instances_by_type = IfcEntities(new IfcEntityList());
bytype[ty] = instances_by_type;
IfcEntities L = EntitiesByType(ty);
if ( L == 0 ) {
L = IfcEntities(new IfcEntityList());
bytype[ty] = L;
}
instances_by_type->push(entity);
ty = Ifc2x3::Type::Parent(ty);
L->push(entity);
ty = IfcSchema::Type::Parent(ty);
} while ( ty > -1 );
int new_id = -1;
// For newly created entities ensure a valid ENTITY_INSTANCE_NAME is set
if ( entity->entity->isWritable() ) {
@@ -863,14 +812,14 @@ void IfcFile::AddEntity(IfcUtil::IfcSchemaEntity entity) {
byid[new_id] = entity;
}
IfcEntities IfcFile::EntitiesByType(Ifc2x3::Type::Enum t) {
IfcEntities IfcFile::EntitiesByType(IfcSchema::Type::Enum t) {
MapEntitiesByType::const_iterator it = bytype.find(t);
return (it == bytype.end()) ? IfcEntities() : it->second;
}
IfcEntities IfcFile::EntitiesByType(const std::string& t) {
std::string ty = t;
for (std::string::iterator p = ty.begin(); p != ty.end(); ++p ) *p = toupper(*p);
return EntitiesByType(Ifc2x3::Type::FromString(ty));
return EntitiesByType(IfcSchema::Type::FromString(ty));
}
IfcEntities IfcFile::EntitiesByReference(int t) {
MapEntitiesByRef::const_iterator it = byref.find(t);
@@ -883,13 +832,13 @@ IfcUtil::IfcSchemaEntity IfcFile::EntityById(int id) {
if ( it2 == offsets.end() ) throw IfcException("Entity not found");
const unsigned int offset = (*it2).second;
EntityPtr e = EntityPtr(new Entity(id,this,offset));
IfcUtil::IfcSchemaEntity entity = Ifc2x3::SchemaEntity(e);
IfcUtil::IfcSchemaEntity entity = IfcSchema::SchemaEntity(e);
byid[id] = entity;
return entity;
}
return it->second;
}
Ifc2x3::IfcRoot::ptr IfcFile::EntityByGuid(const std::string& guid) {
IfcSchema::IfcRoot::ptr IfcFile::EntityByGuid(const std::string& guid) {
MapEntityByGuid::const_iterator it = byguid.find(guid);
if ( it == byguid.end() ) {
throw IfcException("Entity not found");
@@ -922,7 +871,7 @@ MapEntityById::const_iterator IfcFile::end() const {
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
os << "ISO-10303-21;" << std::endl;
os << "HEADER;" << std::endl;
os << "FILE_DESCRIPTION(('ViewDefinition []'),'2;1');" << std::endl;
os << "FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');" << std::endl;
os << "FILE_NAME("
<< static_cast<std::string>(IfcWrite::IfcCharacterEncoder(f.filename())) << ","
<< static_cast<std::string>(IfcWrite::IfcCharacterEncoder(f.timestamp())) << ",("
@@ -932,13 +881,19 @@ std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f) {
<< "),'IfcOpenShell " << IFCOPENSHELL_VERSION
<< "','IfcOpenShell " << IFCOPENSHELL_VERSION
<< "','');" << std::endl;
#ifdef USE_IFC4
os << "FILE_SCHEMA(('IFC4'));" << std::endl;
#else
os << "FILE_SCHEMA(('IFC2X3'));" << std::endl;
#endif
os << "ENDSEC;" << std::endl;
os << "DATA;" << std::endl;
for ( MapEntityById::const_iterator it = f.begin(); it != f.end(); ++ it ) {
const IfcEntity e = it->second;
os << e->entity->toString(true) << ";" << std::endl;
if (!IfcSchema::Type::IsSimple(e->type())) {
os << e->entity->toString(true) << ";" << std::endl;
}
}
os << "ENDSEC;" << std::endl;
+20 -85
View File
@@ -20,14 +20,14 @@
/********************************************************************************
* *
* This file provides functions for loading an IFC file into memory and access *
* its entities either by ID, by an Ifc2x3::Type or by reference *
* its entities either by ID, by an IfcSchema::Type or by reference *
* *
********************************************************************************/
#ifndef IFCPARSE_H
#define IFCPARSE_H
#define IFCOPENSHELL_VERSION "0.4.0-rc2"
#define IFCOPENSHELL_VERSION "0.5.0-dev"
#include <string>
#include <sstream>
@@ -40,8 +40,15 @@
#include "../ifcparse/SharedPointer.h"
#include "../ifcparse/IfcCharacterDecoder.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcUntypedEntity.h"
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
#include "../ifcparse/Ifc2x3.h"
#include "../ifcparse/IfcFile.h"
#endif
#include "../ifcparse/IfcSpfStream.h"
namespace IfcParse {
@@ -163,9 +170,9 @@ namespace IfcParse {
/// ===================== =====================
class EntityArgument : public Argument {
private:
IfcUtil::IfcArgumentSelect* entity;
IfcUntypedEntity* entity;
public:
EntityArgument(Ifc2x3::Type::Enum ty, const Token& t);
EntityArgument(IfcSchema::Type::Enum ty, const Token& t);
~EntityArgument();
operator int() const;
operator bool() const;
@@ -190,7 +197,7 @@ namespace IfcParse {
private:
//IfcFile* file;
ArgumentPtr args;
Ifc2x3::Type::Enum _type;
IfcSchema::Type::Enum _type;
public:
/// The EXPRESS ENTITY_INSTANCE_NAME
unsigned int _id;
@@ -199,100 +206,28 @@ namespace IfcParse {
Entity(unsigned int i, IfcFile* t);
Entity(unsigned int i, IfcFile* t, unsigned int o);
~Entity();
IfcEntities getInverse(Ifc2x3::Type::Enum c = Ifc2x3::Type::ALL);
IfcEntities getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a);
IfcEntities getInverse(IfcSchema::Type::Enum c = IfcSchema::Type::ALL);
IfcEntities getInverse(IfcSchema::Type::Enum c, int i, const std::string& a);
void Load(std::vector<unsigned int>& ids, bool seek=false);
ArgumentPtr getArgument (unsigned int i);
unsigned int getArgumentCount();
std::string toString(bool upper=false);
std::string datatype();
Ifc2x3::Type::Enum type() const;
bool is(Ifc2x3::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool is(IfcSchema::Type::Enum v) const;
unsigned int id();
bool isWritable();
};
typedef IfcUtil::IfcSchemaEntity IfcEntity;
//typedef IfcEntities IfcEntities;
typedef std::map<Ifc2x3::Type::Enum,IfcEntities> MapEntitiesByType;
typedef std::map<IfcSchema::Type::Enum,IfcEntities> MapEntitiesByType;
typedef std::map<unsigned int,IfcEntity> MapEntityById;
typedef std::map<std::string,Ifc2x3::IfcRoot::ptr> MapEntityByGuid;
typedef std::map<std::string,IfcSchema::IfcRoot::ptr> MapEntityByGuid;
typedef std::map<unsigned int,IfcEntities> MapEntitiesByRef;
typedef std::map<unsigned int,unsigned int> MapOffsetById;
/// This class provides several static convenience functions and variables
/// and provide access to the entities in an IFC file
class IfcFile {
private:
MapEntityById byid;
MapEntitiesByType bytype;
MapEntitiesByRef byref;
MapEntityByGuid byguid;
MapOffsetById offsets;
unsigned int lastId;
unsigned int MaxId;
std::string _filename;
std::string _timestamp;
std::string _author;
std::string _author_email;
std::string _author_organisation;
void initTimestamp();
public:
typedef MapEntityById::const_iterator const_iterator;
IfcFile();
~IfcFile();
/// Returns the first entity in the file, this probably is the entity with the lowest id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator begin() const;
/// Returns the last entity in the file, this probably is the entity with the highes id (EXPRESS ENTITY_INSTANCE_NAME)
const_iterator end() const;
IfcParse::IfcSpfStream* file;
IfcParse::Tokens* tokens;
/// Returns all entities in the file that match the template argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
template <class T>
typename T::list EntitiesByType() {
IfcEntities e = EntitiesByType(T::Class());
typename T::list l ( new IfcTemplatedEntityList<T>() );
if ( e && e->Size() )
for ( IfcEntityList::it it = e->begin(); it != e->end(); ++ it ) {
l->push(reinterpret_pointer_cast<IfcUtil::IfcBaseClass,T>(*it));
}
return l;
}
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
IfcEntities EntitiesByType(Ifc2x3::Type::Enum t);
/// Returns all entities in the file that match the positional argument.
/// NOTE: This also returns subtypes of the requested type, for example:
/// IfcWall will also return IfcWallStandardCase entities
IfcEntities EntitiesByType(const std::string& t);
/// Returns all entities in the file that reference the id
IfcEntities EntitiesByReference(int id);
/// Returns the entity with the specified id
IfcEntity EntityById(int id);
/// Returns the entity with the specified GlobalId
Ifc2x3::IfcRoot::ptr EntityByGuid(const std::string& guid);
bool Init(const std::string& fn);
bool Init(std::istream& fn, int len);
bool Init(void* data, int len);
bool Init(IfcParse::IfcSpfStream* f);
unsigned int FreshId() { MaxId ++; return MaxId; }
void AddEntity(IfcUtil::IfcSchemaEntity e);
void AddEntities(IfcEntities es);
void filename(const std::string& s);
std::string filename() const;
void timestamp(const std::string& s);
std::string timestamp() const;
void author(const std::string& name, const std::string& email, const std::string& organisation);
std::string authorName() const;
std::string authorEmail() const;
std::string authorOrganisation() const;
};
double UnitPrefixToValue( Ifc2x3::IfcSIPrefix::IfcSIPrefix v );
double UnitPrefixToValue( IfcSchema::IfcSIPrefix::IfcSIPrefix v );
}
+81
View File
@@ -0,0 +1,81 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
/********************************************************************************
* *
* Reads a file in chunks of BUF_SIZE and provides functions to access its *
* contents randomly and character by character *
* *
********************************************************************************/
#ifndef IFCSPFSTREAM_H
#define IFCSPFSTREAM_H
#include <fstream>
#include <string>
// As of IfcOpenShell version 0.3.0 the paging functionality, which
// loads a file on disk into multiple chunks, has been disabled.
// It proved to be an inefficient way of working with large files,
// as often these did not facilitate to be parsed in a sequential
// manner efficiently. To enable the paging functionality uncomment
// the following statement.
// #define BUF_SIZE (8 * 1024 * 1024)
namespace IfcParse {
/// The IfcSpfStream class represents a ISO 10303-21 IFC-SPF file in memory.
/// The file is interpreted as a sequence of tokens which are lazily
/// interpreted only when requested. If the size of the file is
/// larger than BUF_SIZE, the file is split into seperate pages, of
/// which only one is simultaneously kept in memory, for files
/// that define their entities not in a sequential nature, this is
/// detrimental for the performance of the parser.
class IfcSpfStream {
private:
FILE* stream;
char* buffer;
unsigned int ptr;
unsigned int len;
void ReadBuffer(bool inc=true);
#ifdef BUF_SIZE
unsigned int offset;
bool paging;
#endif
public:
bool valid;
bool eof;
unsigned int size;
IfcSpfStream(const std::string& fn);
IfcSpfStream(std::istream& f, int len);
IfcSpfStream(void* data, int len);
/// Returns the character at the cursor
char Peek();
/// Returns the character at specified offset
char Read(unsigned int offset);
/// Increment the file cursor and reads new page if necessary
void Inc();
void Close();
/// Moves the file cursor to an arbitrary offset in the file
void Seek(unsigned int offset);
/// Returns the cursor position
unsigned int Tell();
};
}
#endif
+191
View File
@@ -0,0 +1,191 @@
#include <sstream>
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/Ifc2x3-rt.h"
#include "IfcUntypedEntity.h"
using namespace IfcUtil;
IfcWrite::IfcWritableEntity* IfcParse::IfcUntypedEntity::writable_entity() {
IfcWrite::IfcWritableEntity* e;
if (entity->isWritable()) {
e = (IfcWrite::IfcWritableEntity*) entity;
} else {
entity = e = new IfcWrite::IfcWritableEntity(entity);
}
return e;
}
IfcParse::IfcUntypedEntity::IfcUntypedEntity(const std::string& s) {
std::string S = s;
for (std::string::iterator i = S.begin(); i != S.end(); ++i ) *i = toupper(*i);
_type = IfcSchema::Type::FromString(S);
entity = new IfcWrite::IfcWritableEntity(_type);
IfcSchema::Type::PopulateDerivedFields(writable_entity());
}
IfcParse::IfcUntypedEntity::IfcUntypedEntity(IfcAbstractEntity* e) {
entity = e;
_type = e->type();
}
unsigned int IfcParse::IfcUntypedEntity::id() const {
if (entity->file) {
return static_cast<unsigned int>(entity->id());
} else {
throw IfcException("Entity not bound to a file");
}
}
bool IfcParse::IfcUntypedEntity::is(IfcSchema::Type::Enum v) const {
IfcSchema::Type::Enum _ty = _type;
if (v == _ty) return true;
while (_ty != -1) {
_ty = IfcSchema::Type::Parent(_ty);
if (v == _ty) return true;
}
return false;
}
std::string IfcParse::IfcUntypedEntity::is_a() const {
return IfcSchema::Type::ToString(_type);
}
bool IfcParse::IfcUntypedEntity::is_a(const std::string& s) const {
std::string S = s;
for (std::string::iterator i = S.begin(); i != S.end(); ++i ) *i = toupper(*i);
return is(IfcSchema::Type::FromString(S));
}
IfcSchema::Type::Enum IfcParse::IfcUntypedEntity::type() const {
return _type;
}
unsigned int IfcParse::IfcUntypedEntity::getArgumentCount() const {
return IfcSchema::Type::GetAttributeCount(_type);
}
IfcUtil::ArgumentType IfcParse::IfcUntypedEntity::getArgumentType(unsigned int i) const {
return IfcSchema::Type::GetAttributeDerived(_type, i)
? IfcUtil::Argument_DERIVED
: IfcSchema::Type::GetAttributeType(_type,i);
}
ArgumentPtr IfcParse::IfcUntypedEntity::getArgument(unsigned int i) const {
return entity->getArgument(i);
}
const char* IfcParse::IfcUntypedEntity::getArgumentName(unsigned int i) const {
return IfcSchema::Type::GetAttributeName(_type,i).c_str();
}
void IfcParse::IfcUntypedEntity::invalid_argument(unsigned int i, const std::string& t) {
const std::string arg_name = IfcSchema::Type::GetAttributeName(_type,i);
throw IfcException(t + " is not a valid type for '" + arg_name + "'");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i) {
bool is_optional = IfcSchema::Type::GetAttributeOptional(_type, i);
if (is_optional) {
writable_entity()->setArgument(i);
} else invalid_argument(i,"NULL");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, int v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_INT) {
writable_entity()->setArgument(i,v);
} else if ( (arg_type == Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
writable_entity()->setArgument(i, v == 1);
} else invalid_argument(i,"INT");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, bool v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_BOOL) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"BOOL");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, double v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_DOUBLE) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"DOUBLE");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, const std::string& a) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_STRING) {
writable_entity()->setArgument(i,a);
} else if (arg_type == Argument_ENUMERATION) {
std::pair<const char*, int> enum_data = IfcSchema::Type::GetEnumerationIndex(IfcSchema::Type::GetAttributeEnumerationClass(_type, i), a);
writable_entity()->setArgument(i, enum_data.second, enum_data.first);
} else invalid_argument(i,"STRING");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, const std::vector<int>& v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_VECTOR_INT) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"LIST of INT");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, const std::vector<double>& v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_VECTOR_DOUBLE) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"LIST of DOUBLE");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, const std::vector<std::string>& v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_VECTOR_STRING) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"LIST of STRING");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, IfcParse::IfcUntypedEntity* v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_ENTITY) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"ENTITY");
}
void IfcParse::IfcUntypedEntity::setArgument(unsigned int i, IfcEntities v) {
IfcUtil::ArgumentType arg_type = IfcSchema::Type::GetAttributeType(_type,i);
if (arg_type == Argument_ENTITY_LIST) {
writable_entity()->setArgument(i,v);
} else invalid_argument(i,"LIST of ENTITY");
}
std::pair<IfcUtil::ArgumentType,ArgumentPtr> IfcParse::IfcUntypedEntity::get_argument(unsigned i) {
return std::pair<IfcUtil::ArgumentType,ArgumentPtr>(getArgumentType(i),getArgument(i));
}
std::pair<IfcUtil::ArgumentType,ArgumentPtr> IfcParse::IfcUntypedEntity::get_argument(const std::string& a) {
return get_argument(IfcSchema::Type::GetAttributeIndex(_type,a));
}
unsigned IfcParse::IfcUntypedEntity::getArgumentIndex(const std::string& a) const {
return IfcSchema::Type::GetAttributeIndex(_type,a);
}
std::string IfcParse::IfcUntypedEntity::toString() {
return entity->toString(false);
}
IfcEntities IfcParse::IfcUntypedEntity::get_inverse(const std::string& a) {
std::pair<IfcSchema::Type::Enum, unsigned> inv = IfcSchema::Type::GetInverseAttribute(_type, a);
IfcEntities invs = entity->getInverse(inv.first);
IfcEntities filtered(new IfcEntityList());
for (IfcEntityList::it it = invs->begin(); it != invs->end(); ++it) {
try {
const int id = *(*it)->entity->getArgument(inv.second);
if (id == this->entity->id()) { filtered->push(*it); }
} catch (...) {}
}
return filtered;
}
bool IfcParse::IfcUntypedEntity::is_valid() {
const unsigned arg_count = getArgumentCount();
bool valid = true;
std::ostringstream oss;
oss << "Argument ";
for (unsigned i = 0; i < arg_count; ++i) {
bool is_null = true;
try {
const Argument& arg = *getArgument(i);
is_null = arg.isNull();
} catch(IfcException) {}
if (!IfcSchema::Type::GetAttributeOptional(_type,i) && is_null) {
if (!valid) {
oss << ", ";
}
oss << "\"" << getArgumentName(i) << "\"";
valid = false;
}
}
oss << " not optional";
if (!valid) {
throw IfcException(oss.str());
}
return valid;
}
+57
View File
@@ -0,0 +1,57 @@
#ifndef IFCUNTYPEDENTITY_H
#define IFCUNTYPEDENTITY_H
#include <string>
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
namespace IfcParse {
class IfcUntypedEntity : public IfcUtil::IfcBaseEntity {
private:
IfcSchema::Type::Enum _type;
IfcWrite::IfcWritableEntity* writable_entity();
void invalid_argument(unsigned int i, const std::string& t);
public:
IfcUntypedEntity(const std::string& s);
IfcUntypedEntity(IfcAbstractEntity* e);
bool is(IfcSchema::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool is_a(const std::string& s) const;
std::string is_a() const;
unsigned int id() const;
unsigned int getArgumentCount() const;
IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
ArgumentPtr getArgument(unsigned int i) const;
const char* getArgumentName(unsigned int i) const;
unsigned getArgumentIndex(const std::string& a) const;
IfcEntities get_inverse(const std::string& a);
void setArgument(unsigned int iz);
void setArgument(unsigned int i, int v);
void setArgument(unsigned int i, bool v);
void setArgument(unsigned int i, double v);
void setArgument(unsigned int i, const std::string& v);
void setArgument(unsigned int i, const std::vector<int>& v);
void setArgument(unsigned int i, const std::vector<double>& v);
void setArgument(unsigned int i, const std::vector<std::string>& v);
void setArgument(unsigned int i, IfcUntypedEntity* v);
void setArgument(unsigned int i, IfcEntities v);
std::string toString();
// TODO: Write as SWIG extension methods
std::pair<IfcUtil::ArgumentType,ArgumentPtr> get_argument(unsigned i);
std::pair<IfcUtil::ArgumentType,ArgumentPtr> get_argument(const std::string& a);
bool is_valid();
};
}
#endif
+7 -7
View File
@@ -34,14 +34,14 @@ IfcEntityList::it IfcEntityList::end() { return ls.end(); }
IfcUtil::IfcSchemaEntity IfcEntityList::operator[] (int i) {
return ls[i];
}
IfcEntities IfcEntityList::getInverse(Ifc2x3::Type::Enum c) {
IfcEntities IfcEntityList::getInverse(IfcSchema::Type::Enum c) {
IfcEntities l = IfcEntities(new IfcEntityList());
for( it i = begin(); i != end(); ++i ) {
l->push((*i)->entity->getInverse(c));
}
return l;
}
IfcEntities IfcEntityList::getInverse(Ifc2x3::Type::Enum c, int ar, const std::string& a) {
IfcEntities IfcEntityList::getInverse(IfcSchema::Type::Enum c, int ar, const std::string& a) {
IfcEntities l = IfcEntities(new IfcEntityList());
for( it i = begin(); i != end(); ++i ) {
l->push((*i)->entity->getInverse(c,ar,a));
@@ -49,16 +49,16 @@ IfcEntities IfcEntityList::getInverse(Ifc2x3::Type::Enum c, int ar, const std::s
return l;
}
bool IfcUtil::IfcEntitySelect::is(Ifc2x3::Type::Enum v) const { return entity->is(v); }
Ifc2x3::Type::Enum IfcUtil::IfcEntitySelect::type() const { return entity->type(); }
bool IfcUtil::IfcEntitySelect::is(IfcSchema::Type::Enum v) const { return entity->is(v); }
IfcSchema::Type::Enum IfcUtil::IfcEntitySelect::type() const { return entity->type(); }
IfcUtil::IfcEntitySelect::IfcEntitySelect(IfcSchemaEntity b) { entity = b->entity; }
IfcUtil::IfcEntitySelect::IfcEntitySelect(IfcAbstractEntityPtr e) { entity = e; }
bool IfcUtil::IfcEntitySelect::isSimpleType() { return false; }
IfcUtil::IfcEntitySelect::~IfcEntitySelect() { delete entity; }
bool IfcUtil::IfcArgumentSelect::is(Ifc2x3::Type::Enum v) const { return _type == v; }
Ifc2x3::Type::Enum IfcUtil::IfcArgumentSelect::type() const { return _type; }
IfcUtil::IfcArgumentSelect::IfcArgumentSelect(Ifc2x3::Type::Enum t, ArgumentPtr a) { _type = t; arg = a; }
bool IfcUtil::IfcArgumentSelect::is(IfcSchema::Type::Enum v) const { return _type == v; }
IfcSchema::Type::Enum IfcUtil::IfcArgumentSelect::type() const { return _type; }
IfcUtil::IfcArgumentSelect::IfcArgumentSelect(IfcSchema::Type::Enum t, ArgumentPtr a) { _type = t; arg = a; }
ArgumentPtr IfcUtil::IfcArgumentSelect::wrappedValue() { return arg; }
bool IfcUtil::IfcArgumentSelect::isSimpleType() { return true; }
IfcUtil::IfcArgumentSelect::~IfcArgumentSelect() { delete arg; }
+20 -15
View File
@@ -25,7 +25,12 @@
#include <sstream>
#include "../ifcparse/SharedPointer.h"
#ifdef USE_IFC4
#include "../ifcparse/Ifc4enum.h"
#else
#include "../ifcparse/Ifc2x3enum.h"
#endif
class IfcAbstractEntity;
//typedef SHARED_PTR<IfcAbstractEntity> IfcAbstractEntityPtr;
@@ -48,7 +53,7 @@ inline T* reinterpret_pointer_cast(F* from) {
namespace IfcUtil {
enum ArgumentType {
Argument_INT, Argument_BOOL, Argument_DOUBLE, Argument_STRING, Argument_VECTOR_INT, Argument_VECTOR_DOUBLE, Argument_VECTOR_STRING, Argument_ENTITY, Argument_ENTITY_LIST, Argument_ENUMERATION, Argument_UNKNOWN
Argument_INT, Argument_BOOL, Argument_DOUBLE, Argument_STRING, Argument_VECTOR_INT, Argument_VECTOR_DOUBLE, Argument_VECTOR_STRING, Argument_ENTITY, Argument_ENTITY_LIST, Argument_ENTITY_LIST_LIST, Argument_ENUMERATION, Argument_DERIVED, Argument_UNKNOWN
};
}
@@ -57,8 +62,8 @@ namespace IfcUtil {
class IfcBaseClass {
public:
IfcAbstractEntityPtr entity;
virtual bool is(Ifc2x3::Type::Enum v) const = 0;
virtual Ifc2x3::Type::Enum type() const = 0;
virtual bool is(IfcSchema::Type::Enum v) const = 0;
virtual IfcSchema::Type::Enum type() const = 0;
};
class IfcBaseEntity : public IfcBaseClass {
@@ -81,8 +86,8 @@ class IfcEntityList {
std::vector<IfcUtil::IfcSchemaEntity> ls;
public:
typedef std::vector<IfcUtil::IfcSchemaEntity>::const_iterator it;
IfcEntities getInverse(Ifc2x3::Type::Enum c = Ifc2x3::Type::ALL);
IfcEntities getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a);
IfcEntities getInverse(IfcSchema::Type::Enum c = IfcSchema::Type::ALL);
IfcEntities getInverse(IfcSchema::Type::Enum c, int i, const std::string& a);
void push(IfcUtil::IfcSchemaEntity l);
void push(IfcEntities l);
it begin();
@@ -134,20 +139,20 @@ namespace IfcUtil {
IfcEntitySelect(IfcSchemaEntity b);
IfcEntitySelect(IfcAbstractEntityPtr e);
~IfcEntitySelect();
bool is(Ifc2x3::Type::Enum v) const;
Ifc2x3::Type::Enum type() const;
bool is(IfcSchema::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool isSimpleType();
};
class IfcArgumentSelect : public IfcAbstractSelect {
Ifc2x3::Type::Enum _type;
IfcSchema::Type::Enum _type;
ArgumentPtr arg;
public:
typedef IfcArgumentSelect* ptr;
IfcArgumentSelect(Ifc2x3::Type::Enum t, ArgumentPtr a);
IfcArgumentSelect(IfcSchema::Type::Enum t, ArgumentPtr a);
~IfcArgumentSelect();
ArgumentPtr wrappedValue();
bool is(Ifc2x3::Type::Enum v) const;
Ifc2x3::Type::Enum type() const;
bool is(IfcSchema::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool isSimpleType();
};
}
@@ -180,14 +185,14 @@ public:
class IfcAbstractEntity {
public:
IfcParse::IfcFile* file;
virtual IfcEntities getInverse(Ifc2x3::Type::Enum c = Ifc2x3::Type::ALL) = 0;
virtual IfcEntities getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a) = 0;
virtual IfcEntities getInverse(IfcSchema::Type::Enum c = IfcSchema::Type::ALL) = 0;
virtual IfcEntities getInverse(IfcSchema::Type::Enum c, int i, const std::string& a) = 0;
virtual std::string datatype() = 0;
virtual ArgumentPtr getArgument (unsigned int i) = 0;
virtual unsigned int getArgumentCount() = 0;
virtual ~IfcAbstractEntity() {};
virtual Ifc2x3::Type::Enum type() const = 0;
virtual bool is(Ifc2x3::Type::Enum v) const = 0;
virtual IfcSchema::Type::Enum type() const = 0;
virtual bool is(IfcSchema::Type::Enum v) const = 0;
virtual std::string toString(bool upper=false) = 0;
virtual unsigned int id() = 0;
virtual bool isWritable() = 0;
+6 -6
View File
@@ -40,23 +40,23 @@ namespace IfcWrite {
private:
std::map<int,bool> writemask;
std::map<int,ArgumentPtr> args;
Ifc2x3::Type::Enum _type;
IfcSchema::Type::Enum _type;
int* _id;
bool arg_writable(int i);
void arg_writable(int i, bool b);
template <typename T> void _setArgument(int i, const T&);
public:
IfcWritableEntity(Ifc2x3::Type::Enum t);
IfcWritableEntity(IfcSchema::Type::Enum t);
~IfcWritableEntity();
int setId(int i=-1);
IfcWritableEntity(IfcAbstractEntity* e);
IfcEntities getInverse(Ifc2x3::Type::Enum c = Ifc2x3::Type::ALL);
IfcEntities getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a);
IfcEntities getInverse(IfcSchema::Type::Enum c = IfcSchema::Type::ALL);
IfcEntities getInverse(IfcSchema::Type::Enum c, int i, const std::string& a);
std::string datatype();
ArgumentPtr getArgument (unsigned int i);
unsigned int getArgumentCount();
Ifc2x3::Type::Enum type() const;
bool is(Ifc2x3::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool is(IfcSchema::Type::Enum v) const;
std::string toString(bool upper=false);
unsigned int id();
bool isWritable();
+34 -40
View File
@@ -18,16 +18,16 @@
********************************************************************************/
#include <iomanip>
#include <locale>
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcWrite.h"
#include "../ifcparse/IfcWritableEntity.h"
#include "../ifcparse/IfcCharacterDecoder.h"
using namespace IfcWrite;
IfcWritableEntity::IfcWritableEntity(Ifc2x3::Type::Enum t) {
IfcWritableEntity::IfcWritableEntity(IfcSchema::Type::Enum t) {
_type = t;
_id = 0;
file = 0;
@@ -51,19 +51,19 @@ IfcWritableEntity::IfcWritableEntity(IfcAbstractEntity* e)
}
}
// TODO: Reove redundancy with IfcParse::Entity
IfcEntities IfcWritableEntity::getInverse(Ifc2x3::Type::Enum c) {
IfcEntities IfcWritableEntity::getInverse(IfcSchema::Type::Enum c) {
IfcEntities l = IfcEntities(new IfcEntityList());
int id = _id ? *_id : setId();
IfcEntities all = file->EntitiesByReference(id);
if ( ! all ) return l;
for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
if ( c == Ifc2x3::Type::ALL || (*it)->is(c) ) {
if ( c == IfcSchema::Type::ALL || (*it)->is(c) ) {
l->push(*it);
}
}
return l;
}
IfcEntities IfcWritableEntity::getInverse(Ifc2x3::Type::Enum c, int i, const std::string& a) {
IfcEntities IfcWritableEntity::getInverse(IfcSchema::Type::Enum c, int i, const std::string& a) {
IfcEntities l = IfcEntities(new IfcEntityList());
IfcEntities all = getInverse(c);
for( IfcEntityList::it it = all->begin(); it != all->end();++ it ) {
@@ -75,21 +75,21 @@ IfcEntities IfcWritableEntity::getInverse(Ifc2x3::Type::Enum c, int i, const std
return l;
}
std::string IfcWritableEntity::datatype() { return Ifc2x3::Type::ToString(_type); }
std::string IfcWritableEntity::datatype() { return IfcSchema::Type::ToString(_type); }
ArgumentPtr IfcWritableEntity::getArgument (unsigned int i) { if ( i >= getArgumentCount() ) throw IfcParse::IfcException("Argument not set"); return args[i]; }
unsigned int IfcWritableEntity::getArgumentCount() {return args.size(); }
Ifc2x3::Type::Enum IfcWritableEntity::type() const { return _type; }
bool IfcWritableEntity::is(Ifc2x3::Type::Enum v) const { return _type == v; }
IfcSchema::Type::Enum IfcWritableEntity::type() const { return _type; }
bool IfcWritableEntity::is(IfcSchema::Type::Enum v) const { return _type == v; }
std::string IfcWritableEntity::toString(bool upper) {
std::stringstream ss;
ss.imbue(std::locale::classic());
std::string dt = datatype();
if ( upper ) {
for (std::string::iterator p = dt.begin(); p != dt.end(); ++p ) *p = toupper(*p);
}
if ( _id ) ss << "#" << *_id;
ss << "=" << dt << "(";
if ( _id && !IfcSchema::Type::IsSimple(_type) ) {
ss << "#" << *_id << "=";
}
ss << dt << "(";
for ( std::map<int,ArgumentPtr>::const_iterator it = args.begin(); it != args.end(); ++ it ) {
if ( it != args.begin() ) ss << ",";
const ArgumentPtr a = it->second;
@@ -199,8 +199,7 @@ private:
// REAL = [ SIGN ] DIGIT { DIGIT } "." { DIGIT } [ "E" [ SIGN ] DIGIT { DIGIT } ] .
std::string format_double(const double& d) {
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss << std::setprecision(15) << d;
oss << std::setprecision(16) << d;
const std::string str = oss.str();
oss.str("");
std::string::size_type e = str.find('e');
@@ -237,11 +236,8 @@ public:
void operator()(const double& i) { data << format_double(i); }
void operator()(const std::string& i) {
std::string s = i;
if (upper) {
data << static_cast<std::string>(IfcCharacterEncoder(s));
} else {
data << '\'' << s << '\'';
}
if (upper) s = IfcCharacterEncoder(s);
data << s;
}
void operator()(const std::vector<int>& i) { serialize(i); }
void operator()(const std::vector<double>& i) { serialize_double(i); }
@@ -251,10 +247,14 @@ public:
}
void operator()(const IfcUtil::IfcSchemaEntity& i) {
IfcAbstractEntity* e = i->entity;
if ( Ifc2x3::Type::IsSimple(e->type()) ) {
if ( IfcSchema::Type::IsSimple(e->type()) ) {
data << e->toString(upper);
} else {
data << "#" << e->id();
if (e->file) {
data << "#" << e->id();
} else {
data << "#?";
}
}
}
void operator()(const IfcEntities& i) {
@@ -271,12 +271,7 @@ public:
IfcWriteArgument::operator int() const { return as<int>(); }
IfcWriteArgument::operator bool() const { return as<bool>(); }
IfcWriteArgument::operator double() const { return as<double>(); }
IfcWriteArgument::operator std::string() const {
if (argumentType() == argument_type_enumeration) {
return as<EnumerationReference>().enumeration_value;
}
return as<std::string>();
}
IfcWriteArgument::operator std::string() const { return as<std::string>(); }
IfcWriteArgument::operator std::vector<double>() const { return as<std::vector<double> >(); }
IfcWriteArgument::operator std::vector<int>() const { return as<std::vector<int> >(); }
IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vector<std::string > >(); }
@@ -286,7 +281,6 @@ bool IfcWriteArgument::isNull() const { return argumentType() == argument_type_n
ArgumentPtr IfcWriteArgument::operator [] (unsigned int i) const { throw IfcParse::IfcException("Invalid cast"); }
std::string IfcWriteArgument::toString(bool upper) const {
std::ostringstream str;
str.imbue(std::locale::classic());
StringBuilderVisitor v(str, upper);
container.apply_visitor(v);
return v;
@@ -304,16 +298,16 @@ IfcWriteArgument::argument_type IfcWriteArgument::argumentType() const {
return static_cast<argument_type>(container.which());
}
IfcEntities IfcSelectHelperEntity::getInverse(Ifc2x3::Type::Enum,int,const std::string &) {throw IfcParse::IfcException("Invalid cast");}
IfcEntities IfcSelectHelperEntity::getInverse(Ifc2x3::Type::Enum) {throw IfcParse::IfcException("Invalid cast");}
std::string IfcSelectHelperEntity::datatype() { return Ifc2x3::Type::ToString(_type); }
IfcEntities IfcSelectHelperEntity::getInverse(IfcSchema::Type::Enum,int,const std::string &) {throw IfcParse::IfcException("Invalid cast");}
IfcEntities IfcSelectHelperEntity::getInverse(IfcSchema::Type::Enum) {throw IfcParse::IfcException("Invalid cast");}
std::string IfcSelectHelperEntity::datatype() { return IfcSchema::Type::ToString(_type); }
ArgumentPtr IfcSelectHelperEntity::getArgument(unsigned int i) {
if ( i != 0 ) throw IfcParse::IfcException("Invalid cast");
return arg;
}
unsigned int IfcSelectHelperEntity::getArgumentCount() { return 1; }
Ifc2x3::Type::Enum IfcSelectHelperEntity::type() const { return _type; }
bool IfcSelectHelperEntity::is(Ifc2x3::Type::Enum t) const { return _type == t; }
IfcSchema::Type::Enum IfcSelectHelperEntity::type() const { return _type; }
bool IfcSelectHelperEntity::is(IfcSchema::Type::Enum t) const { return _type == t; }
std::string IfcSelectHelperEntity::toString(bool upper) {
std::stringstream ss;
std::string dt = datatype();
@@ -326,33 +320,33 @@ std::string IfcSelectHelperEntity::toString(bool upper) {
unsigned int IfcSelectHelperEntity::id() { throw IfcParse::IfcException("Invalid cast"); }
bool IfcSelectHelperEntity::isWritable() { throw IfcParse::IfcException("Invalid cast"); }
IfcSelectHelper::IfcSelectHelper(const std::string& v, Ifc2x3::Type::Enum t) {
IfcSelectHelper::IfcSelectHelper(const std::string& v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(const char* const v, Ifc2x3::Type::Enum t) {
IfcSelectHelper::IfcSelectHelper(const char* const v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set<std::string>(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(int v, Ifc2x3::Type::Enum t) {
IfcSelectHelper::IfcSelectHelper(int v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(double v, Ifc2x3::Type::Enum t) {
IfcSelectHelper::IfcSelectHelper(double v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
IfcSelectHelper::IfcSelectHelper(bool v, Ifc2x3::Type::Enum t) {
IfcSelectHelper::IfcSelectHelper(bool v, IfcSchema::Type::Enum t) {
IfcWriteArgument* a = new IfcWriteArgument(0);
a->set(v);
this->entity = new IfcSelectHelperEntity(t,a);
}
bool IfcSelectHelper::is(Ifc2x3::Type::Enum t) const { return entity->is(t); }
Ifc2x3::Type::Enum IfcSelectHelper::type() const { return entity->type(); }
bool IfcSelectHelper::is(IfcSchema::Type::Enum t) const { return entity->is(t); }
IfcSchema::Type::Enum IfcSelectHelper::type() const { return entity->type(); }
EntityBuffer* EntityBuffer::i = 0;
EntityBuffer* EntityBuffer::instance() {
+14 -13
View File
@@ -33,6 +33,7 @@
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcException.h"
namespace IfcWrite {
@@ -136,18 +137,18 @@ namespace IfcWrite {
/// Proper memory management is difficult for now, so beware.
class IfcSelectHelperEntity : public IfcAbstractEntity {
private:
Ifc2x3::Type::Enum _type;
IfcSchema::Type::Enum _type;
IfcWriteArgument* arg;
public:
// FIXME: Make this a non-pointer argument and implement a copy constructor
IfcSelectHelperEntity(Ifc2x3::Type::Enum t, IfcWriteArgument* a) : _type(t), arg(a) {}
IfcEntities getInverse(Ifc2x3::Type::Enum,int,const std::string &);
IfcEntities getInverse(Ifc2x3::Type::Enum);
IfcSelectHelperEntity(IfcSchema::Type::Enum t, IfcWriteArgument* a) : _type(t), arg(a) {}
IfcEntities getInverse(IfcSchema::Type::Enum,int,const std::string &);
IfcEntities getInverse(IfcSchema::Type::Enum);
std::string datatype();
ArgumentPtr getArgument(unsigned int i);
unsigned int getArgumentCount();
Ifc2x3::Type::Enum type() const;
bool is(Ifc2x3::Type::Enum t) const;
IfcSchema::Type::Enum type() const;
bool is(IfcSchema::Type::Enum t) const;
std::string toString(bool upper = false);
unsigned int id();
bool isWritable();
@@ -159,13 +160,13 @@ namespace IfcWrite {
/// Proper memory management is difficult for now, so beware.
class IfcSelectHelper : public IfcUtil::IfcBaseClass {
public:
IfcSelectHelper(const std::string& v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcText);
IfcSelectHelper(const char* const v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcText);
IfcSelectHelper(int v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcInteger);
IfcSelectHelper(double v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcReal);
IfcSelectHelper(bool v, Ifc2x3::Type::Enum t=Ifc2x3::Type::IfcBoolean);
bool is(Ifc2x3::Type::Enum t) const;
Ifc2x3::Type::Enum type() const;
IfcSelectHelper(const std::string& v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcText);
IfcSelectHelper(const char* const v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcText);
IfcSelectHelper(int v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcInteger);
IfcSelectHelper(double v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcReal);
IfcSelectHelper(bool v, IfcSchema::Type::Enum t=IfcSchema::Type::IfcBoolean);
bool is(IfcSchema::Type::Enum t) const;
IfcSchema::Type::Enum type() const;
};
/// A helper class for the creation of IFC GlobalIds.
-111
View File
@@ -1,111 +0,0 @@
/********************************************************************************
* *
* 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 examples exposes the IfcOpenShell API through a command-based stdin *
* interface *
* *
********************************************************************************/
#include <iostream>
#include "../ifcgeom/IfcGeomObjects.h"
#if defined(WIN32) && !defined(__CYGWIN__)
#include <io.h>
#include <fcntl.h>
#endif
#define PRODUCT ("IfcOpenShell-0.2.3")
#define ACK ("y")
#define NEG ("n")
#define CONFIRM ("ok")
#define CLOSED ("No opened file")
#define QUIT ("Bye :)")
#define UNKNOWN ("Unknown command")
void send_msg(const char* c) {
std::cout.write(c,strlen(c));
std::cout.flush();
}
void send_msg(const std::string& s) {
std::cout << s << std::flush;
}
int main ( int argc, char** argv ) {
#if defined(WIN32) && !defined(__CYGWIN__)
_setmode(_fileno(stdout), _O_BINARY);
std::cout.setf(std::ios_base::binary);
#endif
bool has_more = false;
send_msg(PRODUCT);
const IfcGeomObjects::IfcGeomObject* ifc_geom = 0;
while (1) {
std::string command;
std::cin >> command;
if ( command == "load" ) {
std::string fn;
std::getline(std::cin,fn);
fn = fn.erase(0,fn.find_first_not_of(" "));
has_more = IfcGeomObjects::Init(fn.c_str(),true,0,&std::cerr);
send_msg(has_more ? ACK : NEG);
} else if ( command == "loadstdin" ) {
send_msg(CONFIRM);
int len;
std::cin >> len;
send_msg(CONFIRM);
has_more = IfcGeomObjects::Init(std::cin,len,true,0,&std::cerr);
send_msg(has_more ? ACK : NEG);
} else if ( command == "get" ) {
if ( ! has_more ) send_msg(CLOSED);
else {
ifc_geom = IfcGeomObjects::Get();
const int vcount = ifc_geom->mesh->verts.size() / 3;
std::cout.write((char*)&vcount,sizeof(int));
std::cout.write((char*)&ifc_geom->mesh->verts[0],sizeof(float)*vcount*3);
const int fcount = ifc_geom->mesh->faces.size() / 3;
std::cout.write((char*)&fcount,sizeof(int));
std::cout.write((char*)&ifc_geom->mesh->faces[0],sizeof(int)*fcount*3);
std::cout.flush();
}
} else if ( command == "type" ) {
if ( ifc_geom ) send_msg(ifc_geom->type);
else send_msg(CLOSED);
} else if ( command == "guid" ) {
if ( ifc_geom ) send_msg(ifc_geom->guid);
else send_msg(CLOSED);
} else if ( command == "next" ) {
if ( !has_more ) send_msg(CLOSED);
else {
has_more = IfcGeomObjects::Next();
if ( ! has_more )
IfcGeomObjects::CleanUp();
send_msg(has_more ? ACK : NEG);
}
} else if ( command == "quit" || command == "exit" ) {
send_msg(QUIT);
break;
} else {
send_msg(UNKNOWN);
}
}
return 0;
}
+8 -5
View File
@@ -15,8 +15,10 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON)
SWIG_ADD_MODULE(IfcImport python IfcPython.i)
SWIG_LINK_LIBRARIES(IfcImport ${PYTHON_LIBRARIES} IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet)
SWIG_ADD_MODULE(ifc_wrapper python IfcPython.i)
SWIG_LINK_LIBRARIES(ifc_wrapper ${PYTHON_LIBRARIES} IfcParse IfcGeom TKernel TKMath TKBRep TKGeomBase TKGeomAlgo TKG3d TKG2d TKShHealing TKTopAlgo TKMesh TKPrim TKBool TKBO TKFillet TKOffset)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/ifcopenshell.py" DESTINATION "${CMAKE_BINARY_DIR}/ifcwrap")
# To install IfcPython let's get the site-packackes dir from python
EXECUTE_PROCESS(COMMAND python -c "from distutils.sysconfig import get_python_lib as x; print (x())"
@@ -27,10 +29,11 @@ STRING(REPLACE "\r" "" python_package_dir "${python_package_dir}")
STRING(REPLACE "\n" "" python_package_dir "${python_package_dir}")
INSTALL(FILES
"${CMAKE_BINARY_DIR}/ifcwrap/IfcImport.py"
"${CMAKE_BINARY_DIR}/ifcwrap/ifcopenshell.py"
"${CMAKE_BINARY_DIR}/ifcwrap/ifc_wrapper.py"
"${CMAKE_BINARY_DIR}/ifcwrap/_ifc_wrapper.so"
DESTINATION "${python_package_dir}")
INSTALL(TARGETS _IfcImport DESTINATION "${python_package_dir}")
ENDIF(PYTHONLIBS_FOUND)
ENDIF(SWIG_FOUND)
ENDIF(SWIG_FOUND)
+168 -102
View File
@@ -1,127 +1,193 @@
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* *
* 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. *
* *
* 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/>. *
* *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
%include "std_vector.i"
%include "std_string.i"
%include "exception.i"
%typemap(out) const double* {
// This is only used for RGB colours, hence the size of 3
$result = PyTuple_New(3);
for (int i = 0; i < 3; ++i) {
PyTuple_SetItem($result, i, PyFloat_FromDouble($1[i]));
%ignore IfcParse::IfcUntypedEntity::is;
%ignore IfcParse::IfcUntypedEntity::type;
%ignore IfcParse::IfcUntypedEntity::getArgument;
%ignore IfcParse::IfcUntypedEntity::IfcUntypedEntity(IfcAbstractEntity);
%ignore IfcParse::IfcFile::Init;
%ignore IfcParse::IfcFile::EntityById;
%ignore IfcParse::IfcFile::EntityByGuid;
%ignore IfcParse::IfcFile::AddEntity;
%ignore operator<<;
%rename("by_type") EntitiesByType;
%rename("__len__") getArgumentCount;
%rename("get_argument_type") getArgumentType;
%rename("get_argument_name") getArgumentName;
%rename("get_argument_index") getArgumentIndex;
%rename("_set_argument") setArgument;
%rename("__repr__") toString;
%rename("entity_instance") IfcUntypedEntity;
%rename("file") IfcFile;
%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) IfcEntities {
$1 = (PySequence_Check($input) && !PyUnicode_Check($input) && !PyString_Check($input)) ? 1 : 0;
}
%typemap(in) IfcEntities {
if (PySequence_Check($input)) {
// $1 = std::make_shared<IfcEntityList>();
$1 = SHARED_PTR<IfcEntityList>(new IfcEntityList());
for(Py_ssize_t i = 0; i < PySequence_Size($input); ++i) {
PyObject* obj = PySequence_GetItem($input, i);
if (obj) {
void *arg = 0;
int res = SWIG_ConvertPtr(obj, &arg, SWIGTYPE_p_IfcParse__IfcUntypedEntity, 0);
if (!SWIG_IsOK(res)) {
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "Entity__set_argument" "', argument " "3"" of type '" "IfcParse::IfcUntypedEntity *""'");
} else {
$1->push(reinterpret_cast<IfcParse::IfcUntypedEntity*>(arg));
}
}
}
} else {
SWIG_exception(SWIG_RuntimeError,"Unknown argument type");
}
}
%typemap(out) IfcEntities {
const unsigned size = $1 ? $1->Size() : 0;
$result = PyList_New(size);
for (unsigned i = 0; i < size; ++i) {
PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr((*$1)[i]), SWIGTYPE_p_IfcParse__IfcUntypedEntity, 0);
PyList_SetItem($result,i,o);
}
}
%typemap(out) IfcUtil::ArgumentType {
const char* strs[] = {"INT", "BOOL", "DOUBLE", "STRING", "VECTOR_INT", "VECTOR_DOUBLE", "VECTOR_STRING", "ENTITY", "ENTITY_LIST", "ENTITY_LIST_LIST", "ENUMERATION", "DERIVED", "UNKNOWN"};
$result = SWIG_Python_str_FromChar(strs[$1]);
}
%typemap(out) std::pair<IfcUtil::ArgumentType,ArgumentPtr> {
const Argument& arg = *($1.second);
const IfcUtil::ArgumentType type = $1.first;
if (arg.isNull() || type == IfcUtil::Argument_DERIVED) {
Py_INCREF(Py_None);
$result = Py_None;
} else {
switch(type) {
case IfcUtil::Argument_INT:
$result = PyInt_FromLong((int)arg);
break;
case IfcUtil::Argument_BOOL:
$result = PyBool_FromLong((bool)arg);
break;
case IfcUtil::Argument_DOUBLE:
$result = PyFloat_FromDouble(arg);
break;
case IfcUtil::Argument_ENUMERATION:
case IfcUtil::Argument_STRING: {
const std::string s = arg;
$result = PyString_FromString(s.c_str());
break; }
case IfcUtil::Argument_VECTOR_INT: {
const std::vector<int> v = arg;
const unsigned size = v.size();
$result = PyList_New(size);
for (unsigned int i = 0; i < size; ++i) {
PyList_SetItem($result,i,PyInt_FromLong(v[i]));
}
break; }
case IfcUtil::Argument_VECTOR_DOUBLE: {
const std::vector<double> v = arg;
const unsigned size = v.size();
$result = PyList_New(size);
for (unsigned int i = 0; i < size; ++i) {
PyList_SetItem($result,i,PyFloat_FromDouble(v[i]));
}
break; }
case IfcUtil::Argument_VECTOR_STRING: {
const std::vector<std::string> v = arg;
const unsigned size = v.size();
$result = PyList_New(size);
for (unsigned int i = 0; i < size; ++i) {
PyList_SetItem($result,i,PyString_FromString(v[i].c_str()));
}
break; }
case IfcUtil::Argument_ENTITY: {
IfcUtil::IfcSchemaEntity e = arg;
$result = SWIG_NewPointerObj(SWIG_as_voidptr(e), SWIGTYPE_p_IfcParse__IfcUntypedEntity, 0);
break; }
case IfcUtil::Argument_ENTITY_LIST: {
IfcEntities es = arg;
const unsigned size = es->Size();
$result = PyList_New(size);
for (unsigned i = 0; i < size; ++i) {
PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr((*es)[i]), SWIGTYPE_p_IfcParse__IfcUntypedEntity, 0);
PyList_SetItem($result,i,o);
}
break; }
case IfcUtil::Argument_UNKNOWN:
default:
SWIG_exception(SWIG_RuntimeError,"Unknown argument type");
break;
}
}
}
%exception {
try {
$action
} catch(std::runtime_error& e) {
SWIG_exception(SWIG_RuntimeError, e.what());
} catch(...) {
SWIG_exception(SWIG_RuntimeError, "An unknown error occurred");
} catch(::IfcParse::IfcException& e) {
SWIG_exception(SWIG_RuntimeError,e.what());
}
}
%include "Interface.h"
%module IfcImport %{
#include "Interface.h"
using namespace IfcGeomObjects;
%module ifc_wrapper %{
#include "../ifcparse/IfcException.h"
#include "Interface.h"
using namespace IfcParse;
%}
%extend IfcGeomObjects::IfcRepresentationTriangulation {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
id = property(id)
verts = property(verts)
faces = property(faces)
edges = property(edges)
normals = property(normals)
material_ids = property(material_ids)
materials = property(materials)
def __repr__(self): return "RepresentationTriangulation #%d"%self.id
%}
};
%include "Interface.h"
%extend IfcGeomObjects::IfcRepresentationBrepData {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
id = property(id)
brep_data = property(brep_data)
def __repr__(self): return "RepresentationBrepData #%d"%self.id
%}
};
%extend IfcParse::IfcFile {
IfcParse::IfcUntypedEntity* by_id(unsigned id) {
return (IfcUntypedEntity*) $self->EntityById(id);
}
IfcParse::IfcUntypedEntity* by_guid(const std::string& guid) {
return (IfcUntypedEntity*) $self->EntityByGuid(guid);
}
void add(IfcParse::IfcUntypedEntity* e) {
$self->AddEntity(e);
}
void write(const std::string& fn) {
std::ofstream f(fn.c_str());
f << (*$self);
}
}
%extend IfcGeomObjects::IfcObject {
%extend IfcParse::IfcUntypedEntity {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
id = property(id)
parent_id = property(parent_id)
name = property(name)
type = property(type)
guid = property(guid)
matrix = property(matrix)
def __repr__(self): return "Object #%d"%self.id
%}
};
%extend IfcGeomObjects::IfcGeomObject {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
mesh = property(mesh)
def __repr__(self): return "GeomObject #%d"%self.id
%}
};
%extend IfcGeomObjects::IfcGeomBrepDataObject {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
mesh = property(mesh)
def __repr__(self): return "GeomBrepDataObject #%d"%self.id
%}
};
%extend IfcGeomObjects::Material {
%pythoncode %{
if _newclass:
# Hide the getters with read-only property implementations
has_diffuse = property(hasDiffuse)
has_specular = property(hasSpecular)
has_transparency = property(hasTransparency)
has_specularity = property(hasSpecularity)
diffuse = property(diffuse)
specular = property(specular)
transparency = property(transparency)
specularity = property(specularity)
name = property(name)
def __repr__(self): return "Material"
%}
};
set_argument = lambda self,x,y: self._set_argument(x) if y is None else self._set_argument(x,y)
%}
}
namespace std {
%template(IntVector) vector<int>;
%template(FloatVector) vector<float>;
%template(MaterialVector) vector<IfcGeomObjects::Material>;
};
%template(ints) vector<int>;
%template(doubles) vector<double>;
%template(strings) vector<string>;
};
+119 -135
View File
@@ -1,146 +1,130 @@
/********************************************************************************
* *
* 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/>. *
* *
********************************************************************************/
#define IFCUNTYPEDENTITY_H
namespace IfcGeomObjects {
#include <map>
#include <fstream>
const int WELD_VERTICES = 1;
const int USE_WORLD_COORDS = 2;
const int CONVERT_BACK_UNITS = 3;
const int USE_BREP_DATA = 4;
const int SEW_SHELLS = 5;
const int FASTER_BOOLEANS = 6;
const int FORCE_CCW_FACE_ORIENTATION = 7;
const int DISABLE_OPENING_SUBTRACTIONS = 8;
const int DISABLE_TRIANGULATION = 9;
namespace IfcParse { class IfcUntypedEntity; }
class Material {
#include "../ifcparse/IfcUtil.h"
#include "../ifcparse/Ifc2x3.h"
#include "../ifcgeom/IfcGeom.h"
namespace IfcParse {
class IfcUntypedEntity : public IfcUtil::IfcBaseEntity {
private:
void* style;
IfcSchema::Type::Enum _type;
public:
bool hasDiffuse() const;
bool hasSpecular() const;
bool hasTransparency() const;
bool hasSpecularity() const;
const double* diffuse() const;
const double* specular() const;
double transparency() const;
double specularity() const;
const std::string name() const;
IfcUntypedEntity(const std::string& s);
bool is(IfcSchema::Type::Enum v) const;
IfcSchema::Type::Enum type() const;
bool is_a(const std::string& s) const;
std::string is_a() const;
unsigned int id() const;
unsigned int getArgumentCount() const;
IfcUtil::ArgumentType getArgumentType(unsigned int i) const;
ArgumentPtr getArgument(unsigned int i) const;
ArgumentPtr getArgument(const std::string& a) const;
const char* getArgumentName(unsigned int i) const;
unsigned getArgumentIndex(const std::string& a) const;
IfcEntities get_inverse(const std::string& a);
void setArgument(unsigned int i);
void setArgument(unsigned int i, int v);
void setArgument(unsigned int i, bool v);
void setArgument(unsigned int i, double v);
void setArgument(unsigned int i, const std::string& v);
void setArgument(unsigned int i, const std::vector<int>& v);
void setArgument(unsigned int i, const std::vector<double>& v);
void setArgument(unsigned int i, const std::vector<std::string>& v);
void setArgument(unsigned int i, IfcUntypedEntity* v);
void setArgument(unsigned int i, IfcEntities v);
std::string toString();
std::pair<IfcUtil::ArgumentType,ArgumentPtr> get_argument(unsigned i);
std::pair<IfcUtil::ArgumentType,ArgumentPtr> get_argument(const std::string& a);
bool is_valid();
};
}
typedef IfcUtil::IfcSchemaEntity IfcEntity;
typedef std::map<IfcSchema::Type::Enum,IfcEntities> MapEntitiesByType;
typedef std::map<unsigned int,IfcEntity> MapEntityById;
typedef std::map<std::string,IfcSchema::IfcRoot::ptr> MapEntityByGuid;
typedef std::map<unsigned int,IfcEntities> MapEntitiesByRef;
typedef std::map<unsigned int,unsigned int> MapOffsetById;
namespace IfcParse {
class IfcSpfStream;
class Tokens;
class IfcFile {
private:
MapEntityById byid;
MapEntitiesByType bytype;
MapEntitiesByRef byref;
MapEntityByGuid byguid;
MapOffsetById offsets;
unsigned int lastId;
unsigned int MaxId;
std::string _filename;
std::string _timestamp;
std::string _author;
std::string _author_email;
std::string _author_organisation;
public:
IfcParse::IfcSpfStream* stream;
IfcParse::Tokens* tokens;
bool Init(const std::string& fn);
IfcEntities EntitiesByType(const std::string& t);
IfcEntity EntityById(int id);
IfcSchema::IfcRoot::ptr EntityByGuid(const std::string& guid);
void AddEntity(IfcUtil::IfcSchemaEntity e);
IfcFile();
~IfcFile();
std::vector<int> entity_names() const {
std::vector<int> keys;
keys.reserve(byid.size());
for (MapEntityById::const_iterator it = byid.begin(); it != byid.end(); ++ it) {
keys.push_back(it->first);
}
return keys;
}
};
class IfcRepresentationTriangulation {
private:
int _id;
std::vector<float> _verts;
std::vector<int> _faces;
std::vector<int> _edges;
std::vector<float> _normals;
std::vector<int> _material_ids;
std::vector<Material> _materials;
IfcParse::IfcFile* open(const std::string& s) {
IfcParse::IfcFile* f = new IfcParse::IfcFile();
f->Init(s);
IfcEntities projects = f->EntitiesByType("IfcProject");
if (projects->Size() == 1) {
double unit_magnitude;
std::string unit_name;
IfcGeom::initialize_units_and_precision((IfcSchema::IfcProject*)*projects->begin(), unit_magnitude, unit_name);
}
return f;
}
IfcRepresentationTriangulation();
IfcRepresentationTriangulation(const IfcRepresentationTriangulation&);
IfcRepresentationTriangulation& operator=(const IfcRepresentationTriangulation&);
virtual ~IfcRepresentationTriangulation();
public:
int id() const;
const std::vector<float>& verts() const;
const std::vector<int>& faces() const;
const std::vector<int>& edges() const;
const std::vector<float>& normals() const;
const std::vector<int>& material_ids() const;
const std::vector<Material>& materials() const;
};
std::string create_shape(IfcParse::IfcUntypedEntity* e, unsigned int settings = 0) {
if (!e->is(IfcSchema::Type::IfcProduct)) throw IfcException("Entity is not an IfcProduct");
IfcSchema::IfcProduct* ifc_product = (IfcSchema::IfcProduct*) e;
return IfcGeom::create_brep_data(ifc_product, settings);
}
class IfcRepresentationBrepData {
private:
int _id;
std::string _brep_data;
void clean() {
IfcGeom::Cache::Purge();
}
IfcRepresentationBrepData();
IfcRepresentationBrepData(const IfcRepresentationBrepData&);
IfcRepresentationBrepData& operator=(const IfcRepresentationBrepData&);
virtual ~IfcRepresentationBrepData();
public:
int id() const;
const std::string& brep_data() const;
};
const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0;
const int DISABLE_OBJECT_PLACEMENT = 1 << 1;
const int SEW_SHELLS = 1 << 2;
const int CONVERT_TO_METERS = 1 << 3;
}
class IfcObject {
private:
int _id;
int _parent_id;
std::string _name;
std::string _type;
std::string _guid;
std::vector<float> _matrix;
IfcObject();
IfcObject(const IfcObject& other);
IfcObject& operator=(const IfcObject& other);
virtual ~IfcObject() {}
public:
int id() const;
int parent_id() const;
const std::string& name() const;
const std::string& type() const;
const std::string& guid() const;
const std::vector<float>& matrix() const;
};
class IfcGeomObject : public IfcObject {
private:
IfcRepresentationTriangulation* _mesh;
IfcGeomObject();
IfcGeomObject(const IfcGeomObject& other);
IfcGeomObject& operator=(const IfcGeomObject& other);
virtual ~IfcGeomObject();
public:
const IfcRepresentationTriangulation& mesh() const;
};
class IfcGeomBrepDataObject : public IfcObject {
private:
IfcRepresentationBrepData* _mesh;
IfcGeomBrepDataObject();
IfcGeomBrepDataObject(const IfcGeomBrepDataObject& other);
IfcGeomBrepDataObject& operator=(const IfcGeomBrepDataObject& other);
virtual ~IfcGeomBrepDataObject();
public:
const IfcRepresentationBrepData& mesh() const;
};
void Settings(int setting, bool value);
bool Init(const std::string fn);
const IfcGeomObject* Get();
const IfcGeomBrepDataObject* GetBrepData();
const IfcObject* GetObject(int id);
bool Next();
int Progress();
const std::string GetLog();
bool CleanUp();
};
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);
+116
View File
@@ -0,0 +1,116 @@
import string
import functools
import ifc_wrapper
if hasattr(functools, 'reduce'): reduce = functools.reduce
class entity_instance(object):
def __init__(self, e):
super(entity_instance,self).__setattr__('wrapped_data', e)
def __getattr__(self, name):
try: return entity_instance.wrap_value(self.wrapped_data.get_argument(self.wrapped_data.get_argument_index(name)))
except:
try: return entity_instance.wrap_value(self.wrapped_data.get_inverse(name))
except: raise AttributeError("entity instance of type '%s' has no attribute '%s'"%(self.wrapped_data.is_a(), name))
@staticmethod
def map_value(v):
if isinstance(v, entity_instance): return v.wrapped_data
elif isinstance(v, (tuple, list)) and len(v):
classes = list(map(type, v))
if float in classes: return ifc_wrapper.doubles(v)
elif int in classes: return ifc_wrapper.ints(v)
elif str in classes: return ifc_wrapper.strings(v)
elif entity_instance in classes: return list(map(lambda e: e.wrapped_data, v))
return v
@staticmethod
def wrap_value(v):
wrap = lambda e: entity_instance(e)
if isinstance(v, ifc_wrapper.entity_instance): return wrap(v)
elif isinstance(v, (tuple, list)) and len(v):
classes = list(map(type, v))
if ifc_wrapper.entity_instance in classes: return list(map(wrap, v))
return v
def attribute_type(self, attr):
attr_idx = attr if isinstance(attr, int) else self.wrapped_data.get_argument_index(attr)
return self.wrapped_data.get_argument_type(attr_idx)
def attribute_name(self, attr_idx):
return self.wrapped_data.get_argument_name(attr_idx)
def __setattr__(self, key, value):
self[self.wrapped_data.get_argument_index(key)] = value
def __getitem__(self, key):
return entity_instance.wrap_value(self.wrapped_data.get_argument(key))
def __setitem__(self, idx, value):
self.wrapped_data.set_argument(idx, entity_instance.map_value(value))
def __len__(self): return len(self.wrapped_data)
def __repr__(self): return repr(self.wrapped_data)
def is_a(self, *args): return self.wrapped_data.is_a(*args)
def id(self): return self.wrapped_data.id()
class file:
instances = []
def __init__(self, f=None):
self.wrapped_data = f or ifc_wrapper.file()
def create_entity(self,type,*args,**kwargs):
e = entity_instance(ifc_wrapper.entity_instance(type))
attrs = list(enumerate(args)) + \
[(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
for idx, arg in attrs: e[idx] = arg
self.wrapped_data.add(e.wrapped_data)
self.instances.append(e)
return e
def __getattr__(self,attr):
if attr[0:6] == 'create': return functools.partial(self.create_entity,attr[6:])
def __getitem__(self, key):
if isinstance(key, int):
return entity_instance(self.wrapped_data.by_id(key))
elif isinstance(key, str):
return entity_instance(self.wrapped_data.by_guid(key))
def by_type(self, type):
return [entity_instance(e) for e in self.wrapped_data.by_type(type)]
def write(self, fn):
self.wrapped_data.write(fn)
def __iter__(self):
return iter(self[id] for id in self.wrapped_data.entity_names())
class guid:
chars = string.digits + string.ascii_uppercase + string.ascii_lowercase + '_$'
@staticmethod
def compress(g):
bs = [int(g[i:i+2], 16) for i in range(0, len(g), 2)]
def b64(v, l=4):
return ''.join([guid.chars[(v // (64**i))%64] for i in range(l)][::-1])
return ''.join([b64(bs[0], 2)] + [b64((bs[i] << 16) + (bs[i+1] << 8) + bs[i+2]) for i in range(1,16,3)])
@staticmethod
def expand(g):
def b64(v):
return reduce(lambda a, b: a * 64 + b, map(lambda c: guid.chars.index(c), v))
bs = [b64(g[0:2])]
for i in range(5):
d = b64(g[2+4*i:6+4*i])
bs += [(d >> (8*(2-j)))%256 for j in range(3)]
return ''.join(['%02x'%b for b in bs])
@staticmethod
def split(g):
return '{%s-%s-%s-%s-%s}'%(g[:8], g[8:12], g[12:16], g[16:20], g[20:])
def open(fn=None):
return file(ifc_wrapper.open(fn)) if fn else file()
def create_shape(inst, settings): return ifc_wrapper.create_shape(inst.wrapped_data, settings)
def clean(): return ifc_wrapper.clean()
def create_entity(type,*args,**kwargs):
e = entity_instance(ifc_wrapper.entity_instance(type))
attrs = list(enumerate(args)) + \
[(e.wrapped_data.get_argument_index(name), arg) for name, arg in kwargs.items()]
for idx, arg in attrs: e[idx] = arg
return e
DISABLE_OPENING_SUBTRACTIONS = ifc_wrapper.DISABLE_OPENING_SUBTRACTIONS
DISABLE_OBJECT_PLACEMENT = ifc_wrapper.DISABLE_OBJECT_PLACEMENT
SEW_SHELLS = ifc_wrapper.SEW_SHELLS
CONVERT_TO_METERS = ifc_wrapper.CONVERT_TO_METERS
+1 -2
View File
@@ -63,8 +63,7 @@ scn.render.resolution_x = 2048
scn.render.resolution_y = 2048
scn.world.horizon_color = (1,1,1)
scn.world.ambient_color = (0.05,0.05,0.05)
try: scn.render.color_mode = 'RGBA'
except: scn.render.image_settings.color_mode = 'RGBA'
scn.render.color_mode = 'RGBA'
for m in bpy.data.materials: m.specular_intensity = 0
def material(name,settings):
@@ -1,410 +0,0 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
FILE_NAME('Project Number','2013-08-05T11:05:45',(''),(''),'','','');
FILE_SCHEMA(('IFC2X3'));
ENDSEC;
DATA;
#1= IFCORGANIZATION($,'Autodesk Revit Architecture 2014 (ENU)',$,$,$);
#5= IFCAPPLICATION(#1,'2014','Autodesk Revit Architecture 2014 (ENU)','Revit');
#6= IFCCARTESIANPOINT((0.,0.,0.));
#9= IFCCARTESIANPOINT((0.,0.));
#11= IFCDIRECTION((1.,0.,0.));
#13= IFCDIRECTION((-1.,0.,0.));
#15= IFCDIRECTION((0.,1.,0.));
#17= IFCDIRECTION((0.,-1.,0.));
#19= IFCDIRECTION((0.,0.,1.));
#21= IFCDIRECTION((0.,0.,-1.));
#23= IFCDIRECTION((1.,0.));
#25= IFCDIRECTION((-1.,0.));
#27= IFCDIRECTION((0.,1.));
#29= IFCDIRECTION((0.,-1.));
#31= IFCAXIS2PLACEMENT3D(#6,$,$);
#32= IFCLOCALPLACEMENT(#556,#31);
#35= IFCPERSON($,'','dave.mills',$,$,$,$,$);
#37= IFCORGANIZATION($,'','',$,$);
#38= IFCPERSONANDORGANIZATION(#35,#37,$);
#41= IFCOWNERHISTORY(#38,#5,$,.NOCHANGE.,$,$,$,1375697133);
#42= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#43= IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
#44= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#45= IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
#46= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#47= IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#48= IFCMEASUREWITHUNIT(IFCRATIOMEASURE(0.0174532925199433),#46);
#49= IFCCONVERSIONBASEDUNIT(#47,.PLANEANGLEUNIT.,'DEGREE',#48);
#50= IFCSIUNIT(*,.MASSUNIT.,.KILO.,.GRAM.);
#51= IFCSIUNIT(*,.TIMEUNIT.,$,.SECOND.);
#52= IFCSIUNIT(*,.THERMODYNAMICTEMPERATUREUNIT.,$,.KELVIN.);
#53= IFCDERIVEDUNITELEMENT(#50,1);
#54= IFCDERIVEDUNITELEMENT(#52,-1);
#55= IFCDERIVEDUNITELEMENT(#51,-3);
#56= IFCDERIVEDUNIT((#53,#54,#55),.THERMALTRANSMITTANCEUNIT.,$);
#58= IFCDERIVEDUNITELEMENT(#43,3);
#59= IFCDERIVEDUNITELEMENT(#51,-1);
#60= IFCDERIVEDUNIT((#58,#59),.VOLUMETRICFLOWRATEUNIT.,$);
#62= IFCSIUNIT(*,.POWERUNIT.,$,.WATT.);
#63= IFCUNITASSIGNMENT((#42,#44,#45,#49,#50,#51,#52,#56,#60,#62));
#65= IFCAXIS2PLACEMENT3D(#6,$,$);
#66= IFCDIRECTION((2.,6.12303176911189E-17,1.));
#68= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.00000000000000E-5,#65,#66);
#71= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Axis','Model',*,*,*,*,#68,$,.GRAPH_VIEW.,$);
#73= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#68,$,.MODEL_VIEW.,$);
#74= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Box','Model',*,*,*,*,#68,$,.MODEL_VIEW.,$);
#75= IFCGEOMETRICREPRESENTATIONSUBCONTEXT('FootPrint','Model',*,*,*,*,#68,$,.MODEL_VIEW.,$);
#76= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Annotation',3,1.00000000000000E-5,#65,#66);
#77= IFCGEOMETRICREPRESENTATIONSUBCONTEXT($,'Annotation',*,*,*,*,#76,0.01,.PLAN_VIEW.,$);
#79= IFCPROJECT('0jI6kz9rj7ZAQfwqcKYFL$',#41,'Project Number',$,$,'Project Name','Project Status',(#68,#76),#63);
#85= IFCPOSTALADDRESS($,$,$,$,(''),$,'','','','');
#89= IFCBUILDING('0jI6kz9rj7ZAQfwqcKYFL_',#41,'',$,$,#32,$,'',.ELEMENT.,$,$,#85);
#95= IFCAXIS2PLACEMENT3D(#6,$,$);
#96= IFCLOCALPLACEMENT(#32,#95);
#98= IFCBUILDINGSTOREY('0jI6kz9rj7ZAQfwqbhTmku',#41,'Level 0',$,$,#96,$,'Level 0',.ELEMENT.,0.);
#100= IFCCARTESIANPOINT((0.,0.,4000.));
#102= IFCAXIS2PLACEMENT3D(#100,$,$);
#663= IFCRELDEFINESBYPROPERTIES('0QsHEvgNPBth0JuOfnWkED',#41,$,$,(#98),#597);
#599= IFCRELCONTAINEDINSPATIALSTRUCTURE('3Zu5Bv0LOHrPC10066FoQQ',#41,$,$,(#251),#98);
#106= IFCAXIS2PLACEMENT3D(#6,$,$);
#107= IFCLOCALPLACEMENT(#96,#106);
#109= IFCCARTESIANPOINT((884.601287043893,-1276.36737361194));
#111= IFCCARTESIANPOINT((934.686713370143,-1276.36737361194));
#113= IFCCARTESIANPOINT((1602.61583383912,-389.995493084105));
#115= IFCCARTESIANPOINT((103.386511820466,2683.88014525904));
#117= IFCCARTESIANPOINT((-2181.84467363903,898.461866814632));
#119= IFCCARTESIANPOINT((-947.471090801113,-1002.30676565574));
#121= IFCCARTESIANPOINT((-395.974581633486,362.694993890036));
#123= IFCPOLYLINE((#109,#111,#113,#115,#117,#119,#121,#109));
#125= IFCARBITRARYCLOSEDPROFILEDEF(.AREA.,'Beam and Block 225mm Susp Ground',#123);
#126= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#128= IFCAXIS2PLACEMENT3D(#126,#21,#17);
#129= IFCEXTRUDEDAREASOLID(#125,#128,#19,1157.56227415131);
#130= IFCCARTESIANPOINT((3992.65488561843,3225.15171994683,279.187424717102));
#132= IFCDIRECTION((0.0864098993331847,-0.401659996929606,0.9117031184348));
#134= IFCDIRECTION((0.996259669612912,0.034837704425333,-0.0790759448450934));
#136= IFCAXIS2PLACEMENT3D(#130,#132,#134);
#137= IFCPLANE(#136);
#138= IFCCARTESIANPOINT((103.386511820467,2683.88014525904));
#140= IFCCARTESIANPOINT((-395.974581633486,362.694993890035));
#142= IFCCARTESIANPOINT((-2181.84467363903,898.46186681463));
#144= IFCPOLYLINE((#138,#140,#142,#138));
#146= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#148= IFCAXIS2PLACEMENT3D(#146,#21,#17);
#149= IFCPOLYGONALBOUNDEDHALFSPACE(#137,.F.,#148,#144);
#150= IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE.,#129,#149);
#151= IFCCARTESIANPOINT((5286.89824117145,1774.47765257479,0.));
#153= IFCAXIS2PLACEMENT3D(#151,$,$);
#154= IFCPLANE(#153);
#155= IFCCARTESIANPOINT((103.386511820466,2683.88014525904));
#157= IFCCARTESIANPOINT((1602.61583383912,-389.995493084106));
#159= IFCCARTESIANPOINT((934.686713370143,-1276.36737361194));
#161= IFCCARTESIANPOINT((884.601287043893,-1276.36737361194));
#163= IFCCARTESIANPOINT((-395.974581633486,362.694993890035));
#165= IFCPOLYLINE((#155,#157,#159,#161,#163,#155));
#167= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#169= IFCAXIS2PLACEMENT3D(#167,#21,#17);
#170= IFCPOLYGONALBOUNDEDHALFSPACE(#154,.F.,#169,#165);
#171= IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE.,#150,#170);
#172= IFCCARTESIANPOINT((5221.38385592335,3575.43758748735,279.187424717102));
#174= IFCDIRECTION((0.154049964763331,-0.381287042554964,0.911531019513931));
#176= IFCDIRECTION((0.988063058896757,0.0594468692472838,-0.142117772921897));
#178= IFCAXIS2PLACEMENT3D(#172,#174,#176);
#179= IFCPLANE(#178);
#180= IFCCARTESIANPOINT((-2181.84467363903,898.46186681463));
#182= IFCCARTESIANPOINT((-395.974581633486,362.694993890035));
#184= IFCCARTESIANPOINT((-947.471090801113,-1002.30676565574));
#186= IFCPOLYLINE((#180,#182,#184,#180));
#188= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#190= IFCAXIS2PLACEMENT3D(#188,#21,#17);
#191= IFCPOLYGONALBOUNDEDHALFSPACE(#179,.F.,#190,#186);
#192= IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE.,#171,#191);
#193= IFCCARTESIANPOINT((3992.65488561843,3225.15171994683,-40.8125752828978));
#195= IFCDIRECTION((-0.0864098993331847,0.401659996929606,-0.9117031184348));
#197= IFCDIRECTION((0.996259669612912,0.034837704425333,-0.0790759448450934));
#199= IFCAXIS2PLACEMENT3D(#193,#195,#197);
#200= IFCPLANE(#199);
#201= IFCCARTESIANPOINT((103.386511820467,2683.88014525904));
#203= IFCCARTESIANPOINT((-2181.84467363903,898.46186681463));
#205= IFCCARTESIANPOINT((-395.974581633486,362.694993890035));
#207= IFCPOLYLINE((#201,#203,#205,#201));
#209= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#211= IFCAXIS2PLACEMENT3D(#209,#21,#17);
#212= IFCPOLYGONALBOUNDEDHALFSPACE(#200,.F.,#211,#207);
#213= IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE.,#192,#212);
#214= IFCCARTESIANPOINT((5221.38385592335,3575.43758748735,-40.8125752828978));
#216= IFCDIRECTION((-0.154049964763331,0.381287042554964,-0.911531019513931));
#218= IFCDIRECTION((0.988063058896757,0.0594468692472838,-0.142117772921897));
#220= IFCAXIS2PLACEMENT3D(#214,#216,#218);
#221= IFCPLANE(#220);
#222= IFCCARTESIANPOINT((-2181.84467363903,898.46186681463));
#224= IFCCARTESIANPOINT((-947.471090801113,-1002.30676565574));
#226= IFCCARTESIANPOINT((-395.974581633486,362.694993890035));
#228= IFCPOLYLINE((#222,#224,#226,#222));
#230= IFCCARTESIANPOINT((5307.66722093966,2400.34080546281,837.562274151307));
#232= IFCAXIS2PLACEMENT3D(#230,#21,#17);
#233= IFCPOLYGONALBOUNDEDHALFSPACE(#221,.F.,#232,#228);
#234= IFCBOOLEANCLIPPINGRESULT(.DIFFERENCE.,#213,#233);
#235= IFCCOLOURRGB($,0.752941176470588,0.752941176470588,0.752941176470588);
#236= IFCSURFACESTYLERENDERING(#235,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(128.),.NOTDEFINED.);
#237= IFCSURFACESTYLE('Concrete, Precast',.BOTH.,(#236));
#239= IFCPRESENTATIONSTYLEASSIGNMENT((#237));
#241= IFCSTYLEDITEM(#129,(#239),$);
#244= IFCSHAPEREPRESENTATION(#73,'Body','Clipping',(#234));
#247= IFCPRODUCTDEFINITIONSHAPE($,$,(#244));
#251= IFCSLAB('3HgFLk8TTFhf$2Wq7uxYkv',#41,'Floor:Beam and Block 225mm Susp Ground:217606',$,'Floor:Beam and Block 225mm Susp Ground',#107,#247,'217606',.FLOOR.);
#260= IFCPROPERTYSINGLEVALUE('Height Offset From Level',$,IFCLENGTHMEASURE(0.),$);
#261= IFCPROPERTYSINGLEVALUE('Room Bounding',$,IFCBOOLEAN(.T.),$);
#262= IFCPROPERTYSINGLEVALUE('Structural',$,IFCBOOLEAN(.F.),$);
#263= IFCPROPERTYSINGLEVALUE('Related to Mass',$,IFCBOOLEAN(.F.),$);
#264= IFCPROPERTYSINGLEVALUE('Enable Analytical Model',$,IFCBOOLEAN(.F.),$);
#265= IFCPROPERTYSINGLEVALUE('Curved Edge Condition',$,IFCINTEGER(0),$);
#266= IFCPROPERTYSINGLEVALUE('Perimeter',$,IFCLENGTHMEASURE(13298.5518313399),$);
#267= IFCPROPERTYSINGLEVALUE('Volume',$,IFCVOLUMEMEASURE(2.43360159421361),$);
#268= IFCPROPERTYSINGLEVALUE('Phase Created',$,IFCLABEL('New Construction'),$);
#269= IFCPROPERTYSINGLEVALUE('Area',$,IFCAREAMEASURE(7.60500498191754),$);
#270= IFCPROPERTYSINGLEVALUE('Thickness',$,IFCLENGTHMEASURE(320.),$);
#271= IFCPROPERTYSINGLEVALUE('Level',$,IFCLABEL('Level: Level 0'),$);
#272= IFCPROPERTYSINGLEVALUE('Coarse Scale Fill Pattern',$,IFCLABEL('Solid fill'),$);
#273= IFCPROPERTYSINGLEVALUE('Roughness',$,IFCINTEGER(3),$);
#274= IFCPROPERTYSINGLEVALUE('Assembly Description',$,IFCTEXT(''),$);
#275= IFCPROPERTYSINGLEVALUE('Thermal mass',$,IFCREAL(365368.8),$);
#276= IFCPROPERTYSINGLEVALUE('Coarse Scale Fill Color',$,IFCINTEGER(0),$);
#277= IFCPROPERTYSINGLEVALUE('Structural Material',$,IFCLABEL('Concrete Masonry, Floor Block'),$);
#278= IFCPROPERTYSINGLEVALUE('Heat Transfer Coefficient (U)',$,IFCREAL(0.397589052997394),$);
#279= IFCPROPERTYSINGLEVALUE('Keynote',$,IFCTEXT('E60/130'),$);
#280= IFCPROPERTYSINGLEVALUE('Assembly Code',$,IFCTEXT(''),$);
#281= IFCPROPERTYSINGLEVALUE('Absorptance',$,IFCREAL(0.7),$);
#282= IFCPROPERTYSINGLEVALUE('Thermal Resistance (R)',$,IFCREAL(2.51515979240645),$);
#283= IFCPROPERTYSINGLEVALUE('Function',$,IFCIDENTIFIER('Interior'),$);
#284= IFCPROPERTYSINGLEVALUE('Default Thickness',$,IFCLENGTHMEASURE(320.),$);
#285= IFCPROPERTYSET('16zf0JEeP58uphSUtsukrO',#41,'Constraints',$,(#260,#261,#263,#271));
#290= IFCRELDEFINESBYPROPERTIES('0zCVt71GL9Iv8htsyDhHBl',#41,$,$,(#251),#285);
#294= IFCPROPERTYSET('1FyqoU7Lb9ofPfcfMbWraG',#41,'Structural',$,(#262,#264));
#296= IFCRELDEFINESBYPROPERTIES('1PWunQtunCI9mnhYQ$Ay$Z',#41,$,$,(#251),#294);
#299= IFCPROPERTYSET('3BTw92SBP1sfKJ_LPo$s3_',#41,'Slab Shape Edit',$,(#265));
#301= IFCRELDEFINESBYPROPERTIES('0ZYr5EBWv00uUQU19ErHCQ',#41,$,$,(#251),#299);
#304= IFCPROPERTYSET('2k3_uEr6P8axYydD_nkWqV',#41,'Dimensions',$,(#266,#267,#269,#270));
#306= IFCRELDEFINESBYPROPERTIES('2jPZWgPGjFTuN0DTGBbGW4',#41,$,$,(#251),#304);
#309= IFCPROPERTYSET('1sFPqTlKbBgB77ULTFHXoe',#41,'Phasing',$,(#268));
#311= IFCRELDEFINESBYPROPERTIES('2mC9qrUpzFUe1HC4sLOEFo',#41,$,$,(#251),#309);
#314= IFCPROPERTYSET('02SP_1XZX0Z8uW_ADBFi5I',#41,'Graphics',$,(#272,#276));
#316= IFCPROPERTYSET('0s6ZDK8jn3_Bq8YWsUfrSz',#41,'Identity Data',$,(#274,#279,#280));
#318= IFCPROPERTYSET('2WlKzSxH552QKtFMz0cnc3',#41,'Analytical Properties',$,(#273,#275,#278,#281,#282));
#320= IFCPROPERTYSET('0CFpqTF0DAvRGYsst2wISG',#41,'Construction',$,(#283,#284));
#322= IFCPROPERTYSET('3MgWNgEbfDjxOdrcTzLset',#41,'Materials and Finishes',$,(#277));
#324= IFCMATERIAL('Concrete, Sand/Cement Screed');
#327= IFCCOLOURRGB($,0.498039215686275,0.498039215686275,0.498039215686275);
#328= IFCSURFACESTYLERENDERING(#327,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(0.),.NOTDEFINED.);
#329= IFCSURFACESTYLE('Concrete, Sand/Cement Screed',.BOTH.,(#328));
#331= IFCCOLOURRGB($,0.,0.,0.);
#332= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#333= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#334= IFCCURVESTYLEFONTPATTERN(33.528,1185.672);
#335= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#336= IFCCURVESTYLEFONTPATTERN(33.528,372.872);
#337= IFCCURVESTYLEFONTPATTERN(33.528,982.472);
#338= IFCCURVESTYLEFONT('Sand:1',(#332,#333,#334,#335,#336,#337));
#340= IFCCURVESTYLE('Sand:1',#338,$,#331);
#341= IFCCARTESIANPOINT((812.8,0.));
#343= IFCFILLAREASTYLEHATCHING(#340,IFCPOSITIVELENGTHMEASURE(203.2),$,#341,0.);
#344= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#345= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#346= IFCCURVESTYLEFONTPATTERN(33.528,1185.672);
#347= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#348= IFCCURVESTYLEFONTPATTERN(33.528,372.872);
#349= IFCCURVESTYLEFONTPATTERN(33.528,982.472);
#350= IFCCURVESTYLEFONT('Sand:2',(#344,#345,#346,#347,#348,#349));
#352= IFCCURVESTYLE('Sand:2',#350,$,#331);
#353= IFCCARTESIANPOINT((-101.599999999999,805.505448195993));
#355= IFCFILLAREASTYLEHATCHING(#352,IFCPOSITIVELENGTHMEASURE(203.2),$,#353,120.);
#356= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#357= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#358= IFCCURVESTYLEFONTPATTERN(33.528,1185.672);
#359= IFCCURVESTYLEFONTPATTERN(33.528,576.072);
#360= IFCCURVESTYLEFONTPATTERN(33.528,372.872);
#361= IFCCURVESTYLEFONTPATTERN(33.528,982.472);
#362= IFCCURVESTYLEFONT('Sand:3',(#356,#357,#358,#359,#360,#361));
#364= IFCCURVESTYLE('Sand:3',#362,$,#331);
#365= IFCCARTESIANPOINT((-0.,-195.90544819599));
#367= IFCFILLAREASTYLEHATCHING(#364,IFCPOSITIVELENGTHMEASURE(203.2),$,#365,240.);
#368= IFCFILLAREASTYLE('Sand',(#343,#355,#367));
#370= IFCPRESENTATIONSTYLEASSIGNMENT((#329,#368));
#372= IFCSTYLEDITEM($,(#370),$);
#374= IFCSTYLEDREPRESENTATION(#68,'Style','Material and Cut Pattern',(#372));
#377= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#374),#324);
#380= IFCMATERIALLAYER(#324,65.,$);
#382= IFCMATERIAL('Rigid insulation');
#383= IFCCOLOURRGB($,0.498039215686275,0.498039215686275,0.498039215686275);
#384= IFCSURFACESTYLERENDERING(#383,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(64.),.NOTDEFINED.);
#385= IFCSURFACESTYLE('Rigid insulation',.BOTH.,(#384));
#387= IFCCOLOURRGB($,0.,0.,0.);
#388= IFCDRAUGHTINGPREDEFINEDCURVEFONT('continuous');
#389= IFCCURVESTYLE($,#388,$,#387);
#390= IFCFILLAREASTYLEHATCHING(#389,IFCPOSITIVELENGTHMEASURE(300.),$,#9,0.);
#391= IFCCURVESTYLE($,#388,$,#387);
#392= IFCFILLAREASTYLEHATCHING(#391,IFCPOSITIVELENGTHMEASURE(300.),$,#9,90.);
#393= IFCFILLAREASTYLE('Crosshatch',(#390,#392));
#395= IFCPRESENTATIONSTYLEASSIGNMENT((#385,#393));
#397= IFCSTYLEDITEM($,(#395),$);
#399= IFCSTYLEDREPRESENTATION(#68,'Style','Material and Cut Pattern',(#397));
#401= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#399),#382);
#404= IFCMATERIALLAYER(#382,80.,$);
#405= IFCMATERIAL('Concrete Masonry, Floor Block');
#406= IFCCOLOURRGB($,0.709803921568627,0.709803921568627,0.709803921568627);
#407= IFCSURFACESTYLERENDERING(#406,0.,$,$,$,$,IFCNORMALISEDRATIOMEASURE(0.5),IFCSPECULAREXPONENT(128.),.NOTDEFINED.);
#408= IFCSURFACESTYLE('Concrete Masonry, Floor Block',.BOTH.,(#407));
#410= IFCCOLOURRGB($,0.,0.,0.);
#411= IFCCURVESTYLE($,#388,$,#410);
#412= IFCFILLAREASTYLEHATCHING(#411,IFCPOSITIVELENGTHMEASURE(149.999992057106),$,#9,45.);
#413= IFCFILLAREASTYLE('Diagonal up 1.5mm',(#412));
#415= IFCPRESENTATIONSTYLEASSIGNMENT((#408,#413));
#417= IFCSTYLEDITEM($,(#415),$);
#419= IFCSTYLEDREPRESENTATION(#68,'Style','Material and Cut Pattern',(#417));
#421= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#419),#405);
#424= IFCMATERIALLAYER(#405,100.,$);
#425= IFCMATERIAL('Concrete, Precast');
#426= IFCCOLOURRGB($,0.,0.,0.);
#427= IFCCURVESTYLEFONTPATTERN(76.2,838.2);
#428= IFCCURVESTYLEFONT('Concrete:1',(#427));
#430= IFCCURVESTYLE('Concrete:1',#428,$,#426);
#431= IFCCARTESIANPOINT((269.702496520064,321.418919159413));
#433= IFCFILLAREASTYLEHATCHING(#430,IFCPOSITIVELENGTHMEASURE(599.226132),$,#431,230.);
#434= IFCCURVESTYLEFONTPATTERN(60.96,670.56);
#435= IFCCURVESTYLEFONT('Concrete:2',(#434));
#437= IFCCURVESTYLE('Concrete:2',#435,$,#426);
#438= IFCCARTESIANPOINT((-206.253843026946,18.0448730735145));
#440= IFCFILLAREASTYLEHATCHING(#437,IFCPOSITIVELENGTHMEASURE(749.032538),$,#438,355.);
#441= IFCCURVESTYLEFONTPATTERN(64.7600432,712.360272);
#442= IFCCURVESTYLEFONT('Concrete:3',(#441));
#444= IFCCURVESTYLE('Concrete:3',#442,$,#426);
#445= IFCCARTESIANPOINT((-44.888915909931,567.255017497859));
#447= IFCFILLAREASTYLEHATCHING(#444,IFCPOSITIVELENGTHMEASURE(705.080378),$,#445,280.4514);
#448= IFCCURVESTYLEFONTPATTERN(114.3,1257.3);
#449= IFCCURVESTYLEFONT('Concrete:4',(#448));
#451= IFCCURVESTYLE('Concrete:4',#449,$,#426);
#452= IFCCARTESIANPOINT((435.742098974862,657.336905769826));
#454= IFCFILLAREASTYLEHATCHING(#451,IFCPOSITIVELENGTHMEASURE(898.839198),$,#452,226.1842);
#455= IFCCURVESTYLEFONTPATTERN(97.1400648,1068.540408);
#456= IFCCURVESTYLEFONT('Concrete:5',(#455));
#458= IFCCURVESTYLE('Concrete:5',#456,$,#426);
#459= IFCCARTESIANPOINT((-10.5586587498264,1056.67704007865));
#461= IFCFILLAREASTYLEHATCHING(#458,IFCPOSITIVELENGTHMEASURE(1057.62044),$,#459,276.6356);
#462= IFCCURVESTYLEFONTPATTERN(91.44,1005.84);
#463= IFCCURVESTYLEFONT('Concrete:6',(#462));
#465= IFCCURVESTYLE('Concrete:6',#463,$,#426);
#466= IFCCARTESIANPOINT((777.423344307836,82.628976622327));
#468= IFCFILLAREASTYLEHATCHING(#465,IFCPOSITIVELENGTHMEASURE(1123.548934),$,#466,351.1842);
#469= IFCCURVESTYLEFONTPATTERN(76.2,838.2);
#470= IFCCURVESTYLEFONT('Concrete:7',(#469));
#472= IFCCURVESTYLE('Concrete:7',#470,$,#426);
#473= IFCCARTESIANPOINT((493.314102658805,302.764956026886));
#475= IFCFILLAREASTYLEHATCHING(#472,IFCPOSITIVELENGTHMEASURE(599.226132),$,#473,201.);
#476= IFCCURVESTYLEFONTPATTERN(60.96,670.56);
#477= IFCCURVESTYLEFONT('Concrete:8',(#476));
#479= IFCCURVESTYLE('Concrete:8',#477,$,#426);
#480= IFCCARTESIANPOINT((-70.0453477224384,268.176248915166));
#482= IFCFILLAREASTYLEHATCHING(#479,IFCPOSITIVELENGTHMEASURE(749.032538),$,#480,326.);
#483= IFCCURVESTYLEFONTPATTERN(64.7600432,712.360272);
#484= IFCCURVESTYLEFONT('Concrete:9',(#483));
#486= IFCCURVESTYLE('Concrete:9',#484,$,#426);
#487= IFCCARTESIANPOINT((337.349933176118,670.294961900504));
#489= IFCFILLAREASTYLEHATCHING(#486,IFCPOSITIVELENGTHMEASURE(705.080378),$,#487,251.4514);
#490= IFCCURVESTYLEFONTPATTERN(33.528,628.904);
#491= IFCCURVESTYLEFONTPATTERN(33.528,647.192);
#492= IFCCURVESTYLEFONTPATTERN(33.528,639.572);
#493= IFCCURVESTYLEFONT('Concrete:10',(#490,#491,#492));
#495= IFCCURVESTYLE('Concrete:10',#493,$,#426);
#496= IFCCARTESIANPOINT((171.123776770131,131.307892200608));
#498= IFCFILLAREASTYLEHATCHING(#495,IFCPOSITIVELENGTHMEASURE(260.8072),$,#496,37.5);
#499= IFCCURVESTYLEFONTPATTERN(33.528,354.584);
#500= IFCCURVESTYLEFONTPATTERN(33.528,613.664);
#501= IFCCURVESTYLEFONTPATTERN(33.528,223.012);
#502= IFCCURVESTYLEFONT('Concrete:11',(#499,#500,#501));
#504= IFCCURVESTYLE('Concrete:11',#502,$,#426);
#505= IFCCARTESIANPOINT((314.582281890354,41.4155431076072));
#507= IFCFILLAREASTYLEHATCHING(#504,IFCPOSITIVELENGTHMEASURE(362.4072),$,#505,7.5);
#508= IFCCURVESTYLEFONTPATTERN(33.528,220.472);
#509= IFCCURVESTYLEFONTPATTERN(33.528,758.952);
#510= IFCCURVESTYLEFONTPATTERN(33.528,1018.032);
#511= IFCCURVESTYLEFONT('Concrete:12',(#508,#509,#510));
#513= IFCCURVESTYLE('Concrete:12',#511,$,#426);
#514= IFCCARTESIANPOINT((169.604538674044,-252.389742537839));
#516= IFCFILLAREASTYLEHATCHING(#513,IFCPOSITIVELENGTHMEASURE(272.0848),$,#514,-32.5);
#517= IFCCURVESTYLEFONTPATTERN(33.528,296.672);
#518= IFCCURVESTYLEFONTPATTERN(33.528,492.76);
#519= IFCCURVESTYLEFONTPATTERN(33.528,713.232);
#520= IFCCURVESTYLEFONT('Concrete:13',(#517,#518,#519));
#522= IFCCURVESTYLE('Concrete:13',#520,$,#426);
#523= IFCCARTESIANPOINT((-56.748608656703,-248.710049520697));
#525= IFCFILLAREASTYLEHATCHING(#522,IFCPOSITIVELENGTHMEASURE(475.2848),$,#523,-42.5);
#526= IFCFILLAREASTYLE('Concrete',(#433,#440,#447,#454,#461,#468,#475,#482,#489,#498,#507,#516,#525));
#528= IFCPRESENTATIONSTYLEASSIGNMENT((#237,#526));
#530= IFCSTYLEDITEM($,(#528),$);
#532= IFCSTYLEDREPRESENTATION(#68,'Style','Material and Cut Pattern',(#530));
#534= IFCMATERIALDEFINITIONREPRESENTATION($,$,(#532),#425);
#537= IFCMATERIALLAYER(#425,75.,$);
#538= IFCMATERIALLAYERSET((#380,#404,#424,#537),'Floor:Beam and Block 225mm Susp Ground');
#544= IFCMATERIALLAYERSETUSAGE(#538,.AXIS3.,.POSITIVE.,0.);
#545= IFCPROPERTYSINGLEVALUE('Reference',$,IFCIDENTIFIER('Beam and Block 225mm Susp Ground'),$);
#546= IFCPROPERTYSINGLEVALUE('IsExternal',$,IFCBOOLEAN(.F.),$);
#547= IFCPROPERTYSINGLEVALUE('LoadBearing',$,IFCBOOLEAN(.T.),$);
#548= IFCPROPERTYSINGLEVALUE('ThermalTransmittance',$,IFCTHERMALTRANSMITTANCEMEASURE(0.397589052997394),$);
#549= IFCPROPERTYSINGLEVALUE('PitchAngle',$,IFCPLANEANGLEMEASURE(0.),$);
#550= IFCPROPERTYSET('3HgFLk8TTFhf$2Wq3uxYkv',#41,'Pset_SlabCommon',$,(#545,#546,#547,#548,#549));
#552= IFCRELDEFINESBYPROPERTIES('2wJQGru1D5p89EjPo60WNh',#41,$,$,(#251),#550);
#555= IFCAXIS2PLACEMENT3D(#6,$,$);
#556= IFCLOCALPLACEMENT($,#555);
#557= IFCSITE('0jI6kz9rj7ZAQfwqcKYFLz',#41,'Default',$,'',#556,$,$,.ELEMENT.,$,$,0.,$,$);
#562= IFCPROPERTYSINGLEVALUE('AboveGround',$,IFCLOGICAL(.U.),$);
#563= IFCPROPERTYSET('2y6eFWYEH60Q_1QofreKWl',#41,'Pset_BuildingStoreyCommon',$,(#562));
#565= IFCRELDEFINESBYPROPERTIES('3yc32vkgv4We97hvWdvc7$',#41,$,$,(#98),#563);
#569= IFCPROPERTYSINGLEVALUE('Name',$,IFCTEXT('Level 0'),$);
#570= IFCPROPERTYSINGLEVALUE('Elevation',$,IFCLENGTHMEASURE(0.),$);
#571= IFCPROPERTYSINGLEVALUE('Computation Height',$,IFCLENGTHMEASURE(0.),$);
#572= IFCPROPERTYSINGLEVALUE('Building Story',$,IFCBOOLEAN(.T.),$);
#573= IFCPROPERTYSINGLEVALUE('Line Weight',$,IFCIDENTIFIER('1'),$);
#574= IFCPROPERTYSINGLEVALUE('Elevation Base',$,IFCIDENTIFIER('Project Base Point'),$);
#575= IFCPROPERTYSINGLEVALUE('Symbol at End 2 Default',$,IFCBOOLEAN(.F.),$);
#576= IFCPROPERTYSINGLEVALUE('Symbol',$,IFCLABEL('Level Head - Circle: Level Head - Circle'),$);
#577= IFCPROPERTYSINGLEVALUE('Color',$,IFCINTEGER(0),$);
#578= IFCPROPERTYSINGLEVALUE('Line Pattern',$,IFCLABEL('Centre'),$);
#579= IFCPROPERTYSINGLEVALUE('Symbol at End 1 Default',$,IFCBOOLEAN(.T.),$);
#580= IFCPROPERTYSET('3atPwuYcb8NBVwt6gA_gad',#41,'Identity Data',$,(#569,#262,#572));
#582= IFCRELDEFINESBYPROPERTIES('37Ns5Hz$v9SeRN96BHaKsZ',#41,$,$,(#98),#580);
#585= IFCPROPERTYSET('16xT06UnDCVBcuwrHqVRGC',#41,'Constraints',$,(#570));
#587= IFCRELDEFINESBYPROPERTIES('0GNuiomV5ESO6YYvzLBSMX',#41,$,$,(#98),#585);
#590= IFCPROPERTYSET('0JtEirreL7g8p_k9cYi6Wo',#41,'Dimensions',$,(#571));
#592= IFCRELDEFINESBYPROPERTIES('35oVBWv3T7TOCr2N1LLeCk',#41,$,$,(#98),#590);
#595= IFCPROPERTYSET('0Z7sOLTwTCkRYhZ1rhFAAc',#41,'Graphics',$,(#573,#575,#576,#577,#578,#579));
#597= IFCPROPERTYSET('2aBBUNdC5Ejhl1Dd53Seb_',#41,'Constraints',$,(#574));
#603= IFCRELAGGREGATES('2Or3ed41rD3u76Lm2s7UOd',#41,$,$,#79,(#557));
#607= IFCRELAGGREGATES('0GEoefa211w91carb_gm9p',#41,$,$,#557,(#89));
#611= IFCRELAGGREGATES('2$1LAsj$T3CPRLiPj39tWH',#41,$,$,#89,(#98));
#615= IFCPROPERTYSINGLEVALUE('NumberOfStoreys',$,IFCINTEGER(1),$);
#616= IFCPROPERTYSET('2FiUiubW97e9lZ7ujDAP8i',#41,'Pset_BuildingCommon',$,(#615));
#618= IFCRELDEFINESBYPROPERTIES('1hzN469$b3HgO2UMk8QCfg',#41,$,$,(#89),#616);
#622= IFCPROPERTYSINGLEVALUE('Project Name',$,IFCTEXT('Project Name'),$);
#623= IFCPROPERTYSINGLEVALUE('Project Status',$,IFCTEXT('Project Status'),$);
#624= IFCPROPERTYSINGLEVALUE('Building Name',$,IFCTEXT(''),$);
#625= IFCPROPERTYSINGLEVALUE('Organization Description',$,IFCTEXT(''),$);
#626= IFCPROPERTYSINGLEVALUE('Project Address',$,IFCTEXT('Enter address here'),$);
#627= IFCPROPERTYSINGLEVALUE('Project Number',$,IFCTEXT('Project Number'),$);
#628= IFCPROPERTYSINGLEVALUE('Project Issue Date',$,IFCTEXT('Issue Date'),$);
#629= IFCPROPERTYSINGLEVALUE('Client Name',$,IFCTEXT('Owner'),$);
#630= IFCPROPERTYSINGLEVALUE('Author',$,IFCTEXT(''),$);
#631= IFCPROPERTYSINGLEVALUE('Organization Name',$,IFCTEXT(''),$);
#632= IFCPROPERTYSET('0DRivpXNPD6hheen3gQzqz',#41,'Other',$,(#622,#623,#626,#627,#628,#629));
#634= IFCRELDEFINESBYPROPERTIES('0P9kBw51f1qwgdA_NGzm0h',#41,$,$,(#89),#632);
#637= IFCPROPERTYSET('0bsYiNj3T6zRvCeDr5qzEF',#41,'Identity Data',$,(#624,#625,#630,#631));
#639= IFCRELDEFINESBYPROPERTIES('3dea3nqt1C4hudrQhYfl_0',#41,$,$,(#89),#637);
#642= IFCRELASSOCIATESMATERIAL('0t2BxR6Vf0vAdho1sWfb5o',#41,$,$,(#251),#544);
#645= IFCRELDEFINESBYPROPERTIES('20m5CUwvPCGPz066QBkW0q',#41,$,$,(#251),#314);
#648= IFCRELDEFINESBYPROPERTIES('1qg3Wfj59E0Bq_0hDVvP46',#41,$,$,(#251),#316);
#651= IFCRELDEFINESBYPROPERTIES('2sRfn_msDCCAaKC7pnx2Bw',#41,$,$,(#251),#318);
#654= IFCRELDEFINESBYPROPERTIES('0F0ueYZyrDLQyU6UuD2Gqn',#41,$,$,(#251),#320);
#657= IFCRELDEFINESBYPROPERTIES('1Xktpq4bPCSwElNpZ2fQh3',#41,$,$,(#251),#322);
#660= IFCRELDEFINESBYPROPERTIES('3sCzONGnrDcgbhS3pxRLjd',#41,$,$,(#98),#595);
#666= IFCPRESENTATIONLAYERASSIGNMENT('A-230-M_FLOOR',$,(#244),$);
ENDSEC;
END-ISO-10303-21;
+13 -3
View File
@@ -206,8 +206,18 @@ TestFile("acad2010_objects.ifc")
# Various half space configuration to test cutting tolerances
TestFile("ifcopenshell_halfspaces.ifc")
# Several IfcPolygonalBoundedHalfSpaces cutting a single solid
TestFile("revit2014_multiple_bounded_halfspaces.ifc")
# Several parameterized profile extrusions generated by one
# of the examples from the IfcOpenShell repository
TestFile("IfcCShapeProfileDef.ifc")
TestFile("IfcCircleProfileDef.ifc")
TestFile("IfcEllipseProfileDef.ifc")
TestFile("IfcIShapeProfileDef.ifc")
TestFile("IfcLShapeProfileDef.ifc")
TestFile("IfcRectangleProfileDef.ifc")
TestFile("IfcTShapeProfileDef.ifc")
TestFile("IfcTrapeziumProfileDef.ifc")
TestFile("IfcUShapeProfileDef.ifc")
TestFile("IfcZShapeProfileDef.ifc")
for test in test_cases:
succes = test()
@@ -220,4 +230,4 @@ if len(failed):
print (test)
else:
print("[Notice] All cases succeeded")
-224
View File
@@ -1,224 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="IfcConvert"
ProjectGUID="{5B0BAAB3-9FC4-4C0C-9D38-8BF4B07F4A85}"
RootNamespace="IfcConvert"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\build\debug"
IntermediateDirectory="..\temp\obj\debug"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/DWNT"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKerneld.lib TKMathd.lib TKBRepd.lib TKGeomBased.lib TKGeomAlgod.lib TKG3dd.lib TKG2dd.lib TKShHealingd.lib TKTopAlgod.lib TKMeshd.lib TKPrimd.lib TKBoold.lib TKBOd.lib TKFilletd.lib TKSTEPd.lib TKSTEPBased.lib TKSTEPAttrd.lib TKXSBased.lib TKSTEP209d.lib TKIGESd.lib"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\build\release"
IntermediateDirectory="..\temp\obj\release"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/DWNT"
Optimization="2"
EnableIntrinsicFunctions="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKernel.lib TKMath.lib TKBRep.lib TKGeomBase.lib TKGeomAlgo.lib TKG3d.lib TKG2d.lib TKShHealing.lib TKTopAlgo.lib TKMesh.lib TKPrim.lib TKBool.lib TKBO.lib TKFillet.lib TKSTEP.lib TKSTEPBase.lib TKSTEPAttr.lib TKXSBase.lib TKSTEP209.lib TKIGES.lib"
GenerateDebugInformation="true"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\src\ifcconvert\ColladaSerializer.cpp"
>
</File>
<File
RelativePath="..\src\ifcconvert\IfcConvert.cpp"
>
</File>
<File
RelativePath="..\src\ifcconvert\OpenCascadeBasedSerializer.cpp"
>
</File>
<File
RelativePath="..\src\ifcconvert\WavefrontObjSerializer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\src\ifcconvert\ColladaSerializer.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\GeometrySerializer.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\IgesSerializer.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\OpenCascadeBasedSerializer.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\StepSerializer.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\SurfaceStyle.h"
>
</File>
<File
RelativePath="..\src\ifcconvert\WavefrontObjSerializer.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+9 -9
View File
@@ -170,10 +170,6 @@
RelativePath="..\src\ifcgeom\IfcGeomObjects.cpp"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.cpp"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcGeomShapes.cpp"
>
@@ -186,6 +182,10 @@
RelativePath="..\src\ifcgeom\IfcRegister.cpp"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@@ -200,10 +200,6 @@
RelativePath="..\src\ifcgeom\IfcGeomObjects.h"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.h"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcRegister.h"
>
@@ -244,10 +240,14 @@
RelativePath="..\src\ifcgeom\IfcRegisterUndef.h"
>
</File>
<File
<File
RelativePath="..\src\ifcgeom\IfcRepresentationShapeItem.h"
>
</File>
<File
RelativePath="..\src\ifcgeom\IfcGeomRenderStyles.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
-184
View File
@@ -1,184 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="IfcOpenHouse"
ProjectGUID="{163D7E4F-5337-4FAD-AC11-4D40078395A3}"
RootNamespace="IfcOpenHouse"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\build\debug"
IntermediateDirectory="..\temp\house\debug"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/DWNT"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
ProgramDataBaseFileName="$(IntDir)\vc90.pdb"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKerneld.lib TKMathd.lib TKBRepd.lib TKGeomBased.lib TKGeomAlgod.lib TKG3dd.lib TKG2dd.lib TKShHealingd.lib TKTopAlgod.lib TKMeshd.lib TKPrimd.lib TKBoold.lib TKBOd.lib TKFilletd.lib"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\build\release"
IntermediateDirectory="..\temp\house\release"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/DWNT"
Optimization="2"
EnableIntrinsicFunctions="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKernel.lib TKMath.lib TKBRep.lib TKGeomBase.lib TKGeomAlgo.lib TKG3d.lib TKG2d.lib TKShHealing.lib TKTopAlgo.lib TKMesh.lib TKPrim.lib TKBool.lib TKBO.lib TKFillet.lib"
GenerateDebugInformation="true"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\src\examples\IfcOpenHouse.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
-16
View File
@@ -13,12 +13,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcMax", "IfcMax.vcproj", "
{F7600775-3D48-426A-88E2-F3A4BF4408A2} = {F7600775-3D48-426A-88E2-F3A4BF4408A2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcConvert", "IfcConvert.vcproj", "{5B0BAAB3-9FC4-4C0C-9D38-8BF4B07F4A85}"
ProjectSection(ProjectDependencies) = postProject
{BA57AF0F-1D12-4FAC-BD40-7474D729CAE9} = {BA57AF0F-1D12-4FAC-BD40-7474D729CAE9}
{F7600775-3D48-426A-88E2-F3A4BF4408A2} = {F7600775-3D48-426A-88E2-F3A4BF4408A2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcGeom", "IfcGeom.vcproj", "{BA57AF0F-1D12-4FAC-BD40-7474D729CAE9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcParseExamples", "IfcParseExamples.vcproj", "{4DA9E9D7-60A6-4031-BA78-A3741BD62CB9}"
@@ -26,12 +20,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcParseExamples", "IfcPars
{F7600775-3D48-426A-88E2-F3A4BF4408A2} = {F7600775-3D48-426A-88E2-F3A4BF4408A2}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IfcOpenHouse", "IfcOpenHouse.vcproj", "{163D7E4F-5337-4FAD-AC11-4D40078395A3}"
ProjectSection(ProjectDependencies) = postProject
{BA57AF0F-1D12-4FAC-BD40-7474D729CAE9} = {BA57AF0F-1D12-4FAC-BD40-7474D729CAE9}
{F7600775-3D48-426A-88E2-F3A4BF4408A2} = {F7600775-3D48-426A-88E2-F3A4BF4408A2}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -62,10 +50,6 @@ Global
{4DA9E9D7-60A6-4031-BA78-A3741BD62CB9}.Debug|Win32.Build.0 = Debug|Win32
{4DA9E9D7-60A6-4031-BA78-A3741BD62CB9}.Release|Win32.ActiveCfg = Release|Win32
{4DA9E9D7-60A6-4031-BA78-A3741BD62CB9}.Release|Win32.Build.0 = Release|Win32
{163D7E4F-5337-4FAD-AC11-4D40078395A3}.Debug|Win32.ActiveCfg = Debug|Win32
{163D7E4F-5337-4FAD-AC11-4D40078395A3}.Debug|Win32.Build.0 = Debug|Win32
{163D7E4F-5337-4FAD-AC11-4D40078395A3}.Release|Win32.ActiveCfg = Release|Win32
{163D7E4F-5337-4FAD-AC11-4D40078395A3}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+83 -11
View File
@@ -149,6 +149,18 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\src\ifcparse\Ifc2x3-rt.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ifcparse\Ifc2x3.cpp"
>
@@ -161,36 +173,68 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ifcparse\Ifc4-rt.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ifcparse\Ifc4.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/bigobj"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ifcparse\IfcCharacterDecoder.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcGuidHelper.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcHierarchyHelper.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcParse.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcUntypedEntity.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcUtil.cpp"
>
</File>
<File
<File
RelativePath="..\src\ifcparse\IfcWrite.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcGuidHelper.cpp"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcHierarchyHelper.cpp"
>
</File>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\src\ifcparse\Ifc2x3-rt.h"
>
</File>
<File
RelativePath="..\src\ifcparse\Ifc2x3.h"
>
@@ -199,7 +243,23 @@
RelativePath="..\src\ifcparse\Ifc2x3enum.h"
>
</File>
<File
<File
RelativePath="..\src\ifcparse\Ifc4-rt.h"
>
</File>
<File
RelativePath="..\src\ifcparse\Ifc4.h"
>
</File>
<File
RelativePath="..\src\ifcparse\Ifc4enum.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcEntityDescriptor.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcHierarchyHelper.h"
>
</File>
@@ -207,6 +267,14 @@
RelativePath="..\src\ifcparse\IfcParse.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcSpfStream.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcUntypedEntity.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcSchema.h"
>
@@ -219,6 +287,10 @@
RelativePath="..\src\ifcparse\SharedPointer.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcUntypedEntity.h"
>
</File>
<File
RelativePath="..\src\ifcparse\IfcWrite.h"
>
+2 -2
View File
@@ -61,7 +61,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKerneld.lib TKMathd.lib TKBRepd.lib TKGeomBased.lib TKGeomAlgod.lib TKG3dd.lib TKG2dd.lib TKShHealingd.lib TKTopAlgod.lib TKMeshd.lib TKPrimd.lib TKBoold.lib TKBOd.lib TKFilletd.lib"
AdditionalDependencies="TKerneld.lib TKMathd.lib TKBRepd.lib TKGeomBased.lib TKGeomAlgod.lib TKG3dd.lib TKG2dd.lib TKShHealingd.lib TKTopAlgod.lib TKMeshd.lib TKPrimd.lib TKBoold.lib TKBOd.lib TKFilletd.lib TKOffsetd.lib"
OutputFile="$(OutDir)\_IfcImport.pyd"
GenerateDebugInformation="true"
TargetMachine="1"
@@ -132,7 +132,7 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="TKernel.lib TKMath.lib TKBRep.lib TKGeomBase.lib TKGeomAlgo.lib TKG3d.lib TKG2d.lib TKShHealing.lib TKTopAlgo.lib TKMesh.lib TKPrim.lib TKBool.lib TKBO.lib TKFillet.lib"
AdditionalDependencies="TKernel.lib TKMath.lib TKBRep.lib TKGeomBase.lib TKGeomAlgo.lib TKG3d.lib TKG2d.lib TKShHealing.lib TKTopAlgo.lib TKMesh.lib TKPrim.lib TKBool.lib TKBO.lib TKFillet.lib TKOffset.lib"
OutputFile="$(OutDir)\_IfcImport.pyd"
GenerateDebugInformation="true"
OptimizeReferences="2"