summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/code/IFCCurve.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/code/IFCCurve.cpp')
-rw-r--r--src/3rdparty/assimp/code/IFCCurve.cpp850
1 files changed, 420 insertions, 430 deletions
diff --git a/src/3rdparty/assimp/code/IFCCurve.cpp b/src/3rdparty/assimp/code/IFCCurve.cpp
index 1079c1e2b..97d9fd574 100644
--- a/src/3rdparty/assimp/code/IFCCurve.cpp
+++ b/src/3rdparty/assimp/code/IFCCurve.cpp
@@ -2,11 +2,11 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
-Copyright (c) 2006-2012, assimp team
+Copyright (c) 2006-2016, assimp team
All rights reserved.
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
@@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior
written permission of the assimp team.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
@@ -42,14 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Read profile and curves entities from IFC files
*/
-#include "AssimpPCH.h"
+
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h"
namespace Assimp {
- namespace IFC {
- namespace {
+ namespace IFC {
+ namespace {
// --------------------------------------------------------------------------------
@@ -60,47 +60,47 @@ class Conic : public Curve
public:
- // --------------------------------------------------
- Conic(const IfcConic& entity, ConversionData& conv)
- : Curve(entity,conv)
- {
- IfcMatrix4 trafo;
- ConvertAxisPlacement(trafo,*entity.Position,conv);
+ // --------------------------------------------------
+ Conic(const IfcConic& entity, ConversionData& conv)
+ : Curve(entity,conv)
+ {
+ IfcMatrix4 trafo;
+ ConvertAxisPlacement(trafo,*entity.Position,conv);
- // for convenience, extract the matrix rows
- location = IfcVector3(trafo.a4,trafo.b4,trafo.c4);
- p[0] = IfcVector3(trafo.a1,trafo.b1,trafo.c1);
- p[1] = IfcVector3(trafo.a2,trafo.b2,trafo.c2);
- p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
- }
+ // for convenience, extract the matrix rows
+ location = IfcVector3(trafo.a4,trafo.b4,trafo.c4);
+ p[0] = IfcVector3(trafo.a1,trafo.b1,trafo.c1);
+ p[1] = IfcVector3(trafo.a2,trafo.b2,trafo.c2);
+ p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
+ }
public:
- // --------------------------------------------------
- bool IsClosed() const {
- return true;
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
+ // --------------------------------------------------
+ bool IsClosed() const {
+ return true;
+ }
+
+ // --------------------------------------------------
+ size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
- a *= conv.angle_scale;
- b *= conv.angle_scale;
+ a *= conv.angle_scale;
+ b *= conv.angle_scale;
a = std::fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
b = std::fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
- const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 );
+ const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 );
return static_cast<size_t>( std::ceil(std::abs( b-a)) / setting);
- }
+ }
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
- }
+ // --------------------------------------------------
+ ParamRange GetParametricRange() const {
+ return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
+ }
protected:
- IfcVector3 location, p[3];
+ IfcVector3 location, p[3];
};
@@ -112,24 +112,24 @@ class Circle : public Conic
public:
- // --------------------------------------------------
- Circle(const IfcCircle& entity, ConversionData& conv)
- : Conic(entity,conv)
- , entity(entity)
- {
- }
+ // --------------------------------------------------
+ Circle(const IfcCircle& entity, ConversionData& conv)
+ : Conic(entity,conv)
+ , entity(entity)
+ {
+ }
public:
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- u = -conv.angle_scale * u;
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat u) const {
+ u = -conv.angle_scale * u;
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
static_cast<IfcFloat>(std::sin(u))*p[1]);
- }
+ }
private:
- const IfcCircle& entity;
+ const IfcCircle& entity;
};
@@ -141,374 +141,364 @@ class Ellipse : public Conic
public:
- // --------------------------------------------------
- Ellipse(const IfcEllipse& entity, ConversionData& conv)
- : Conic(entity,conv)
- , entity(entity)
- {
- }
+ // --------------------------------------------------
+ Ellipse(const IfcEllipse& entity, ConversionData& conv)
+ : Conic(entity,conv)
+ , entity(entity)
+ {
+ }
public:
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- u = -conv.angle_scale * u;
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat u) const {
+ u = -conv.angle_scale * u;
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
- }
+ }
private:
- const IfcEllipse& entity;
+ const IfcEllipse& entity;
};
// --------------------------------------------------------------------------------
// Line
// --------------------------------------------------------------------------------
-class Line : public Curve
+class Line : public Curve
{
public:
- // --------------------------------------------------
- Line(const IfcLine& entity, ConversionData& conv)
- : Curve(entity,conv)
- , entity(entity)
- {
- ConvertCartesianPoint(p,entity.Pnt);
- ConvertVector(v,entity.Dir);
- }
+ // --------------------------------------------------
+ Line(const IfcLine& entity, ConversionData& conv)
+ : Curve(entity,conv)
+ {
+ ConvertCartesianPoint(p,entity.Pnt);
+ ConvertVector(v,entity.Dir);
+ }
public:
- // --------------------------------------------------
- bool IsClosed() const {
- return false;
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- return p + u*v;
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
- // two points are always sufficient for a line segment
- return a==b ? 1 : 2;
- }
-
-
- // --------------------------------------------------
- void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
- {
- ai_assert(InRange(a) && InRange(b));
-
- if (a == b) {
- out.verts.push_back(Eval(a));
- return;
- }
- out.verts.reserve(out.verts.size()+2);
- out.verts.push_back(Eval(a));
- out.verts.push_back(Eval(b));
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
-
- return std::make_pair(-inf,+inf);
- }
+ // --------------------------------------------------
+ bool IsClosed() const {
+ return false;
+ }
+
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat u) const {
+ return p + u*v;
+ }
+
+ // --------------------------------------------------
+ size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
+ // two points are always sufficient for a line segment
+ return a==b ? 1 : 2;
+ }
+
+
+ // --------------------------------------------------
+ void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
+ {
+ ai_assert(InRange(a) && InRange(b));
+
+ if (a == b) {
+ out.verts.push_back(Eval(a));
+ return;
+ }
+ out.verts.reserve(out.verts.size()+2);
+ out.verts.push_back(Eval(a));
+ out.verts.push_back(Eval(b));
+ }
+
+ // --------------------------------------------------
+ ParamRange GetParametricRange() const {
+ const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
+
+ return std::make_pair(-inf,+inf);
+ }
private:
- const IfcLine& entity;
- IfcVector3 p,v;
+ IfcVector3 p,v;
};
// --------------------------------------------------------------------------------
// CompositeCurve joins multiple smaller, bounded curves
// --------------------------------------------------------------------------------
-class CompositeCurve : public BoundedCurve
+class CompositeCurve : public BoundedCurve
{
- typedef std::pair< boost::shared_ptr< BoundedCurve >, bool > CurveEntry;
+ typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry;
public:
- // --------------------------------------------------
- CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- , entity(entity)
- , total()
- {
- curves.reserve(entity.Segments.size());
- BOOST_FOREACH(const IfcCompositeCurveSegment& curveSegment,entity.Segments) {
- // according to the specification, this must be a bounded curve
- boost::shared_ptr< Curve > cv(Curve::Convert(curveSegment.ParentCurve,conv));
- boost::shared_ptr< BoundedCurve > bc = boost::dynamic_pointer_cast<BoundedCurve>(cv);
-
- if (!bc) {
- IFCImporter::LogError("expected segment of composite curve to be a bounded curve");
- continue;
- }
-
- if ( (std::string)curveSegment.Transition != "CONTINUOUS" ) {
- IFCImporter::LogDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
- }
-
- curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
- total += bc->GetParametricRangeDelta();
- }
-
- if (curves.empty()) {
- throw CurveError("empty composite curve");
- }
- }
+ // --------------------------------------------------
+ CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
+ : BoundedCurve(entity,conv)
+ , total()
+ {
+ curves.reserve(entity.Segments.size());
+ for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) {
+ // according to the specification, this must be a bounded curve
+ std::shared_ptr< Curve > cv(Curve::Convert(curveSegment.ParentCurve,conv));
+ std::shared_ptr< BoundedCurve > bc = std::dynamic_pointer_cast<BoundedCurve>(cv);
+
+ if (!bc) {
+ IFCImporter::LogError("expected segment of composite curve to be a bounded curve");
+ continue;
+ }
+
+ if ( (std::string)curveSegment.Transition != "CONTINUOUS" ) {
+ IFCImporter::LogDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
+ }
+
+ curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
+ total += bc->GetParametricRangeDelta();
+ }
+
+ if (curves.empty()) {
+ throw CurveError("empty composite curve");
+ }
+ }
public:
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- if (curves.empty()) {
- return IfcVector3();
- }
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat u) const {
+ if (curves.empty()) {
+ return IfcVector3();
+ }
- IfcFloat acc = 0;
- BOOST_FOREACH(const CurveEntry& entry, curves) {
- const ParamRange& range = entry.first->GetParametricRange();
+ IfcFloat acc = 0;
+ for(const CurveEntry& entry : curves) {
+ const ParamRange& range = entry.first->GetParametricRange();
const IfcFloat delta = std::abs(range.second-range.first);
- if (u < acc+delta) {
- return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
- }
-
- acc += delta;
- }
- // clamp to end
- return curves.back().first->Eval(curves.back().first->GetParametricRange().second);
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
- size_t cnt = 0;
-
- IfcFloat acc = 0;
- BOOST_FOREACH(const CurveEntry& entry, curves) {
- const ParamRange& range = entry.first->GetParametricRange();
+ if (u < acc+delta) {
+ return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
+ }
+
+ acc += delta;
+ }
+ // clamp to end
+ return curves.back().first->Eval(curves.back().first->GetParametricRange().second);
+ }
+
+ // --------------------------------------------------
+ size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
+ size_t cnt = 0;
+
+ IfcFloat acc = 0;
+ for(const CurveEntry& entry : curves) {
+ const ParamRange& range = entry.first->GetParametricRange();
const IfcFloat delta = std::abs(range.second-range.first);
- if (a <= acc+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 );
- }
+ if (a <= acc+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 );
+ }
- acc += delta;
- }
+ acc += delta;
+ }
- return cnt;
- }
+ return cnt;
+ }
- // --------------------------------------------------
- void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
- {
- ai_assert(InRange(a) && InRange(b));
+ // --------------------------------------------------
+ void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const
+ {
+ ai_assert(InRange(a) && InRange(b));
- const size_t cnt = EstimateSampleCount(a,b);
- out.verts.reserve(out.verts.size() + cnt);
+ const size_t cnt = EstimateSampleCount(a,b);
+ out.verts.reserve(out.verts.size() + cnt);
- BOOST_FOREACH(const CurveEntry& entry, curves) {
- const size_t cnt = out.verts.size();
- entry.first->SampleDiscrete(out);
+ for(const CurveEntry& entry : curves) {
+ const size_t cnt = out.verts.size();
+ entry.first->SampleDiscrete(out);
- if (!entry.second && cnt != out.verts.size()) {
- std::reverse(out.verts.begin()+cnt,out.verts.end());
- }
- }
- }
+ if (!entry.second && cnt != out.verts.size()) {
+ std::reverse(out.verts.begin()+cnt,out.verts.end());
+ }
+ }
+ }
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ),total);
- }
+ // --------------------------------------------------
+ ParamRange GetParametricRange() const {
+ return std::make_pair(static_cast<IfcFloat>( 0. ),total);
+ }
private:
- const IfcCompositeCurve& entity;
- std::vector< CurveEntry > curves;
+ std::vector< CurveEntry > curves;
- IfcFloat total;
+ IfcFloat total;
};
// --------------------------------------------------------------------------------
// TrimmedCurve can be used to trim an unbounded curve to a bounded range
// --------------------------------------------------------------------------------
-class TrimmedCurve : public BoundedCurve
+class TrimmedCurve : public BoundedCurve
{
public:
- // --------------------------------------------------
- TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- , entity(entity)
- , ok()
- {
- base = boost::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
-
- typedef boost::shared_ptr<const STEP::EXPRESS::DataType> Entry;
-
- // for some reason, trimmed curves can either specify a parametric value
- // or a point on the curve, or both. And they can even specify which of the
- // two representations they prefer, even though an information invariant
- // claims that they must be identical if both are present.
- // oh well.
- bool have_param = false, have_point = false;
- IfcVector3 point;
- BOOST_FOREACH(const Entry sel,entity.Trim1) {
- if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
- range.first = *r;
- have_param = true;
- break;
- }
- else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
- ConvertCartesianPoint(point,*r);
- have_point = true;
- }
- }
- if (!have_param) {
- if (!have_point || !base->ReverseEval(point,range.first)) {
- throw CurveError("IfcTrimmedCurve: failed to read first trim parameter, ignoring curve");
- }
- }
- have_param = false, have_point = false;
- BOOST_FOREACH(const Entry sel,entity.Trim2) {
- if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
- range.second = *r;
- have_param = true;
- break;
- }
- else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
- ConvertCartesianPoint(point,*r);
- have_point = true;
- }
- }
- if (!have_param) {
- if (!have_point || !base->ReverseEval(point,range.second)) {
- throw CurveError("IfcTrimmedCurve: failed to read second trim parameter, ignoring curve");
- }
- }
-
- agree_sense = IsTrue(entity.SenseAgreement);
- if( !agree_sense ) {
- std::swap(range.first,range.second);
- }
-
- // "NOTE In case of a closed curve, it may be necessary to increment t1 or t2
- // by the parametric length for consistency with the sense flag."
- if (base->IsClosed()) {
- if( range.first > range.second ) {
- range.second += base->GetParametricRangeDelta();
- }
- }
-
- maxval = range.second-range.first;
- ai_assert(maxval >= 0);
- }
+ // --------------------------------------------------
+ TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
+ : BoundedCurve(entity,conv)
+ {
+ base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
+
+ typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
+
+ // for some reason, trimmed curves can either specify a parametric value
+ // or a point on the curve, or both. And they can even specify which of the
+ // two representations they prefer, even though an information invariant
+ // claims that they must be identical if both are present.
+ // oh well.
+ bool have_param = false, have_point = false;
+ IfcVector3 point;
+ for(const Entry sel :entity.Trim1) {
+ if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
+ range.first = *r;
+ have_param = true;
+ break;
+ }
+ else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
+ ConvertCartesianPoint(point,*r);
+ have_point = true;
+ }
+ }
+ if (!have_param) {
+ if (!have_point || !base->ReverseEval(point,range.first)) {
+ throw CurveError("IfcTrimmedCurve: failed to read first trim parameter, ignoring curve");
+ }
+ }
+ have_param = false, have_point = false;
+ for(const Entry sel :entity.Trim2) {
+ if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
+ range.second = *r;
+ have_param = true;
+ break;
+ }
+ else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
+ ConvertCartesianPoint(point,*r);
+ have_point = true;
+ }
+ }
+ if (!have_param) {
+ if (!have_point || !base->ReverseEval(point,range.second)) {
+ throw CurveError("IfcTrimmedCurve: failed to read second trim parameter, ignoring curve");
+ }
+ }
+
+ agree_sense = IsTrue(entity.SenseAgreement);
+ if( !agree_sense ) {
+ std::swap(range.first,range.second);
+ }
+
+ // "NOTE In case of a closed curve, it may be necessary to increment t1 or t2
+ // by the parametric length for consistency with the sense flag."
+ if (base->IsClosed()) {
+ if( range.first > range.second ) {
+ range.second += base->GetParametricRangeDelta();
+ }
+ }
+
+ maxval = range.second-range.first;
+ ai_assert(maxval >= 0);
+ }
public:
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat p) const {
- ai_assert(InRange(p));
- return base->Eval( TrimParam(p) );
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
- return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
- }
-
- // --------------------------------------------------
- void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
- return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
- }
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat p) const {
+ ai_assert(InRange(p));
+ return base->Eval( TrimParam(p) );
+ }
+
+ // --------------------------------------------------
+ size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
+ return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
+ }
+
+ // --------------------------------------------------
+ void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
+ return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
+ }
+
+ // --------------------------------------------------
+ ParamRange GetParametricRange() const {
+ return std::make_pair(static_cast<IfcFloat>( 0. ),maxval);
+ }
private:
- // --------------------------------------------------
- IfcFloat TrimParam(IfcFloat f) const {
- return agree_sense ? f + range.first : range.second - f;
- }
+ // --------------------------------------------------
+ IfcFloat TrimParam(IfcFloat f) const {
+ return agree_sense ? f + range.first : range.second - f;
+ }
private:
- const IfcTrimmedCurve& entity;
- ParamRange range;
- IfcFloat maxval;
- bool agree_sense;
- bool ok;
+ ParamRange range;
+ IfcFloat maxval;
+ bool agree_sense;
- boost::shared_ptr<const Curve> base;
+ std::shared_ptr<const Curve> base;
};
// --------------------------------------------------------------------------------
// PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
// --------------------------------------------------------------------------------
-class PolyLine : public BoundedCurve
+class PolyLine : public BoundedCurve
{
public:
- // --------------------------------------------------
- PolyLine(const IfcPolyline& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- , entity(entity)
- {
- points.reserve(entity.Points.size());
+ // --------------------------------------------------
+ PolyLine(const IfcPolyline& entity, ConversionData& conv)
+ : BoundedCurve(entity,conv)
+ {
+ points.reserve(entity.Points.size());
- IfcVector3 t;
- BOOST_FOREACH(const IfcCartesianPoint& cp, entity.Points) {
- ConvertCartesianPoint(t,cp);
- points.push_back(t);
- }
- }
+ IfcVector3 t;
+ for(const IfcCartesianPoint& cp : entity.Points) {
+ ConvertCartesianPoint(t,cp);
+ points.push_back(t);
+ }
+ }
public:
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat p) const {
- ai_assert(InRange(p));
-
+ // --------------------------------------------------
+ IfcVector3 Eval(IfcFloat p) const {
+ ai_assert(InRange(p));
+
const size_t b = static_cast<size_t>(std::floor(p));
- if (b == points.size()-1) {
- return points.back();
- }
+ if (b == points.size()-1) {
+ return points.back();
+ }
- const IfcFloat d = p-static_cast<IfcFloat>(b);
- return points[b+1] * d + points[b] * (static_cast<IfcFloat>( 1. )-d);
- }
+ const IfcFloat d = p-static_cast<IfcFloat>(b);
+ return points[b+1] * d + points[b] * (static_cast<IfcFloat>( 1. )-d);
+ }
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
+ // --------------------------------------------------
+ size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
+ ai_assert(InRange(a) && InRange(b));
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
- }
+ }
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
- }
+ // --------------------------------------------------
+ ParamRange GetParametricRange() const {
+ return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
+ }
private:
- const IfcPolyline& entity;
- std::vector<IfcVector3> points;
+ std::vector<IfcVector3> points;
};
@@ -516,159 +506,159 @@ private:
// ------------------------------------------------------------------------------------------------
-Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
+Curve* Curve :: Convert(const IFC::IfcCurve& curve,ConversionData& conv)
{
- if(curve.ToPtr<IfcBoundedCurve>()) {
- if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
- return new PolyLine(*c,conv);
- }
- if(const IfcTrimmedCurve* c = curve.ToPtr<IfcTrimmedCurve>()) {
- return new TrimmedCurve(*c,conv);
- }
- if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
- return new CompositeCurve(*c,conv);
- }
- //if(const IfcBSplineCurve* c = curve.ToPtr<IfcBSplineCurve>()) {
- // return new BSplineCurve(*c,conv);
- //}
- }
-
- if(curve.ToPtr<IfcConic>()) {
- if(const IfcCircle* c = curve.ToPtr<IfcCircle>()) {
- return new Circle(*c,conv);
- }
- if(const IfcEllipse* c = curve.ToPtr<IfcEllipse>()) {
- return new Ellipse(*c,conv);
- }
- }
-
- if(const IfcLine* c = curve.ToPtr<IfcLine>()) {
- return new Line(*c,conv);
- }
-
- // XXX OffsetCurve2D, OffsetCurve3D not currently supported
- return NULL;
+ if(curve.ToPtr<IfcBoundedCurve>()) {
+ if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
+ return new PolyLine(*c,conv);
+ }
+ if(const IfcTrimmedCurve* c = curve.ToPtr<IfcTrimmedCurve>()) {
+ return new TrimmedCurve(*c,conv);
+ }
+ if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
+ return new CompositeCurve(*c,conv);
+ }
+ //if(const IfcBSplineCurve* c = curve.ToPtr<IfcBSplineCurve>()) {
+ // return new BSplineCurve(*c,conv);
+ //}
+ }
+
+ if(curve.ToPtr<IfcConic>()) {
+ if(const IfcCircle* c = curve.ToPtr<IfcCircle>()) {
+ return new Circle(*c,conv);
+ }
+ if(const IfcEllipse* c = curve.ToPtr<IfcEllipse>()) {
+ return new Ellipse(*c,conv);
+ }
+ }
+
+ if(const IfcLine* c = curve.ToPtr<IfcLine>()) {
+ return new Line(*c,conv);
+ }
+
+ // XXX OffsetCurve2D, OffsetCurve3D not currently supported
+ return NULL;
}
#ifdef ASSIMP_BUILD_DEBUG
// ------------------------------------------------------------------------------------------------
-bool Curve :: InRange(IfcFloat u) const
+bool Curve :: InRange(IfcFloat u) const
{
- const ParamRange range = GetParametricRange();
- if (IsClosed()) {
- return true;
- //ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
+ const ParamRange range = GetParametricRange();
+ if (IsClosed()) {
+ return true;
+ //ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
//u = range.first + std::fmod(u-range.first,range.second-range.first);
- }
- const IfcFloat epsilon = 1e-5;
- return u - range.first > -epsilon && range.second - u > -epsilon;
+ }
+ const IfcFloat epsilon = 1e-5;
+ return u - range.first > -epsilon && range.second - u > -epsilon;
}
-#endif
+#endif
// ------------------------------------------------------------------------------------------------
IfcFloat Curve :: GetParametricRangeDelta() const
{
- const ParamRange& range = GetParametricRange();
+ const ParamRange& range = GetParametricRange();
return std::abs(range.second - range.first);
}
// ------------------------------------------------------------------------------------------------
size_t Curve :: EstimateSampleCount(IfcFloat a, IfcFloat b) const
{
- ai_assert(InRange(a) && InRange(b));
+ ai_assert(InRange(a) && InRange(b));
- // arbitrary default value, deriving classes should supply better suited values
- return 16;
+ // arbitrary default value, deriving classes should supply better suited values
+ return 16;
}
// ------------------------------------------------------------------------------------------------
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);
-
- const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
- IfcFloat min_point[2] = {a,b}, min_diff[2] = {inf,inf};
- IfcFloat runner = a;
-
- for (unsigned int i = 0; i < samples; ++i, runner += delta) {
- const IfcFloat diff = (cv->Eval(runner)-val).SquareLength();
- if (diff < min_diff[0]) {
- min_diff[1] = min_diff[0];
- min_point[1] = min_point[0];
-
- min_diff[0] = diff;
- min_point[0] = runner;
- }
- else if (diff < min_diff[1]) {
- min_diff[1] = diff;
- min_point[1] = runner;
- }
- }
-
- ai_assert(min_diff[0] != inf && min_diff[1] != inf);
+ ai_assert(samples>1);
+
+ const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
+ IfcFloat min_point[2] = {a,b}, min_diff[2] = {inf,inf};
+ IfcFloat runner = a;
+
+ for (unsigned int i = 0; i < samples; ++i, runner += delta) {
+ const IfcFloat diff = (cv->Eval(runner)-val).SquareLength();
+ if (diff < min_diff[0]) {
+ min_diff[1] = min_diff[0];
+ min_point[1] = min_point[0];
+
+ min_diff[0] = diff;
+ min_point[0] = runner;
+ }
+ else if (diff < min_diff[1]) {
+ min_diff[1] = diff;
+ min_point[1] = runner;
+ }
+ }
+
+ ai_assert(min_diff[0] != inf && min_diff[1] != inf);
if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
- return min_point[0];
- }
+ return min_point[0];
+ }
- // 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() && std::fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) {
- const Curve::ParamRange& range = cv->GetParametricRange();
- const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
+ const Curve::ParamRange& range = cv->GetParametricRange();
+ const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
- if (wrapdiff < min_diff[0]) {
- const IfcFloat t = min_point[0];
- min_point[0] = min_point[1] > min_point[0] ? range.first : range.second;
- min_point[1] = t;
- }
- }
+ if (wrapdiff < min_diff[0]) {
+ const IfcFloat t = min_point[0];
+ min_point[0] = min_point[1] > min_point[0] ? range.first : range.second;
+ min_point[1] = t;
+ }
+ }
- return RecursiveSearch(cv,val,min_point[0],min_point[1],samples,threshold,recurse+1,max_recurse);
+ return RecursiveSearch(cv,val,min_point[0],min_point[1],samples,threshold,recurse+1,max_recurse);
}
// ------------------------------------------------------------------------------------------------
bool Curve :: ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
{
- // 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
- // will never fail in the default implementation.
+ // 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
+ // will never fail in the default implementation.
- // XXX derive threshold from curve topology
- const IfcFloat threshold = 1e-4f;
- const unsigned int samples = 16;
+ // XXX derive threshold from curve topology
+ const IfcFloat threshold = 1e-4f;
+ const unsigned int samples = 16;
- const ParamRange& range = GetParametricRange();
- paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
+ const ParamRange& range = GetParametricRange();
+ paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
- return true;
+ return true;
}
// ------------------------------------------------------------------------------------------------
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));
- out.verts.reserve( out.verts.size() + cnt );
+ const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
+ out.verts.reserve( out.verts.size() + cnt + 1);
- IfcFloat p = a, delta = (b-a)/cnt;
- for(size_t i = 0; i < cnt; ++i, p += delta) {
- out.verts.push_back(Eval(p));
- }
+ IfcFloat p = a, delta = (b-a)/cnt;
+ for(size_t i = 0; i <= cnt; ++i, p += delta) {
+ out.verts.push_back(Eval(p));
+ }
}
// ------------------------------------------------------------------------------------------------
bool BoundedCurve :: IsClosed() const
{
- return false;
+ return false;
}
// ------------------------------------------------------------------------------------------------
void BoundedCurve :: SampleDiscrete(TempMesh& out) const
{
- const ParamRange& range = GetParametricRange();
- ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
+ const ParamRange& range = GetParametricRange();
+ 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);
}
} // IFC