diff options
Diffstat (limited to 'src/3rdparty/assimp/code/IFCBoolean.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/IFCBoolean.cpp | 729 |
1 files changed, 0 insertions, 729 deletions
diff --git a/src/3rdparty/assimp/code/IFCBoolean.cpp b/src/3rdparty/assimp/code/IFCBoolean.cpp deleted file mode 100644 index 8573e4d62..000000000 --- a/src/3rdparty/assimp/code/IFCBoolean.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2010, 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 -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - 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 -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -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 -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 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file IFCBoolean.cpp - * @brief Implements a subset of Ifc boolean operations - */ - -#include "AssimpPCH.h" - -#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER -#include "IFCUtil.h" -#include "PolyTools.h" -#include "ProcessHelper.h" - -#include <iterator> - -namespace Assimp { - namespace IFC { - -// ------------------------------------------------------------------------------------------------ -enum Intersect { - Intersect_No, - Intersect_LiesOnPlane, - Intersect_Yes -}; - -// ------------------------------------------------------------------------------------------------ -Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0, - const IfcVector3& e1, - IfcVector3& out) -{ - const IfcVector3 pdelta = e0 - p, seg = e1-e0; - const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta); - - if (fabs(dotOne) < 1e-6) { - return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No; - } - - const IfcFloat t = dotTwo/dotOne; - // t must be in [0..1] if the intersection point is within the given segment - if (t > 1.f || t < 0.f) { - return Intersect_No; - } - out = e0+t*seg; - return Intersect_Yes; -} - -// ------------------------------------------------------------------------------------------------ -void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, - const TempMesh& first_operand, - ConversionData& conv) -{ - ai_assert(hs != NULL); - - const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); - if(!plane) { - IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); - return; - } - - // extract plane base position vector and normal vector - IfcVector3 p,n(0.f,0.f,1.f); - if (plane->Position->Axis) { - ConvertDirection(n,plane->Position->Axis.Get()); - } - ConvertCartesianPoint(p,plane->Position->Location); - - if(!IsTrue(hs->AgreementFlag)) { - n *= -1.f; - } - - // clip the current contents of `meshout` against the plane we obtained from the second operand - const std::vector<IfcVector3>& in = first_operand.verts; - std::vector<IfcVector3>& outvert = result.verts; - - std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), - end = first_operand.vertcnt.end(), iit; - - outvert.reserve(in.size()); - result.vertcnt.reserve(first_operand.vertcnt.size()); - - unsigned int vidx = 0; - for(iit = begin; iit != end; vidx += *iit++) { - - unsigned int newcount = 0; - for(unsigned int i = 0; i < *iit; ++i) { - const IfcVector3& e0 = in[vidx+i], e1 = in[vidx+(i+1)%*iit]; - - // does the next segment intersect the plane? - IfcVector3 isectpos; - const Intersect isect = IntersectSegmentPlane(p,n,e0,e1,isectpos); - if (isect == Intersect_No || isect == Intersect_LiesOnPlane) { - if ( (e0-p).Normalize()*n > 0 ) { - outvert.push_back(e0); - ++newcount; - } - } - else if (isect == Intersect_Yes) { - if ( (e0-p).Normalize()*n > 0 ) { - // e0 is on the right side, so keep it - outvert.push_back(e0); - outvert.push_back(isectpos); - newcount += 2; - } - else { - // e0 is on the wrong side, so drop it and keep e1 instead - outvert.push_back(isectpos); - ++newcount; - } - } - } - - if (!newcount) { - continue; - } - - IfcVector3 vmin,vmax; - ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); - - // filter our IfcFloat points - those may happen if a point lies - // directly on the intersection line. However, due to IfcFloat - // precision a bitwise comparison is not feasible to detect - // this case. - const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f; - FuzzyVectorCompare fz(epsilon); - - std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); - - if (e != outvert.end()) { - newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); - outvert.erase(e,outvert.end()); - } - if (fz(*( outvert.end()-newcount),outvert.back())) { - outvert.pop_back(); - --newcount; - } - if(newcount > 2) { - result.vertcnt.push_back(newcount); - } - else while(newcount-->0) { - result.verts.pop_back(); - } - - } - IFCImporter::LogDebug("generating CSG geometry by plane clipping (IfcBooleanClippingResult)"); -} - -// ------------------------------------------------------------------------------------------------ -// Check if e0-e1 intersects a sub-segment of the given boundary line. -// note: this functions works on 3D vectors, but performs its intersection checks solely in xy. -bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, const std::vector<IfcVector3>& boundary, - std::vector<size_t>& intersected_boundary_segments, - std::vector<IfcVector3>& intersected_boundary_points, - bool half_open = false, - bool* e0_hits_border = NULL) -{ - ai_assert(intersected_boundary_segments.empty()); - ai_assert(intersected_boundary_points.empty()); - - if(e0_hits_border) { - *e0_hits_border = false; - } - - const IfcVector3& e = e1 - e0; - - for (size_t i = 0, bcount = boundary.size(); i < bcount; ++i) { - // boundary segment i: b0-b1 - const IfcVector3& b0 = boundary[i]; - const IfcVector3& b1 = boundary[(i+1) % bcount]; - - const IfcVector3& b = b1 - b0; - - // segment-segment intersection - // solve b0 + b*s = e0 + e*t for (s,t) - const IfcFloat det = (-b.x * e.y + e.x * b.y); - if(fabs(det) < 1e-6) { - // no solutions (parallel lines) - continue; - } - - const IfcFloat x = b0.x - e0.x; - const IfcFloat y = b0.y - e0.y; - - const IfcFloat s = (x*e.y - e.x*y)/det; - const IfcFloat t = (x*b.y - b.x*y)/det; - -#ifdef ASSIMP_BUILD_DEBUG - const IfcVector3 check = b0 + b*s - (e0 + e*t); - ai_assert((IfcVector2(check.x,check.y)).SquareLength() < 1e-5); -#endif - - // for a valid intersection, s-t should be in range [0,1]. - // note that for t (i.e. the segment point) we only use a - // half-sided epsilon because the next segment should catch - // this case. - const IfcFloat epsilon = 1e-6; - if (t >= -epsilon && (t <= 1.0+epsilon || half_open) && s >= -epsilon && s <= 1.0) { - - if (e0_hits_border && !*e0_hits_border) { - *e0_hits_border = fabs(t) < 1e-5f; - } - - const IfcVector3& p = e0 + e*t; - - // only insert the point into the list if it is sufficiently - // far away from the previous intersection point. This way, - // we avoid duplicate detection if the intersection is - // directly on the vertex between two segments. - if (!intersected_boundary_points.empty() && intersected_boundary_segments.back()==i-1 ) { - const IfcVector3 diff = intersected_boundary_points.back() - p; - if(IfcVector2(diff.x, diff.y).SquareLength() < 1e-7) { - continue; - } - } - intersected_boundary_segments.push_back(i); - intersected_boundary_points.push_back(p); - } - } - - return !intersected_boundary_segments.empty(); -} - - -// ------------------------------------------------------------------------------------------------ -// note: this functions works on 3D vectors, but performs its intersection checks solely in xy. -bool PointInPoly(const IfcVector3& p, const std::vector<IfcVector3>& boundary) -{ - // even-odd algorithm: take a random vector that extends from p to infinite - // and counts how many times it intersects edges of the boundary. - // because checking for segment intersections is prone to numeric inaccuracies - // or double detections (i.e. when hitting multiple adjacent segments at their - // shared vertices) we do it thrice with different rays and vote on it. - - // the even-odd algorithm doesn't work for points which lie directly on - // the border of the polygon. If any of our attempts produces this result, - // we return false immediately. - - std::vector<size_t> intersected_boundary_segments; - std::vector<IfcVector3> intersected_boundary_points; - size_t votes = 0; - - bool is_border; - IntersectsBoundaryProfile(p, p + IfcVector3(1.0,0,0), boundary, - intersected_boundary_segments, - intersected_boundary_points, true, &is_border); - - if(is_border) { - return false; - } - - votes += intersected_boundary_segments.size() % 2; - - intersected_boundary_segments.clear(); - intersected_boundary_points.clear(); - - IntersectsBoundaryProfile(p, p + IfcVector3(0,1.0,0), boundary, - intersected_boundary_segments, - intersected_boundary_points, true, &is_border); - - if(is_border) { - return false; - } - - votes += intersected_boundary_segments.size() % 2; - - intersected_boundary_segments.clear(); - intersected_boundary_points.clear(); - - IntersectsBoundaryProfile(p, p + IfcVector3(0.6,-0.6,0.0), boundary, - intersected_boundary_segments, - intersected_boundary_points, true, &is_border); - - if(is_border) { - return false; - } - - votes += intersected_boundary_segments.size() % 2; - //ai_assert(votes == 3 || votes == 0); - return votes > 1; -} - - -// ------------------------------------------------------------------------------------------------ -void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBoundedHalfSpace* hs, TempMesh& result, - const TempMesh& first_operand, - ConversionData& conv) -{ - ai_assert(hs != NULL); - - const IfcPlane* const plane = hs->BaseSurface->ToPtr<IfcPlane>(); - if(!plane) { - IFCImporter::LogError("expected IfcPlane as base surface for the IfcHalfSpaceSolid"); - return; - } - - // extract plane base position vector and normal vector - IfcVector3 p,n(0.f,0.f,1.f); - if (plane->Position->Axis) { - ConvertDirection(n,plane->Position->Axis.Get()); - } - ConvertCartesianPoint(p,plane->Position->Location); - - if(!IsTrue(hs->AgreementFlag)) { - n *= -1.f; - } - - n.Normalize(); - - // obtain the polygonal bounding volume - boost::shared_ptr<TempMesh> profile = boost::shared_ptr<TempMesh>(new TempMesh()); - if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) { - IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace"); - return; - } - - IfcMatrix4 proj_inv; - ConvertAxisPlacement(proj_inv,hs->Position); - - // and map everything into a plane coordinate space so all intersection - // tests can be done in 2D space. - IfcMatrix4 proj = proj_inv; - proj.Inverse(); - - // clip the current contents of `meshout` against the plane we obtained from the second operand - const std::vector<IfcVector3>& in = first_operand.verts; - std::vector<IfcVector3>& outvert = result.verts; - - std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin(), - end = first_operand.vertcnt.end(), iit; - - outvert.reserve(in.size()); - result.vertcnt.reserve(first_operand.vertcnt.size()); - - std::vector<size_t> intersected_boundary_segments; - std::vector<IfcVector3> intersected_boundary_points; - - // TODO: the following algorithm doesn't handle all cases. - unsigned int vidx = 0; - for(iit = begin; iit != end; vidx += *iit++) { - if (!*iit) { - continue; - } - - unsigned int newcount = 0; - bool was_outside_boundary = !PointInPoly(proj * in[vidx], profile->verts); - - // used any more? - //size_t last_intersected_boundary_segment; - IfcVector3 last_intersected_boundary_point; - - bool extra_point_flag = false; - IfcVector3 extra_point; - - IfcVector3 enter_volume; - bool entered_volume_flag = false; - - for(unsigned int i = 0; i < *iit; ++i) { - // current segment: [i,i+1 mod size] or [*extra_point,i] if extra_point_flag is set - const IfcVector3& e0 = extra_point_flag ? extra_point : in[vidx+i]; - const IfcVector3& e1 = extra_point_flag ? in[vidx+i] : in[vidx+(i+1)%*iit]; - - // does the current segment intersect the polygonal boundary? - const IfcVector3& e0_plane = proj * e0; - const IfcVector3& e1_plane = proj * e1; - - intersected_boundary_segments.clear(); - intersected_boundary_points.clear(); - - const bool is_outside_boundary = !PointInPoly(e1_plane, profile->verts); - const bool is_boundary_intersection = is_outside_boundary != was_outside_boundary; - - IntersectsBoundaryProfile(e0_plane, e1_plane, profile->verts, - intersected_boundary_segments, - intersected_boundary_points); - - ai_assert(!is_boundary_intersection || !intersected_boundary_segments.empty()); - - // does the current segment intersect the plane? - // (no extra check if this is an extra point) - IfcVector3 isectpos; - const Intersect isect = extra_point_flag ? Intersect_No : IntersectSegmentPlane(p,n,e0,e1,isectpos); - -#ifdef ASSIMP_BUILD_DEBUG - if (isect == Intersect_Yes) { - const IfcFloat f = fabs((isectpos - p)*n); - ai_assert(f < 1e-5); - } -#endif - - const bool is_white_side = (e0-p)*n >= -1e-6; - - // e0 on good side of plane? (i.e. we should keep all geometry on this side) - if (is_white_side) { - // but is there an intersection in e0-e1 and is e1 in the clipping - // boundary? In this case, generate a line that only goes to the - // intersection point. - if (isect == Intersect_Yes && !is_outside_boundary) { - outvert.push_back(e0); - ++newcount; - - outvert.push_back(isectpos); - ++newcount; - - /* - // this is, however, only a line that goes to the plane, but not - // necessarily to the point where the bounding volume on the - // black side of the plane is hit. So basically, we need another - // check for [isectpos-e1], which should yield an intersection - // point. - extra_point_flag = true; - extra_point = isectpos; - - was_outside_boundary = true; - continue; */ - - // [isectpos, enter_volume] potentially needs extra points. - // For this, we determine the intersection point with the - // bounding volume and project it onto the plane. - /* - const IfcVector3& enter_volume_proj = proj * enter_volume; - const IfcVector3& enter_isectpos = proj * isectpos; - - intersected_boundary_segments.clear(); - intersected_boundary_points.clear(); - - IntersectsBoundaryProfile(enter_volume_proj, enter_isectpos, profile->verts, - intersected_boundary_segments, - intersected_boundary_points); - - if(!intersected_boundary_segments.empty()) { - - vec = vec + ((p - vec) * n) * n; - } - */ - - //entered_volume_flag = true; - } - else { - outvert.push_back(e0); - ++newcount; - } - } - // e0 on bad side of plane, e1 on good (i.e. we should remove geometry on this side, - // but only if it is within the bounding volume). - else if (isect == Intersect_Yes) { - // is e0 within the clipping volume? Insert the intersection point - // of [e0,e1] and the plane instead of e0. - if(was_outside_boundary) { - outvert.push_back(e0); - } - else { - if(entered_volume_flag) { - const IfcVector3& fix_point = enter_volume + ((p - enter_volume) * n) * n; - outvert.push_back(fix_point); - ++newcount; - } - - outvert.push_back(isectpos); - } - entered_volume_flag = false; - ++newcount; - } - else { // no intersection with plane or parallel; e0,e1 are on the bad side - - // did we just pass the boundary line to the poly bounding? - if (is_boundary_intersection) { - - // and are now outside the clipping boundary? - if (is_outside_boundary) { - // in this case, get the point where the clipping boundary - // was entered first. Then, get the point where the clipping - // boundary volume was left! These two points with the plane - // normal form another plane that intersects the clipping - // volume. There are two ways to get from the first to the - // second point along the intersection curve, try to pick the - // one that lies within the current polygon. - - // TODO this approach doesn't handle all cases - - // ... - - IfcFloat d = 1e20; - IfcVector3 vclosest; - BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { - const IfcFloat dn = (v-e1_plane).SquareLength(); - if (dn < d) { - d = dn; - vclosest = v; - } - } - - vclosest = proj_inv * vclosest; - if(entered_volume_flag) { - const IfcVector3& fix_point = vclosest + ((p - vclosest) * n) * n; - outvert.push_back(fix_point); - ++newcount; - - entered_volume_flag = false; - } - - outvert.push_back(vclosest); - ++newcount; - - //outvert.push_back(e1); - //++newcount; - } - else { - entered_volume_flag = true; - - // we just entered the clipping boundary. Record the point - // and the segment where we entered and also generate this point. - //last_intersected_boundary_segment = intersected_boundary_segments.front(); - //last_intersected_boundary_point = intersected_boundary_points.front(); - - outvert.push_back(e0); - ++newcount; - - IfcFloat d = 1e20; - IfcVector3 vclosest; - BOOST_FOREACH(const IfcVector3& v, intersected_boundary_points) { - const IfcFloat dn = (v-e0_plane).SquareLength(); - if (dn < d) { - d = dn; - vclosest = v; - } - } - - enter_volume = proj_inv * vclosest; - outvert.push_back(enter_volume); - ++newcount; - } - } - // if not, we just keep the vertex - else if (is_outside_boundary) { - outvert.push_back(e0); - ++newcount; - - entered_volume_flag = false; - } - } - - was_outside_boundary = is_outside_boundary; - extra_point_flag = false; - } - - if (!newcount) { - continue; - } - - IfcVector3 vmin,vmax; - ArrayBounds(&*(outvert.end()-newcount),newcount,vmin,vmax); - - // filter our IfcFloat points - those may happen if a point lies - // directly on the intersection line. However, due to IfcFloat - // precision a bitwise comparison is not feasible to detect - // this case. - const IfcFloat epsilon = (vmax-vmin).SquareLength() / 1e6f; - FuzzyVectorCompare fz(epsilon); - - std::vector<IfcVector3>::iterator e = std::unique( outvert.end()-newcount, outvert.end(), fz ); - - if (e != outvert.end()) { - newcount -= static_cast<unsigned int>(std::distance(e,outvert.end())); - outvert.erase(e,outvert.end()); - } - if (fz(*( outvert.end()-newcount),outvert.back())) { - outvert.pop_back(); - --newcount; - } - if(newcount > 2) { - result.vertcnt.push_back(newcount); - } - else while(newcount-->0) { - result.verts.pop_back(); - } - - } - IFCImporter::LogDebug("generating CSG geometry by plane clipping with polygonal bounding (IfcBooleanClippingResult)"); -} - -// ------------------------------------------------------------------------------------------------ -void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, TempMesh& result, - const TempMesh& first_operand, - ConversionData& conv) -{ - ai_assert(as != NULL); - - // This case is handled by reduction to an instance of the quadrify() algorithm. - // Obviously, this won't work for arbitrarily complex cases. In fact, the first - // operand should be near-planar. Luckily, this is usually the case in Ifc - // buildings. - - boost::shared_ptr<TempMesh> meshtmp = boost::shared_ptr<TempMesh>(new TempMesh()); - ProcessExtrudedAreaSolid(*as,*meshtmp,conv,false); - - std::vector<TempOpening> openings(1, TempOpening(as,IfcVector3(0,0,0),meshtmp,boost::shared_ptr<TempMesh>())); - - result = first_operand; - - TempMesh temp; - - std::vector<IfcVector3>::const_iterator vit = first_operand.verts.begin(); - BOOST_FOREACH(unsigned int pcount, first_operand.vertcnt) { - temp.Clear(); - - temp.verts.insert(temp.verts.end(), vit, vit + pcount); - temp.vertcnt.push_back(pcount); - - // The algorithms used to generate mesh geometry sometimes - // spit out lines or other degenerates which must be - // filtered to avoid running into assertions later on. - - // ComputePolygonNormal returns the Newell normal, so the - // length of the normal is the area of the polygon. - const IfcVector3& normal = temp.ComputeLastPolygonNormal(false); - if (normal.SquareLength() < static_cast<IfcFloat>(1e-5)) { - IFCImporter::LogWarn("skipping degenerate polygon (ProcessBooleanExtrudedAreaSolidDifference)"); - continue; - } - - GenerateOpenings(openings, std::vector<IfcVector3>(1,IfcVector3(1,0,0)), temp, false, true); - result.Append(temp); - - vit += pcount; - } - - IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)"); -} - -// ------------------------------------------------------------------------------------------------ -void ProcessBoolean(const IfcBooleanResult& boolean, TempMesh& result, ConversionData& conv) -{ - // supported CSG operations: - // DIFFERENCE - if(const IfcBooleanResult* const clip = boolean.ToPtr<IfcBooleanResult>()) { - if(clip->Operator != "DIFFERENCE") { - IFCImporter::LogWarn("encountered unsupported boolean operator: " + (std::string)clip->Operator); - return; - } - - // supported cases (1st operand): - // IfcBooleanResult -- call ProcessBoolean recursively - // IfcSweptAreaSolid -- obtain polygonal geometry first - - // supported cases (2nd operand): - // IfcHalfSpaceSolid -- easy, clip against plane - // IfcExtrudedAreaSolid -- reduce to an instance of the quadrify() algorithm - - - const IfcHalfSpaceSolid* const hs = clip->SecondOperand->ResolveSelectPtr<IfcHalfSpaceSolid>(conv.db); - const IfcExtrudedAreaSolid* const as = clip->SecondOperand->ResolveSelectPtr<IfcExtrudedAreaSolid>(conv.db); - if(!hs && !as) { - IFCImporter::LogError("expected IfcHalfSpaceSolid or IfcExtrudedAreaSolid as second clipping operand"); - return; - } - - TempMesh first_operand; - if(const IfcBooleanResult* const op0 = clip->FirstOperand->ResolveSelectPtr<IfcBooleanResult>(conv.db)) { - ProcessBoolean(*op0,first_operand,conv); - } - else if (const IfcSweptAreaSolid* const swept = clip->FirstOperand->ResolveSelectPtr<IfcSweptAreaSolid>(conv.db)) { - ProcessSweptAreaSolid(*swept,first_operand,conv); - } - else { - IFCImporter::LogError("expected IfcSweptAreaSolid or IfcBooleanResult as first clipping operand"); - return; - } - - if(hs) { - - const IfcPolygonalBoundedHalfSpace* const hs_bounded = clip->SecondOperand->ResolveSelectPtr<IfcPolygonalBoundedHalfSpace>(conv.db); - if (hs_bounded) { - ProcessPolygonalBoundedBooleanHalfSpaceDifference(hs_bounded, result, first_operand, conv); - } - else { - ProcessBooleanHalfSpaceDifference(hs, result, first_operand, conv); - } - } - else { - ProcessBooleanExtrudedAreaSolidDifference(as, result, first_operand, conv); - } - } - else { - IFCImporter::LogWarn("skipping unknown IfcBooleanResult entity, type is " + boolean.GetClassName()); - } -} - -} // ! IFC -} // ! Assimp - -#endif - |