vrshoot

view libs/assimp/IFCUtil.h @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 /** @file IFC.cpp
42 * @brief Implementation of the Industry Foundation Classes loader.
43 */
45 #ifndef INCLUDED_IFCUTIL_H
46 #define INCLUDED_IFCUTIL_H
48 #include "IFCReaderGen.h"
49 #include "IFCLoader.h"
51 namespace Assimp {
52 namespace IFC {
54 typedef double IfcFloat;
56 // IfcFloat-precision math data types
57 typedef aiVector2t<IfcFloat> IfcVector2;
58 typedef aiVector3t<IfcFloat> IfcVector3;
59 typedef aiMatrix4x4t<IfcFloat> IfcMatrix4;
60 typedef aiMatrix3x3t<IfcFloat> IfcMatrix3;
61 typedef aiColor4t<IfcFloat> IfcColor4;
64 // ------------------------------------------------------------------------------------------------
65 // Helper for std::for_each to delete all heap-allocated items in a container
66 // ------------------------------------------------------------------------------------------------
67 template<typename T>
68 struct delete_fun
69 {
70 void operator()(T* del) {
71 delete del;
72 }
73 };
77 // ------------------------------------------------------------------------------------------------
78 // Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons.
79 // ------------------------------------------------------------------------------------------------
80 struct TempMesh
81 {
82 std::vector<IfcVector3> verts;
83 std::vector<unsigned int> vertcnt;
85 // utilities
86 aiMesh* ToMesh();
87 void Clear();
88 void Transform(const IfcMatrix4& mat);
89 IfcVector3 Center() const;
90 void Append(const TempMesh& other);
92 bool IsEmpty() const {
93 return verts.empty() && vertcnt.empty();
94 }
96 void RemoveAdjacentDuplicates();
97 void RemoveDegenerates();
99 void FixupFaceOrientation();
100 IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const;
101 void ComputePolygonNormals(std::vector<IfcVector3>& normals,
102 bool normalize = true,
103 size_t ofs = 0) const;
105 void Swap(TempMesh& other);
106 };
109 // ------------------------------------------------------------------------------------------------
110 // Temporary representation of an opening in a wall or a floor
111 // ------------------------------------------------------------------------------------------------
112 struct TempOpening
113 {
114 const IFC::IfcSolidModel* solid;
115 IfcVector3 extrusionDir;
117 boost::shared_ptr<TempMesh> profileMesh;
118 boost::shared_ptr<TempMesh> profileMesh2D;
120 // list of points generated for this opening. This is used to
121 // create connections between two opposing holes created
122 // from a single opening instance (two because walls tend to
123 // have two sides). If !empty(), the other side of the wall
124 // has already been processed.
125 std::vector<IfcVector3> wallPoints;
127 // ------------------------------------------------------------------------------
128 TempOpening()
129 : solid()
130 , extrusionDir()
131 , profileMesh()
132 {
133 }
135 // ------------------------------------------------------------------------------
136 TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir,
137 boost::shared_ptr<TempMesh> profileMesh,
138 boost::shared_ptr<TempMesh> profileMesh2D)
139 : solid(solid)
140 , extrusionDir(extrusionDir)
141 , profileMesh(profileMesh)
142 , profileMesh2D(profileMesh2D)
143 {
144 }
146 // ------------------------------------------------------------------------------
147 void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet
151 // ------------------------------------------------------------------------------
152 // Helper to sort openings by distance from a given base point
153 struct DistanceSorter {
155 DistanceSorter(const IfcVector3& base) : base(base) {}
157 bool operator () (const TempOpening& a, const TempOpening& b) const {
158 return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength();
159 }
161 IfcVector3 base;
162 };
163 };
166 // ------------------------------------------------------------------------------------------------
167 // Intermediate data storage during conversion. Keeps everything and a bit more.
168 // ------------------------------------------------------------------------------------------------
169 struct ConversionData
170 {
171 ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings)
172 : len_scale(1.0)
173 , angle_scale(-1.0)
174 , db(db)
175 , proj(proj)
176 , out(out)
177 , settings(settings)
178 , apply_openings()
179 , collect_openings()
180 {}
182 ~ConversionData() {
183 std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>());
184 std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
185 }
187 IfcFloat len_scale, angle_scale;
188 bool plane_angle_in_radians;
190 const STEP::DB& db;
191 const IFC::IfcProject& proj;
192 aiScene* out;
194 IfcMatrix4 wcs;
195 std::vector<aiMesh*> meshes;
196 std::vector<aiMaterial*> materials;
198 typedef std::map<const IFC::IfcRepresentationItem*, std::vector<unsigned int> > MeshCache;
199 MeshCache cached_meshes;
201 const IFCImporter::Settings& settings;
203 // Intermediate arrays used to resolve openings in walls: only one of them
204 // can be given at a time. apply_openings if present if the current element
205 // is a wall and needs its openings to be poured into its geometry while
206 // collect_openings is present only if the current element is an
207 // IfcOpeningElement, for which all the geometry needs to be preserved
208 // for later processing by a parent, which is a wall.
209 std::vector<TempOpening>* apply_openings;
210 std::vector<TempOpening>* collect_openings;
212 std::set<uint64_t> already_processed;
213 };
216 // ------------------------------------------------------------------------------------------------
217 // Binary predicate to compare vectors with a given, quadratic epsilon.
218 // ------------------------------------------------------------------------------------------------
219 struct FuzzyVectorCompare {
221 FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
222 bool operator()(const IfcVector3& a, const IfcVector3& b) {
223 return fabs((a-b).SquareLength()) < epsilon;
224 }
226 const IfcFloat epsilon;
227 };
230 // ------------------------------------------------------------------------------------------------
231 // Ordering predicate to totally order R^2 vectors first by x and then by y
232 // ------------------------------------------------------------------------------------------------
233 struct XYSorter {
235 // sort first by X coordinates, then by Y coordinates
236 bool operator () (const IfcVector2&a, const IfcVector2& b) const {
237 if (a.x == b.x) {
238 return a.y < b.y;
239 }
240 return a.x < b.x;
241 }
242 };
246 // conversion routines for common IFC entities, implemented in IFCUtil.cpp
247 void ConvertColor(aiColor4D& out, const IfcColourRgb& in);
248 void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base);
249 void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in);
250 void ConvertDirection(IfcVector3& out, const IfcDirection& in);
251 void ConvertVector(IfcVector3& out, const IfcVector& in);
252 void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z);
253 void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in);
254 void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in);
255 void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in);
256 void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv);
257 void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op);
258 bool IsTrue(const EXPRESS::BOOLEAN& in);
259 IfcFloat ConvertSIPrefix(const std::string& prefix);
262 // IFCProfile.cpp
263 bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
265 // IFCMaterial.cpp
266 unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv);
268 // IFCGeometry.cpp
269 IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut);
270 bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv);
271 void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/);
273 void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
274 ConversionData& conv);
276 void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
277 ConversionData& conv, bool collect_openings);
279 // IFCBoolean.cpp
281 void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv);
282 void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result,
283 const TempMesh& first_operand,
284 ConversionData& conv);
286 void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result,
287 const TempMesh& first_operand,
288 ConversionData& conv);
289 void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result,
290 const TempMesh& first_operand,
291 ConversionData& conv);
294 // IFCOpenings.cpp
296 bool GenerateOpenings(std::vector<TempOpening>& openings,
297 const std::vector<IfcVector3>& nors,
298 TempMesh& curmesh,
299 bool check_intersection,
300 bool generate_connection_geometry,
301 const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0));
305 // IFCCurve.cpp
307 // ------------------------------------------------------------------------------------------------
308 // Custom exception for use by members of the Curve class
309 // ------------------------------------------------------------------------------------------------
310 class CurveError
311 {
312 public:
313 CurveError(const std::string& s)
314 : s(s)
315 {
316 }
318 std::string s;
319 };
322 // ------------------------------------------------------------------------------------------------
323 // Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves
324 // to obtain a list of line segments.
325 // ------------------------------------------------------------------------------------------------
326 class Curve
327 {
328 protected:
330 Curve(const IfcCurve& base_entity, ConversionData& conv)
331 : base_entity(base_entity)
332 , conv(conv)
333 {}
335 public:
337 typedef std::pair<IfcFloat, IfcFloat> ParamRange;
339 public:
342 virtual ~Curve() {}
345 // check if a curve is closed
346 virtual bool IsClosed() const = 0;
348 // evaluate the curve at the given parametric position
349 virtual IfcVector3 Eval(IfcFloat p) const = 0;
351 // try to match a point on the curve to a given parameter
352 // for self-intersecting curves, the result is not ambiguous and
353 // it is undefined which parameter is returned.
354 virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const;
356 // get the range of the curve (both inclusive).
357 // +inf and -inf are valid return values, the curve is not bounded in such a case.
358 virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0;
359 IfcFloat GetParametricRangeDelta() const;
361 // estimate the number of sample points that this curve will require
362 virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const;
364 // intelligently sample the curve based on the current settings
365 // and append the result to the mesh
366 virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
368 #ifdef _DEBUG
369 // check if a particular parameter value lies within the well-defined range
370 bool InRange(IfcFloat) const;
371 #endif
373 public:
375 static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv);
377 protected:
379 const IfcCurve& base_entity;
380 ConversionData& conv;
381 };
384 // --------------------------------------------------------------------------------
385 // A BoundedCurve always holds the invariant that GetParametricRange()
386 // never returns infinite values.
387 // --------------------------------------------------------------------------------
388 class BoundedCurve : public Curve
389 {
390 public:
392 BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv)
393 : Curve(entity,conv)
394 {}
396 public:
398 bool IsClosed() const;
400 public:
402 // sample the entire curve
403 void SampleDiscrete(TempMesh& out) const;
404 using Curve::SampleDiscrete;
405 };
407 // IfcProfile.cpp
408 bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
409 }
410 }
412 #endif