vrshoot
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/IFCUtil.h Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,412 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 +/** @file IFC.cpp 1.45 + * @brief Implementation of the Industry Foundation Classes loader. 1.46 + */ 1.47 + 1.48 +#ifndef INCLUDED_IFCUTIL_H 1.49 +#define INCLUDED_IFCUTIL_H 1.50 + 1.51 +#include "IFCReaderGen.h" 1.52 +#include "IFCLoader.h" 1.53 + 1.54 +namespace Assimp { 1.55 +namespace IFC { 1.56 + 1.57 + typedef double IfcFloat; 1.58 + 1.59 + // IfcFloat-precision math data types 1.60 + typedef aiVector2t<IfcFloat> IfcVector2; 1.61 + typedef aiVector3t<IfcFloat> IfcVector3; 1.62 + typedef aiMatrix4x4t<IfcFloat> IfcMatrix4; 1.63 + typedef aiMatrix3x3t<IfcFloat> IfcMatrix3; 1.64 + typedef aiColor4t<IfcFloat> IfcColor4; 1.65 + 1.66 + 1.67 +// ------------------------------------------------------------------------------------------------ 1.68 +// Helper for std::for_each to delete all heap-allocated items in a container 1.69 +// ------------------------------------------------------------------------------------------------ 1.70 +template<typename T> 1.71 +struct delete_fun 1.72 +{ 1.73 + void operator()(T* del) { 1.74 + delete del; 1.75 + } 1.76 +}; 1.77 + 1.78 + 1.79 + 1.80 +// ------------------------------------------------------------------------------------------------ 1.81 +// Helper used during mesh construction. Aids at creating aiMesh'es out of relatively few polygons. 1.82 +// ------------------------------------------------------------------------------------------------ 1.83 +struct TempMesh 1.84 +{ 1.85 + std::vector<IfcVector3> verts; 1.86 + std::vector<unsigned int> vertcnt; 1.87 + 1.88 + // utilities 1.89 + aiMesh* ToMesh(); 1.90 + void Clear(); 1.91 + void Transform(const IfcMatrix4& mat); 1.92 + IfcVector3 Center() const; 1.93 + void Append(const TempMesh& other); 1.94 + 1.95 + bool IsEmpty() const { 1.96 + return verts.empty() && vertcnt.empty(); 1.97 + } 1.98 + 1.99 + void RemoveAdjacentDuplicates(); 1.100 + void RemoveDegenerates(); 1.101 + 1.102 + void FixupFaceOrientation(); 1.103 + IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const; 1.104 + void ComputePolygonNormals(std::vector<IfcVector3>& normals, 1.105 + bool normalize = true, 1.106 + size_t ofs = 0) const; 1.107 + 1.108 + void Swap(TempMesh& other); 1.109 +}; 1.110 + 1.111 + 1.112 +// ------------------------------------------------------------------------------------------------ 1.113 +// Temporary representation of an opening in a wall or a floor 1.114 +// ------------------------------------------------------------------------------------------------ 1.115 +struct TempOpening 1.116 +{ 1.117 + const IFC::IfcSolidModel* solid; 1.118 + IfcVector3 extrusionDir; 1.119 + 1.120 + boost::shared_ptr<TempMesh> profileMesh; 1.121 + boost::shared_ptr<TempMesh> profileMesh2D; 1.122 + 1.123 + // list of points generated for this opening. This is used to 1.124 + // create connections between two opposing holes created 1.125 + // from a single opening instance (two because walls tend to 1.126 + // have two sides). If !empty(), the other side of the wall 1.127 + // has already been processed. 1.128 + std::vector<IfcVector3> wallPoints; 1.129 + 1.130 + // ------------------------------------------------------------------------------ 1.131 + TempOpening() 1.132 + : solid() 1.133 + , extrusionDir() 1.134 + , profileMesh() 1.135 + { 1.136 + } 1.137 + 1.138 + // ------------------------------------------------------------------------------ 1.139 + TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir, 1.140 + boost::shared_ptr<TempMesh> profileMesh, 1.141 + boost::shared_ptr<TempMesh> profileMesh2D) 1.142 + : solid(solid) 1.143 + , extrusionDir(extrusionDir) 1.144 + , profileMesh(profileMesh) 1.145 + , profileMesh2D(profileMesh2D) 1.146 + { 1.147 + } 1.148 + 1.149 + // ------------------------------------------------------------------------------ 1.150 + void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet 1.151 + 1.152 + 1.153 + 1.154 + // ------------------------------------------------------------------------------ 1.155 + // Helper to sort openings by distance from a given base point 1.156 + struct DistanceSorter { 1.157 + 1.158 + DistanceSorter(const IfcVector3& base) : base(base) {} 1.159 + 1.160 + bool operator () (const TempOpening& a, const TempOpening& b) const { 1.161 + return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength(); 1.162 + } 1.163 + 1.164 + IfcVector3 base; 1.165 + }; 1.166 +}; 1.167 + 1.168 + 1.169 +// ------------------------------------------------------------------------------------------------ 1.170 +// Intermediate data storage during conversion. Keeps everything and a bit more. 1.171 +// ------------------------------------------------------------------------------------------------ 1.172 +struct ConversionData 1.173 +{ 1.174 + ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings) 1.175 + : len_scale(1.0) 1.176 + , angle_scale(-1.0) 1.177 + , db(db) 1.178 + , proj(proj) 1.179 + , out(out) 1.180 + , settings(settings) 1.181 + , apply_openings() 1.182 + , collect_openings() 1.183 + {} 1.184 + 1.185 + ~ConversionData() { 1.186 + std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>()); 1.187 + std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>()); 1.188 + } 1.189 + 1.190 + IfcFloat len_scale, angle_scale; 1.191 + bool plane_angle_in_radians; 1.192 + 1.193 + const STEP::DB& db; 1.194 + const IFC::IfcProject& proj; 1.195 + aiScene* out; 1.196 + 1.197 + IfcMatrix4 wcs; 1.198 + std::vector<aiMesh*> meshes; 1.199 + std::vector<aiMaterial*> materials; 1.200 + 1.201 + typedef std::map<const IFC::IfcRepresentationItem*, std::vector<unsigned int> > MeshCache; 1.202 + MeshCache cached_meshes; 1.203 + 1.204 + const IFCImporter::Settings& settings; 1.205 + 1.206 + // Intermediate arrays used to resolve openings in walls: only one of them 1.207 + // can be given at a time. apply_openings if present if the current element 1.208 + // is a wall and needs its openings to be poured into its geometry while 1.209 + // collect_openings is present only if the current element is an 1.210 + // IfcOpeningElement, for which all the geometry needs to be preserved 1.211 + // for later processing by a parent, which is a wall. 1.212 + std::vector<TempOpening>* apply_openings; 1.213 + std::vector<TempOpening>* collect_openings; 1.214 + 1.215 + std::set<uint64_t> already_processed; 1.216 +}; 1.217 + 1.218 + 1.219 +// ------------------------------------------------------------------------------------------------ 1.220 +// Binary predicate to compare vectors with a given, quadratic epsilon. 1.221 +// ------------------------------------------------------------------------------------------------ 1.222 +struct FuzzyVectorCompare { 1.223 + 1.224 + FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {} 1.225 + bool operator()(const IfcVector3& a, const IfcVector3& b) { 1.226 + return fabs((a-b).SquareLength()) < epsilon; 1.227 + } 1.228 + 1.229 + const IfcFloat epsilon; 1.230 +}; 1.231 + 1.232 + 1.233 +// ------------------------------------------------------------------------------------------------ 1.234 +// Ordering predicate to totally order R^2 vectors first by x and then by y 1.235 +// ------------------------------------------------------------------------------------------------ 1.236 +struct XYSorter { 1.237 + 1.238 + // sort first by X coordinates, then by Y coordinates 1.239 + bool operator () (const IfcVector2&a, const IfcVector2& b) const { 1.240 + if (a.x == b.x) { 1.241 + return a.y < b.y; 1.242 + } 1.243 + return a.x < b.x; 1.244 + } 1.245 +}; 1.246 + 1.247 + 1.248 + 1.249 +// conversion routines for common IFC entities, implemented in IFCUtil.cpp 1.250 +void ConvertColor(aiColor4D& out, const IfcColourRgb& in); 1.251 +void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base); 1.252 +void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in); 1.253 +void ConvertDirection(IfcVector3& out, const IfcDirection& in); 1.254 +void ConvertVector(IfcVector3& out, const IfcVector& in); 1.255 +void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z); 1.256 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in); 1.257 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in); 1.258 +void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in); 1.259 +void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv); 1.260 +void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op); 1.261 +bool IsTrue(const EXPRESS::BOOLEAN& in); 1.262 +IfcFloat ConvertSIPrefix(const std::string& prefix); 1.263 + 1.264 + 1.265 +// IFCProfile.cpp 1.266 +bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv); 1.267 + 1.268 +// IFCMaterial.cpp 1.269 +unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, ConversionData& conv); 1.270 + 1.271 +// IFCGeometry.cpp 1.272 +IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut); 1.273 +bool ProcessRepresentationItem(const IfcRepresentationItem& item, std::vector<unsigned int>& mesh_indices, ConversionData& conv); 1.274 +void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,ConversionData& /*conv*/); 1.275 + 1.276 +void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, 1.277 + ConversionData& conv); 1.278 + 1.279 +void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result, 1.280 + ConversionData& conv, bool collect_openings); 1.281 + 1.282 +// IFCBoolean.cpp 1.283 + 1.284 +void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv); 1.285 +void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, 1.286 + const TempMesh& first_operand, 1.287 + ConversionData& conv); 1.288 + 1.289 +void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, 1.290 + const TempMesh& first_operand, 1.291 + ConversionData& conv); 1.292 +void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, 1.293 + const TempMesh& first_operand, 1.294 + ConversionData& conv); 1.295 + 1.296 + 1.297 +// IFCOpenings.cpp 1.298 + 1.299 +bool GenerateOpenings(std::vector<TempOpening>& openings, 1.300 + const std::vector<IfcVector3>& nors, 1.301 + TempMesh& curmesh, 1.302 + bool check_intersection, 1.303 + bool generate_connection_geometry, 1.304 + const IfcVector3& wall_extrusion_axis = IfcVector3(0,1,0)); 1.305 + 1.306 + 1.307 + 1.308 +// IFCCurve.cpp 1.309 + 1.310 +// ------------------------------------------------------------------------------------------------ 1.311 +// Custom exception for use by members of the Curve class 1.312 +// ------------------------------------------------------------------------------------------------ 1.313 +class CurveError 1.314 +{ 1.315 +public: 1.316 + CurveError(const std::string& s) 1.317 + : s(s) 1.318 + { 1.319 + } 1.320 + 1.321 + std::string s; 1.322 +}; 1.323 + 1.324 + 1.325 +// ------------------------------------------------------------------------------------------------ 1.326 +// Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves 1.327 +// to obtain a list of line segments. 1.328 +// ------------------------------------------------------------------------------------------------ 1.329 +class Curve 1.330 +{ 1.331 +protected: 1.332 + 1.333 + Curve(const IfcCurve& base_entity, ConversionData& conv) 1.334 + : base_entity(base_entity) 1.335 + , conv(conv) 1.336 + {} 1.337 + 1.338 +public: 1.339 + 1.340 + typedef std::pair<IfcFloat, IfcFloat> ParamRange; 1.341 + 1.342 +public: 1.343 + 1.344 + 1.345 + virtual ~Curve() {} 1.346 + 1.347 + 1.348 + // check if a curve is closed 1.349 + virtual bool IsClosed() const = 0; 1.350 + 1.351 + // evaluate the curve at the given parametric position 1.352 + virtual IfcVector3 Eval(IfcFloat p) const = 0; 1.353 + 1.354 + // try to match a point on the curve to a given parameter 1.355 + // for self-intersecting curves, the result is not ambiguous and 1.356 + // it is undefined which parameter is returned. 1.357 + virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const; 1.358 + 1.359 + // get the range of the curve (both inclusive). 1.360 + // +inf and -inf are valid return values, the curve is not bounded in such a case. 1.361 + virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0; 1.362 + IfcFloat GetParametricRangeDelta() const; 1.363 + 1.364 + // estimate the number of sample points that this curve will require 1.365 + virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const; 1.366 + 1.367 + // intelligently sample the curve based on the current settings 1.368 + // and append the result to the mesh 1.369 + virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const; 1.370 + 1.371 +#ifdef _DEBUG 1.372 + // check if a particular parameter value lies within the well-defined range 1.373 + bool InRange(IfcFloat) const; 1.374 +#endif 1.375 + 1.376 +public: 1.377 + 1.378 + static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv); 1.379 + 1.380 +protected: 1.381 + 1.382 + const IfcCurve& base_entity; 1.383 + ConversionData& conv; 1.384 +}; 1.385 + 1.386 + 1.387 +// -------------------------------------------------------------------------------- 1.388 +// A BoundedCurve always holds the invariant that GetParametricRange() 1.389 +// never returns infinite values. 1.390 +// -------------------------------------------------------------------------------- 1.391 +class BoundedCurve : public Curve 1.392 +{ 1.393 +public: 1.394 + 1.395 + BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv) 1.396 + : Curve(entity,conv) 1.397 + {} 1.398 + 1.399 +public: 1.400 + 1.401 + bool IsClosed() const; 1.402 + 1.403 +public: 1.404 + 1.405 + // sample the entire curve 1.406 + void SampleDiscrete(TempMesh& out) const; 1.407 + using Curve::SampleDiscrete; 1.408 +}; 1.409 + 1.410 +// IfcProfile.cpp 1.411 +bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv); 1.412 +} 1.413 +} 1.414 + 1.415 +#endif