diff --git a/code/IFCCurve.cpp b/code/IFCCurve.cpp index f23c5a516..4d9f499e0 100644 --- a/code/IFCCurve.cpp +++ b/code/IFCCurve.cpp @@ -424,6 +424,12 @@ public: 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( 0. ),maxval); diff --git a/code/IFCGeometry.cpp b/code/IFCGeometry.cpp index a06471cdb..525208abc 100644 --- a/code/IFCGeometry.cpp +++ b/code/IFCGeometry.cpp @@ -560,13 +560,19 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv result.verts.reserve(cnt_segments * samples * 4); result.vertcnt.reserve((cnt_segments - 1) * samples); - // XXX while EstimateSampleCount() works well for non-composite curves, it - // fails badly for composite curves that require non-uniform sampling - // for good results. - IfcFloat p = solid.StartParam, delta = (solid.EndParam-solid.StartParam)/ (samples - 1); + std::vector points; + points.reserve(cnt_segments * samples); - - IfcVector3 current = curve->Eval(p); + TempMesh temp; + curve->SampleDiscrete(temp,solid.StartParam,solid.EndParam); + const std::vector& curve_points = temp.verts; + + if(curve_points.empty()) { + IFCImporter::LogWarn("curve evaluation yielded no points (IfcSweptDiskSolid)"); + return; + } + + IfcVector3 current = curve_points[0]; IfcVector3 previous = current; IfcVector3 next; @@ -575,15 +581,12 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv startvec.y = 1.0f; startvec.z = 1.0f; - std::vector points; - points.reserve(cnt_segments * samples); - - p += delta; - // generate circles at the sweep positions - for(size_t i = 0; i < samples; ++i, p += delta) { + for(size_t i = 0; i < samples; ++i) { - next = curve->Eval(p); + if(i != samples - 1) { + next = curve_points[i + 1]; + } // get a direction vector reflecting the approximate curvature (i.e. tangent) IfcVector3 d = (current-previous) + (next-previous); diff --git a/code/IFCLoader.cpp b/code/IFCLoader.cpp index add16565a..b4ef88aee 100644 --- a/code/IFCLoader.cpp +++ b/code/IFCLoader.cpp @@ -154,7 +154,7 @@ void IFCImporter::SetupProperties(const Importer* pImp) settings.skipCurveRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS,true); settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION,true); - settings.conicSamplingAngle = 10.f; + settings.conicSamplingAngle = 5.f; settings.skipAnnotations = true; }