- Ifc: better handling of degenerate primitives occuring in clipping operations.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1317 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/6/merge
aramis_acg 2012-10-21 18:10:56 +00:00
parent f6f2c087db
commit 7ed1400c68
1 changed files with 32 additions and 16 deletions

View File

@ -546,40 +546,48 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh) { IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok)
{
const std::vector<IfcVector3>& out = curmesh.verts; const std::vector<IfcVector3>& out = curmesh.verts;
IfcMatrix3 m; IfcMatrix3 m;
ok = true;
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 IfcVector3 any_point = out[s-1]; const IfcVector3 any_point = out[s-1];
IfcVector3 nor; IfcVector3 nor;
// The input polygon is arbitrarily shaped, so we might need some tries // The input polygon is arbitrarily shaped, therefore 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. Note that Newells algorithm would give
// right in all cases, Newell's algorithm would be the correct one ... ). // a more robust result, but this variant also gives us a suitable first
// axis for the 2D coordinate space on the polygon plane, exploiting the
// fact that the input polygon is nearly always a quad.
bool done = false;
size_t base = s-curmesh.vertcnt.back(), i, j; size_t base = s-curmesh.vertcnt.back(), i, j;
for (i = base; i < s-1; ++i) { for (i = base; !done && i < s-1; !done && ++i) {
for (j = i+1; j < s; ++j) { for (j = i+1; j < s; ++j) {
nor = -((out[i]-any_point)^(out[j]-any_point)); nor = -((out[i]-any_point)^(out[j]-any_point));
if(fabs(nor.Length()) > 1e-8f) { if(fabs(nor.Length()) > 1e-8f) {
goto out; done = true;
break;
} }
} }
} }
assert(0); if(!done) {
ok = false;
out: return m;
}
nor.Normalize(); nor.Normalize();
IfcVector3 r = (out[i]-any_point); IfcVector3 r = (out[i]-any_point);
r.Normalize(); r.Normalize();
// reconstruct orthonormal basis // Reconstruct orthonormal basis
// XXX use Gram Schmidt for increased robustness
IfcVector3 u = r ^ nor; IfcVector3 u = r ^ nor;
u.Normalize(); u.Normalize();
@ -599,7 +607,8 @@ out:
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors, TempMesh& curmesh) bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std::vector<IfcVector3>& nors,
TempMesh& curmesh)
{ {
std::vector<IfcVector3>& out = curmesh.verts; std::vector<IfcVector3>& out = curmesh.verts;
@ -607,7 +616,12 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
// 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 IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh); bool ok;
const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh, ok);
if (!ok) {
return false;
}
const IfcMatrix3 minv = IfcMatrix3(m).Inverse(); const IfcMatrix3 minv = IfcMatrix3(m).Inverse();
const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3); const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3);
@ -1397,7 +1411,11 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
// 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.
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(curmesh)); bool ok;
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(curmesh,ok));
if(!ok) {
return false;
}
const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3); const IfcVector3& nor = IfcVector3(m.c1, m.c2, m.c3);
IfcFloat coord = -1; IfcFloat coord = -1;
@ -1924,8 +1942,6 @@ void ProcessBooleanExtrudedAreaSolidDifference(const IfcExtrudedAreaSolid* as, T
vit += pcount; vit += pcount;
} }
IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)"); IFCImporter::LogDebug("generating CSG geometry by geometric difference to a solid (IfcExtrudedAreaSolid)");
} }