vrshoot

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