diff --git a/COPYING.LESSER b/COPYING.LESSER
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ 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.
diff --git a/README.md b/README.md
index 151f1a1..876df9a 100644
--- a/README.md
+++ b/README.md
@@ -3,106 +3,9 @@ IfcOpenShell
open source (LGPL) software library for working with the IFC file format
-http://IfcOpenShell.org
+http://ifcopenshell.org
+http://academy.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 ifc
- >>> f = ifc.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 = ifc.create_shape(wall, ifc.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 "", line 1, in
- File ".\ifc.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 "", line 1, in
- File ".\ifc.py", line 26, in __setattr__
- self[self.wrapped_data.get_argument_index(key)] = value
- File ".\ifc.py", line 30, in __setitem__
- self.wrapped_data.set_argument(idx, entity_instance.map_value(value))
- File ".\ifc_wrapper.py", line 118, in
- 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
- >>> ifc.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
-
-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
+Outdated
+========
+This is an old repository that has been superseded by [https://github.com/IfcOpenShell/IfcOpenShell/](https://github.com/IfcOPenShell/IfcOpenShell/).
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 4cd45bb..48d0212 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -123,21 +123,20 @@ ENDIF(MSVC)
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES} ${OCC_INCLUDE_DIR} ${OPENCOLLADA_INCLUDE_DIRS} /usr/inc /usr/local/inc /usr/local/include/oce ${ICU_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
-ADD_LIBRARY(IfcParse STATIC
+ADD_LIBRARY(IfcParse STATIC
+ ../src/ifcparse/Ifc2x3-latebound.cpp
../src/ifcparse/Ifc2x3.cpp
+ ../src/ifcparse/Ifc4-latebound.cpp
../src/ifcparse/Ifc4.cpp
- ../src/ifcparse/IfcUtil.cpp
- ../src/ifcparse/IfcParse.cpp
../src/ifcparse/IfcCharacterDecoder.cpp
-
- ../src/ifcparse/IfcWrite.cpp
../src/ifcparse/IfcGuidHelper.cpp
-
../src/ifcparse/IfcHierarchyHelper.cpp
-
- ../src/ifcparse/Ifc2x3-rt.cpp
- ../src/ifcparse/Ifc4-rt.cpp
- ../src/ifcparse/IfcUntypedEntity.cpp
+ ../src/ifcparse/IfcLateBoundEntity.cpp
+ ../src/ifcparse/IfcParse.cpp
+ ../src/ifcparse/IfcSIPrefix.cpp
+ ../src/ifcparse/IfcSpfHeader.cpp
+ ../src/ifcparse/IfcUtil.cpp
+ ../src/ifcparse/IfcWrite.cpp
)
ADD_LIBRARY(IfcGeom STATIC
@@ -145,8 +144,9 @@ ADD_LIBRARY(IfcGeom STATIC
../src/ifcgeom/IfcGeomFaces.cpp
../src/ifcgeom/IfcGeomFunctions.cpp
../src/ifcgeom/IfcGeomHelpers.cpp
- ../src/ifcgeom/IfcGeomObjects.cpp
+ ../src/ifcgeom/IfcGeomMaterial.cpp
../src/ifcgeom/IfcGeomRenderStyles.cpp
+ ../src/ifcgeom/IfcGeomRepresentation.cpp
../src/ifcgeom/IfcGeomShapes.cpp
../src/ifcgeom/IfcGeomWires.cpp
../src/ifcgeom/IfcRegister.cpp
@@ -160,11 +160,12 @@ TARGET_LINK_LIBRARIES(IfcGeom IfcParse)
LINK_DIRECTORIES (${LINK_DIRECTORIES} ${IfcOpenShell_BINARY_DIR} ${OCC_LIBRARY_DIR} ${OPENCOLLADA_LIBRARY_DIR} /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 ${ICU_LIBRARY_DIR} ${Boost_LIBRARY_DIRS})
-ADD_EXECUTABLE(IfcConvert
+ADD_EXECUTABLE(IfcConvert
../src/ifcconvert/ColladaSerializer.cpp
../src/ifcconvert/IfcConvert.cpp
../src/ifcconvert/OpenCascadeBasedSerializer.cpp
- ../src/ifcconvert/WavefrontObjSerializer.cpp
+ ../src/ifcconvert/WavefrontObjSerializer.cpp
+ ../src/ifcconvert/XmlSerializer.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 TKOffset ${Boost_LIBRARIES} ${OPENCOLLADA_LIBRARIES})
@@ -186,8 +187,12 @@ ADD_SUBDIRECTORY(../src/examples examples)
# CMake installation targets
SET(include_files_geom
../src/ifcgeom/IfcGeom.h
- ../src/ifcgeom/IfcGeomObjects.h
+ ../src/ifcgeom/IfcGeomElement.h
+ ../src/ifcgeom/IfcGeomIterator.h
+ ../src/ifcgeom/IfcGeomIteratorSettings.h
+ ../src/ifcgeom/IfcGeomMaterial.h
../src/ifcgeom/IfcGeomRenderStyles.h
+ ../src/ifcgeom/IfcGeomRepresentation.h
../src/ifcgeom/IfcRegister.h
../src/ifcgeom/IfcRegisterConvertCurve.h
../src/ifcgeom/IfcRegisterConvertFace.h
@@ -200,29 +205,29 @@ 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-latebound.h
../src/ifcparse/Ifc2x3.h
../src/ifcparse/Ifc2x3enum.h
+ ../src/ifcparse/Ifc4-latebound.h
../src/ifcparse/Ifc4.h
../src/ifcparse/Ifc4enum.h
../src/ifcparse/IfcCharacterDecoder.h
+ ../src/ifcparse/IfcEntityDescriptor.h
../src/ifcparse/IfcException.h
../src/ifcparse/IfcFile.h
../src/ifcparse/IfcHierarchyHelper.h
+ ../src/ifcparse/IfcLateBoundEntity.h
../src/ifcparse/IfcParse.h
+ ../src/ifcparse/IfcSIPrefix.h
+ ../src/ifcparse/IfcSpfHeader.h
+ ../src/ifcparse/IfcSpfStream.h
../src/ifcparse/IfcUtil.h
- ../src/ifcparse/SharedPointer.h
-
- ../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
+ ../src/ifcparse/IfcWrite.h
+ ../src/ifcparse/SharedPointer.h
)
INSTALL(FILES ${include_files_geom} DESTINATION include/ifcgeom)
INSTALL(FILES ${include_files_parse} DESTINATION include/ifcparse)
diff --git a/src/bimserver_plugin/.classpath b/src/bimserver_plugin/.classpath
deleted file mode 100644
index befbd75..0000000
--- a/src/bimserver_plugin/.classpath
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/bimserver_plugin/.project b/src/bimserver_plugin/.project
deleted file mode 100644
index 1a20de4..0000000
--- a/src/bimserver_plugin/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- IfcOpenShellPlugin
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
diff --git a/src/bimserver_plugin/lib/32/IfcJni.dll b/src/bimserver_plugin/lib/32/IfcJni.dll
deleted file mode 100644
index 1c29797..0000000
Binary files a/src/bimserver_plugin/lib/32/IfcJni.dll and /dev/null differ
diff --git a/src/bimserver_plugin/lib/32/libIfcJni.dylib b/src/bimserver_plugin/lib/32/libIfcJni.dylib
deleted file mode 100644
index 67d9a25..0000000
Binary files a/src/bimserver_plugin/lib/32/libIfcJni.dylib and /dev/null differ
diff --git a/src/bimserver_plugin/lib/32/libIfcJni.so b/src/bimserver_plugin/lib/32/libIfcJni.so
deleted file mode 100644
index 968647d..0000000
Binary files a/src/bimserver_plugin/lib/32/libIfcJni.so and /dev/null differ
diff --git a/src/bimserver_plugin/lib/64/IfcJni.dll b/src/bimserver_plugin/lib/64/IfcJni.dll
deleted file mode 100644
index f1471da..0000000
Binary files a/src/bimserver_plugin/lib/64/IfcJni.dll and /dev/null differ
diff --git a/src/bimserver_plugin/lib/64/libIfcJni.dylib b/src/bimserver_plugin/lib/64/libIfcJni.dylib
deleted file mode 100644
index b39ae6d..0000000
Binary files a/src/bimserver_plugin/lib/64/libIfcJni.dylib and /dev/null differ
diff --git a/src/bimserver_plugin/lib/64/libIfcJni.so b/src/bimserver_plugin/lib/64/libIfcJni.so
deleted file mode 100644
index fc6da5f..0000000
Binary files a/src/bimserver_plugin/lib/64/libIfcJni.so and /dev/null differ
diff --git a/src/bimserver_plugin/plugin/plugin.xml b/src/bimserver_plugin/plugin/plugin.xml
deleted file mode 100644
index 6af07c5..0000000
--- a/src/bimserver_plugin/plugin/plugin.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- org.bimserver.plugins.ifcengine.IfcEnginePlugin
- org.ifcopenshell.IfcOpenShellEnginePlugin
-
-
\ No newline at end of file
diff --git a/src/bimserver_plugin/src/org/ifcopenshell/IfcGeomObject.java b/src/bimserver_plugin/src/org/ifcopenshell/IfcGeomObject.java
deleted file mode 100644
index 3a22f56..0000000
--- a/src/bimserver_plugin/src/org/ifcopenshell/IfcGeomObject.java
+++ /dev/null
@@ -1,48 +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 . *
-* *
-********************************************************************************/
-
-/*******************************************************************************
-* *
-* This class is a literal translation of the interface class IfcGeomObject in *
-* the C++ implementation of IfcOpenShell, these babies are returned from the *
-* JNI interface. *
-* *
-********************************************************************************/
-
-package org.ifcopenshell;
-
-public class IfcGeomObject {
- public int id;
- public String name;
- public String type;
- public String guid;
- public int[] indices;
- public float[] vertices;
- public float[] normals;
-
- public IfcGeomObject(int i, String nm, String t, String g, int[] is, float[] vs, float[] ns) {
- id = i;
- name = nm;
- type = t;
- guid = g;
- indices = is;
- vertices = vs;
- normals = ns;
- }
-}
diff --git a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEngine.java b/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEngine.java
deleted file mode 100644
index 0361f36..0000000
--- a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEngine.java
+++ /dev/null
@@ -1,83 +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 . *
-* *
-********************************************************************************/
-
-/*******************************************************************************
-* *
-* An intermediate between the Plugin implementation and the Model *
-* implementation, nothing fancy going on here. *
-* *
-********************************************************************************/
-
-package org.ifcopenshell;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.bimserver.plugins.ifcengine.IfcEngine;
-import org.bimserver.plugins.ifcengine.IfcEngineException;
-import org.bimserver.plugins.ifcengine.IfcEngineModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IfcOpenShellEngine implements IfcEngine {
- private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellEngine.class);
- public static final Boolean debug = false;
- private String filename;
-
- public IfcOpenShellEngine(String fn) throws IOException {
- filename = fn;
- }
-
- @Override
- public void init() throws IfcEngineException {
- LOGGER.info("Initializing IfcOpenShell engine");
- }
-
- @Override
- public void close() {
- LOGGER.info("Closing IfcOpenShell engine");
- }
-
- @Override
- public IfcEngineModel openModel(File ifcFile) throws IfcEngineException {
- try {
- return openModel(new FileInputStream(ifcFile),(int)ifcFile.length());
- } catch (IOException e) {
- throw new IfcEngineException("Failed to open model");
- }
- }
-
- @Override
- public IfcEngineModel openModel(InputStream inputStream, int size) throws IfcEngineException {
- try {
- byte[] bytes = new byte[size];
- inputStream.read(bytes);
- return openModel(bytes);
- } catch (IOException e) {
- throw new IfcEngineException("Failed to open model");
- }
- }
-
- @Override
- public IfcEngineModel openModel(byte[] bytes) throws IfcEngineException {
- return new IfcOpenShellModel(filename,bytes);
- }
-}
\ No newline at end of file
diff --git a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEnginePlugin.java b/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEnginePlugin.java
deleted file mode 100644
index f410e3d..0000000
--- a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEnginePlugin.java
+++ /dev/null
@@ -1,121 +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 . *
-* *
-********************************************************************************/
-
-/*******************************************************************************
-* *
-* This class ensures that a valid binary is available for the platform the *
-* code is running on. *
-* *
-********************************************************************************/
-
-package org.ifcopenshell;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.bimserver.models.store.ObjectDefinition;
-import org.bimserver.plugins.PluginContext;
-import org.bimserver.plugins.PluginManager;
-import org.bimserver.plugins.ifcengine.IfcEngine;
-import org.bimserver.plugins.ifcengine.IfcEngineException;
-import org.bimserver.plugins.ifcengine.IfcEnginePlugin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IfcOpenShellEnginePlugin implements IfcEnginePlugin {
- private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellEnginePlugin.class);
- private boolean initialized = false;
- private String filename;
-
- @Override
- public IfcEngine createIfcEngine() throws IfcEngineException {
- try {
- return new IfcOpenShellEngine(filename);
- } catch (IOException e) {
- throw new IfcEngineException(e);
- }
- }
-
- @Override
- public String getDescription() {
- return "Open source IFC geometry engine
visit ifcopenshell.org";
- }
-
- public static String getVersionStatic() {
- return "0.3.0-rc3";
- }
-
- @Override
- public String getVersion() {
- return getVersionStatic();
- }
-
- @Override
- public void init(PluginManager pluginManager) {
- PluginContext pluginContext = pluginManager.getPluginContext(this);
- String os = System.getProperty("os.name").toLowerCase();
- String libraryName = "";
- if (os.contains("windows")) {
- libraryName = "IfcJni.dll";
- } else if (os.contains("osx") || os.contains("os x") || os.contains("darwin")) {
- libraryName = "libIfcJni.dylib";
- } else if (os.contains("linux")) {
- libraryName = "libIfcJni.so";
- }
- InputStream inputStream = pluginContext.getResourceAsInputStream("lib/" + System.getProperty("sun.arch.data.model") + "/" + libraryName);
- if (inputStream != null) {
- File nativeFolder = new File(pluginManager.getTempDir(), "IfcOpenShellEngine");
- try {
- if (nativeFolder.exists()) {
- try {
- FileUtils.deleteDirectory(nativeFolder);
- } catch (IOException e) {
- // Ignore
- }
- }
- FileUtils.forceMkdir(nativeFolder);
- File file = new File(nativeFolder, libraryName);
- IOUtils.copy(inputStream, new FileOutputStream(file));
- this.filename = file.getAbsolutePath();
- initialized = new File(filename).exists();
- } catch (IOException e) {
- LOGGER.error("", e);
- }
- }
- }
-
- @Override
- public boolean isInitialized() {
- return initialized;
- }
-
- @Override
- public String getDefaultName() {
- return "IfcOpenShell Engine";
- }
-
- @Override
- public ObjectDefinition getSettingsDefinition() {
- return null;
- }
-}
diff --git a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEntityInstance.java b/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEntityInstance.java
deleted file mode 100644
index 68c7803..0000000
--- a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellEntityInstance.java
+++ /dev/null
@@ -1,42 +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 . *
-* *
-********************************************************************************/
-
-package org.ifcopenshell;
-
-import org.bimserver.plugins.ifcengine.IfcEngineException;
-import org.bimserver.plugins.ifcengine.IfcEngineInstance;
-import org.bimserver.plugins.ifcengine.IfcEngineInstanceVisualisationProperties;
-
-public class IfcOpenShellEntityInstance implements IfcEngineInstance {
- private int startVertex;
- private int startIndex;
- private int primitiveCount;
-
- public IfcOpenShellEntityInstance(int startVertex, int startIndex, int primitiveCount) {
- this.startVertex = startVertex;
- this.startIndex = startIndex;
- this.primitiveCount = primitiveCount;
- }
- @Override
- public IfcEngineInstanceVisualisationProperties getVisualisationProperties()
- throws IfcEngineException {
- return new IfcEngineInstanceVisualisationProperties(startVertex, startIndex, primitiveCount);
- }
-
-}
diff --git a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellModel.java b/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellModel.java
deleted file mode 100644
index a65e40b..0000000
--- a/src/bimserver_plugin/src/org/ifcopenshell/IfcOpenShellModel.java
+++ /dev/null
@@ -1,198 +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 . *
-* *
-********************************************************************************/
-
-/*******************************************************************************
-* *
-* This class communicates with the JNI wrapper of IfcOpenShell. Note that, *
-* contrary to the Bonsma IFC engine, if the wrapper crashes it will take the *
-* BIMserver down with her. Since loading the wrapper involves loading a *
-* considerable binary into memory, it would have been better to make the *
-* System.load() call somewhere in IfcOpenShellEngine.java. *
-* *
-********************************************************************************/
-
-package org.ifcopenshell;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-
-import org.bimserver.plugins.ifcengine.IfcEngineClash;
-import org.bimserver.plugins.ifcengine.IfcEngineException;
-import org.bimserver.plugins.ifcengine.IfcEngineGeometry;
-import org.bimserver.plugins.ifcengine.IfcEngineInstance;
-import org.bimserver.plugins.ifcengine.IfcEngineModel;
-import org.bimserver.plugins.ifcengine.IfcEngineSurfaceProperties;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IfcOpenShellModel implements IfcEngineModel {
- private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellModel.class);
- private Boolean validModel = false;
- private HashMap> instances;
- private HashMap instances_byid;
-
- // Native C++ functions implemented in IfcOpenShell
- private native IfcGeomObject getGeometry();
- private native boolean setIfcData(byte[] b);
- private native String getPluginVersion();
-
- // Convenience functions to concatenate arrays
- private static float[] concatFloatArray(float[] a, float[] b) {
- if ( a == null ) return b;
- float[] r = new float[a.length+b.length];
- System.arraycopy(a,0,r,0,a.length);
- System.arraycopy(b,0,r,a.length,b.length);
- return r;
- }
- private static int[] concatIntArray(int[] a, int[] b) {
- if ( a == null ) return b;
- int[] r = new int[a.length+b.length];
- System.arraycopy(a,0,r,0,a.length);
- System.arraycopy(b,0,r,a.length,b.length);
- return r;
- }
-
- // Load the binary and pass the IFC data to IfcOpenShell
- public IfcOpenShellModel(String fn, byte[] input) throws IfcEngineException {
- try {
- System.load(fn);
- } catch ( Throwable e ) {
- e.printStackTrace();
- throw new IfcEngineException("Failed to load IfcOpenShell library");
- }
- String java_version = IfcOpenShellEnginePlugin.getVersionStatic();
- String cpp_version = "";
- try {
- cpp_version = getPluginVersion();
- } catch ( UnsatisfiedLinkError e ) {
- throw new IfcEngineException("Unable to determine IfcOpenShell version");
- }
- if ( !java_version.equalsIgnoreCase(cpp_version) ) {
- throw new IfcEngineException(String.format("Version mismatch: Plugin version %s does not match IfcOpenShell version %s",java_version,cpp_version));
- }
- validModel = setIfcData(input);
- }
-
- @Override
- public void close() throws IfcEngineException {
- validModel = false;
- }
-
- @Override
- public IfcEngineGeometry finalizeModelling(
- IfcEngineSurfaceProperties surfaceProperties)
- throws IfcEngineException {
-
- if ( ! validModel ) throw new IfcEngineException("No valid model supplied");
-
- int[] indices = null;
- float[] normals = null;
- float[] vertices = null;
-
- // We keep track of instances ourselves
- instances = new HashMap>();
-
- instances_byid = new HashMap();
-
- while ( true ) {
- // Get the geometry from IfcOpenShell, this goes one instance at a time
- IfcGeomObject obj = getGeometry();
- if (obj == null) break;
-
- // Store the instance in our dictionary
- List entity_list;
- String type = obj.type.toUpperCase();
- if ( ! instances.containsKey(type) ) {
- entity_list = new ArrayList();
- instances.put(type, entity_list);
- } else {
- entity_list = instances.get(type);
- }
-
- int start_vertex = vertices == null ? 0 : vertices.length;
- int start_index = indices == null ? 0 : indices.length;
- int fcount = obj.indices.length / 3;
-
- // The indices have to take previous entities into account
- for ( int i = 0; i < obj.indices.length; ++ i ) {
- obj.indices[i] += start_vertex / 3;
- }
-
- indices = concatIntArray(indices,obj.indices);
- vertices = concatFloatArray(vertices,obj.vertices);
- normals = concatFloatArray(normals,obj.normals);
-
- IfcOpenShellEntityInstance instance = new IfcOpenShellEntityInstance(start_vertex,start_index,fcount);
- entity_list.add(instance);
- instances_byid.put(obj.id, instance);
- }
- return new IfcEngineGeometry(indices,vertices,normals);
- }
-
- @Override
- public Set findClashesWithEids(double d)
- throws IfcEngineException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Set findClashesWithGuids(double d)
- throws IfcEngineException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public List extends IfcEngineInstance> getInstances(String name)
- throws IfcEngineException {
- if ( instances.containsKey(name)) return instances.get(name);
- else return new ArrayList();
- }
-
- @Override
- public IfcEngineSurfaceProperties initializeModelling()
- throws IfcEngineException {
- return null;
- }
-
- @Override
- public void setPostProcessing(boolean postProcessing)
- throws IfcEngineException {
- }
- @Override
- public IfcEngineInstance getInstanceFromExpressId(int oid)
- throws IfcEngineException {
- if ( instances_byid.containsKey(oid) ) {
- return instances_byid.get(oid);
- } else {
- // Probably something went wrong with the processing of this element in
- // the IfcOpenShell binary, as it has not been included in the enumerated
- // set of elements with geometry.
- LOGGER.warn(String.format("Entity #%d not found in model", oid));
- return new IfcOpenShellEntityInstance(0,0,0);
- }
- }
- @Override
- public void setFormat(int format, int mask) throws IfcEngineException {
- }
-
-}
diff --git a/src/examples/IfcOpenHouse.cpp b/src/examples/IfcOpenHouse.cpp
index 907b52b..cb96d92 100644
--- a/src/examples/IfcOpenHouse.cpp
+++ b/src/examples/IfcOpenHouse.cpp
@@ -55,7 +55,7 @@ int main(int argc, char** argv) {
// The IfcHierarchyHelper is a subclass of the regular IfcFile that provides several
// convenience functions for working with geometry in IFC files.
IfcHierarchyHelper file;
- file.filename("IfcOpenHouse.ifc");
+ file.header().file_name().name("IfcOpenHouse.ifc");
// Start by adding a wall to the file, initially leaving most attributes blank.
IfcSchema::IfcWallStandardCase* south_wall = new IfcSchema::IfcWallStandardCase(
@@ -83,17 +83,23 @@ int main(int argc, char** argv) {
// An IfcOwnerHistory has been initialized as well, which should be assigned to the wall.
south_wall->setOwnerHistory(file.getSingle());
- // The wall will be shaped as a box, with the dimensions specified in millimeters.
- IfcSchema::IfcProductDefinitionShape* south_wall_shape = file.addBox(10000, 360, 3000);
+ // The wall will be shaped as a box, with the dimensions specified in millimeters. The resulting
+ // product definition will consist of both a body representation as well as an axis representation
+ // that runs over the centerline of the box in the X-axis.
+ IfcSchema::IfcProductDefinitionShape* south_wall_shape = file.addAxisBox(10000, 360, 3000);
+
+ // Obtain a reference to the placement of the IfcBuildingStorey in order to create a hierarchy
+ // of placements for the products
+ IfcSchema::IfcObjectPlacement* storey_placement = file.getSingle()->ObjectPlacement();
// The shape has to be assigned to the representation of the wall and is placed at the origin
// of the coordinate system.
south_wall->setRepresentation(south_wall_shape);
- south_wall->setObjectPlacement(file.addLocalPlacement());
+ south_wall->setObjectPlacement(file.addLocalPlacement(storey_placement));
// A pale white colour is assigned to the wall.
IfcSchema::IfcPresentationStyleAssignment* wall_colour = file.setSurfaceColour(
- south_wall->Representation(), 0.75, 0.73, 0.68);
+ south_wall_shape, 0.75, 0.73, 0.68);
// Now create a footing for the wall to rest on.
IfcSchema::IfcFooting* footing = new IfcSchema::IfcFooting(guid(), file.getSingle(),
@@ -104,122 +110,158 @@ int main(int argc, char** argv) {
// The footing will span the entire floor plan of our building. The IfcRepresentationContext is
// something that has been created automatically as well, but representations could have been
// assigned to a specific context, for example to add a two dimensional plan representation as well.
- footing->setRepresentation(file.addBox(10100, 5460, 2000, 0, 0, 0, file.getSingle()));
- footing->setObjectPlacement(file.addLocalPlacement(0, 2500, -2000));
+ footing->setRepresentation(file.addBox(10100, 5460, 2000));
+ footing->setObjectPlacement(file.addLocalPlacement(storey_placement, 0, 2500, -2000));
// The footing will have a dark gray colour
IfcSchema::IfcPresentationStyleAssignment* footing_colour = file.setSurfaceColour(footing->Representation(), 0.26, 0.22, 0.18);
// IFC has two ways to apply boolean operations to geometry. IfcBooleanResults are commonly used
// to clip geometry to a surface, for example to a slanted roof. For openings that are filled
// with another element, for example a door or a window, an IfcOpeningElement is used instead.
- // An opening element is created with rectangular geometry
+
+ // An opening element is created with rectangular geometry:
IfcSchema::IfcOpeningElement* west_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(),
- null, null, null, file.addLocalPlacement(-2500, 0, 400),
- file.addBox(6000, 3630, 1600, 0, 0, 0, file.getSingle()), null
+ null, null, null, file.addLocalPlacement(south_wall->ObjectPlacement(), -2500, 0, 400),
+ file.addBox(6000, 3630, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
- file.AddEntity(west_opening);
+ file.addEntity(west_opening);
// Relate the opening element to the wall.
IfcSchema::IfcRelVoidsElement* void_element = new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(),
null, null, south_wall, west_opening);
- file.AddEntity(void_element);
+ file.addEntity(void_element);
// Now create an additional opening
IfcSchema::IfcOpeningElement* south_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(),
- null, null, null, file.addLocalPlacement(3000, 0, 400),
- file.addBox(1860, 3000, 1600, 0, 0, 0, file.getSingle()), null
+ null, null, null, file.addLocalPlacement(storey_placement, 3000, 0, 400),
+ file.addBox(1860, 3000, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
- file.AddEntity(south_opening);
- file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, south_wall, south_opening));
-
- // Create a roof element
- IfcSchema::IfcRoof* south_roof = new IfcSchema::IfcRoof(guid(), file.getSingle(), S("South roof"), null, null,
- 0, 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
+ file.addEntity(south_opening);
+ file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, south_wall, south_opening));
+ // Create a roof element that will consist of two slabs:
+ IfcSchema::IfcRoof* roof = new IfcSchema::IfcRoof(guid(), file.getSingle(), S("Roof"), null, null,
+ file.addLocalPlacement(storey_placement), 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
+
// The roof geometry is slanted 45 degrees by specifying a direction for the box extrusion
- south_roof->setRepresentation(file.addBox(10200, 360, sqrt(2.0*2900*2900), 0, file.addPlacement3d(0, 0, 0, 0, 1, 0),
- file.addTriplet(0, -sqrt(0.5), sqrt(0.5)), file.getSingle()));
- south_roof->setObjectPlacement(file.addLocalPlacement(0, -400, 2700));
- file.addBuildingProduct(south_roof);
+ IfcSchema::IfcShapeRepresentation* roof_rep = file.addEmptyRepresentation();
+ file.addBox(roof_rep, 10200, 360, sqrt(2.0*2900*2900), 0, file.addPlacement3d(0, 0, 0, 0, 1, 0),
+ file.addTriplet(0, -sqrt(0.5), sqrt(0.5)));
+ // CV-2x3-144: Roofs are aggregates and shall have at least one contained element and no own geometry
+ IfcSchema::IfcSlab* south_roof_part = new IfcSchema::IfcSlab(guid(), file.getSingle(), S("South roof"),
+ null, null, 0, 0, null, IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF);
+
+ // The geometry is instantiated by using IfcMappedItems. This way geometry definitions can
+ // be reused while maintaining the cardinality constraint that the ShapeOfProduct relation
+ // imposes on the IfcProductDefinitionShape. Note that this constrained is lifted in IFC4.
+ south_roof_part->setRepresentation(file.addMappedItem(roof_rep));
+ south_roof_part->setObjectPlacement(file.addLocalPlacement(roof->ObjectPlacement(), 0, -400, 2700));
+
// The same roof geometry is re-used on the north side of the roof, by inverting the X-axis of
// the local placement the roof is rotated 180 degrees around the Z-axis
- IfcSchema::IfcRoof* north_roof = new IfcSchema::IfcRoof(guid(), file.getSingle(), S("North roof"),
- null, null, 0, 0, null, IfcSchema::IfcRoofTypeEnum::IfcRoofType_GABLE_ROOF);
- north_roof->setOwnerHistory(file.getSingle());
- north_roof->setRepresentation(south_roof->Representation());
- north_roof->setObjectPlacement(file.addLocalPlacement(0, 5400, 2700, 0, 0, 1, -1, 0, 0));
- file.addBuildingProduct(north_roof);
+ IfcSchema::IfcSlab* north_roof_part = new IfcSchema::IfcSlab(guid(), file.getSingle(), S("North roof"),
+ null, null, 0, 0, null, IfcSchema::IfcSlabTypeEnum::IfcSlabType_ROOF);
+ north_roof_part->setOwnerHistory(file.getSingle());
+ north_roof_part->setRepresentation(file.addMappedItem(roof_rep));
+ north_roof_part->setObjectPlacement(file.addLocalPlacement(roof->ObjectPlacement(), 0, 5400, 2700, 0, 0, 1, -1, 0, 0));
+
+ IfcSchema::IfcObjectDefinition::list::ptr roof_parts(new IfcSchema::IfcObjectDefinition::list);
+ roof_parts->push(south_roof_part);
+ roof_parts->push(north_roof_part);
+ IfcSchema::IfcRelDecomposes* roof_decomposition = new IfcSchema::IfcRelAggregates(guid(), file.getSingle(),
+ null, null, roof, roof_parts);
+ file.addEntity(roof_decomposition);
+
+ file.addBuildingProduct(south_roof_part);
+ file.addBuildingProduct(north_roof_part);
+ file.addBuildingProduct(roof);
- // By specifying a surface style for the south part of the roof, it gets assigned to the other
- // roof part as well, because they share the same representation.
- file.setSurfaceColour(south_roof->Representation(), 0.24, 0.08, 0.04);
+ file.setSurfaceColour(roof_rep, 0.24, 0.08, 0.04);
// Copy the south wall to the north
- file.addBuildingProduct(new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(), S("North wall"),
- null, null, file.addLocalPlacement(0, 5000, 0), south_wall->Representation(), null
+ IfcSchema::IfcWallStandardCase* north_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(), S("North wall"),
+ null, null, file.addLocalPlacement(storey_placement, 0, 5000, 0), file.addAxisBox(10000, 360, 3000), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
- ));
+ );
+ file.addBuildingProduct(north_wall);
+ file.setSurfaceColour(north_wall->Representation(), wall_colour);
+
+ IfcSchema::IfcShapeRepresentation* clipped_wall_body_rep = file.addEmptyRepresentation();
+ file.addBox(clipped_wall_body_rep, 5000, 360, 6000);
+ // The east wall geometry is clipped using two IfcHalfSpaceSolids, created from an
+ // 'axis 3d placement' that specifies the plane against which the geometry is clipped.
+ file.clipRepresentation(clipped_wall_body_rep, file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
+ file.clipRepresentation(clipped_wall_body_rep, file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
// Now create a wall on the east of the building, again starting with just a box shape
IfcSchema::IfcWallStandardCase* east_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(),
- S("East wall"), null, null, file.addLocalPlacement(4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addBox(5000, 360, 6000), null
+ S("East wall"), null, null, file.addLocalPlacement(storey_placement, 4820, 2500, 0, 0, 0, 1, 0, 1, 0), file.addMappedItem(clipped_wall_body_rep), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(east_wall);
- // The east wall geometry is clipped using two IfcHalfSpaceSolids, created from an
- // 'axis 3d placement' that specifies the plane against which the geometry is clipped.
- file.clipRepresentation(east_wall->Representation(), file.addPlacement3d(-2500, 0, 3000, -1, 0, 1), false);
- file.clipRepresentation(east_wall->Representation(), file.addPlacement3d(2500, 0, 3000, 1, 0, 1), false);
-
- file.setSurfaceColour(east_wall->Representation(), wall_colour);
+ file.setSurfaceColour(clipped_wall_body_rep, wall_colour);
// The east wall is copied to the west location of the house
IfcSchema::IfcWallStandardCase* west_wall = new IfcSchema::IfcWallStandardCase(guid(), file.getSingle(),
- S("West wall"), null, null, file.addLocalPlacement(-4820, 2500, 0, 0, 0, 1, 0, -1, 0), east_wall->Representation(), null
+ S("West wall"), null, null, file.addLocalPlacement(storey_placement, -4820, 2500, 0, 0, 0, 1, 0, -1, 0), file.addMappedItem(clipped_wall_body_rep), null
#ifdef USE_IFC4
, IfcSchema::IfcWallTypeEnum::IfcWallType_STANDARD
#endif
);
file.addBuildingProduct(west_wall);
+ for (int i = 0; i < 2; ++i) {
+ // CV-2x3-161: MappedItems are not allowed for Axis representations
+ IfcSchema::IfcWallStandardCase* wall = i == 0 ? east_wall : west_wall;
+ IfcSchema::IfcShapeRepresentation* wall_axis_rep = file.addEmptyRepresentation("Axis", "Curve2D");
+ file.addAxis(wall_axis_rep, 5000);
+ IfcSchema::IfcRepresentation::list::ptr reps = wall->Representation()->Representations();
+ reps->push(wall_axis_rep);
+ wall->Representation()->setRepresentations(reps);
+ }
+
// The west wall is assigned an opening element we created for the south wall, opening elements are
// not shared accross building elements, even if they share the same representation. Hence, the east
// wall will not feature this opening.
// NB: an Opening Element can only be used to create a single void within a single Element, as per:
// http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcproductextension/lexical/ifcfeatureelementsubtraction.htm
+
+ // Not all viewers support opening elements with mapped representations, hence an exact copy of the
+ // same subtraction box is instantiated for the otherwise identical opening element.
IfcSchema::IfcOpeningElement* west_opening_copy = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(),
- null, null, null, west_opening->ObjectPlacement(), west_opening->Representation(), null
+ null, null, null, file.addLocalPlacement(west_wall->ObjectPlacement(), 2500, -2500+4820, 400, 0, 0, 1, 0, 1, 0),
+ file.addBox(6000, 3630, 1600), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
- file.AddEntity(west_opening_copy);
- file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, west_wall, west_opening_copy));
+ file.addEntity(west_opening_copy);
+ file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), 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
// will be tesselated using the deflection specified.
TopoDS_Shape shape;
createGroundShape(shape);
- IfcEntities geometrical_entities(new IfcEntityList());
+ IfcEntityList::ptr geometrical_entities(new IfcEntityList);
IfcSchema::IfcProductDefinitionShape* ground_representation = IfcGeom::tesselate(shape, 100., geometrical_entities);
file.getSingle()->setRepresentation(ground_representation);
- file.AddEntities(geometrical_entities);
- IfcSchema::IfcShapeRepresentation::list ground_reps = geometrical_entities->as();
- for (IfcSchema::IfcShapeRepresentation::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
- (*it)->setContextOfItems(file.getSingle());
+ file.addEntities(geometrical_entities);
+ IfcSchema::IfcShapeRepresentation::list::ptr ground_reps = geometrical_entities->as();
+ for (IfcSchema::IfcShapeRepresentation::list::it it = ground_reps->begin(); it != ground_reps->end(); ++it) {
+ (*it)->setContextOfItems(file.getRepresentationContext("Model"));
}
file.setSurfaceColour(ground_representation, 0.15, 0.25, 0.05);
@@ -246,7 +288,7 @@ int main(int argc, char** argv) {
, null
#endif
);
- IfcSchema::IfcMaterialLayer::list layers (new IfcTemplatedEntityList());
+ IfcSchema::IfcMaterialLayer::list::ptr layers (new IfcTemplatedEntityList());
layers->push(layer);
IfcSchema::IfcMaterialLayerSet* layer_set = new IfcSchema::IfcMaterialLayerSet(
layers,
@@ -271,17 +313,17 @@ int main(int argc, char** argv) {
null,
null,
#ifdef USE_IFC4
- file.EntitiesByType()->generalize(),
+ file.entitiesByType()->generalize(),
#else
- file.EntitiesByType()->as(),
+ file.entitiesByType()->as(),
#endif
layer_usage);
- file.AddEntity(material);
- file.AddEntity(layer);
- file.AddEntity(layer_set);
- file.AddEntity(layer_usage);
- file.AddEntity(associates_material);
+ file.addEntity(material);
+ file.addEntity(layer);
+ file.addEntity(layer_set);
+ file.addEntity(layer_usage);
+ file.addEntity(associates_material);
// In addition, another common way to represent geometry in IFC files is to use extrusions of
// planar areas bounded by a polygon.
@@ -293,7 +335,7 @@ int main(int argc, char** argv) {
stair_points.push_back(XY(500, 400));
stair_points.push_back(XY( 0, 400));
IfcSchema::IfcStairFlight* stair = new IfcSchema::IfcStairFlight(guid(), file.getSingle(),
- null, null, null, file.addLocalPlacement(5050, 1000, 0, 0, 1, 0, 1, 0, 0),
+ null, null, null, file.addLocalPlacement(storey_placement, 5050, 1000, 0, 0, 1, 0, 1, 0, 0),
file.addExtrudedPolyline(stair_points, 1200), null, 2, 2, 0.2, 0.25
#ifdef USE_IFC4
, IfcSchema::IfcStairFlightTypeEnum::IfcStairFlightType_STRAIGHT
@@ -304,19 +346,19 @@ int main(int argc, char** argv) {
file.setSurfaceColour(stair->Representation(), footing_colour);
IfcSchema::IfcOpeningElement* door_opening = new IfcSchema::IfcOpeningElement(guid(), file.getSingle(),
- null, null, null, file.addLocalPlacement(5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null
+ null, null, null, file.addLocalPlacement(storey_placement, 5000-180, 2500-900, 0), file.addBox(1000, 1000, 2200), null
#ifdef USE_IFC4
, IfcSchema::IfcOpeningElementTypeEnum::IfcOpeningElementType_OPENING
#endif
);
- file.AddEntity(door_opening);
- file.AddEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), null, null, east_wall, door_opening));
+ file.addEntity(door_opening);
+ file.addEntity(new IfcSchema::IfcRelVoidsElement(guid(), file.getSingle(), 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.
IfcSchema::IfcDoor* door = new IfcSchema::IfcDoor(guid(), file.getSingle(), null, null, null,
- file.addLocalPlacement(4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000
+ file.addLocalPlacement(storey_placement, 4800, 1600, 0, 0, 0, 1, 0, 1, 0), 0, null, 2200, 1000
#ifdef USE_IFC4
, IfcSchema::IfcDoorTypeEnum::IfcDoorType_DOOR
, IfcSchema::IfcDoorTypeOperationEnum::IfcDoorTypeOperation_SINGLE_SWING_LEFT
@@ -324,9 +366,9 @@ int main(int argc, char** argv) {
#endif
);
door->setRepresentation(file.addBox(80, 80, 2120, 0, file.addPlacement3d(460, 0, 0)));
- IfcSchema::IfcRepresentation::list door_representations = door->Representation()->Representations();
+ IfcSchema::IfcRepresentation::list::ptr door_representations = door->Representation()->Representations();
IfcSchema::IfcShapeRepresentation* door_body = 0;
- for (IfcSchema::IfcRepresentation::it i = door_representations->begin(); i != door_representations->end(); ++i) {
+ for (IfcSchema::IfcRepresentation::list::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;
@@ -337,7 +379,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 IfcSchema::IfcRelFillsElement(guid(), file.getSingle(), null, null, door_opening, door));
+ file.addEntity(new IfcSchema::IfcRelFillsElement(guid(), file.getSingle(), 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
@@ -350,32 +392,39 @@ int main(int argc, char** argv) {
// Therefore the OverallWidth and OverallHeight of the window attributes will need to
// match the bounding box of the representation. Furthermore, the window placement needs
// to align with the lowerleft corner of the constituent parts.
- IfcSchema::IfcProductDefinitionShape::list frame_representations (new IfcTemplatedEntityList());
- frame_representations->push(file.addBox(1860, 90, 90));
- frame_representations->push(*frame_representations->begin()); // Add a reference to the shape created above
- frame_representations->push(file.addBox(90, 90, 1420));
- frame_representations->push(*(frame_representations->end()-1)); // Add a reference to the shape created above
+ IfcSchema::IfcShapeRepresentation::list::ptr frame_representations(new IfcSchema::IfcShapeRepresentation::list);
+
+ IfcSchema::IfcShapeRepresentation* horizontal_bar = file.addEmptyRepresentation();
+ IfcSchema::IfcShapeRepresentation* vertical_bar = file.addEmptyRepresentation();
+ file.addBox(horizontal_bar, 1860, 90, 90);
+ file.addBox(vertical_bar, 90, 90, 1420);
+
+ frame_representations->push(horizontal_bar);
+ frame_representations->push(horizontal_bar); // Add another reference to the horizontal bar created above
+ frame_representations->push(vertical_bar);
+ frame_representations->push(vertical_bar); // Add another reference to the vertical bar created above
// The beams all have the same surface style assigned
IfcSchema::IfcPresentationStyleAssignment* frame_style = 0;
- for (IfcSchema::IfcProductDefinitionShape::it i = frame_representations->begin(); i != frame_representations->end(); ++i) {
+ for (IfcSchema::IfcShapeRepresentation::list::it i = frame_representations->begin(); i != frame_representations->end(); i += 2) {
if (frame_style) {
file.setSurfaceColour(*i, frame_style);
} else {
frame_style = file.setSurfaceColour(*i, 0.5, 0.4, 0.3);
}
+ // Because of the duplication the iterator is incremented twice
}
// This window will be placed at five locations within the building. A list of placements is
// created and is iterated over to create all window instances.
- IfcSchema::IfcLocalPlacement::list window_placements (new IfcTemplatedEntityList());
- window_placements->push(file.addLocalPlacement(2*-1770-430-930, -45, 400));
- window_placements->push(file.addLocalPlacement( -1770-430-930, -45, 400));
- window_placements->push(file.addLocalPlacement( -430-930, -45, 400));
- window_placements->push(file.addLocalPlacement( 3000-930, -45, 400));
- window_placements->push(file.addLocalPlacement( -4855+45, 885-930, 400, 0, 0, 1, 0, 1, 0));
+ IfcSchema::IfcLocalPlacement::list::ptr window_placements (new IfcSchema::IfcLocalPlacement::list);
+ window_placements->push(file.addLocalPlacement(storey_placement, 2*-1770-430-930, -45, 400));
+ window_placements->push(file.addLocalPlacement(storey_placement, -1770-430-930, -45, 400));
+ window_placements->push(file.addLocalPlacement(storey_placement, -430-930, -45, 400));
+ window_placements->push(file.addLocalPlacement(storey_placement, 3000-930, -45, 400));
+ window_placements->push(file.addLocalPlacement(storey_placement, -4855+45, 885-930, 400, 0, 0, 1, 0, 1, 0));
- for (IfcSchema::IfcLocalPlacement::it it = window_placements->begin(); it != window_placements->end(); ++it) {
+ for (IfcSchema::IfcLocalPlacement::list::it it = window_placements->begin(); it != window_placements->end(); ++it) {
// Create the window at the current location
IfcSchema::IfcLocalPlacement* place = *it;
@@ -390,42 +439,42 @@ int main(int argc, char** argv) {
file.addBuildingProduct(window);
// Initalize a list of parts for the window to be composed of
- IfcSchema::IfcObjectDefinition::list window_parts(new IfcTemplatedEntityList());
+ IfcSchema::IfcObjectDefinition::list::ptr window_parts(new IfcTemplatedEntityList());
// The placements for the beams are not shared accross the different windows because every
// beam is placed relative to its parent window entity.
- IfcSchema::IfcLocalPlacement::list frame_placements (new IfcTemplatedEntityList());
- 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));
+ IfcSchema::IfcLocalPlacement::list::ptr frame_placements (new IfcTemplatedEntityList());
+ frame_placements->push(file.addLocalPlacement(storey_placement, 930,45));
+ frame_placements->push(file.addLocalPlacement(storey_placement, 930, 45, 1510));
+ frame_placements->push(file.addLocalPlacement(storey_placement, -885+930, 45, 90));
+ frame_placements->push(file.addLocalPlacement(storey_placement, 885+930, 45, 90));
// Now iterate over the placements and representations of the beam and add them to list of parts
- IfcSchema::IfcLocalPlacement::it frame_placement;
- IfcSchema::IfcProductDefinitionShape::it frame_representation;
+ IfcSchema::IfcLocalPlacement::list::it frame_placement;
+ IfcSchema::IfcShapeRepresentation::list::it frame_representation;
for (frame_placement = frame_placements->begin(), frame_representation = frame_representations->begin();
frame_placement != frame_placements->end() && frame_representation != frame_representations->end();
++frame_placement, ++frame_representation)
{
IfcSchema::IfcMember* frame_part = new IfcSchema::IfcMember(guid(), file.getSingle(),
- null, null, null, *frame_placement, *frame_representation, null
+ null, null, null, *frame_placement, file.addMappedItem(*frame_representation), null
#ifdef USE_IFC4
, IfcSchema::IfcMemberTypeEnum::IfcMemberType_MULLION
#endif
);
- file.AddEntity(frame_part);
+ file.addEntity(frame_part);
window_parts->push(frame_part);
file.relatePlacements(window, frame_part);
}
// Add the glass plate to the list of parts
IfcSchema::IfcPlate* glass_part = new IfcSchema::IfcPlate(guid(), file.getSingle(), null,
- null, null, file.addLocalPlacement(930, 45, 90), file.addBox(1680, 10, 1420), null
+ null, null, file.addLocalPlacement(storey_placement, 930, 45, 90), file.addBox(1680, 10, 1420), null
#ifdef USE_IFC4
, IfcSchema::IfcPlateTypeEnum::IfcPlateType_SHEET
#endif
);
- file.AddEntity(glass_part);
+ file.addEntity(glass_part);
window_parts->push(glass_part);
file.relatePlacements(window, glass_part);
file.setSurfaceColour(glass_part->Representation(), 0.6, 0.7, 0.75, 0.1);
@@ -434,7 +483,7 @@ int main(int argc, char** argv) {
// tools will consider the window a single entity that can be selected as a whole.
IfcSchema::IfcRelDecomposes* decomposition = new IfcSchema::IfcRelAggregates(guid(), file.getSingle(),
null, null, window, window_parts);
- file.AddEntity(decomposition);
+ file.addEntity(decomposition);
}
// Finally create a file stream for our output and write the IFC file to it.
@@ -479,6 +528,6 @@ void createGroundShape(TopoDS_Shape& shape) {
#if OCC_VERSION_HEX < 0x60502
shape = BRepBuilderAPI_MakeFace(surf);
#else
- shape = BRepBuilderAPI_MakeFace(surf, 1);
+ shape = BRepBuilderAPI_MakeFace(surf, Precision::Confusion());
#endif
}
diff --git a/src/examples/IfcParseExamples.cpp b/src/examples/IfcParseExamples.cpp
index e6e8712..0fac9b3 100644
--- a/src/examples/IfcParseExamples.cpp
+++ b/src/examples/IfcParseExamples.cpp
@@ -17,7 +17,6 @@
* *
********************************************************************************/
-#include "../ifcparse/IfcParse.h"
#include "../ifcparse/IfcFile.h"
using namespace IfcSchema;
@@ -41,7 +40,7 @@ int main(int argc, char** argv) {
// Lets get a list of IfcBuildingElements, this is the parent
// type of things like walls, windows and doors.
- // EntitiesByType is a templated function and returns a
+ // entitiesByType is a templated function and returns a
// templated class that behaves like a std::vector.
// Note that the return types are all typedef'ed as members of
// the generated classes, ::list for the templated vector class,
@@ -55,17 +54,17 @@ int main(int argc, char** argv) {
// we need to cast them to IfcWindows. Since these properties
// are optional we need to make sure the properties are
// defined for the window in question before accessing them.
- IfcBuildingElement::list elements = file.EntitiesByType();
+ IfcBuildingElement::list::ptr elements = file.entitiesByType();
- std::cout << "Found " << elements->Size() << " elements in " << argv[1] << ":" << std::endl;
+ std::cout << "Found " << elements->size() << " elements in " << argv[1] << ":" << std::endl;
- for ( IfcBuildingElement::it it = elements->begin(); it != elements->end(); ++ it ) {
+ for ( IfcBuildingElement::list::it it = elements->begin(); it != elements->end(); ++ it ) {
- const IfcBuildingElement::ptr element = *it;
+ const IfcBuildingElement* element = *it;
std::cout << element->entity->toString() << std::endl;
if ( element->is(IfcWindow::Class()) ) {
- const IfcWindow::ptr window = reinterpret_pointer_cast(element);
+ const IfcWindow* window = (IfcWindow*)element;
if ( window->hasOverallWidth() && window->hasOverallHeight() ) {
const double area = window->OverallWidth()*window->OverallHeight();
diff --git a/src/examples/arbitrary_open_profile_def.cpp b/src/examples/arbitrary_open_profile_def.cpp
index f20b4d8..20ae1bb 100644
--- a/src/examples/arbitrary_open_profile_def.cpp
+++ b/src/examples/arbitrary_open_profile_def.cpp
@@ -51,7 +51,7 @@ void create_product_from_item(IfcHierarchyHelper& file, IfcSchema::IfcRepresenta
if (s == "GeometricSet") {
IfcSchema::IfcGeometricSet* set = new IfcSchema::IfcGeometricSet(items->generalize());
- file.AddEntity(set);
+ file.addEntity(set);
items = IfcSchema::IfcRepresentationItem::list(new IfcTemplatedEntityList());
items->push(set);
}
@@ -61,20 +61,20 @@ void create_product_from_item(IfcHierarchyHelper& file, IfcSchema::IfcRepresenta
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
- file.AddEntity(rep);
- file.AddEntity(shape);
+ 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(0, 0, 1), 100.);
- file.AddEntity(extrusion);
+ file.addEntity(extrusion);
IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet(0,100,0), file.addTriplet(1,0,0));
IfcSchema::IfcSurfaceOfRevolution* revolution = new IfcSchema::IfcSurfaceOfRevolution(profile, file.addPlacement3d(), ax1);
- file.AddEntity(ax1);
- file.AddEntity(revolution);
+ file.addEntity(ax1);
+ file.addEntity(revolution);
create_product_from_item(file, extrusion, "GeometricSet");
create_product_from_item(file, revolution, "GeometricSet");
@@ -82,14 +82,14 @@ void create_surfaces_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfil
void create_solids_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileDef* profile) {
IfcSchema::IfcExtrudedAreaSolid* extrusion = new IfcSchema::IfcExtrudedAreaSolid(profile, file.addPlacement3d(), file.addTriplet(0, 0, 1), 100.);
- file.AddEntity(extrusion);
+ file.addEntity(extrusion);
IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet(0,100,0), file.addTriplet(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);
+ file.addEntity(ax1);
+ file.addEntity(revolution1);
+ file.addEntity(revolution2);
create_product_from_item(file, extrusion, "SweptSolid");
create_product_from_item(file, revolution1, "SweptSolid");
@@ -99,8 +99,8 @@ void create_solids_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileD
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);
+ file.addEntity(open);
+ file.addEntity(center_line);
create_surfaces_from_profile(file, open);
create_solids_from_profile(file, center_line);
@@ -116,20 +116,20 @@ int main(int argc, char** argv) {
IfcSchema::IfcCartesianPoint::list points (new IfcTemplatedEntityList());
points->push(new IfcSchema::IfcCartesianPoint(std::vector(coords1, coords1+2)));
points->push(new IfcSchema::IfcCartesianPoint(std::vector(coords2, coords2+2)));
- file.AddEntities(points->generalize());
+ file.addEntities(points->generalize());
IfcSchema::IfcPolyline* poly = new IfcSchema::IfcPolyline(points);
- file.AddEntity(poly);
+ 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());
+ file.addEntity(ellipse);
+ IfcEntityList::ptr trim1(new IfcEntityList);
+ IfcEntityList::ptr 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);
+ file.addEntity(trim);
create_products_from_curve(file, trim);
diff --git a/src/examples/composite_profile_def.cpp b/src/examples/composite_profile_def.cpp
index fa84c5c..8e495e9 100644
--- a/src/examples/composite_profile_def.cpp
+++ b/src/examples/composite_profile_def.cpp
@@ -65,11 +65,11 @@ int main(int argc, char** argv) {
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(p2);
+ file.addEntity(p3);
- file.AddEntity(transform1);
- file.AddEntity(transform2);
+ 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);
@@ -79,7 +79,7 @@ int main(int argc, char** argv) {
profiles->push(p6);
profiles->push(p4);
- file.AddEntities(profiles->generalize());
+ file.addEntities(profiles->generalize());
IfcSchema::IfcCompositeProfileDef* composite = new IfcSchema::IfcCompositeProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, S("IFC"), profiles, null);
@@ -95,8 +95,8 @@ int main(int argc, char** argv) {
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(composite,
file.addPlacement3d(), file.addTriplet(0, 0, 1), 20.0);
- file.AddEntity(composite);
- file.AddEntity(solid);
+ file.addEntity(composite);
+ file.addEntity(solid);
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList());
@@ -107,8 +107,8 @@ int main(int argc, char** argv) {
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
- file.AddEntity(rep);
- file.AddEntity(shape);
+ file.addEntity(rep);
+ file.addEntity(shape);
product->setRepresentation(shape);
diff --git a/src/examples/csg_primitive.cpp b/src/examples/csg_primitive.cpp
index ced4635..d849a1c 100644
--- a/src/examples/csg_primitive.cpp
+++ b/src/examples/csg_primitive.cpp
@@ -127,7 +127,7 @@ class Node {
}
my = new IfcSchema::IfcBooleanResult(o, left->serialize(file), right->serialize(file));
}
- file.AddEntity(my);
+ file.addEntity(my);
return my;
}
};
@@ -181,8 +181,8 @@ int main(int argc, char** argv) {
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
- file.AddEntity(rep);
- file.AddEntity(shape);
+ file.addEntity(rep);
+ file.addEntity(shape);
product->setRepresentation(shape);
diff --git a/src/examples/ellipse_pies.cpp b/src/examples/ellipse_pies.cpp
index 967eb2c..eeef6cc 100644
--- a/src/examples/ellipse_pies.cpp
+++ b/src/examples/ellipse_pies.cpp
@@ -62,13 +62,13 @@ void create_testcase_for(IfcHierarchyHelper& file, const EllipsePie& pie, Ifc2x3
points->push(p3);
points->push(p1);
points->push(p2);
- file.AddEntities(points->generalize());
+ 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());
+ file.addEntity(ellipse);
+ IfcEntityList::ptr trim1(new IfcEntityList);
+ IfcEntityList::ptr 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));
@@ -77,23 +77,23 @@ void create_testcase_for(IfcHierarchyHelper& file, const EllipsePie& pie, Ifc2x3
trim2->push(p3);
}
Ifc2x3::IfcTrimmedCurve* trim = new Ifc2x3::IfcTrimmedCurve(ellipse, trim1, trim2, true, pref);
- file.AddEntity(trim);
+ file.addEntity(trim);
Ifc2x3::IfcCompositeCurveSegment::list segments(new IfcTemplatedEntityList());
Ifc2x3::IfcCompositeCurveSegment* s2 = new Ifc2x3::IfcCompositeCurveSegment(Ifc2x3::IfcTransitionCode::IfcTransitionCode_CONTINUOUS, true, trim);
Ifc2x3::IfcPolyline* poly = new Ifc2x3::IfcPolyline(points);
- file.AddEntity(poly);
+ 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());
+ 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);
+ file.addEntity(ccurve);
+ file.addEntity(profile);
IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy(
guid(), 0, S("profile"), null, null, 0, 0, null, null);
@@ -105,7 +105,7 @@ void create_testcase_for(IfcHierarchyHelper& file, const EllipsePie& pie, Ifc2x3
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(profile,
file.addPlacement3d(), file.addTriplet(0, 0, 1), 20.0);
- file.AddEntity(solid);
+ file.addEntity(solid);
IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList());
IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList());
@@ -116,8 +116,8 @@ void create_testcase_for(IfcHierarchyHelper& file, const EllipsePie& pie, Ifc2x3
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
- file.AddEntity(rep);
- file.AddEntity(shape);
+ file.addEntity(rep);
+ file.addEntity(shape);
product->setRepresentation(shape);
}
diff --git a/src/examples/profiles.cpp b/src/examples/profiles.cpp
index 3092648..d171745 100644
--- a/src/examples/profiles.cpp
+++ b/src/examples/profiles.cpp
@@ -35,7 +35,7 @@ typedef std::string S;
typedef IfcWrite::IfcGuidHelper guid;
boost::none_t const null = (static_cast(0));
-void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
+void create_testcase_for(IfcSchema::IfcProfileDef::list::ptr profiles) {
IfcSchema::IfcProfileDef* profile = *profiles->begin();
const std::string profile_type = IfcSchema::Type::ToString(profile->type());
const std::string filename = profile_type + ".ifc";
@@ -44,7 +44,7 @@ void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
file.filename(filename);
int i = 0;
- for (IfcSchema::IfcProfileDef::it it = profiles->begin(); it != profiles->end(); ++it, ++i) {
+ for (IfcSchema::IfcProfileDef::list::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);
@@ -52,7 +52,7 @@ void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
file.getSingle()->setName(profile_type);
product->setOwnerHistory(file.getSingle());
- product->setObjectPlacement(file.addLocalPlacement(100 * i));
+ product->setObjectPlacement(file.addLocalPlacement(0, 100. * i));
if (profile->is(IfcSchema::Type::IfcParameterizedProfileDef)) {
((IfcSchema::IfcParameterizedProfileDef*) profile)->setPosition(file.addPlacement2d());
@@ -61,11 +61,11 @@ void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
IfcSchema::IfcExtrudedAreaSolid* solid = new IfcSchema::IfcExtrudedAreaSolid(profile,
file.addPlacement3d(), file.addTriplet(0, 0, 1), 20.0);
- file.AddEntity(profile);
- file.AddEntity(solid);
+ file.addEntity(profile);
+ file.addEntity(solid);
- IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList());
- IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList());
+ IfcSchema::IfcRepresentation::list::ptr reps (new IfcSchema::IfcRepresentation::list);
+ IfcSchema::IfcRepresentationItem::list::ptr items (new IfcSchema::IfcRepresentationItem::list);
items->push(solid);
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(
@@ -73,8 +73,8 @@ void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
reps->push(rep);
IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps);
- file.AddEntity(rep);
- file.AddEntity(shape);
+ file.addEntity(rep);
+ file.addEntity(shape);
product->setRepresentation(shape);
}
@@ -84,7 +84,7 @@ void create_testcase_for(IfcSchema::IfcProfileDef::list profiles) {
}
int main(int argc, char** argv) {
- { IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList());
+ { IfcSchema::IfcProfileDef::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcUShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null, null, null));
@@ -99,7 +99,7 @@ int main(int argc, char** argv) {
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::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
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));
@@ -114,7 +114,7 @@ int main(int argc, char** argv) {
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::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcZShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 5.0, null, null));
@@ -123,7 +123,7 @@ int main(int argc, char** argv) {
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::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcEllipseProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0, 15.0));
@@ -132,16 +132,19 @@ int main(int argc, char** argv) {
null, 0, 15.0, 25.0));
create_testcase_for(profiles); }
- { IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList());
+ { IfcSchema::IfcProfileDef::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
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));
+ profiles->push(new Ifc2x3::IfcAsymmetricIShapeProfileDef(
+ IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
+ null, 0, 25.0, 50.0, 5.0, 5.0, 2.0, 20.0, 10.0, 5.0, null));
create_testcase_for(profiles); }
- { IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList());
+ { IfcSchema::IfcProfileDef::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcLShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, null, null, null, null, null));
@@ -156,7 +159,7 @@ int main(int argc, char** argv) {
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::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcCShapeProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0, 5.0, 10.0, null, null));
@@ -165,7 +168,7 @@ int main(int argc, char** argv) {
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::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcCircleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 25.0));
@@ -174,7 +177,7 @@ int main(int argc, char** argv) {
null, 0, 25.0, 5.0));
create_testcase_for(profiles); }
- { IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList());
+ { IfcSchema::IfcProfileDef::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcRectangleProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 25.0));
@@ -189,7 +192,7 @@ int main(int argc, char** argv) {
null, 0, 50.0, 25.0, 5.0, 2.0, 4.0));
create_testcase_for(profiles); }
- { IfcSchema::IfcProfileDef::list profiles (new IfcTemplatedEntityList());
+ { IfcSchema::IfcProfileDef::list::ptr profiles (new IfcSchema::IfcProfileDef::list);
profiles->push(new Ifc2x3::IfcTrapeziumProfileDef(
IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA,
null, 0, 50.0, 30.0, 25.0, 0.0));
diff --git a/src/ifcblender/io_import_scene_ifc/__init__.py b/src/ifcblender/io_import_scene_ifc/__init__.py
index 9a5b29b..b5493fa 100644
--- a/src/ifcblender/io_import_scene_ifc/__init__.py
+++ b/src/ifcblender/io_import_scene_ifc/__init__.py
@@ -30,27 +30,16 @@
"description": "Import files in the "\
"Industry Foundation Classes (.ifc) file format",
"author": "Thomas Krijnen, IfcOpenShell",
- "blender": (2, 5, 8),
- "api": 37702,
+ "blender": (2, 73, 0),
"location": "File > Import",
- "warning": "",
- "wiki_url": "http://sourceforge.net/apps/"\
- "mediawiki/ifcopenshell/index.php",
- "tracker_url": "http://sourceforge.net/tracker/?group_id=543113",
+ "tracker_url": "https://sourceforge.net/p/ifcopenshell/"\
+ "_list/tickets?source=navbar",
"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():
- imp.reload(IfcImport)
+ if "ifcopenshell" in locals():
+ imp.reload(ifcopenshell)
import bpy
import mathutils
@@ -70,54 +59,64 @@
description="The STEP Datatype keyword")
-def import_ifc(filename, use_names, process_relations):
- global wrong_unicode
- from . import IfcImport
+def import_ifc(filename, use_names, process_relations, blender_booleans):
+ from . import ifcopenshell
+ from .ifcopenshell import geom as ifcopenshell_geom
print("Reading %s..."%bpy.path.basename(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)
+ settings = ifcopenshell_geom.settings()
+ settings.set(settings.DISABLE_OPENING_SUBTRACTIONS, blender_booleans)
+ iterator = ifcopenshell_geom.iterator(settings, filename)
+ valid_file = iterator.findContext()
if not valid_file:
- IfcImport.CleanUp()
return False
print("Done reading file")
id_to_object = {}
id_to_parent = {}
id_to_matrix = {}
+ openings = []
old_progress = -1
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
- m = ob.matrix
- t = ob_type[0:21]
- nm = ob_name if len(ob_name) and use_names else ob_guid
+ ob = iterator.get()
+
+ f = ob.geometry.faces
+ v = ob.geometry.verts
+ mats = ob.geometry.materials
+ matids = ob.geometry.material_ids
+ m = ob.transformation.matrix.data
+ 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)]
faces = [[f[i], f[i + 1], f[i + 2]] \
for i in range(0, len(f), 3)]
- me = bpy.data.meshes.new('mesh%d' % ob.mesh.id)
+ me = bpy.data.meshes.new('mesh%d' % ob.geometry.id)
me.from_pydata(verts, [], faces)
- 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)
+
+ 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)
bob = bpy.data.objects.new(nm, me)
mat = mathutils.Matrix(([m[0], m[1], m[2], 0],
@@ -138,10 +137,12 @@ 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_render = bob.hide
+ if ob.type == 'IfcSpace' or ob.type == 'IfcOpeningElement':
+ if not (ob.type == 'IfcOpeningElement' and blender_booleans):
+ bob.hide = bob.hide_render = True
+ bob.draw_type = 'WIRE'
if ob.id not in id_to_object: id_to_object[ob.id] = []
id_to_object[ob.id].append(bob)
@@ -149,11 +150,19 @@ def import_ifc(filename, use_names, process_relations):
if ob.parent_id > 0:
id_to_parent[ob.id] = ob.parent_id
- progress = IfcImport.Progress() // 2
+ if blender_booleans and ob.type == 'IfcOpeningElement':
+ openings.append(ob.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 = iterator.progress() // 2
if progress > old_progress:
print("\r[" + "#" * progress + " " * (50 - progress) + "]", end="")
old_progress = progress
- if not IfcImport.Next():
+ if not iterator.next():
break
print("\rDone creating geometry" + " " * 30)
@@ -169,24 +178,13 @@ def import_ifc(filename, use_names, process_relations):
if parent_id in id_to_object:
bob = id_to_object[parent_id][0]
else:
- parent_ob = IfcImport.GetObject(parent_id)
+ parent_ob = iterator.getObject(parent_id)
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
+ m = parent_ob.transformation.matrix.data
+ 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((
@@ -201,7 +199,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
@@ -226,13 +224,19 @@ def import_ifc(filename, use_names, process_relations):
if process_relations:
print("Done processing relations")
-
- if not wrong_unicode:
- txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
- txt.from_string(IfcImport.GetLog())
+
+ for opening_id in openings:
+ parent_id = id_to_parent[opening_id]
+ if parent_id in id_to_object:
+ parent_ob = id_to_object[parent_id][0]
+ for opening_ob in id_to_object[opening_id]:
+ mod = parent_ob.modifiers.new("opening", "BOOLEAN")
+ mod.operation = "DIFFERENCE"
+ mod.object = opening_ob
+
+ txt = bpy.data.texts.new("%s.log"%bpy.path.basename(filename))
+ txt.from_string(iterator.getLog())
- IfcImport.CleanUp()
-
return True
@@ -251,15 +255,13 @@ class ImportIFC(bpy.types.Operator, ImportHelper):
" relations to parenting" \
" (warning: may be slow on large files)",
default=False)
+ blender_booleans = BoolProperty(name="Use Blender booleans",
+ description="Use Blender boolean modifiers for opening" \
+ " elements",
+ default=False)
def execute(self, context):
- 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):
+ if not import_ifc(self.filepath, self.use_names, self.process_relations, self.blender_booleans):
self.report({'ERROR'},
'Unable to parse .ifc file or no geometrical entities found'
)
diff --git a/src/ifcconvert/ColladaSerializer.cpp b/src/ifcconvert/ColladaSerializer.cpp
index 908022a..7f69d2d 100644
--- a/src/ifcconvert/ColladaSerializer.cpp
+++ b/src/ifcconvert/ColladaSerializer.cpp
@@ -35,7 +35,7 @@ std::string collada_id(const std::string& s) {
return id;
}
-void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords /* = "XYZ" */) {
+void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords /* = "XYZ" */) {
COLLADASW::FloatSource source(mSW);
source.setId(mesh_id + suffix);
source.setArrayId(mesh_id + suffix + COLLADASW::LibraryGeometries::ARRAY_ID_SUFFIX);
@@ -45,13 +45,18 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
source.getParameterNameList().push_back(std::string(1, coords[i]));
}
source.prepareToAppendValues();
- for (std::vector::const_iterator it = floats.begin(); it != floats.end(); ++it) {
+ for (std::vector::const_iterator it = floats.begin(); it != floats.end(); ++it) {
source.appendValues(*it);
}
source.finish();
}
-void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials) {
+void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials) {
+ // The goal of the IfcGeom::Iterator is to filter out empty geometries, but
+ // since this function would crash trying to deference the material_ids in
+ // that case, a hard return statement is added just in case.
+ if (indices.empty()) return;
+
openMesh(mesh_id);
// The normals vector can be empty for example when the WELD_VERTICES setting is used.
@@ -70,17 +75,13 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(const std::str
std::vector::const_iterator index_range_start = indices.begin();
std::vector::const_iterator material_it = material_ids.begin();
- int previous_material_id = -2;
+ int previous_material_id = -1;
for (std::vector::const_iterator it = indices.begin(); ; it += 3) {
- const int current_material_id = material_it == material_ids.end()
- ? -3
- : *(material_it++);
+ const int current_material_id = *(material_it++);
const int num_triangles = std::distance(index_range_start, it) / 3;
if ((previous_material_id != current_material_id && num_triangles > 0) || (it == indices.end())) {
COLLADASW::Triangles triangles(mSW);
- triangles.setMaterial(collada_id(previous_material_id < 0
- ? default_material_name
- : materials[previous_material_id].name()));
+ triangles.setMaterial(materials[previous_material_id].name());
triangles.setCount(num_triangles);
int offset = 0;
triangles.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX,"#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset++ ) );
@@ -113,7 +114,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
closeLibrary();
}
-void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix) {
+void ColladaSerializer::ColladaExporter::ColladaScene::add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix) {
if (!scene_opened) {
openVisualScene(scene_id);
scene_opened = true;
@@ -155,7 +156,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
}
}
-void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeomObjects::Material& material) {
+void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material) {
openEffect(collada_id(material.name()) + "-fx");
COLLADASW::EffectProfile effect(mSW);
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
@@ -186,20 +187,20 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close
closeLibrary();
}
-void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeomObjects::Material& material) {
+void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) {
if (!contains(material)) {
effects.write(material);
materials.push_back(material);
}
}
-bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeomObjects::Material& material) {
+bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::Material& material) {
return std::find(materials.begin(), materials.end(), material) != materials.end();
}
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
effects.close();
- for (std::vector::const_iterator it = materials.begin(); it != materials.end(); ++it) {
+ for (std::vector::const_iterator it = materials.begin(); it != materials.end(); ++it) {
const std::string& material_name = collada_id((*it).name());
openMaterial(material_name);
addInstanceEffect("#" + material_name + "-fx");
@@ -218,18 +219,10 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
asset.add();
}
-void ColladaSerializer::ColladaExporter::writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& _materials) {
- const IfcGeomObjects::Material default_for_type = IfcGeomObjects::Material(IfcGeom::get_default_style(type));
+void ColladaSerializer::ColladaExporter::write(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& _materials) {
std::vector material_references;
- const bool needs_default = std::find(material_ids.begin(), material_ids.end(), -1) != material_ids.end();
- if (needs_default) {
- if (!materials.contains(default_for_type)) {
- materials.add(default_for_type);
- }
- material_references.push_back(collada_id(default_for_type.name()));
- }
- for (std::vector::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
- const IfcGeomObjects::Material& material = *it;
+ for (std::vector::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
+ const IfcGeom::Material& material = *it;
if (!materials.contains(material)) {
materials.add(material);
}
@@ -273,9 +266,9 @@ void ColladaSerializer::writeHeader() {
exporter.startDocument(unit_name, unit_magnitude);
}
-void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
- const IfcGeomObjects::IfcRepresentationTriangulation& mesh = o->mesh();
- exporter.writeTesselated(o->guid(), o->name(), o->type(), o->id(), o->matrix(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.material_ids(), mesh.materials());
+void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) {
+ const IfcGeom::Representation::Triangulation& mesh = o->geometry();
+ exporter.write(o->guid(), o->name(), o->type(), o->id(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.material_ids(), mesh.materials());
}
void ColladaSerializer::finalize() {
diff --git a/src/ifcconvert/ColladaSerializer.h b/src/ifcconvert/ColladaSerializer.h
index 7bb7f80..6c3618f 100644
--- a/src/ifcconvert/ColladaSerializer.h
+++ b/src/ifcconvert/ColladaSerializer.h
@@ -35,7 +35,7 @@
#include
#include
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcconvert/GeometrySerializer.h"
@@ -51,8 +51,8 @@ class ColladaSerializer : public GeometrySerializer
explicit ColladaGeometries(COLLADASW::StreamWriter& stream)
: COLLADASW::LibraryGeometries(&stream)
{}
- void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords = "XYZ");
- void write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials);
+ void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords = "XYZ");
+ void write(const std::string mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& indices, const std::vector material_ids, const std::vector& materials);
void close();
};
class ColladaScene : public COLLADASW::LibraryVisualScenes
@@ -66,7 +66,7 @@ class ColladaSerializer : public GeometrySerializer
, scene_id(scene_id)
, scene_opened(false)
{}
- void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix);
+ void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix);
void write();
};
class ColladaMaterials : public COLLADASW::LibraryMaterials
@@ -78,34 +78,34 @@ class ColladaSerializer : public GeometrySerializer
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
: COLLADASW::LibraryEffects(&stream)
{}
- void write(const IfcGeomObjects::Material& material);
+ void write(const IfcGeom::Material& material);
void close();
};
- std::vector materials;
+ std::vector materials;
ColladaEffects effects;
public:
explicit ColladaMaterials(COLLADASW::StreamWriter& stream)
: COLLADASW::LibraryMaterials(&stream)
, effects(stream)
{}
- void add(const IfcGeomObjects::Material& material);
- bool contains(const IfcGeomObjects::Material& material);
+ void add(const IfcGeom::Material& material);
+ bool contains(const IfcGeom::Material& material);
void write();
};
class DeferredObject {
public:
std::string guid, name, type;
int obj_id;
- std::vector matrix;
- std::vector vertices;
- std::vector normals;
+ std::vector matrix;
+ std::vector vertices;
+ std::vector normals;
std::vector indices;
std::vector material_ids;
- std::vector materials;
+ std::vector materials;
std::vector material_references;
- DeferredObject(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices,
- const std::vector& normals, const std::vector& indices, const std::vector& material_ids,
- const std::vector& materials, const std::vector& material_references)
+ DeferredObject(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices,
+ const std::vector& normals, const std::vector& indices, const std::vector& material_ids,
+ const std::vector& materials, const std::vector& material_references)
: guid(guid)
, name(name)
, type(type)
@@ -136,7 +136,7 @@ class ColladaSerializer : public GeometrySerializer
std::vector deferreds;
virtual ~ColladaExporter() {}
void startDocument(const std::string& unit_name, float unit_magnitude);
- void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& materials);
+ void write(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& indices, const std::vector& material_ids, const std::vector& materials);
void endDocument();
};
ColladaExporter exporter;
@@ -149,14 +149,15 @@ class ColladaSerializer : public GeometrySerializer
{}
bool ready();
void writeHeader();
- void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
- void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
+ void write(const IfcGeom::TriangulationElement* o);
+ void write(const IfcGeom::BRepElement* o) {}
void finalize();
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
unit_name = name;
unit_magnitude = magnitude;
}
+ void setFile(IfcParse::IfcFile*) {}
};
#endif
diff --git a/src/ifcconvert/GeometrySerializer.h b/src/ifcconvert/GeometrySerializer.h
index c489506..0a62def 100644
--- a/src/ifcconvert/GeometrySerializer.h
+++ b/src/ifcconvert/GeometrySerializer.h
@@ -20,17 +20,16 @@
#ifndef GEOMETRYSERIALIZER_H
#define GEOMETRYSERIALIZER_H
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcconvert/Serializer.h"
+#include "../ifcgeom/IfcGeomIterator.h"
-class GeometrySerializer {
+class GeometrySerializer : public Serializer {
public:
- virtual bool ready() = 0;
- virtual void writeHeader() = 0;
- virtual void finalize() = 0;
- virtual bool isTesselated() const = 0;
virtual ~GeometrySerializer() {}
- virtual void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) = 0;
- virtual void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) = 0;
+
+ virtual bool isTesselated() const = 0;
+ virtual void write(const IfcGeom::TriangulationElement* o) = 0;
+ virtual void write(const IfcGeom::BRepElement* o) = 0;
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
};
diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp
index f700e93..12dd686 100644
--- a/src/ifcconvert/IfcConvert.cpp
+++ b/src/ifcconvert/IfcConvert.cpp
@@ -33,12 +33,13 @@
#include
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcconvert/ColladaSerializer.h"
#include "../ifcconvert/IgesSerializer.h"
#include "../ifcconvert/StepSerializer.h"
#include "../ifcconvert/WavefrontObjSerializer.h"
+#include "../ifcconvert/XmlSerializer.h"
void printVersion() {
std::cerr << "IfcOpenShell IfcConvert " << IFCOPENSHELL_VERSION << std::endl;
@@ -55,6 +56,7 @@ void printUsage(const boost::program_options::options_description& generic_optio
#endif
std::cerr << " .stp STEP Standard for the Exchange of Product Data" << std::endl
<< " .igs IGES Initial Graphics Exchange Specification" << std::endl
+ << " .xml XML Property definitions and decomposition tree" << std::endl
<< std::endl
<< "Command line options" << std::endl << generic_options << std::endl
<< "Advanced options" << std::endl << geom_options << std::endl;
@@ -84,35 +86,48 @@ int main(int argc, char** argv) {
("input-file", boost::program_options::value(), "input IFC file")
("output-file", boost::program_options::value(), "output geometry file");
- std::vector ignore_types_vector;
+ std::vector entity_vector;
boost::program_options::options_description geom_options;
geom_options.add_options()
- ("weld-vertices", "Specifies whether vertices are welded, meaning that the coordinates "
- "vector will only contain unique xyz-triplets. This results in a "
- "manifold mesh which is useful for modelling applications, but might "
- "result in unwanted shading artifacts in rendering applications.")
- ("use-world-coords", "Specifies whether to apply the local placements of building elements "
- "directly to the coordinates of the representation mesh rather than "
- "to represent the local placement in the 4x3 matrix, which will in that "
- "case be the identity matrix.")
- ("convert-back-units", "Specifies whether to convert back geometrical output back to the "
- "unit of measure in which it is defined in the IFC file. Default is "
- "to use meters.")
- ("sew-shells", "Specifies whether to sew the faces of IfcConnectedFaceSets together. This is a "
- "potentially time consuming operation, but guarantees a consistent orientation "
- "of surface normals, even if the faces are not properly oriented in the IFC file.")
- ("merge-boolean-operands", "Specifies whether to merge all IfcOpeningElement operands into a single "
- "operand before applying the subtraction operation. This may "
- "introduce a performance improvement at the risk of failing, in "
- "which case the subtraction is applied one-by-one.")
- ("force-ccw-face-orientation", "Recompute topological face normals using Newell's Method to "
- "guarantee that face vertices are defined in a Counter Clock "
- "Wise order, even if the faces are not part of a closed shell.")
- ("disable-opening-subtractions", "Specifies whether to disable the boolean subtraction of "
- "IfcOpeningElement Representations from their RelatingElements.")
- ("ignore-types", boost::program_options::value< std::vector >(&ignore_types_vector)->multitoken(),
- "A list of IFC datatype keywords that should not be included in the geometrical output. "
- "Defaults to IfcOpeningElement and IfcSpace");
+ ("weld-vertices",
+ "Specifies whether vertices are welded, meaning that the coordinates "
+ "vector will only contain unique xyz-triplets. This results in a "
+ "manifold mesh which is useful for modelling applications, but might "
+ "result in unwanted shading artefacts in rendering applications.")
+ ("use-world-coords",
+ "Specifies whether to apply the local placements of building elements "
+ "directly to the coordinates of the representation mesh rather than "
+ "to represent the local placement in the 4x3 matrix, which will in that "
+ "case be the identity matrix.")
+ ("convert-back-units",
+ "Specifies whether to convert back geometrical output back to the "
+ "unit of measure in which it is defined in the IFC file. Default is "
+ "to use meters.")
+ ("sew-shells",
+ "Specifies whether to sew the faces of IfcConnectedFaceSets together. "
+ "This is a potentially time consuming operation, but guarantees a "
+ "consistent orientation of surface normals, even if the faces are not "
+ "properly oriented in the IFC file.")
+ ("merge-boolean-operands",
+ "Specifies whether to merge all IfcOpeningElement operands into a single "
+ "operand before applying the subtraction operation. This may "
+ "introduce a performance improvement at the risk of failing, in "
+ "which case the subtraction is applied one-by-one.")
+ ("force-ccw-face-orientation",
+ "Recompute topological face normals using Newell's Method to "
+ "guarantee that face vertices are defined in a Counter Clock "
+ "Wise order, even if the faces are not part of a closed shell.")
+ ("disable-opening-subtractions",
+ "Specifies whether to disable the boolean subtraction of "
+ "IfcOpeningElement Representations from their RelatingElements.")
+ ("include",
+ "Specifies that the entities listed after --entities are to be included")
+ ("exclude",
+ "Specifies that the entities listed after --entities are to be excluded")
+ ("entities", boost::program_options::value< std::vector >(&entity_vector)->multitoken(),
+ "A list of entities that should be included in or excluded from the "
+ "geometrical output, depending on whether --ignore or --include is "
+ "specified. Defaults to IfcOpeningElement and IfcSpace to be excluded.");
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(fileio_options).add(geom_options);
@@ -128,13 +143,19 @@ 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);
if (vmap.count("version")) {
printVersion();
- return 1;
+ return 0;
} else if (vmap.count("help") || !vmap.count("input-file")) {
+ printUsage(generic_options, geom_options);
+ return vmap.count("help") ? 0 : 1;
+ } else if (vmap.count("include") && vmap.count("exclude")) {
+ std::cerr << "[Error] --include and --ignore can not be specified together" << std::endl;
printUsage(generic_options, geom_options);
return 1;
}
@@ -147,20 +168,22 @@ int main(int argc, char** argv) {
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
const bool force_ccw_face_orientation = vmap.count("force-ccw-face-orientation") != 0;
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
+ const bool include_entities = vmap.count("include") != 0;
// Gets the set ifc types to be ignored from the command line.
- std::set ignore_types;
- for (std::vector::const_iterator it = ignore_types_vector.begin(); it != ignore_types_vector.end(); ++it) {
+ std::set entities;
+ for (std::vector::const_iterator it = entity_vector.begin(); it != entity_vector.end(); ++it) {
std::string lowercase_type = *it;
for (std::string::iterator c = lowercase_type.begin(); c != lowercase_type.end(); ++c) {
*c = tolower(*c);
}
- ignore_types.insert(lowercase_type);
+ entities.insert(lowercase_type);
}
- // If none are specified these are the defaults to skip from output
- if (ignore_types_vector.empty()) {
- ignore_types.insert("ifcopeningelement");
- ignore_types.insert("ifcspace");
+
+ // If no entities are specified these are the defaults to skip from output
+ if (entity_vector.empty()) {
+ entities.insert("ifcopeningelement");
+ entities.insert("ifcspace");
}
const std::string input_filename = vmap["input-file"].as();
@@ -175,14 +198,6 @@ int main(int argc, char** argv) {
return 1;
}
- IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, use_world_coords);
- IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES, weld_vertices);
- IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS, sew_shells);
- IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS, convert_back_units);
- IfcGeomObjects::Settings(IfcGeomObjects::FASTER_BOOLEANS, merge_boolean_operands);
- IfcGeomObjects::Settings(IfcGeomObjects::FORCE_CCW_FACE_ORIENTATION, force_ccw_face_orientation);
- IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
-
std::string output_extension = output_filename.substr(output_filename.size()-4);
for (std::string::iterator c = output_extension.begin(); c != output_extension.end(); ++c) {
*c = tolower(*c);
@@ -191,12 +206,40 @@ int main(int argc, char** argv) {
Logger::SetOutput(&std::cout, &log_stream);
Logger::Verbosity(verbose ? Logger::LOG_NOTICE : Logger::LOG_ERROR);
+ if (output_extension == ".xml") {
+ int exit_code = 1;
+ try {
+ XmlSerializer s(output_filename);
+ IfcParse::IfcFile f;
+ if (!f.Init(input_filename)) {
+ Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file");
+ } else {
+ s.setFile(&f);
+ s.finalize();
+ exit_code = 0;
+ }
+ } catch (...) {}
+ write_log();
+ return exit_code;
+ }
+
+ IfcGeom::IteratorSettings settings;
+
+ settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true);
+ settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, use_world_coords);
+ settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices);
+ settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, sew_shells);
+ settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, convert_back_units);
+ settings.set(IfcGeom::IteratorSettings::FASTER_BOOLEANS, merge_boolean_operands);
+ settings.set(IfcGeom::IteratorSettings::FORCE_CCW_FACE_ORIENTATION, force_ccw_face_orientation);
+ settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
+
GeometrySerializer* serializer;
if (output_extension == ".obj") {
const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl";
if (!use_world_coords) {
Logger::Message(Logger::LOG_NOTICE, "Using world coords when writing WaveFront OBJ files");
- IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, true);
+ settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
}
serializer = new WaveFrontOBJSerializer(output_filename, mtl_filename);
#ifdef WITH_OPENCOLLADA
@@ -217,30 +260,43 @@ int main(int argc, char** argv) {
return 1;
}
- if (!serializer->ready()) {
- Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing");
- write_log();
- return 1;
- }
-
if (!serializer->isTesselated()) {
- IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_TRIANGULATION, true);
if (weld_vertices) {
Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing STEP or IGES files");
}
+ settings.disable_triangulation() = true;
+ }
+
+ IfcGeom::Iterator context_iterator(settings, input_filename);
+
+ try {
+ if (include_entities) {
+ context_iterator.includeEntities(entities);
+ } else {
+ context_iterator.excludeEntities(entities);
+ }
+ } catch (const IfcParse::IfcException& e) {
+ std::cout << "[Error] " << e.what() << std::endl;
+ return 1;
+ }
+
+ if (!serializer->ready()) {
+ Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing");
+ write_log();
+ return 1;
}
time_t start,end;
time(&start);
- // Parse the file supplied in argv[1]. Returns true on succes.
- if ( ! IfcGeomObjects::Init(input_filename, &std::cout, &log_stream) ) {
+
+ if (!context_iterator.findContext()) {
Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file or no geometrical entities found");
write_log();
return 1;
}
if (convert_back_units) {
- serializer->setUnitNameAndMagnitude(IfcGeomObjects::GetUnitName(), IfcGeomObjects::GetUnitMagnitude());
+ serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude()));
} else {
serializer->setUnitNameAndMagnitude("METER", 1.0f);
}
@@ -252,35 +308,30 @@ int main(int argc, char** argv) {
int old_progress = -1;
Logger::Status("Creating geometry...");
- // 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 IfcGeomObjects.h for definition)
- // IfcGeomObjects::Next() is used to poll whether more geometrical entities are available
+ // The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
+ // wrap an iterator of all geometrical products in the Ifc file.
+ // IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or
+ // -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
+ // for definition) IfcGeom::Iterator::next() is used to poll whether more
+ // geometrical entities are available. None of these functions throw
+ // exceptions, neither for parsing errors or geometrical errors. Upon
+ // calling next() the entity to be returned has already been processed, a
+ // true return value guarantees that a successfully processed product is
+ // available.
do {
- const IfcGeomObjects::IfcObject* geom_object;
+ const IfcGeom::Element* geom_object = context_iterator.get();
if (serializer->isTesselated()) {
- geom_object = IfcGeomObjects::Get();
- } else {
- geom_object = IfcGeomObjects::GetShapeModel();
- }
-
- std::string lowercase_type = geom_object->type();
- for (std::string::iterator c = lowercase_type.begin(); c != lowercase_type.end(); ++c) {
- *c = tolower(*c);
- }
- if (ignore_types.find(lowercase_type) != ignore_types.end()) continue;
-
- if (serializer->isTesselated()) {
- serializer->writeTesselated(static_cast(geom_object));
+ serializer->write(static_cast*>(geom_object));
} else {
- serializer->writeShapeModel(static_cast(geom_object));
+ serializer->write(static_cast*>(geom_object));
}
-
- const int progress = IfcGeomObjects::Progress() / 2;
- if ( old_progress!= progress ) Logger::ProgressBar(progress);
+
+ const int progress = context_iterator.progress() / 2;
+ if (old_progress!= progress) Logger::ProgressBar(progress);
old_progress = progress;
- } while ( IfcGeomObjects::Next() );
+ } while (context_iterator.next());
serializer->finalize();
delete serializer;
@@ -292,6 +343,8 @@ int main(int argc, char** argv) {
time(&end);
int dif = (int) difftime (end,start);
printf ("\nConversion took %d seconds\n", dif );
+
+ return 0;
}
void write_log() {
diff --git a/src/ifcconvert/IgesSerializer.h b/src/ifcconvert/IgesSerializer.h
index d18082c..8591af9 100644
--- a/src/ifcconvert/IgesSerializer.h
+++ b/src/ifcconvert/IgesSerializer.h
@@ -24,7 +24,7 @@
#include
#include
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcconvert/OpenCascadeBasedSerializer.h"
diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.cpp b/src/ifcconvert/OpenCascadeBasedSerializer.cpp
index 0bf3f0c..77bc7e7 100644
--- a/src/ifcconvert/OpenCascadeBasedSerializer.cpp
+++ b/src/ifcconvert/OpenCascadeBasedSerializer.cpp
@@ -24,6 +24,8 @@
#include
#include
+#include
+
#include "OpenCascadeBasedSerializer.h"
bool OpenCascadeBasedSerializer::ready() {
@@ -34,18 +36,25 @@ bool OpenCascadeBasedSerializer::ready() {
return succeeded;
}
-void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {
- for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->mesh().begin(); it != o->mesh().end(); ++ it) {
+void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) {
+ for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
gp_GTrsf gtrsf = it->Placement();
+
+ const std::vector& matrix = o->transformation().matrix().data();
- // 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++]);
-
+ // 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(
+ matrix[0], matrix[3], matrix[6], matrix[ 9],
+ matrix[1], matrix[4], matrix[7], matrix[10],
+ matrix[2], matrix[5], matrix[8], matrix[11]
+#if OCC_VERSION_HEX < 0x60800
+ , Precision::Angular(), Precision::Confusion()
+#endif
+ );
gtrsf.PreMultiply(o_trsf);
+
const TopoDS_Shape& s = it->Shape();
bool trsf_valid = false;
@@ -64,18 +73,18 @@ void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomSh
}
#define RATHER_SMALL (1e-3)
-#define ALMOST_THE_SAME(a,b) (fabs(a-b) < RATHER_SMALL)
+#define APPROXIMATELY_THE_SAME(a,b) (fabs(a-b) < RATHER_SMALL)
const char* OpenCascadeBasedSerializer::getSymbolForUnitMagnitude(float mag) {
- if (ALMOST_THE_SAME(mag, 0.001f)) {
+ if (APPROXIMATELY_THE_SAME(mag, 0.001f)) {
return "MM";
- } else if (ALMOST_THE_SAME(mag, 0.01f)) {
+ } else if (APPROXIMATELY_THE_SAME(mag, 0.01f)) {
return "CM";
- } else if (ALMOST_THE_SAME(mag, 1.0f)) {
+ } else if (APPROXIMATELY_THE_SAME(mag, 1.0f)) {
return "M";
- } else if (ALMOST_THE_SAME(mag, 0.3048f)) {
+ } else if (APPROXIMATELY_THE_SAME(mag, 0.3048f)) {
return "FT";
- } else if (ALMOST_THE_SAME(mag, 0.0254f)) {
+ } else if (APPROXIMATELY_THE_SAME(mag, 0.0254f)) {
return "INCH";
} else {
return 0;
diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.h b/src/ifcconvert/OpenCascadeBasedSerializer.h
index 1547236..74a76ca 100644
--- a/src/ifcconvert/OpenCascadeBasedSerializer.h
+++ b/src/ifcconvert/OpenCascadeBasedSerializer.h
@@ -20,7 +20,7 @@
#ifndef OPENCASCADEBASEDSERIALIZER_H
#define OPENCASCADEBASEDSERIALIZER_H
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcconvert/GeometrySerializer.h"
@@ -38,9 +38,10 @@ class OpenCascadeBasedSerializer : public GeometrySerializer {
void writeMaterial(const IfcGeom::SurfaceStyle& style) {}
bool ready();
virtual void writeShape(const TopoDS_Shape& shape) = 0;
- void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {}
- void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o);
+ void write(const IfcGeom::TriangulationElement* o) {}
+ void write(const IfcGeom::BRepElement* o);
bool isTesselated() const { return false; }
+ void setFile(IfcParse::IfcFile*) {}
};
#endif
\ No newline at end of file
diff --git a/src/ifcconvert/Serializer.h b/src/ifcconvert/Serializer.h
new file mode 100644
index 0000000..ba5d6fa
--- /dev/null
+++ b/src/ifcconvert/Serializer.h
@@ -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 . *
+ * *
+ ********************************************************************************/
+
+#ifndef SERIALIZER_H
+#define SERIALIZER_H
+
+#include "../ifcparse/IfcFile.h"
+
+class Serializer {
+public:
+ virtual ~Serializer() {}
+
+ virtual bool ready() = 0;
+ virtual void writeHeader() = 0;
+ virtual void finalize() = 0;
+ virtual void setFile(IfcParse::IfcFile*) = 0;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/ifcconvert/StepSerializer.h b/src/ifcconvert/StepSerializer.h
index d0db600..4667104 100644
--- a/src/ifcconvert/StepSerializer.h
+++ b/src/ifcconvert/StepSerializer.h
@@ -24,7 +24,7 @@
#include
#include
-#include "../ifcgeom/IfcGeomObjects.h"
+#include "../ifcgeom/IfcGeomIterator.h"
#include "../ifcconvert/OpenCascadeBasedSerializer.h"
diff --git a/src/ifcconvert/WavefrontObjSerializer.cpp b/src/ifcconvert/WavefrontObjSerializer.cpp
index 60dea65..a931a30 100644
--- a/src/ifcconvert/WavefrontObjSerializer.cpp
+++ b/src/ifcconvert/WavefrontObjSerializer.cpp
@@ -43,7 +43,7 @@ void WaveFrontOBJSerializer::writeHeader() {
mtl_stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
}
-void WaveFrontOBJSerializer::writeMaterial(const IfcGeomObjects::Material& style) {
+void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style) {
mtl_stream << "newmtl " << style.name() << "\n";
if (style.hasDiffuse()) {
const double* diffuse = style.diffuse();
@@ -65,7 +65,7 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeomObjects::Material& style
}
}
}
-void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
+void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o) {
std::string tmp = o->name().empty() ? o->guid() : o->name();
@@ -74,16 +74,16 @@ void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject
obj_stream << "g " << name << "\n";
obj_stream << "s 1" << "\n";
- const IfcGeomObjects::IfcRepresentationTriangulation& mesh = o->mesh();
+ const IfcGeom::Representation::Triangulation& mesh = o->geometry();
const int vcount = mesh.verts().size() / 3;
- for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
+ for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
obj_stream << "v " << x << " " << y << " " << z << "\n";
}
- for ( std::vector::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) {
+ for ( std::vector::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
@@ -97,12 +97,7 @@ void WaveFrontOBJSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject
const int material_id = *(material_it++);
if (material_id != previous_material_id) {
- IfcGeomObjects::Material material(0);
- if (material_id >= 0) {
- material = mesh.materials()[material_id];
- } else {
- material = IfcGeomObjects::Material(IfcGeom::get_default_style(o->type()));
- }
+ const IfcGeom::Material& material = mesh.materials()[material_id];
const std::string material_name = material.name();
obj_stream << "usemtl " << material_name << "\n";
if (materials.find(material_name) == materials.end()) {
diff --git a/src/ifcconvert/WavefrontObjSerializer.h b/src/ifcconvert/WavefrontObjSerializer.h
index b31dcc1..7cb6790 100644
--- a/src/ifcconvert/WavefrontObjSerializer.h
+++ b/src/ifcconvert/WavefrontObjSerializer.h
@@ -44,12 +44,13 @@ class WaveFrontOBJSerializer : public GeometrySerializer {
virtual ~WaveFrontOBJSerializer() {}
bool ready();
void writeHeader();
- void writeMaterial(const IfcGeomObjects::Material& style);
- void writeTesselated(const IfcGeomObjects::IfcGeomObject* o);
- void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
+ void writeMaterial(const IfcGeom::Material& style);
+ void write(const IfcGeom::TriangulationElement* o);
+ void write(const IfcGeom::BRepElement* o) {}
void finalize() {}
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {}
+ void setFile(IfcParse::IfcFile*) {}
};
#endif
\ No newline at end of file
diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp
new file mode 100644
index 0000000..bdfbc66
--- /dev/null
+++ b/src/ifcconvert/XmlSerializer.cpp
@@ -0,0 +1,257 @@
+#include