- Ifc: make code base ready for running double precision by using the new math templates with a customizable float type, IfcFloat. (still using floats with this commit).

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1133 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/5/head
aramis_acg 2012-02-02 02:09:49 +00:00
parent 0f541f5e2b
commit e867c73327
7 changed files with 368 additions and 358 deletions

View File

@ -64,14 +64,14 @@ public:
Conic(const IfcConic& entity, ConversionData& conv) Conic(const IfcConic& entity, ConversionData& conv)
: Curve(entity,conv) : Curve(entity,conv)
{ {
aiMatrix4x4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo,*entity.Position,conv); ConvertAxisPlacement(trafo,*entity.Position,conv);
// for convenience, extract the matrix rows // for convenience, extract the matrix rows
location = aiVector3D(trafo.a4,trafo.b4,trafo.c4); location = IfcVector3(trafo.a4,trafo.b4,trafo.c4);
p[0] = aiVector3D(trafo.a1,trafo.b1,trafo.c1); p[0] = IfcVector3(trafo.a1,trafo.b1,trafo.c1);
p[1] = aiVector3D(trafo.a2,trafo.b2,trafo.c2); p[1] = IfcVector3(trafo.a2,trafo.b2,trafo.c2);
p[2] = aiVector3D(trafo.a3,trafo.b3,trafo.c3); p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
} }
public: public:
@ -82,21 +82,21 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(float a, float b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
a = fmod(a,360.f); a = fmod(a,static_cast<IfcFloat>( 360. ));
b = fmod(b,360.f); b = fmod(b,static_cast<IfcFloat>( 360. ));
return static_cast<size_t>( fabs(ceil(( b-a)) / conv.settings.conicSamplingAngle) ); return static_cast<size_t>( abs(ceil(( b-a)) / conv.settings.conicSamplingAngle) );
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const {
return std::make_pair(0.f,360.f); return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( 360. ));
} }
protected: protected:
aiVector3D location, p[3]; IfcVector3 location, p[3];
}; };
@ -118,7 +118,7 @@ public:
public: public:
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float u) const { IfcVector3 Eval(IfcFloat u) const {
u = -conv.angle_scale * u; u = -conv.angle_scale * u;
return location + entity.Radius*(::cos(u)*p[0] + ::sin(u)*p[1]); return location + entity.Radius*(::cos(u)*p[0] + ::sin(u)*p[1]);
} }
@ -146,7 +146,7 @@ public:
public: public:
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float u) const { IfcVector3 Eval(IfcFloat u) const {
u = -conv.angle_scale * u; u = -conv.angle_scale * u;
return location + entity.SemiAxis1*::cos(u)*p[0] + entity.SemiAxis2*::sin(u)*p[1]; return location + entity.SemiAxis1*::cos(u)*p[0] + entity.SemiAxis2*::sin(u)*p[1];
} }
@ -181,12 +181,12 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float u) const { IfcVector3 Eval(IfcFloat u) const {
return p + u*v; return p + u*v;
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(float a, float b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
// two points are always sufficient for a line segment // two points are always sufficient for a line segment
return a==b ? 1 : 2; return a==b ? 1 : 2;
@ -194,7 +194,7 @@ public:
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,float a, float b) const void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
{ {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
@ -209,14 +209,14 @@ public:
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const {
const float inf = std::numeric_limits<float>::infinity(); const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
return std::make_pair(-inf,+inf); return std::make_pair(-inf,+inf);
} }
private: private:
const IfcLine& entity; const IfcLine& entity;
aiVector3D p,v; IfcVector3 p,v;
}; };
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
@ -262,15 +262,15 @@ public:
public: public:
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float u) const { IfcVector3 Eval(IfcFloat u) const {
if (curves.empty()) { if (curves.empty()) {
return aiVector3D(); return IfcVector3();
} }
float acc = 0; IfcFloat acc = 0;
BOOST_FOREACH(const CurveEntry& entry, curves) { BOOST_FOREACH(const CurveEntry& entry, curves) {
const ParamRange& range = entry.first->GetParametricRange(); const ParamRange& range = entry.first->GetParametricRange();
const float delta = range.second-range.first; const IfcFloat delta = range.second-range.first;
if (u < acc+delta) { if (u < acc+delta) {
return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc)); return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
} }
@ -282,16 +282,16 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(float a, float b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
size_t cnt = 0; size_t cnt = 0;
float acc = 0; IfcFloat acc = 0;
BOOST_FOREACH(const CurveEntry& entry, curves) { BOOST_FOREACH(const CurveEntry& entry, curves) {
const ParamRange& range = entry.first->GetParametricRange(); const ParamRange& range = entry.first->GetParametricRange();
const float delta = range.second-range.first; const IfcFloat delta = range.second-range.first;
if (a <= acc+delta && b >= acc) { if (a <= acc+delta && b >= acc) {
const float at = std::max(0.f,a-acc), bt = std::min(delta,b-acc); const IfcFloat at = std::max(static_cast<IfcFloat>( 0. ),a-acc), bt = std::min(delta,b-acc);
cnt += entry.first->EstimateSampleCount( entry.second ? at + range.first : range.second - bt, entry.second ? bt + range.first : range.second - at ); cnt += entry.first->EstimateSampleCount( entry.second ? at + range.first : range.second - bt, entry.second ? bt + range.first : range.second - at );
} }
@ -302,7 +302,7 @@ public:
} }
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,float a, float b) const void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
{ {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
@ -321,14 +321,14 @@ public:
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const {
return std::make_pair(0.f,total); return std::make_pair(static_cast<IfcFloat>( 0. ),total);
} }
private: private:
const IfcCompositeCurve& entity; const IfcCompositeCurve& entity;
std::vector< CurveEntry > curves; std::vector< CurveEntry > curves;
float total; IfcFloat total;
}; };
@ -356,7 +356,7 @@ public:
// claims that they must be identical if both are present. // claims that they must be identical if both are present.
// oh well. // oh well.
bool have_param = false, have_point = false; bool have_param = false, have_point = false;
aiVector3D point; IfcVector3 point;
BOOST_FOREACH(const Entry sel,entity.Trim1) { BOOST_FOREACH(const Entry sel,entity.Trim1) {
if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) { if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
range.first = *r; range.first = *r;
@ -411,26 +411,26 @@ public:
public: public:
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float p) const { IfcVector3 Eval(IfcFloat p) const {
ai_assert(InRange(p)); ai_assert(InRange(p));
return base->Eval( TrimParam(p) ); return base->Eval( TrimParam(p) );
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(float a, float b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
return base->EstimateSampleCount(TrimParam(a),TrimParam(b)); return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const {
return std::make_pair(0.f,maxval); return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
} }
private: private:
// -------------------------------------------------- // --------------------------------------------------
float TrimParam(float f) const { IfcFloat TrimParam(IfcFloat f) const {
return agree_sense ? f + range.first : range.second - f; return agree_sense ? f + range.first : range.second - f;
} }
@ -438,7 +438,7 @@ private:
private: private:
const IfcTrimmedCurve& entity; const IfcTrimmedCurve& entity;
ParamRange range; ParamRange range;
float maxval; IfcFloat maxval;
bool agree_sense; bool agree_sense;
bool ok; bool ok;
@ -461,7 +461,7 @@ public:
{ {
points.reserve(entity.Points.size()); points.reserve(entity.Points.size());
aiVector3D t; IfcVector3 t;
BOOST_FOREACH(const IfcCartesianPoint& cp, entity.Points) { BOOST_FOREACH(const IfcCartesianPoint& cp, entity.Points) {
ConvertCartesianPoint(t,cp); ConvertCartesianPoint(t,cp);
points.push_back(t); points.push_back(t);
@ -471,7 +471,7 @@ public:
public: public:
// -------------------------------------------------- // --------------------------------------------------
aiVector3D Eval(float p) const { IfcVector3 Eval(IfcFloat p) const {
ai_assert(InRange(p)); ai_assert(InRange(p));
const size_t b = static_cast<size_t>(floor(p)); const size_t b = static_cast<size_t>(floor(p));
@ -479,24 +479,24 @@ public:
return points.back(); return points.back();
} }
const float d = p-static_cast<float>(b); const IfcFloat d = p-static_cast<IfcFloat>(b);
return points[b+1] * d + points[b] * (1.f-d); return points[b+1] * d + points[b] * (static_cast<IfcFloat>( 1. )-d);
} }
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(float a, float b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
return static_cast<size_t>( ceil(b) - floor(a) ); return static_cast<size_t>( ceil(b) - floor(a) );
} }
// -------------------------------------------------- // --------------------------------------------------
ParamRange GetParametricRange() const { ParamRange GetParametricRange() const {
return std::make_pair(0.f,static_cast<float>(points.size()-1)); return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
} }
private: private:
const IfcPolyline& entity; const IfcPolyline& entity;
std::vector<aiVector3D> points; std::vector<IfcVector3> points;
}; };
@ -540,11 +540,11 @@ Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
#ifdef _DEBUG #ifdef _DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Curve :: InRange(float u) const bool Curve :: InRange(IfcFloat u) const
{ {
const ParamRange range = GetParametricRange(); const ParamRange range = GetParametricRange();
if (IsClosed()) { if (IsClosed()) {
ai_assert(range.first != std::numeric_limits<float>::infinity() && range.second != std::numeric_limits<float>::infinity()); ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
u = range.first + fmod(u-range.first,range.second-range.first); u = range.first + fmod(u-range.first,range.second-range.first);
} }
return u >= range.first && u <= range.second; return u >= range.first && u <= range.second;
@ -552,14 +552,14 @@ bool Curve :: InRange(float u) const
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float Curve :: GetParametricRangeDelta() const IfcFloat Curve :: GetParametricRangeDelta() const
{ {
const ParamRange& range = GetParametricRange(); const ParamRange& range = GetParametricRange();
return range.second - range.first; return range.second - range.first;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
size_t Curve :: EstimateSampleCount(float a, float b) const size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const
{ {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
@ -568,16 +568,16 @@ size_t Curve :: EstimateSampleCount(float a, float b) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float RecursiveSearch(const Curve* cv, const aiVector3D& val, float a, float b, unsigned int samples, float threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b, unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15)
{ {
ai_assert(samples>1); ai_assert(samples>1);
const float delta = (b-a)/samples, inf = std::numeric_limits<float>::infinity(); const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
float min_point[2] = {a,b}, min_diff[2] = {inf,inf}; IfcFloat min_point[2] = {a,b}, min_diff[2] = {inf,inf};
float runner = a; IfcFloat runner = a;
for (unsigned int i = 0; i < samples; ++i, runner += delta) { for (unsigned int i = 0; i < samples; ++i, runner += delta) {
const float diff = (cv->Eval(runner)-val).SquareLength(); const IfcFloat diff = (cv->Eval(runner)-val).SquareLength();
if (diff < min_diff[0]) { if (diff < min_diff[0]) {
min_diff[1] = min_diff[0]; min_diff[1] = min_diff[0];
min_point[1] = min_point[0]; min_point[1] = min_point[0];
@ -599,10 +599,10 @@ float RecursiveSearch(const Curve* cv, const aiVector3D& val, float a, float b,
// fix for closed curves to take their wrap-over into account // fix for closed curves to take their wrap-over into account
if (cv->IsClosed() && fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) { if (cv->IsClosed() && fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) {
const Curve::ParamRange& range = cv->GetParametricRange(); const Curve::ParamRange& range = cv->GetParametricRange();
const float wrapdiff = (cv->Eval(range.first)-val).SquareLength(); const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
if (wrapdiff < min_diff[0]) { if (wrapdiff < min_diff[0]) {
const float t = min_point[0]; const IfcFloat t = min_point[0];
min_point[0] = min_point[1] > min_point[0] ? range.first : range.second; min_point[0] = min_point[1] > min_point[0] ? range.first : range.second;
min_point[1] = t; min_point[1] = t;
} }
@ -612,14 +612,14 @@ float RecursiveSearch(const Curve* cv, const aiVector3D& val, float a, float b,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool Curve :: ReverseEval(const aiVector3D& val, float& paramOut) const bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
{ {
// note: the following algorithm is not guaranteed to find the 'right' parameter value // note: the following algorithm is not guaranteed to find the 'right' parameter value
// in all possible cases, but it will always return at least some value so this function // in all possible cases, but it will always return at least some value so this function
// will never fail in the default implementation. // will never fail in the default implementation.
// XXX derive threshold from curve topology // XXX derive threshold from curve topology
const float threshold = 1e-4f; const IfcFloat threshold = 1e-4f;
const unsigned int samples = 16; const unsigned int samples = 16;
const ParamRange& range = GetParametricRange(); const ParamRange& range = GetParametricRange();
@ -629,14 +629,14 @@ bool Curve :: ReverseEval(const aiVector3D& val, float& paramOut) const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Curve :: SampleDiscrete(TempMesh& out,float a, float b) const void Curve :: SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
{ {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a) && InRange(b));
const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b)); const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
out.verts.reserve( out.verts.size() + cnt ); out.verts.reserve( out.verts.size() + cnt );
float p = a, delta = (b-a)/cnt; IfcFloat p = a, delta = (b-a)/cnt;
for(size_t i = 0; i < cnt; ++i, p += delta) { for(size_t i = 0; i < cnt; ++i, p += delta) {
out.verts.push_back(Eval(p)); out.verts.push_back(Eval(p));
} }
@ -652,7 +652,7 @@ bool BoundedCurve :: IsClosed() const
void BoundedCurve :: SampleDiscrete(TempMesh& out) const void BoundedCurve :: SampleDiscrete(TempMesh& out) const
{ {
const ParamRange& range = GetParametricRange(); const ParamRange& range = GetParametricRange();
ai_assert(range.first != std::numeric_limits<float>::infinity() && range.second != std::numeric_limits<float>::infinity()); ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
return SampleDiscrete(out,range.first,range.second); return SampleDiscrete(out,range.first,range.second);
} }

View File

@ -61,17 +61,17 @@ namespace Assimp {
// XXX use full -+ range ... // XXX use full -+ range ...
const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var const ClipperLib::long64 max_ulong64 = 1518500249; // clipper.cpp / hiRange var
//#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<double>((p)), 1.) ) * max_ulong64 )) //#define to_int64(p) (static_cast<ulong64>( std::max( 0., std::min( static_cast<IfcFloat>((p)), 1.) ) * max_ulong64 ))
#define to_int64(p) (static_cast<ulong64>(static_cast<double>((p) ) * max_ulong64 )) #define to_int64(p) (static_cast<ulong64>(static_cast<IfcFloat>((p) ) * max_ulong64 ))
#define from_int64(p) (static_cast<double>((p)) / max_ulong64) #define from_int64(p) (static_cast<IfcFloat>((p)) / max_ulong64)
#define from_int64_f(p) (static_cast<float>(from_int64((p)))) #define from_int64_f(p) (static_cast<IfcFloat>(from_int64((p))))
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/) bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/)
{ {
size_t cnt = 0; size_t cnt = 0;
BOOST_FOREACH(const IfcCartesianPoint& c, loop.Polygon) { BOOST_FOREACH(const IfcCartesianPoint& c, loop.Polygon) {
aiVector3D tmp; IfcVector3 tmp;
ConvertCartesianPoint(tmp,c); ConvertCartesianPoint(tmp,c);
meshout.verts.push_back(tmp); meshout.verts.push_back(tmp);
@ -93,7 +93,7 @@ bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData&
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ComputePolygonNormals(const TempMesh& meshout, std::vector<aiVector3D>& normals, bool normalize = true, size_t ofs = 0) void ComputePolygonNormals(const TempMesh& meshout, std::vector<IfcVector3>& normals, bool normalize = true, size_t ofs = 0)
{ {
size_t max_vcount = 0; size_t max_vcount = 0;
std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin()+ofs, end=meshout.vertcnt.end(), iit; std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin()+ofs, end=meshout.vertcnt.end(), iit;
@ -101,7 +101,7 @@ void ComputePolygonNormals(const TempMesh& meshout, std::vector<aiVector3D>& nor
max_vcount = std::max(max_vcount,static_cast<size_t>(*iit)); max_vcount = std::max(max_vcount,static_cast<size_t>(*iit));
} }
std::vector<float> temp((max_vcount+2)*4); std::vector<IfcFloat> temp((max_vcount+2)*4);
normals.reserve( normals.size() + meshout.vertcnt.size()-ofs ); normals.reserve( normals.size() + meshout.vertcnt.size()-ofs );
// `NewellNormal()` currently has a relatively strange interface and need to // `NewellNormal()` currently has a relatively strange interface and need to
@ -109,26 +109,26 @@ void ComputePolygonNormals(const TempMesh& meshout, std::vector<aiVector3D>& nor
size_t vidx = std::accumulate(meshout.vertcnt.begin(),begin,0); size_t vidx = std::accumulate(meshout.vertcnt.begin(),begin,0);
for(iit = begin; iit != end; vidx += *iit++) { for(iit = begin; iit != end; vidx += *iit++) {
if (!*iit) { if (!*iit) {
normals.push_back(aiVector3D()); normals.push_back(IfcVector3());
continue; continue;
} }
for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) { for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
const aiVector3D& v = meshout.verts[vidx+vofs]; const IfcVector3& v = meshout.verts[vidx+vofs];
temp[cnt++] = v.x; temp[cnt++] = v.x;
temp[cnt++] = v.y; temp[cnt++] = v.y;
temp[cnt++] = v.z; temp[cnt++] = v.z;
#ifdef _DEBUG #ifdef _DEBUG
temp[cnt] = std::numeric_limits<float>::quiet_NaN(); temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN();
#endif #endif
++cnt; ++cnt;
} }
normals.push_back(aiVector3D()); normals.push_back(IfcVector3());
NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]); NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
} }
if(normalize) { if(normalize) {
BOOST_FOREACH(aiVector3D& n, normals) { BOOST_FOREACH(IfcVector3& n, normals) {
n.Normalize(); n.Normalize();
} }
} }
@ -136,17 +136,17 @@ void ComputePolygonNormals(const TempMesh& meshout, std::vector<aiVector3D>& nor
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Compute the normal of the last polygon in the given mesh // Compute the normal of the last polygon in the given mesh
aiVector3D ComputePolygonNormal(const TempMesh& inmesh, bool normalize = true) IfcVector3 ComputePolygonNormal(const TempMesh& inmesh, bool normalize = true)
{ {
size_t total = inmesh.vertcnt.back(), vidx = inmesh.verts.size() - total; size_t total = inmesh.vertcnt.back(), vidx = inmesh.verts.size() - total;
std::vector<float> temp((total+2)*3); std::vector<IfcFloat> temp((total+2)*3);
for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) { for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) {
const aiVector3D& v = inmesh.verts[vidx+vofs]; const IfcVector3& v = inmesh.verts[vidx+vofs];
temp[cnt++] = v.x; temp[cnt++] = v.x;
temp[cnt++] = v.y; temp[cnt++] = v.y;
temp[cnt++] = v.z; temp[cnt++] = v.z;
} }
aiVector3D nor; IfcVector3 nor;
NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]); NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]);
return normalize ? nor.Normalize() : nor; return normalize ? nor.Normalize() : nor;
} }
@ -154,15 +154,15 @@ aiVector3D ComputePolygonNormal(const TempMesh& inmesh, bool normalize = true)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void FixupFaceOrientation(TempMesh& result) void FixupFaceOrientation(TempMesh& result)
{ {
const aiVector3D vavg = result.Center(); const IfcVector3 vavg = result.Center();
std::vector<aiVector3D> normals; std::vector<IfcVector3> normals;
ComputePolygonNormals(result,normals); ComputePolygonNormals(result,normals);
size_t c = 0, ofs = 0; size_t c = 0, ofs = 0;
BOOST_FOREACH(unsigned int cnt, result.vertcnt) { BOOST_FOREACH(unsigned int cnt, result.vertcnt) {
if (cnt>2){ if (cnt>2){
const aiVector3D& thisvert = result.verts[c]; const IfcVector3& thisvert = result.verts[c];
if (normals[ofs]*(thisvert-vavg) < 0) { if (normals[ofs]*(thisvert-vavg) < 0) {
std::reverse(result.verts.begin()+c,result.verts.begin()+cnt+c); std::reverse(result.verts.begin()+c,result.verts.begin()+cnt+c);
} }
@ -173,7 +173,7 @@ void FixupFaceOrientation(TempMesh& result)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void RecursiveMergeBoundaries(TempMesh& final_result, const TempMesh& in, const TempMesh& boundary, std::vector<aiVector3D>& normals, const aiVector3D& nor_boundary) void RecursiveMergeBoundaries(TempMesh& final_result, const TempMesh& in, const TempMesh& boundary, std::vector<IfcVector3>& normals, const IfcVector3& nor_boundary)
{ {
ai_assert(in.vertcnt.size() >= 1); ai_assert(in.vertcnt.size() >= 1);
ai_assert(boundary.vertcnt.size() == 1); ai_assert(boundary.vertcnt.size() == 1);
@ -185,15 +185,15 @@ void RecursiveMergeBoundaries(TempMesh& final_result, const TempMesh& in, const
// to the outer boundary is actually the shortest possible. // to the outer boundary is actually the shortest possible.
size_t vidx = 0, best_vidx_start = 0; size_t vidx = 0, best_vidx_start = 0;
size_t best_ofs, best_outer = boundary.verts.size(); size_t best_ofs, best_outer = boundary.verts.size();
float best_dist = 1e10; IfcFloat best_dist = 1e10;
for(std::vector<unsigned int>::const_iterator iit = begin; iit != end; vidx += *iit++) { for(std::vector<unsigned int>::const_iterator iit = begin; iit != end; vidx += *iit++) {
for(size_t vofs = 0; vofs < *iit; ++vofs) { for(size_t vofs = 0; vofs < *iit; ++vofs) {
const aiVector3D& v = in.verts[vidx+vofs]; const IfcVector3& v = in.verts[vidx+vofs];
for(size_t outer = 0; outer < boundary.verts.size(); ++outer) { for(size_t outer = 0; outer < boundary.verts.size(); ++outer) {
const aiVector3D& o = boundary.verts[outer]; const IfcVector3& o = boundary.verts[outer];
const float d = (o-v).SquareLength(); const IfcFloat d = (o-v).SquareLength();
if (d < best_dist) { if (d < best_dist) {
best_dist = d; best_dist = d;
@ -214,7 +214,7 @@ void RecursiveMergeBoundaries(TempMesh& final_result, const TempMesh& in, const
out.verts.reserve(cnt); out.verts.reserve(cnt);
for(size_t outer = 0; outer < boundary.verts.size(); ++outer) { for(size_t outer = 0; outer < boundary.verts.size(); ++outer) {
const aiVector3D& o = boundary.verts[outer]; const IfcVector3& o = boundary.verts[outer];
out.verts.push_back(o); out.verts.push_back(o);
if (outer == best_outer) { if (outer == best_outer) {
@ -286,12 +286,12 @@ void MergePolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t mas
size_t outer_polygon_start = 0; size_t outer_polygon_start = 0;
// do not normalize 'normals', we need the original length for computing the polygon area // do not normalize 'normals', we need the original length for computing the polygon area
std::vector<aiVector3D> normals; std::vector<IfcVector3> normals;
ComputePolygonNormals(meshout,normals,false); ComputePolygonNormals(meshout,normals,false);
// see if one of the polygons is a IfcFaceOuterBound (in which case `master_bounds` is its index). // see if one of the polygons is a IfcFaceOuterBound (in which case `master_bounds` is its index).
// sadly we can't rely on it, the docs say 'At most one of the bounds shall be of the type IfcFaceOuterBound' // sadly we can't rely on it, the docs say 'At most one of the bounds shall be of the type IfcFaceOuterBound'
float area_outer_polygon = 1e-10f; IfcFloat area_outer_polygon = 1e-10f;
if (master_bounds != (size_t)-1) { if (master_bounds != (size_t)-1) {
outer_polygon = begin + master_bounds; outer_polygon = begin + master_bounds;
outer_polygon_start = std::accumulate(begin,outer_polygon,0); outer_polygon_start = std::accumulate(begin,outer_polygon,0);
@ -301,8 +301,8 @@ void MergePolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t mas
size_t vidx = 0; size_t vidx = 0;
for(iit = begin; iit != meshout.vertcnt.end(); vidx += *iit++) { for(iit = begin; iit != meshout.vertcnt.end(); vidx += *iit++) {
// find the polygon with the largest area, it must be the outer bound. // find the polygon with the largest area, it must be the outer bound.
aiVector3D& n = normals[std::distance(begin,iit)]; IfcVector3& n = normals[std::distance(begin,iit)];
const float area = n.SquareLength(); const IfcFloat area = n.SquareLength();
if (area > area_outer_polygon) { if (area > area_outer_polygon) {
area_outer_polygon = area; area_outer_polygon = area;
outer_polygon = iit; outer_polygon = iit;
@ -312,18 +312,18 @@ void MergePolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t mas
} }
ai_assert(outer_polygon != meshout.vertcnt.end()); ai_assert(outer_polygon != meshout.vertcnt.end());
std::vector<aiVector3D>& in = meshout.verts; std::vector<IfcVector3>& in = meshout.verts;
// skip over extremely small boundaries - this is a workaround to fix cases // skip over extremely small boundaries - this is a workaround to fix cases
// in which the number of holes is so extremely large that the // in which the number of holes is so extremely large that the
// triangulation code fails. // triangulation code fails.
#define IFC_VERTICAL_HOLE_SIZE_THRESHOLD 0.000001f #define IFC_VERTICAL_HOLE_SIZE_THRESHOLD 0.000001f
size_t vidx = 0, removed = 0, index = 0; size_t vidx = 0, removed = 0, index = 0;
const float threshold = area_outer_polygon * IFC_VERTICAL_HOLE_SIZE_THRESHOLD; const IfcFloat threshold = area_outer_polygon * IFC_VERTICAL_HOLE_SIZE_THRESHOLD;
for(iit = begin; iit != end ;++index) { for(iit = begin; iit != end ;++index) {
const float sqlen = normals[index].SquareLength(); const IfcFloat sqlen = normals[index].SquareLength();
if (sqlen < threshold) { if (sqlen < threshold) {
std::vector<aiVector3D>::iterator inbase = in.begin()+vidx; std::vector<IfcVector3>::iterator inbase = in.begin()+vidx;
in.erase(inbase,inbase+*iit); in.erase(inbase,inbase+*iit);
outer_polygon_start -= outer_polygon_start>vidx ? *iit : 0; outer_polygon_start -= outer_polygon_start>vidx ? *iit : 0;
@ -355,19 +355,19 @@ next_loop:
continue; continue;
} }
const size_t next = (vofs+1)%*iit; const size_t next = (vofs+1)%*iit;
const aiVector3D& v = in[vidx+vofs], &vnext = in[vidx+next],&vd = (vnext-v).Normalize(); const IfcVector3& v = in[vidx+vofs], &vnext = in[vidx+next],&vd = (vnext-v).Normalize();
for(size_t outer = 0; outer < *outer_polygon; ++outer) { for(size_t outer = 0; outer < *outer_polygon; ++outer) {
const aiVector3D& o = in[outer_polygon_start+outer], &onext = in[outer_polygon_start+(outer+1)%*outer_polygon], &od = (onext-o).Normalize(); const IfcVector3& o = in[outer_polygon_start+outer], &onext = in[outer_polygon_start+(outer+1)%*outer_polygon], &od = (onext-o).Normalize();
if (fabs(vd * od) > 1.f-1e-6f && (onext-v).Normalize() * vd > 1.f-1e-6f && (onext-v)*(o-v) < 0) { if (fabs(vd * od) > 1.f-1e-6f && (onext-v).Normalize() * vd > 1.f-1e-6f && (onext-v)*(o-v) < 0) {
IFCImporter::LogDebug("got an inner hole that lies partly on the outer polygonal boundary, merging them to a single contour"); IFCImporter::LogDebug("got an inner hole that lies partly on the outer polygonal boundary, merging them to a single contour");
// in between outer and outer+1 insert all vertices of this loop, then drop the original altogether. // in between outer and outer+1 insert all vertices of this loop, then drop the original altogether.
std::vector<aiVector3D> tmp(*iit); std::vector<IfcVector3> tmp(*iit);
const size_t start = (v-o).SquareLength() > (vnext-o).SquareLength() ? vofs : next; const size_t start = (v-o).SquareLength() > (vnext-o).SquareLength() ? vofs : next;
std::vector<aiVector3D>::iterator inbase = in.begin()+vidx, it = std::copy(inbase+start, inbase+*iit,tmp.begin()); std::vector<IfcVector3>::iterator inbase = in.begin()+vidx, it = std::copy(inbase+start, inbase+*iit,tmp.begin());
std::copy(inbase, inbase+start,it); std::copy(inbase, inbase+start,it);
std::reverse(tmp.begin(),tmp.end()); std::reverse(tmp.begin(),tmp.end());
@ -398,12 +398,12 @@ next_loop:
boundary.vertcnt.resize(1,*outer_polygon); boundary.vertcnt.resize(1,*outer_polygon);
boundary.verts.resize(*outer_polygon); boundary.verts.resize(*outer_polygon);
std::vector<aiVector3D>::iterator b = in.begin()+outer_polygon_start; std::vector<IfcVector3>::iterator b = in.begin()+outer_polygon_start;
std::copy(b,b+*outer_polygon,boundary.verts.begin()); std::copy(b,b+*outer_polygon,boundary.verts.begin());
in.erase(b,b+*outer_polygon); in.erase(b,b+*outer_polygon);
std::vector<aiVector3D>::iterator norit = normals.begin()+std::distance(meshout.vertcnt.begin(),outer_polygon); std::vector<IfcVector3>::iterator norit = normals.begin()+std::distance(meshout.vertcnt.begin(),outer_polygon);
const aiVector3D nor_boundary = *norit; const IfcVector3 nor_boundary = *norit;
normals.erase(norit); normals.erase(norit);
meshout.vertcnt.erase(outer_polygon); meshout.vertcnt.erase(outer_polygon);
@ -463,18 +463,18 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
return; return;
} }
aiVector3D axis, pos; IfcVector3 axis, pos;
ConvertAxisPlacement(axis,pos,solid.Axis); ConvertAxisPlacement(axis,pos,solid.Axis);
aiMatrix4x4 tb0,tb1; IfcMatrix4 tb0,tb1;
aiMatrix4x4::Translation(pos,tb0); IfcMatrix4::Translation(pos,tb0);
aiMatrix4x4::Translation(-pos,tb1); IfcMatrix4::Translation(-pos,tb1);
const std::vector<aiVector3D>& in = meshout.verts; const std::vector<IfcVector3>& in = meshout.verts;
const size_t size=in.size(); const size_t size=in.size();
bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2; bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
const float max_angle = solid.Angle*conv.angle_scale; const IfcFloat max_angle = solid.Angle*conv.angle_scale;
if(fabs(max_angle) < 1e-3) { if(fabs(max_angle) < 1e-3) {
if(has_area) { if(has_area) {
result = meshout; result = meshout;
@ -483,18 +483,18 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
} }
const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * fabs(max_angle)/AI_MATH_HALF_PI_F)); const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * fabs(max_angle)/AI_MATH_HALF_PI_F));
const float delta = max_angle/cnt_segments; const IfcFloat delta = max_angle/cnt_segments;
has_area = has_area && fabs(max_angle) < AI_MATH_TWO_PI_F*0.99; has_area = has_area && fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0))); result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0)));
result.vertcnt.reserve(size*cnt_segments+2); result.vertcnt.reserve(size*cnt_segments+2);
aiMatrix4x4 rot; IfcMatrix4 rot;
rot = tb0 * aiMatrix4x4::Rotation(delta,axis,rot) * tb1; rot = tb0 * IfcMatrix4::Rotation(delta,axis,rot) * tb1;
size_t base = 0; size_t base = 0;
std::vector<aiVector3D>& out = result.verts; std::vector<IfcVector3>& out = result.verts;
// dummy data to simplify later processing // dummy data to simplify later processing
for(size_t i = 0; i < size; ++i) { for(size_t i = 0; i < size; ++i) {
@ -506,7 +506,7 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
const size_t next = (i+1)%size; const size_t next = (i+1)%size;
result.vertcnt.push_back(4); result.vertcnt.push_back(4);
const aiVector3D& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3]; const IfcVector3& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];
out.push_back(base_0); out.push_back(base_0);
out.push_back(base_1); out.push_back(base_1);
@ -533,7 +533,7 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
result.vertcnt.push_back(size); result.vertcnt.push_back(size);
} }
aiMatrix4x4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo, solid.Position); ConvertAxisPlacement(trafo, solid.Position);
result.Transform(trafo); result.Transform(trafo);
@ -541,16 +541,16 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMatrix3x3 DerivePlaneCoordinateSpace(const TempMesh& curmesh) { IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh) {
const std::vector<aiVector3D>& out = curmesh.verts; const std::vector<IfcVector3>& out = curmesh.verts;
aiMatrix3x3 m; IfcMatrix3 m;
const size_t s = out.size(); const size_t s = out.size();
assert(curmesh.vertcnt.size() == 1 && curmesh.vertcnt.back() == s); assert(curmesh.vertcnt.size() == 1 && curmesh.vertcnt.back() == s);
const aiVector3D any_point = out[s-1]; const IfcVector3 any_point = out[s-1];
aiVector3D nor; IfcVector3 nor;
// The input polygon is arbitrarily shaped, so we might need some tries // The input polygon is arbitrarily shaped, so we might need some tries
// until we find a suitable normal (and it does not even need to be // until we find a suitable normal (and it does not even need to be
@ -571,11 +571,11 @@ out:
nor.Normalize(); nor.Normalize();
aiVector3D r = (out[i]-any_point); IfcVector3 r = (out[i]-any_point);
r.Normalize(); r.Normalize();
// reconstruct orthonormal basis // reconstruct orthonormal basis
aiVector3D u = r ^ nor; IfcVector3 u = r ^ nor;
u.Normalize(); u.Normalize();
m.a1 = r.x; m.a1 = r.x;
@ -594,29 +594,29 @@ out:
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<aiVector3D>& nors, TempMesh& curmesh) bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh)
{ {
std::vector<aiVector3D>& out = curmesh.verts; std::vector<IfcVector3>& out = curmesh.verts;
bool result = false; bool result = false;
// Try to derive a solid base plane within the current surface for use as // Try to derive a solid base plane within the current surface for use as
// working coordinate system. // working coordinate system.
const aiMatrix3x3& m = DerivePlaneCoordinateSpace(curmesh); const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh);
const aiMatrix3x3 minv = aiMatrix3x3(m).Inverse(); const IfcMatrix3 minv = IfcMatrix3(m).Inverse();
const aiVector3D& nor = aiVector3D(m.c1, m.c2, m.c3); const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3);
float coord = -1; IfcFloat coord = -1;
std::vector<aiVector2D> contour_flat; std::vector<IfcVector2> contour_flat;
contour_flat.reserve(out.size()); contour_flat.reserve(out.size());
aiVector2D vmin, vmax; IfcVector2 vmin, vmax;
MinMaxChooser<aiVector2D>()(vmin, vmax); MinMaxChooser<IfcVector2>()(vmin, vmax);
// Move all points into the new coordinate system, collecting min/max verts on the way // Move all points into the new coordinate system, collecting min/max verts on the way
BOOST_FOREACH(aiVector3D& x, out) { BOOST_FOREACH(IfcVector3& x, out) {
const aiVector3D vv = m * x; const IfcVector3 vv = m * x;
// keep Z offset in the plane coordinate system. Ignoring precision issues // keep Z offset in the plane coordinate system. Ignoring precision issues
// (which are present, of course), this should be the same value for // (which are present, of course), this should be the same value for
@ -631,10 +631,10 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
coord = vv.z; coord = vv.z;
vmin = std::min(aiVector2D(vv.x, vv.y), vmin); vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
vmax = std::max(aiVector2D(vv.x, vv.y), vmax); vmax = std::max(IfcVector2(vv.x, vv.y), vmax);
contour_flat.push_back(aiVector2D(vv.x,vv.y)); contour_flat.push_back(IfcVector2(vv.x,vv.y));
} }
// With the current code in DerivePlaneCoordinateSpace, // With the current code in DerivePlaneCoordinateSpace,
@ -650,7 +650,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
ClipperLib::Polygons holes_union; ClipperLib::Polygons holes_union;
aiVector3D wall_extrusion; IfcVector3 wall_extrusion;
bool do_connections = false, first = true; bool do_connections = false, first = true;
try { try {
@ -659,21 +659,21 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
size_t c = 0; size_t c = 0;
BOOST_FOREACH(const TempOpening& t,openings) { BOOST_FOREACH(const TempOpening& t,openings) {
const aiVector3D& outernor = nors[c++]; const IfcVector3& outernor = nors[c++];
const float dot = nor * outernor; const IfcFloat dot = nor * outernor;
if (fabs(dot)<1.f-1e-6f) { if (fabs(dot)<1.f-1e-6f) {
continue; continue;
} }
const std::vector<aiVector3D>& va = t.profileMesh->verts; const std::vector<IfcVector3>& va = t.profileMesh->verts;
if(va.size() <= 2) { if(va.size() <= 2) {
continue; continue;
} }
std::vector<aiVector2D> contour; std::vector<IfcVector2> contour;
BOOST_FOREACH(const aiVector3D& xx, t.profileMesh->verts) { BOOST_FOREACH(const IfcVector3& xx, t.profileMesh->verts) {
aiVector3D vv = m * xx, vv_extr = m * (xx + t.extrusionDir); IfcVector3 vv = m * xx, vv_extr = m * (xx + t.extrusionDir);
const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord); const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord);
if (first) { if (first) {
@ -689,11 +689,11 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
// XXX should not be necessary - but it is. Why? For precision reasons? // XXX should not be necessary - but it is. Why? For precision reasons?
vv = is_extruded_side ? vv_extr : vv; vv = is_extruded_side ? vv_extr : vv;
contour.push_back(aiVector2D(vv.x,vv.y)); contour.push_back(IfcVector2(vv.x,vv.y));
} }
ClipperLib::Polygon hole; ClipperLib::Polygon hole;
BOOST_FOREACH(aiVector2D& pip, contour) { BOOST_FOREACH(IfcVector2& pip, contour) {
pip.x = (pip.x - vmin.x) / vmax.x; pip.x = (pip.x - vmin.x) / vmax.x;
pip.y = (pip.y - vmin.y) / vmax.y; pip.y = (pip.y - vmin.y) / vmax.y;
@ -720,7 +720,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
// to obtain the final polygon to feed into the triangulator. // to obtain the final polygon to feed into the triangulator.
{ {
ClipperLib::Polygon poly; ClipperLib::Polygon poly;
BOOST_FOREACH(aiVector2D& pip, contour_flat) { BOOST_FOREACH(IfcVector2& pip, contour_flat) {
pip.x = (pip.x - vmin.x) / vmax.x; pip.x = (pip.x - vmin.x) / vmax.x;
pip.y = (pip.y - vmin.y) / vmax.y; pip.y = (pip.y - vmin.y) / vmax.y;
@ -747,7 +747,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
return false; return false;
} }
std::vector<aiVector3D> old_verts; std::vector<IfcVector3> old_verts;
std::vector<unsigned int> old_vertcnt; std::vector<unsigned int> old_vertcnt;
old_verts.swap(curmesh.verts); old_verts.swap(curmesh.verts);
@ -759,7 +759,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
// would be emitted twice. // would be emitted twice.
if (false && do_connections) { if (false && do_connections) {
std::vector<aiVector3D> tmpvec; std::vector<IfcVector3> tmpvec;
BOOST_FOREACH(ClipperLib::Polygon& opening, holes_union) { BOOST_FOREACH(ClipperLib::Polygon& opening, holes_union) {
assert(ClipperLib::Orientation(opening)); assert(ClipperLib::Orientation(opening));
@ -768,7 +768,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
BOOST_FOREACH(ClipperLib::IntPoint& point, opening) { BOOST_FOREACH(ClipperLib::IntPoint& point, opening) {
tmpvec.push_back( minv * aiVector3D( tmpvec.push_back( minv * IfcVector3(
vmin.x + from_int64_f(point.X) * vmax.x, vmin.x + from_int64_f(point.X) * vmax.x,
vmin.y + from_int64_f(point.Y) * vmax.y, vmin.y + from_int64_f(point.Y) * vmax.y,
coord)); coord));
@ -779,8 +779,8 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
curmesh.vertcnt.push_back(4); curmesh.vertcnt.push_back(4);
const aiVector3D& in_world = tmpvec[i]; const IfcVector3& in_world = tmpvec[i];
const aiVector3D& next_world = tmpvec[next]; const IfcVector3& next_world = tmpvec[next];
// Assumptions: no 'partial' openings, wall thickness roughly the same across the wall // Assumptions: no 'partial' openings, wall thickness roughly the same across the wall
curmesh.verts.push_back(in_world); curmesh.verts.push_back(in_world);
@ -846,13 +846,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
BOOST_FOREACH(p2t::Triangle* tri, tris) { BOOST_FOREACH(p2t::Triangle* tri, tris) {
for(int i = 0; i < 3; ++i) { for(int i = 0; i < 3; ++i) {
const aiVector2D& v = aiVector2D( const IfcVector2& v = IfcVector2(
static_cast<float>( tri->GetPoint(i)->x ), static_cast<IfcFloat>( tri->GetPoint(i)->x ),
static_cast<float>( tri->GetPoint(i)->y ) static_cast<IfcFloat>( tri->GetPoint(i)->y )
); );
assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0); assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0);
const aiVector3D v3 = minv * aiVector3D(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ; const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ;
curmesh.verts.push_back(v3); curmesh.verts.push_back(v3);
} }
@ -876,20 +876,20 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct DistanceSorter { struct DistanceSorter {
DistanceSorter(const aiVector3D& base) : base(base) {} DistanceSorter(const IfcVector3& base) : base(base) {}
bool operator () (const TempOpening& a, const TempOpening& b) const { bool operator () (const TempOpening& a, const TempOpening& b) const {
return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength(); return (a.profileMesh->Center()-base).SquareLength() < (b.profileMesh->Center()-base).SquareLength();
} }
aiVector3D base; IfcVector3 base;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct XYSorter { struct XYSorter {
// sort first by X coordinates, then by Y coordinates // sort first by X coordinates, then by Y coordinates
bool operator () (const aiVector2D&a, const aiVector2D& b) const { bool operator () (const IfcVector2&a, const IfcVector2& b) const {
if (a.x == b.x) { if (a.x == b.x) {
return a.y < b.y; return a.y < b.y;
} }
@ -897,19 +897,19 @@ struct XYSorter {
} }
}; };
typedef std::pair< aiVector2D, aiVector2D > BoundingBox; typedef std::pair< IfcVector2, IfcVector2 > BoundingBox;
typedef std::map<aiVector2D,size_t,XYSorter> XYSortedField; typedef std::map<IfcVector2,size_t,XYSorter> XYSortedField;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void QuadrifyPart(const aiVector2D& pmin, const aiVector2D& pmax, XYSortedField& field, const std::vector< BoundingBox >& bbs, void QuadrifyPart(const IfcVector2& pmin, const IfcVector2& pmax, XYSortedField& field, const std::vector< BoundingBox >& bbs,
std::vector<aiVector2D>& out) std::vector<IfcVector2>& out)
{ {
if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) { if (!(pmin.x-pmax.x) || !(pmin.y-pmax.y)) {
return; return;
} }
float xs = 1e10, xe = 1e10; IfcFloat xs = 1e10, xe = 1e10;
bool found = false; bool found = false;
// Search along the x-axis until we find an opening // Search along the x-axis until we find an opening
@ -931,9 +931,9 @@ void QuadrifyPart(const aiVector2D& pmin, const aiVector2D& pmax, XYSortedField&
if (!found) { if (!found) {
// the rectangle [pmin,pend] is opaque, fill it // the rectangle [pmin,pend] is opaque, fill it
out.push_back(pmin); out.push_back(pmin);
out.push_back(aiVector2D(pmin.x,pmax.y)); out.push_back(IfcVector2(pmin.x,pmax.y));
out.push_back(pmax); out.push_back(pmax);
out.push_back(aiVector2D(pmax.x,pmin.y)); out.push_back(IfcVector2(pmax.x,pmin.y));
return; return;
} }
@ -943,13 +943,13 @@ void QuadrifyPart(const aiVector2D& pmin, const aiVector2D& pmax, XYSortedField&
// see if there's an offset to fill at the top of our quad // see if there's an offset to fill at the top of our quad
if (xs - pmin.x) { if (xs - pmin.x) {
out.push_back(pmin); out.push_back(pmin);
out.push_back(aiVector2D(pmin.x,pmax.y)); out.push_back(IfcVector2(pmin.x,pmax.y));
out.push_back(aiVector2D(xs,pmax.y)); out.push_back(IfcVector2(xs,pmax.y));
out.push_back(aiVector2D(xs,pmin.y)); out.push_back(IfcVector2(xs,pmin.y));
} }
// search along the y-axis for all openings that overlap xs and our quad // search along the y-axis for all openings that overlap xs and our quad
float ylast = pmin.y; IfcFloat ylast = pmin.y;
found = false; found = false;
for(; start != field.end(); ++start) { for(; start != field.end(); ++start) {
const BoundingBox& bb = bbs[(*start).second]; const BoundingBox& bb = bbs[(*start).second];
@ -960,47 +960,47 @@ void QuadrifyPart(const aiVector2D& pmin, const aiVector2D& pmax, XYSortedField&
if (bb.second.y > ylast) { if (bb.second.y > ylast) {
found = true; found = true;
const float ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y); const IfcFloat ys = std::max(bb.first.y,pmin.y), ye = std::min(bb.second.y,pmax.y);
if (ys - ylast) { if (ys - ylast) {
QuadrifyPart( aiVector2D(xs,ylast), aiVector2D(xe,ys) ,field,bbs,out); QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,ys) ,field,bbs,out);
} }
// the following are the window vertices // the following are the window vertices
/*wnd.push_back(aiVector2D(xs,ys)); /*wnd.push_back(IfcVector2(xs,ys));
wnd.push_back(aiVector2D(xs,ye)); wnd.push_back(IfcVector2(xs,ye));
wnd.push_back(aiVector2D(xe,ye)); wnd.push_back(IfcVector2(xe,ye));
wnd.push_back(aiVector2D(xe,ys));*/ wnd.push_back(IfcVector2(xe,ys));*/
ylast = ye; ylast = ye;
} }
} }
if (!found) { if (!found) {
// the rectangle [pmin,pend] is opaque, fill it // the rectangle [pmin,pend] is opaque, fill it
out.push_back(aiVector2D(xs,pmin.y)); out.push_back(IfcVector2(xs,pmin.y));
out.push_back(aiVector2D(xs,pmax.y)); out.push_back(IfcVector2(xs,pmax.y));
out.push_back(aiVector2D(xe,pmax.y)); out.push_back(IfcVector2(xe,pmax.y));
out.push_back(aiVector2D(xe,pmin.y)); out.push_back(IfcVector2(xe,pmin.y));
return; return;
} }
if (ylast < pmax.y) { if (ylast < pmax.y) {
QuadrifyPart( aiVector2D(xs,ylast), aiVector2D(xe,pmax.y) ,field,bbs,out); QuadrifyPart( IfcVector2(xs,ylast), IfcVector2(xe,pmax.y) ,field,bbs,out);
} }
// now for the whole rest // now for the whole rest
if (pmax.x-xe) { if (pmax.x-xe) {
QuadrifyPart(aiVector2D(xe,pmin.y), pmax ,field,bbs,out); QuadrifyPart(IfcVector2(xe,pmin.y), pmax ,field,bbs,out);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void InsertWindowContours(const std::vector< BoundingBox >& bbs, void InsertWindowContours(const std::vector< BoundingBox >& bbs,
const std::vector< std::vector<aiVector2D> >& contours, const std::vector< std::vector<IfcVector2> >& contours,
const std::vector<TempOpening>& openings, const std::vector<TempOpening>& openings,
const std::vector<aiVector3D>& nors, const std::vector<IfcVector3>& nors,
const aiMatrix3x3& minv, const IfcMatrix3& minv,
const aiVector2D& scale, const IfcVector2& scale,
const aiVector2D& offset, const IfcVector2& offset,
float coord, IfcFloat coord,
TempMesh& curmesh) TempMesh& curmesh)
{ {
ai_assert(contours.size() == bbs.size()); ai_assert(contours.size() == bbs.size());
@ -1008,29 +1008,29 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
// fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now // fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now
for(size_t i = 0; i < contours.size();++i) { for(size_t i = 0; i < contours.size();++i) {
const BoundingBox& bb = bbs[i]; const BoundingBox& bb = bbs[i];
const std::vector<aiVector2D>& contour = contours[i]; const std::vector<IfcVector2>& contour = contours[i];
// check if we need to do it at all - many windows just fit perfectly into their quadratic holes, // check if we need to do it at all - many windows just fit perfectly into their quadratic holes,
// i.e. their contours *are* already their bounding boxes. // i.e. their contours *are* already their bounding boxes.
if (contour.size() == 4) { if (contour.size() == 4) {
std::set<aiVector2D,XYSorter> verts; std::set<IfcVector2,XYSorter> verts;
for(size_t n = 0; n < 4; ++n) { for(size_t n = 0; n < 4; ++n) {
verts.insert(contour[n]); verts.insert(contour[n]);
} }
const std::set<aiVector2D,XYSorter>::const_iterator end = verts.end(); const std::set<IfcVector2,XYSorter>::const_iterator end = verts.end();
if (verts.find(bb.first)!=end && verts.find(bb.second)!=end if (verts.find(bb.first)!=end && verts.find(bb.second)!=end
&& verts.find(aiVector2D(bb.first.x,bb.second.y))!=end && verts.find(IfcVector2(bb.first.x,bb.second.y))!=end
&& verts.find(aiVector2D(bb.second.x,bb.first.y))!=end && verts.find(IfcVector2(bb.second.x,bb.first.y))!=end
) { ) {
continue; continue;
} }
} }
const float epsilon = (bb.first-bb.second).Length()/1000.f; const IfcFloat epsilon = (bb.first-bb.second).Length()/1000.f;
// walk through all contour points and find those that lie on the BB corner // walk through all contour points and find those that lie on the BB corner
size_t last_hit = -1, very_first_hit = -1; size_t last_hit = -1, very_first_hit = -1;
aiVector2D edge; IfcVector2 edge;
for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) { for(size_t n = 0, e=0, size = contour.size();; n=(n+1)%size, ++e) {
// sanity checking // sanity checking
@ -1039,7 +1039,7 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
break; break;
} }
const aiVector2D& v = contour[n]; const IfcVector2& v = contour[n];
bool hit = false; bool hit = false;
if (fabs(v.x-bb.first.x)<epsilon) { if (fabs(v.x-bb.first.x)<epsilon) {
@ -1066,13 +1066,13 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
const size_t old = curmesh.verts.size(); const size_t old = curmesh.verts.size();
size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit; size_t cnt = last_hit > n ? size-(last_hit-n) : n-last_hit;
for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) { for(size_t a = last_hit, e = 0; e <= cnt; a=(a+1)%size, ++e) {
const aiVector3D v3 = minv * aiVector3D(offset.x + contour[a].x * scale.x, offset.y + contour[a].y * scale.y,coord); const IfcVector3 v3 = minv * IfcVector3(offset.x + contour[a].x * scale.x, offset.y + contour[a].y * scale.y,coord);
curmesh.verts.push_back(v3); curmesh.verts.push_back(v3);
} }
if (edge != contour[last_hit]) { if (edge != contour[last_hit]) {
aiVector2D corner = edge; IfcVector2 corner = edge;
if (fabs(contour[last_hit].x-bb.first.x)<epsilon) { if (fabs(contour[last_hit].x-bb.first.x)<epsilon) {
corner.x = bb.first.x; corner.x = bb.first.x;
@ -1088,7 +1088,7 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
corner.y = bb.second.y; corner.y = bb.second.y;
} }
const aiVector3D v3 = minv * aiVector3D(offset.x + corner.x * scale.x, offset.y + corner.y * scale.y,coord); const IfcVector3 v3 = minv * IfcVector3(offset.x + corner.x * scale.x, offset.y + corner.y * scale.y,coord);
curmesh.verts.push_back(v3); curmesh.verts.push_back(v3);
} }
else if (cnt == 1) { else if (cnt == 1) {
@ -1115,27 +1115,27 @@ void InsertWindowContours(const std::vector< BoundingBox >& bbs,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const std::vector<aiVector3D>& nors, TempMesh& curmesh) bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh)
{ {
std::vector<aiVector3D>& out = curmesh.verts; std::vector<IfcVector3>& out = curmesh.verts;
// Try to derive a solid base plane within the current surface for use as // Try to derive a solid base plane within the current surface for use as
// working coordinate system. // working coordinate system.
const aiMatrix3x3& m = DerivePlaneCoordinateSpace(curmesh); const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh);
const aiMatrix3x3 minv = aiMatrix3x3(m).Inverse(); const IfcMatrix3 minv = IfcMatrix3(m).Inverse();
const aiVector3D& nor = aiVector3D(m.c1, m.c2, m.c3); const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3);
float coord = -1; IfcFloat coord = -1;
std::vector<aiVector2D> contour_flat; std::vector<IfcVector2> contour_flat;
contour_flat.reserve(out.size()); contour_flat.reserve(out.size());
aiVector2D vmin, vmax; IfcVector2 vmin, vmax;
MinMaxChooser<aiVector2D>()(vmin, vmax); MinMaxChooser<IfcVector2>()(vmin, vmax);
// Move all points into the new coordinate system, collecting min/max verts on the way // Move all points into the new coordinate system, collecting min/max verts on the way
BOOST_FOREACH(aiVector3D& x, out) { BOOST_FOREACH(IfcVector3& x, out) {
const aiVector3D vv = m * x; const IfcVector3 vv = m * x;
// keep Z offset in the plane coordinate system. Ignoring precision issues // keep Z offset in the plane coordinate system. Ignoring precision issues
// (which are present, of course), this should be the same value for // (which are present, of course), this should be the same value for
@ -1149,10 +1149,10 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
// } // }
coord = vv.z; coord = vv.z;
vmin = std::min(aiVector2D(vv.x, vv.y), vmin); vmin = std::min(IfcVector2(vv.x, vv.y), vmin);
vmax = std::max(aiVector2D(vv.x, vv.y), vmax); vmax = std::max(IfcVector2(vv.x, vv.y), vmax);
contour_flat.push_back(aiVector2D(vv.x,vv.y)); contour_flat.push_back(IfcVector2(vv.x,vv.y));
} }
// With the current code in DerivePlaneCoordinateSpace, // With the current code in DerivePlaneCoordinateSpace,
@ -1160,7 +1160,7 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
// but here we won't rely on this. // but here we won't rely on this.
vmax -= vmin; vmax -= vmin;
BOOST_FOREACH(aiVector2D& vv, contour_flat) { BOOST_FOREACH(IfcVector2& vv, contour_flat) {
vv.x = (vv.x - vmin.x) / vmax.x; vv.x = (vv.x - vmin.x) / vmax.x;
vv.y = (vv.y - vmin.y) / vmax.y; vv.y = (vv.y - vmin.y) / vmax.y;
} }
@ -1170,31 +1170,31 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
std::vector< BoundingBox > bbs; std::vector< BoundingBox > bbs;
XYSortedField field; XYSortedField field;
std::vector< std::vector<aiVector2D> > contours; std::vector< std::vector<IfcVector2> > contours;
size_t c = 0; size_t c = 0;
BOOST_FOREACH(const TempOpening& t,openings) { BOOST_FOREACH(const TempOpening& t,openings) {
const aiVector3D& outernor = nors[c++]; const IfcVector3& outernor = nors[c++];
const float dot = nor * outernor; const IfcFloat dot = nor * outernor;
if (fabs(dot)<1.f-1e-6f) { if (fabs(dot)<1.f-1e-6f) {
continue; continue;
} }
const std::vector<aiVector3D>& va = t.profileMesh->verts; const std::vector<IfcVector3>& va = t.profileMesh->verts;
if(va.size() <= 2) { if(va.size() <= 2) {
continue; continue;
} }
aiVector2D vpmin,vpmax; IfcVector2 vpmin,vpmax;
MinMaxChooser<aiVector2D>()(vpmin,vpmax); MinMaxChooser<IfcVector2>()(vpmin,vpmax);
contours.push_back(std::vector<aiVector2D>()); contours.push_back(std::vector<IfcVector2>());
std::vector<aiVector2D>& contour = contours.back(); std::vector<IfcVector2>& contour = contours.back();
BOOST_FOREACH(const aiVector3D& x, t.profileMesh->verts) { BOOST_FOREACH(const IfcVector3& x, t.profileMesh->verts) {
const aiVector3D v = m * x; const IfcVector3 v = m * x;
aiVector2D vv(v.x, v.y); IfcVector2 vv(v.x, v.y);
// rescale // rescale
vv.x = (vv.x - vmin.x) / vmax.x; vv.x = (vv.x - vmin.x) / vmax.x;
@ -1231,12 +1231,12 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
return false; return false;
} }
std::vector<aiVector2D> outflat; std::vector<IfcVector2> outflat;
outflat.reserve(openings.size()*4); outflat.reserve(openings.size()*4);
QuadrifyPart(aiVector2D(0.f,0.f),aiVector2D(1.f,1.f),field,bbs,outflat); QuadrifyPart(IfcVector2(0.f,0.f),IfcVector2(1.f,1.f),field,bbs,outflat);
ai_assert(!(outflat.size() % 4)); ai_assert(!(outflat.size() % 4));
std::vector<aiVector3D> vold; std::vector<IfcVector3> vold;
std::vector<unsigned int> iold; std::vector<unsigned int> iold;
vold.reserve(outflat.size()); vold.reserve(outflat.size());
@ -1251,7 +1251,7 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
ClipperLib::Polygon clip; ClipperLib::Polygon clip;
clip.reserve(contour_flat.size()); clip.reserve(contour_flat.size());
BOOST_FOREACH(const aiVector2D& pip, contour_flat) { BOOST_FOREACH(const IfcVector2& pip, contour_flat) {
clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); clip.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
} }
@ -1264,7 +1264,7 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
// previous steps // previous steps
subject.reserve(4); subject.reserve(4);
size_t cnt = 0; size_t cnt = 0;
BOOST_FOREACH(const aiVector2D& pip, outflat) { BOOST_FOREACH(const IfcVector2& pip, outflat) {
subject.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) )); subject.push_back(ClipperLib::IntPoint( to_int64(pip.x), to_int64(pip.y) ));
if (!(++cnt % 4)) { if (!(++cnt % 4)) {
if (!ClipperLib::Orientation(subject)) { if (!ClipperLib::Orientation(subject)) {
@ -1279,7 +1279,7 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
BOOST_FOREACH(const ClipperLib::ExPolygon& ex, clipped) { BOOST_FOREACH(const ClipperLib::ExPolygon& ex, clipped) {
iold.push_back(ex.outer.size()); iold.push_back(ex.outer.size());
BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) { BOOST_FOREACH(const ClipperLib::IntPoint& point, ex.outer) {
vold.push_back( minv * aiVector3D( vold.push_back( minv * IfcVector3(
vmin.x + from_int64_f(point.X) * vmax.x, vmin.x + from_int64_f(point.X) * vmax.x,
vmin.y + from_int64_f(point.Y) * vmax.y, vmin.y + from_int64_f(point.Y) * vmax.y,
coord)); coord));
@ -1300,8 +1300,8 @@ bool TryAddOpenings_Quadrulate(const std::vector<TempOpening>& openings,const st
iold.resize(outflat.size()/4,4); iold.resize(outflat.size()/4,4);
BOOST_FOREACH(const aiVector2D& vproj, outflat) { BOOST_FOREACH(const IfcVector2& vproj, outflat) {
const aiVector3D v3 = minv * aiVector3D(vmin.x + vproj.x * vmax.x, vmin.y + vproj.y * vmax.y,coord); const IfcVector3 v3 = minv * IfcVector3(vmin.x + vproj.x * vmax.x, vmin.y + vproj.y * vmax.y,coord);
vold.push_back(v3); vold.push_back(v3);
} }
} }
@ -1325,7 +1325,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
return; return;
} }
aiVector3D dir; IfcVector3 dir;
ConvertDirection(dir,solid.ExtrudedDirection); ConvertDirection(dir,solid.ExtrudedDirection);
dir *= solid.Depth; dir *= solid.Depth;
@ -1334,7 +1334,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
// the underlying profile, extrude along the given axis, forming new // the underlying profile, extrude along the given axis, forming new
// triangles. // triangles.
std::vector<aiVector3D>& in = meshout.verts; std::vector<IfcVector3>& in = meshout.verts;
const size_t size=in.size(); const size_t size=in.size();
const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2; const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
@ -1349,16 +1349,16 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
result.vertcnt.reserve(meshout.vertcnt.size()+2); result.vertcnt.reserve(meshout.vertcnt.size()+2);
// First step: transform all vertices into the target coordinate space // First step: transform all vertices into the target coordinate space
aiMatrix4x4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo, solid.Position); ConvertAxisPlacement(trafo, solid.Position);
BOOST_FOREACH(aiVector3D& v,in) { BOOST_FOREACH(IfcVector3& v,in) {
v *= trafo; v *= trafo;
} }
aiVector3D min = in[0]; IfcVector3 min = in[0];
dir *= aiMatrix3x3(trafo); dir *= IfcMatrix3(trafo);
std::vector<aiVector3D> nors; std::vector<IfcVector3> nors;
const bool openings = !!conv.apply_openings && conv.apply_openings->size(); const bool openings = !!conv.apply_openings && conv.apply_openings->size();
// Compute the normal vectors for all opening polygons as a prerequisite // Compute the normal vectors for all opening polygons as a prerequisite
@ -1378,7 +1378,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
TempMesh& bounds = *t.profileMesh.get(); TempMesh& bounds = *t.profileMesh.get();
if (bounds.verts.size() <= 2) { if (bounds.verts.size() <= 2) {
nors.push_back(aiVector3D()); nors.push_back(IfcVector3());
continue; continue;
} }
nors.push_back(((bounds.verts[2]-bounds.verts[0])^(bounds.verts[1]-bounds.verts[0]) ).Normalize()); nors.push_back(((bounds.verts[2]-bounds.verts[0])^(bounds.verts[1]-bounds.verts[0]) ).Normalize());
@ -1388,7 +1388,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
TempMesh temp; TempMesh temp;
TempMesh& curmesh = openings ? temp : result; TempMesh& curmesh = openings ? temp : result;
std::vector<aiVector3D>& out = curmesh.verts; std::vector<IfcVector3>& out = curmesh.verts;
size_t sides_with_openings = 0; size_t sides_with_openings = 0;
for(size_t i = 0; i < size; ++i) { for(size_t i = 0; i < size; ++i) {
@ -1416,7 +1416,7 @@ void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& resul
for(size_t n = 0; n < 2; ++n) { for(size_t n = 0; n < 2; ++n) {
for(size_t i = size; i--; ) { for(size_t i = size; i--; ) {
out.push_back(in[i]+(n?dir:aiVector3D())); out.push_back(in[i]+(n?dir:IfcVector3()));
} }
curmesh.vertcnt.push_back(size); curmesh.vertcnt.push_back(size);
@ -1451,13 +1451,13 @@ void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout, Co
boost::shared_ptr<TempMesh> meshtmp(new TempMesh()); boost::shared_ptr<TempMesh> meshtmp(new TempMesh());
ProcessProfile(swept.SweptArea,*meshtmp,conv); ProcessProfile(swept.SweptArea,*meshtmp,conv);
aiMatrix4x4 m; IfcMatrix4 m;
ConvertAxisPlacement(m,solid->Position); ConvertAxisPlacement(m,solid->Position);
meshtmp->Transform(m); meshtmp->Transform(m);
aiVector3D dir; IfcVector3 dir;
ConvertDirection(dir,solid->ExtrudedDirection); ConvertDirection(dir,solid->ExtrudedDirection);
conv.collect_openings->push_back(TempOpening(solid, aiMatrix3x3(m) * (dir*solid->Depth),meshtmp)); conv.collect_openings->push_back(TempOpening(solid, IfcMatrix3(m) * (dir*solid->Depth),meshtmp));
return; return;
} }
@ -1480,16 +1480,16 @@ enum Intersect {
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Intersect IntersectSegmentPlane(const aiVector3D& p,const aiVector3D& n, const aiVector3D& e0, const aiVector3D& e1, aiVector3D& out) Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0, const IfcVector3& e1, IfcVector3& out)
{ {
const aiVector3D pdelta = e0 - p, seg = e1-e0; const IfcVector3 pdelta = e0 - p, seg = e1-e0;
const float dotOne = n*seg, dotTwo = -(n*pdelta); const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta);
if (fabs(dotOne) < 1e-6) { if (fabs(dotOne) < 1e-6) {
return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No; return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No;
} }
const float t = dotTwo/dotOne; const IfcFloat t = dotTwo/dotOne;
// t must be in [0..1] if the intersection point is within the given segment // t must be in [0..1] if the intersection point is within the given segment
if (t > 1.f || t < 0.f) { if (t > 1.f || t < 0.f) {
return Intersect_No; return Intersect_No;
@ -1532,7 +1532,7 @@ void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, Conversio
} }
// extract plane base position vector and normal vector // extract plane base position vector and normal vector
aiVector3D p,n(0.f,0.f,1.f); IfcVector3 p,n(0.f,0.f,1.f);
if (plane->Position->Axis) { if (plane->Position->Axis) {
ConvertDirection(n,plane->Position->Axis.Get()); ConvertDirection(n,plane->Position->Axis.Get());
} }
@ -1543,8 +1543,8 @@ void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, Conversio
} }
// clip the current contents of `meshout` against the plane we obtained from the second operand // clip the current contents of `meshout` against the plane we obtained from the second operand
const std::vector<aiVector3D>& in = meshout.verts; const std::vector<IfcVector3>& in = meshout.verts;
std::vector<aiVector3D>& outvert = result.verts; std::vector<IfcVector3>& outvert = result.verts;
std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin(), end=meshout.vertcnt.end(), iit; std::vector<unsigned int>::const_iterator begin=meshout.vertcnt.begin(), end=meshout.vertcnt.end(), iit;
outvert.reserve(in.size()); outvert.reserve(in.size());
@ -1555,10 +1555,10 @@ void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, Conversio
unsigned int newcount = 0; unsigned int newcount = 0;
for(unsigned int i = 0; i < *iit; ++i) { for(unsigned int i = 0; i < *iit; ++i) {
const aiVector3D& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit]; const IfcVector3& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit];
// does the next segment intersect the plane? // does the next segment intersect the plane?
aiVector3D isectpos; IfcVector3 isectpos;
const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos); const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos);
if (isect == Intersect_No || isect == Intersect_LiesOnPlane) { if (isect == Intersect_No || isect == Intersect_LiesOnPlane) {
if ( (e0-p).Normalize()*n > 0 ) { if ( (e0-p).Normalize()*n > 0 ) {
@ -1585,17 +1585,17 @@ void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, Conversio
continue; continue;
} }
aiVector3D vmin,vmax; IfcVector3 vmin,vmax;
ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax);
// filter our double points - those may happen if a point lies // filter our IfcFloat points - those may happen if a point lies
// directly on the intersection line. However, due to float // directly on the intersection line. However, due to IfcFloat
// precision a bitwise comparison is not feasible to detect // precision a bitwise comparison is not feasible to detect
// this case. // this case.
const float epsilon = (vmax-vmin).SquareLength() / 1e6f; const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f;
FuzzyVectorCompare fz(epsilon); FuzzyVectorCompare fz(epsilon);
std::vector<aiVector3D>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz );
if (e != outvert.end()) { if (e != outvert.end()) {
newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); newcount -= static_cast<unsigned int>(std::distance(e,outvert.end()));
outvert.erase(e,outvert.end()); outvert.erase(e,outvert.end());

View File

@ -228,7 +228,7 @@ void IFCImporter::InternReadFile( const std::string& pFile,
// apply world coordinate system (which includes the scaling to convert to meters and a -90 degrees rotation around x) // apply world coordinate system (which includes the scaling to convert to meters and a -90 degrees rotation around x)
aiMatrix4x4 scale, rot; aiMatrix4x4 scale, rot;
aiMatrix4x4::Scaling(aiVector3D(conv.len_scale,conv.len_scale,conv.len_scale),scale); aiMatrix4x4::Scaling(static_cast<aiVector3D>(IfcVector3(conv.len_scale)),scale);
aiMatrix4x4::RotationX(-AI_MATH_HALF_PI_F,rot); aiMatrix4x4::RotationX(-AI_MATH_HALF_PI_F,rot);
pScene->mRootNode->mTransformation = rot * scale * conv.wcs * pScene->mRootNode->mTransformation; pScene->mRootNode->mTransformation = rot * scale * conv.wcs * pScene->mRootNode->mTransformation;
@ -356,10 +356,10 @@ bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector<
nd->mName.Set("IfcMappedItem"); nd->mName.Set("IfcMappedItem");
// handle the Cartesian operator // handle the Cartesian operator
aiMatrix4x4 m; IfcMatrix4 m;
ConvertTransformOperator(m, *mapped.MappingTarget); ConvertTransformOperator(m, *mapped.MappingTarget);
aiMatrix4x4 msrc; IfcMatrix4 msrc;
ConvertAxisPlacement(msrc,*mapped.MappingSource->MappingOrigin,conv); ConvertAxisPlacement(msrc,*mapped.MappingSource->MappingOrigin,conv);
msrc = m*msrc; msrc = m*msrc;
@ -367,7 +367,7 @@ bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector<
std::vector<unsigned int> meshes; std::vector<unsigned int> meshes;
const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0; const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0;
if (conv.apply_openings) { if (conv.apply_openings) {
aiMatrix4x4 minv = msrc; IfcMatrix4 minv = msrc;
minv.Inverse(); minv.Inverse();
BOOST_FOREACH(TempOpening& open,*conv.apply_openings){ BOOST_FOREACH(TempOpening& open,*conv.apply_openings){
open.Transform(minv); open.Transform(minv);
@ -401,7 +401,7 @@ bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector<
} }
} }
nd->mTransformation = nd_src->mTransformation * msrc; nd->mTransformation = nd_src->mTransformation * static_cast<aiMatrix4x4>( msrc );
subnodes_src.push_back(nd.release()); subnodes_src.push_back(nd.release());
return true; return true;
@ -543,7 +543,7 @@ aiNode* ProcessSpatialStructure(aiNode* parent, const IfcProduct& el, Conversion
std::vector<TempOpening> openings; std::vector<TempOpening> openings;
aiMatrix4x4 myInv; IfcMatrix4 myInv;
bool didinv = false; bool didinv = false;
// convert everything contained directly within this structure, // convert everything contained directly within this structure,
@ -733,7 +733,7 @@ void ProcessSpatialStructures(ConversionData& conv)
void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined) void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
{ {
// combined is the parent's absolute transformation matrix // combined is the parent's absolute transformation matrix
aiMatrix4x4 old = start->mTransformation; const aiMatrix4x4 old = start->mTransformation;
if (!combined.IsIdentity()) { if (!combined.IsIdentity()) {
start->mTransformation = aiMatrix4x4(combined).Inverse() * start->mTransformation; start->mTransformation = aiMatrix4x4(combined).Inverse() * start->mTransformation;
@ -748,7 +748,7 @@ void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MakeTreeRelative(ConversionData& conv) void MakeTreeRelative(ConversionData& conv)
{ {
MakeTreeRelative(conv.out->mRootNode,aiMatrix4x4()); MakeTreeRelative(conv.out->mRootNode,IfcMatrix4());
} }
} // !anon } // !anon

View File

@ -76,7 +76,7 @@ void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionDat
// now see which kinds of surface information are present // now see which kinds of surface information are present
BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) { BOOST_FOREACH(boost::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2, surf->Styles) {
if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) { if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) {
aiColor4D col_base,col; IfcColor4 col_base,col;
ConvertColor(col_base, shade->SurfaceColour); ConvertColor(col_base, shade->SurfaceColour);
mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE);
@ -84,7 +84,7 @@ void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionDat
if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) { if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) {
if (ren->Transparency) { if (ren->Transparency) {
const float t = 1.f-ren->Transparency.Get(); const IfcFloat t = 1.f-ren->Transparency.Get();
mat->AddProperty(&t,1, AI_MATKEY_OPACITY); mat->AddProperty(&t,1, AI_MATKEY_OPACITY);
} }
@ -115,7 +115,7 @@ void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionDat
if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) { if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) {
// at this point we don't distinguish between the two distinct ways of // at this point we don't distinguish between the two distinct ways of
// specifying highlight intensities. leave this to the user. // specifying highlight intensities. leave this to the user.
const float e = *rt; const IfcFloat e = *rt;
mat->AddProperty(&e,1,AI_MATKEY_SHININESS); mat->AddProperty(&e,1,AI_MATKEY_SHININESS);
} }
else { else {
@ -141,7 +141,7 @@ unsigned int ProcessMaterials(const IFC::IfcRepresentationItem& item, Conversion
name.Set("<IFCDefault>"); name.Set("<IFCDefault>");
mat->AddProperty(&name,AI_MATKEY_NAME); mat->AddProperty(&name,AI_MATKEY_NAME);
aiColor4D col = aiColor4D(0.6f,0.6f,0.6f,1.0f); IfcColor4 col = IfcColor4(0.6f,0.6f,0.6f,1.0f);
mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
conv.materials.push_back(mat.release()); conv.materials.push_back(mat.release());

View File

@ -54,7 +54,7 @@ namespace Assimp {
void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/) void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
{ {
// this won't produce a valid mesh, it just spits out a list of vertices // this won't produce a valid mesh, it just spits out a list of vertices
aiVector3D t; IfcVector3 t;
BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) { BOOST_FOREACH(const IfcCartesianPoint& cp, def.Points) {
ConvertCartesianPoint(t,cp); ConvertCartesianPoint(t,cp);
meshout.verts.push_back(t); meshout.verts.push_back(t);
@ -104,13 +104,13 @@ void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout
void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv) void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv)
{ {
if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) { if(const IfcRectangleProfileDef* const cprofile = def.ToPtr<IfcRectangleProfileDef>()) {
const float x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f;
meshout.verts.reserve(meshout.verts.size()+4); meshout.verts.reserve(meshout.verts.size()+4);
meshout.verts.push_back( aiVector3D( x, y, 0.f )); meshout.verts.push_back( IfcVector3( x, y, 0.f ));
meshout.verts.push_back( aiVector3D(-x, y, 0.f )); meshout.verts.push_back( IfcVector3(-x, y, 0.f ));
meshout.verts.push_back( aiVector3D(-x,-y, 0.f )); meshout.verts.push_back( IfcVector3(-x,-y, 0.f ));
meshout.verts.push_back( aiVector3D( x,-y, 0.f )); meshout.verts.push_back( IfcVector3( x,-y, 0.f ));
meshout.vertcnt.push_back(4); meshout.vertcnt.push_back(4);
} }
else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) { else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
@ -118,13 +118,13 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
// TODO // TODO
} }
const size_t segments = 32; const size_t segments = 32;
const float delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius; const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
meshout.verts.reserve(segments); meshout.verts.reserve(segments);
float angle = 0.f; IfcFloat angle = 0.f;
for(size_t i = 0; i < segments; ++i, angle += delta) { for(size_t i = 0; i < segments; ++i, angle += delta) {
meshout.verts.push_back( aiVector3D( cos(angle)*radius, sin(angle)*radius, 0.f )); meshout.verts.push_back( IfcVector3( cos(angle)*radius, sin(angle)*radius, 0.f ));
} }
meshout.vertcnt.push_back(segments); meshout.vertcnt.push_back(segments);
@ -134,7 +134,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
return; return;
} }
aiMatrix4x4 trafo; IfcMatrix4 trafo;
ConvertAxisPlacement(trafo, *def.Position); ConvertAxisPlacement(trafo, *def.Position);
meshout.Transform(trafo); meshout.Transform(trafo);
} }

View File

@ -52,12 +52,12 @@ namespace Assimp {
namespace IFC { namespace IFC {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempOpening::Transform(const aiMatrix4x4& mat) void TempOpening::Transform(const IfcMatrix4& mat)
{ {
if(profileMesh) { if(profileMesh) {
profileMesh->Transform(mat); profileMesh->Transform(mat);
} }
extrusionDir *= aiMatrix3x3(mat); extrusionDir *= IfcMatrix3(mat);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -107,17 +107,17 @@ void TempMesh::Clear()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TempMesh::Transform(const aiMatrix4x4& mat) void TempMesh::Transform(const IfcMatrix4& mat)
{ {
BOOST_FOREACH(aiVector3D& v, verts) { BOOST_FOREACH(IfcVector3& v, verts) {
v *= mat; v *= mat;
} }
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
aiVector3D TempMesh::Center() const IfcVector3 TempMesh::Center() const
{ {
return std::accumulate(verts.begin(),verts.end(),aiVector3D(0.f,0.f,0.f)) / static_cast<float>(verts.size()); return std::accumulate(verts.begin(),verts.end(),IfcVector3()) / static_cast<IfcFloat>(verts.size());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -132,32 +132,32 @@ void TempMesh::RemoveAdjacentDuplicates()
{ {
bool drop = false; bool drop = false;
std::vector<aiVector3D>::iterator base = verts.begin(); std::vector<IfcVector3>::iterator base = verts.begin();
BOOST_FOREACH(unsigned int& cnt, vertcnt) { BOOST_FOREACH(unsigned int& cnt, vertcnt) {
if (cnt < 2){ if (cnt < 2){
base += cnt; base += cnt;
continue; continue;
} }
aiVector3D vmin,vmax; IfcVector3 vmin,vmax;
ArrayBounds(&*base, cnt ,vmin,vmax); ArrayBounds(&*base, cnt ,vmin,vmax);
const float epsilon = (vmax-vmin).SquareLength() / 1e9f; const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
//const float dotepsilon = 1e-9; //const IfcFloat dotepsilon = 1e-9;
//// look for vertices that lie directly on the line between their predecessor and their //// look for vertices that lie directly on the line between their predecessor and their
//// successor and replace them with either of them. //// successor and replace them with either of them.
//for(size_t i = 0; i < cnt; ++i) { //for(size_t i = 0; i < cnt; ++i) {
// aiVector3D& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt); // IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
// const aiVector3D& d0 = (v1-v0), &d1 = (v2-v1); // const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1);
// const float l0 = d0.SquareLength(), l1 = d1.SquareLength(); // const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength();
// if (!l0 || !l1) { // if (!l0 || !l1) {
// continue; // continue;
// } // }
// const float d = (d0/sqrt(l0))*(d1/sqrt(l1)); // const IfcFloat d = (d0/sqrt(l0))*(d1/sqrt(l1));
// if ( d >= 1.f-dotepsilon ) { // if ( d >= 1.f-dotepsilon ) {
// v1 = v0; // v1 = v0;
@ -171,7 +171,7 @@ void TempMesh::RemoveAdjacentDuplicates()
// drop any identical, adjacent vertices. this pass will collect the dropouts // drop any identical, adjacent vertices. this pass will collect the dropouts
// of the previous pass as a side-effect. // of the previous pass as a side-effect.
FuzzyVectorCompare fz(epsilon); FuzzyVectorCompare fz(epsilon);
std::vector<aiVector3D>::iterator end = base+cnt, e = std::unique( base, end, fz ); std::vector<IfcVector3>::iterator end = base+cnt, e = std::unique( base, end, fz );
if (e != end) { if (e != end) {
cnt -= static_cast<unsigned int>(std::distance(e, end)); cnt -= static_cast<unsigned int>(std::distance(e, end));
verts.erase(e,end); verts.erase(e,end);
@ -200,7 +200,7 @@ bool IsTrue(const EXPRESS::BOOLEAN& in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float ConvertSIPrefix(const std::string& prefix) IfcFloat ConvertSIPrefix(const std::string& prefix)
{ {
if (prefix == "EXA") { if (prefix == "EXA") {
return 1e18f; return 1e18f;
@ -257,7 +257,7 @@ float ConvertSIPrefix(const std::string& prefix)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const IfcColourRgb& in) void ConvertColor(IfcColor4& out, const IfcColourRgb& in)
{ {
out.r = in.Red; out.r = in.Red;
out.g = in.Green; out.g = in.Green;
@ -266,7 +266,7 @@ void ConvertColor(aiColor4D& out, const IfcColourRgb& in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base) void ConvertColor(IfcColor4& out, const IfcColourOrFactor& in,ConversionData& conv,const IfcColor4* base)
{ {
if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) { if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) {
out.r = out.g = out.b = *r; out.r = out.g = out.b = *r;
@ -287,29 +287,29 @@ void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& co
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCartesianPoint(aiVector3D& out, const IfcCartesianPoint& in) void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in)
{ {
out = aiVector3D(); out = IfcVector3();
for(size_t i = 0; i < in.Coordinates.size(); ++i) { for(size_t i = 0; i < in.Coordinates.size(); ++i) {
out[i] = in.Coordinates[i]; out[i] = in.Coordinates[i];
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertVector(aiVector3D& out, const IfcVector& in) void ConvertVector(IfcVector3& out, const IfcVector& in)
{ {
ConvertDirection(out,in.Orientation); ConvertDirection(out,in.Orientation);
out *= in.Magnitude; out *= in.Magnitude;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertDirection(aiVector3D& out, const IfcDirection& in) void ConvertDirection(IfcVector3& out, const IfcDirection& in)
{ {
out = aiVector3D(); out = IfcVector3();
for(size_t i = 0; i < in.DirectionRatios.size(); ++i) { for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
out[i] = in.DirectionRatios[i]; out[i] = in.DirectionRatios[i];
} }
const float len = out.Length(); const IfcFloat len = out.Length();
if (len<1e-6) { if (len<1e-6) {
IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero"); IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero");
return; return;
@ -318,7 +318,7 @@ void ConvertDirection(aiVector3D& out, const IfcDirection& in)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void AssignMatrixAxes(aiMatrix4x4& out, const aiVector3D& x, const aiVector3D& y, const aiVector3D& z) void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z)
{ {
out.a1 = x.x; out.a1 = x.x;
out.b1 = x.y; out.b1 = x.y;
@ -334,12 +334,12 @@ void AssignMatrixAxes(aiMatrix4x4& out, const aiVector3D& x, const aiVector3D& y
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement3D& in) void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in)
{ {
aiVector3D loc; IfcVector3 loc;
ConvertCartesianPoint(loc,in.Location); ConvertCartesianPoint(loc,in.Location);
aiVector3D z(0.f,0.f,1.f),r(1.f,0.f,0.f),x; IfcVector3 z(0.f,0.f,1.f),r(1.f,0.f,0.f),x;
if (in.Axis) { if (in.Axis) {
ConvertDirection(z,*in.Axis.Get()); ConvertDirection(z,*in.Axis.Get());
@ -348,47 +348,47 @@ void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement3D& in)
ConvertDirection(r,*in.RefDirection.Get()); ConvertDirection(r,*in.RefDirection.Get());
} }
aiVector3D v = r.Normalize(); IfcVector3 v = r.Normalize();
aiVector3D tmpx = z * (v*z); IfcVector3 tmpx = z * (v*z);
x = (v-tmpx).Normalize(); x = (v-tmpx).Normalize();
aiVector3D y = (z^x); IfcVector3 y = (z^x);
aiMatrix4x4::Translation(loc,out); IfcMatrix4::Translation(loc,out);
AssignMatrixAxes(out,x,y,z); AssignMatrixAxes(out,x,y,z);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement2D& in) void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in)
{ {
aiVector3D loc; IfcVector3 loc;
ConvertCartesianPoint(loc,in.Location); ConvertCartesianPoint(loc,in.Location);
aiVector3D x(1.f,0.f,0.f); IfcVector3 x(1.f,0.f,0.f);
if (in.RefDirection) { if (in.RefDirection) {
ConvertDirection(x,*in.RefDirection.Get()); ConvertDirection(x,*in.RefDirection.Get());
} }
const aiVector3D y = aiVector3D(x.y,-x.x,0.f); const IfcVector3 y = IfcVector3(x.y,-x.x,0.f);
aiMatrix4x4::Translation(loc,out); IfcMatrix4::Translation(loc,out);
AssignMatrixAxes(out,x,y,aiVector3D(0.f,0.f,1.f)); AssignMatrixAxes(out,x,y,IfcVector3(0.f,0.f,1.f));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(aiVector3D& axis, aiVector3D& pos, const IfcAxis1Placement& in) void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IfcAxis1Placement& in)
{ {
ConvertCartesianPoint(pos,in.Location); ConvertCartesianPoint(pos,in.Location);
if (in.Axis) { if (in.Axis) {
ConvertDirection(axis,in.Axis.Get()); ConvertDirection(axis,in.Axis.Get());
} }
else { else {
axis = aiVector3D(0.f,0.f,1.f); axis = IfcVector3(0.f,0.f,1.f);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement& in, ConversionData& conv) void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv)
{ {
if(const IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<IfcAxis2Placement3D>(conv.db)) { if(const IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<IfcAxis2Placement3D>(conv.db)) {
ConvertAxisPlacement(out,*pl3); ConvertAxisPlacement(out,*pl3);
@ -402,12 +402,12 @@ void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement& in, Convers
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertTransformOperator(aiMatrix4x4& out, const IfcCartesianTransformationOperator& op) void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op)
{ {
aiVector3D loc; IfcVector3 loc;
ConvertCartesianPoint(loc,op.LocalOrigin); ConvertCartesianPoint(loc,op.LocalOrigin);
aiVector3D x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f); IfcVector3 x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f);
if (op.Axis1) { if (op.Axis1) {
ConvertDirection(x,*op.Axis1.Get()); ConvertDirection(x,*op.Axis1.Get());
} }
@ -420,24 +420,24 @@ void ConvertTransformOperator(aiMatrix4x4& out, const IfcCartesianTransformation
} }
} }
aiMatrix4x4 locm; IfcMatrix4 locm;
aiMatrix4x4::Translation(loc,locm); IfcMatrix4::Translation(loc,locm);
AssignMatrixAxes(out,x,y,z); AssignMatrixAxes(out,x,y,z);
aiVector3D vscale; IfcVector3 vscale;
if (const IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<IfcCartesianTransformationOperator3DnonUniform>()) { if (const IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<IfcCartesianTransformationOperator3DnonUniform>()) {
vscale.x = nuni->Scale?op.Scale.Get():1.f; vscale.x = nuni->Scale?op.Scale.Get():1.f;
vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f; vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f; vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
} }
else { else {
const float sc = op.Scale?op.Scale.Get():1.f; const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
vscale = aiVector3D(sc,sc,sc); vscale = IfcVector3(sc,sc,sc);
} }
aiMatrix4x4 s; IfcMatrix4 s;
aiMatrix4x4::Scaling(vscale,s); IfcMatrix4::Scaling(vscale,s);
out = locm * out * s; out = locm * out * s;
} }

View File

@ -51,6 +51,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace IFC { namespace IFC {
typedef float IfcFloat;
// IfcFloat-precision math data types
typedef aiVector2t<IfcFloat> IfcVector2;
typedef aiVector3t<IfcFloat> IfcVector3;
typedef aiMatrix4x4t<IfcFloat> IfcMatrix4;
typedef aiMatrix3x3t<IfcFloat> IfcMatrix3;
typedef aiColor4t<IfcFloat> IfcColor4;
// helper for std::for_each to delete all heap-allocated items in a container // helper for std::for_each to delete all heap-allocated items in a container
template<typename T> template<typename T>
struct delete_fun struct delete_fun
@ -67,11 +77,11 @@ struct TempMesh;
struct TempOpening struct TempOpening
{ {
const IFC::IfcExtrudedAreaSolid* solid; const IFC::IfcExtrudedAreaSolid* solid;
aiVector3D extrusionDir; IfcVector3 extrusionDir;
boost::shared_ptr<TempMesh> profileMesh; boost::shared_ptr<TempMesh> profileMesh;
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
TempOpening(const IFC::IfcExtrudedAreaSolid* solid,aiVector3D extrusionDir,boost::shared_ptr<TempMesh> profileMesh) TempOpening(const IFC::IfcExtrudedAreaSolid* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
: solid(solid) : solid(solid)
, extrusionDir(extrusionDir) , extrusionDir(extrusionDir)
, profileMesh(profileMesh) , profileMesh(profileMesh)
@ -79,7 +89,7 @@ struct TempOpening
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
void Transform(const aiMatrix4x4& mat); // defined later since TempMesh is not complete yet void Transform(const IfcMatrix4& mat); // defined later since TempMesh is not complete yet
}; };
@ -104,14 +114,14 @@ struct ConversionData
std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>()); std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
} }
float len_scale, angle_scale; IfcFloat len_scale, angle_scale;
bool plane_angle_in_radians; bool plane_angle_in_radians;
const STEP::DB& db; const STEP::DB& db;
const IFC::IfcProject& proj; const IFC::IfcProject& proj;
aiScene* out; aiScene* out;
aiMatrix4x4 wcs; IfcMatrix4 wcs;
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials; std::vector<aiMaterial*> materials;
@ -135,12 +145,12 @@ struct ConversionData
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct FuzzyVectorCompare { struct FuzzyVectorCompare {
FuzzyVectorCompare(float epsilon) : epsilon(epsilon) {} FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
bool operator()(const aiVector3D& a, const aiVector3D& b) { bool operator()(const IfcVector3& a, const IfcVector3& b) {
return fabs((a-b).SquareLength()) < epsilon; return fabs((a-b).SquareLength()) < epsilon;
} }
const float epsilon; const IfcFloat epsilon;
}; };
@ -149,14 +159,14 @@ struct FuzzyVectorCompare {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct TempMesh struct TempMesh
{ {
std::vector<aiVector3D> verts; std::vector<IfcVector3> verts;
std::vector<unsigned int> vertcnt; std::vector<unsigned int> vertcnt;
// utilities // utilities
aiMesh* ToMesh(); aiMesh* ToMesh();
void Clear(); void Clear();
void Transform(const aiMatrix4x4& mat); void Transform(const IfcMatrix4& mat);
aiVector3D Center() const; IfcVector3 Center() const;
void Append(const TempMesh& other); void Append(const TempMesh& other);
void RemoveAdjacentDuplicates(); void RemoveAdjacentDuplicates();
}; };
@ -166,19 +176,19 @@ struct TempMesh
// conversion routines for common IFC entities, implemented in IFCUtil.cpp // conversion routines for common IFC entities, implemented in IFCUtil.cpp
void ConvertColor(aiColor4D& out, const IfcColourRgb& in); void ConvertColor(IfcColor4& out, const IfcColourRgb& in);
void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base); void ConvertColor(IfcColor4& out, const IfcColourOrFactor& in,ConversionData& conv,const IfcColor4* base);
void ConvertCartesianPoint(aiVector3D& out, const IfcCartesianPoint& in); void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in);
void ConvertDirection(aiVector3D& out, const IfcDirection& in); void ConvertDirection(IfcVector3& out, const IfcDirection& in);
void ConvertVector(aiVector3D& out, const IfcVector& in); void ConvertVector(IfcVector3& out, const IfcVector& in);
void AssignMatrixAxes(aiMatrix4x4& out, const aiVector3D& x, const aiVector3D& y, const aiVector3D& z); void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z);
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement3D& in); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in);
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement2D& in); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in);
void ConvertAxisPlacement(aiVector3D& axis, aiVector3D& pos, const IFC::IfcAxis1Placement& in); void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in);
void ConvertAxisPlacement(aiMatrix4x4& out, const IfcAxis2Placement& in, ConversionData& conv); void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv);
void ConvertTransformOperator(aiMatrix4x4& out, const IfcCartesianTransformationOperator& op); void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op);
bool IsTrue(const EXPRESS::BOOLEAN& in); bool IsTrue(const EXPRESS::BOOLEAN& in);
float ConvertSIPrefix(const std::string& prefix); IfcFloat ConvertSIPrefix(const std::string& prefix);
// IFCProfile.cpp // IFCProfile.cpp
@ -224,7 +234,7 @@ protected:
public: public:
typedef std::pair<float,float> ParamRange; typedef std::pair<IfcFloat, IfcFloat> ParamRange;
public: public:
@ -232,28 +242,28 @@ public:
virtual bool IsClosed() const = 0; virtual bool IsClosed() const = 0;
// evaluate the curve at the given parametric position // evaluate the curve at the given parametric position
virtual aiVector3D Eval(float p) const = 0; virtual IfcVector3 Eval(IfcFloat p) const = 0;
// try to match a point on the curve to a given parameter // try to match a point on the curve to a given parameter
// for self-intersecting curves, the result is not ambiguous and // for self-intersecting curves, the result is not ambiguous and
// it is undefined which parameter is returned. // it is undefined which parameter is returned.
virtual bool ReverseEval(const aiVector3D& val, float& paramOut) const; virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const;
// get the range of the curve (both inclusive). // get the range of the curve (both inclusive).
// +inf and -inf are valid return values, the curve is not bounded in such a case. // +inf and -inf are valid return values, the curve is not bounded in such a case.
virtual std::pair<float,float> GetParametricRange() const = 0; virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0;
float GetParametricRangeDelta() const; IfcFloat GetParametricRangeDelta() const;
// estimate the number of sample points that this curve will require // estimate the number of sample points that this curve will require
virtual size_t EstimateSampleCount(float start,float end) const; virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const;
// intelligently sample the curve based on the current settings // intelligently sample the curve based on the current settings
// and append the result to the mesh // and append the result to the mesh
virtual void SampleDiscrete(TempMesh& out,float start,float end) const; virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
#ifdef _DEBUG #ifdef _DEBUG
// check if a particular parameter value lies within the well-defined range // check if a particular parameter value lies within the well-defined range
bool InRange(float) const; bool InRange(IfcFloat) const;
#endif #endif
public: public: