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