- Ifc: fix regressions caused by previous commit. This also fixes a bug which caused openings to appear at the wrong place.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1324 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/6/merge
parent
39ae26bfd8
commit
11b2219b1a
|
@ -69,7 +69,8 @@ namespace Assimp {
|
||||||
|
|
||||||
bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
const std::vector<IfcVector3>& nors,
|
const std::vector<IfcVector3>& nors,
|
||||||
TempMesh& curmesh);
|
TempMesh& curmesh,
|
||||||
|
bool check_intersection = true);
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -152,6 +153,8 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
|
|
||||||
const size_t outer_polygon_size = *outer_polygon_it;
|
const size_t outer_polygon_size = *outer_polygon_it;
|
||||||
const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
|
const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
|
||||||
|
const IfcVector3& master_normal_norm = IfcVector3(master_normal).Normalize();
|
||||||
|
|
||||||
|
|
||||||
// Generate fake openings to meet the interface for the quadrulate
|
// Generate fake openings to meet the interface for the quadrulate
|
||||||
// algorithm. It boils down to generating small boxes given the
|
// algorithm. It boils down to generating small boxes given the
|
||||||
|
@ -198,7 +201,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
|
||||||
std::copy(outer_vit, outer_vit+outer_polygon_size,
|
std::copy(outer_vit, outer_vit+outer_polygon_size,
|
||||||
std::back_inserter(temp.verts));
|
std::back_inserter(temp.verts));
|
||||||
|
|
||||||
TryAddOpenings_Quadrulate(fake_openings, normals, temp);
|
TryAddOpenings_Quadrulate(fake_openings, normals, temp, false);
|
||||||
result.Append(temp);
|
result.Append(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +477,7 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok)
|
IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcFloat* d = NULL)
|
||||||
{
|
{
|
||||||
const std::vector<IfcVector3>& out = curmesh.verts;
|
const std::vector<IfcVector3>& out = curmesh.verts;
|
||||||
IfcMatrix3 m;
|
IfcMatrix3 m;
|
||||||
|
@ -514,6 +517,10 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok)
|
||||||
IfcVector3 r = (out[i]-any_point);
|
IfcVector3 r = (out[i]-any_point);
|
||||||
r.Normalize();
|
r.Normalize();
|
||||||
|
|
||||||
|
if(d) {
|
||||||
|
*d = -any_point * nor;
|
||||||
|
}
|
||||||
|
|
||||||
// Reconstruct orthonormal basis
|
// Reconstruct orthonormal basis
|
||||||
// XXX use Gram Schmidt for increased robustness
|
// XXX use Gram Schmidt for increased robustness
|
||||||
IfcVector3 u = r ^ nor;
|
IfcVector3 u = r ^ nor;
|
||||||
|
@ -1332,7 +1339,8 @@ void CloseWindows(const ContourVector& contours, const IfcMatrix4& minv,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
const std::vector<IfcVector3>& nors,
|
const std::vector<IfcVector3>& nors,
|
||||||
TempMesh& curmesh)
|
TempMesh& curmesh,
|
||||||
|
bool check_intersection)
|
||||||
{
|
{
|
||||||
std::vector<IfcVector3>& out = curmesh.verts;
|
std::vector<IfcVector3>& out = curmesh.verts;
|
||||||
OpeningRefVector contours_to_openings;
|
OpeningRefVector contours_to_openings;
|
||||||
|
@ -1340,7 +1348,8 @@ 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.
|
||||||
bool ok;
|
bool ok;
|
||||||
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(curmesh,ok));
|
IfcFloat base_d;
|
||||||
|
IfcMatrix4 m = IfcMatrix4(DerivePlaneCoordinateSpace(curmesh,ok,&base_d));
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1412,11 +1421,18 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
IfcVector2 vpmin,vpmax;
|
IfcVector2 vpmin,vpmax;
|
||||||
MinMaxChooser<IfcVector2>()(vpmin,vpmax);
|
MinMaxChooser<IfcVector2>()(vpmin,vpmax);
|
||||||
|
|
||||||
|
|
||||||
// The opening meshes are real 3D meshes so skip over all faces
|
// The opening meshes are real 3D meshes so skip over all faces
|
||||||
// clearly facing into the wrong direction.
|
// clearly facing into the wrong direction. Also, we need to check
|
||||||
|
// whether the meshes do actually intersect the base surface plane.
|
||||||
|
// This is done by recording minimum and maximum values for the
|
||||||
|
// d component of the plane equation for all polys and checking
|
||||||
|
// against the surface d.
|
||||||
|
IfcFloat dmin, dmax;
|
||||||
|
MinMaxChooser<IfcFloat>()(dmin,dmax);
|
||||||
|
|
||||||
std::vector<IfcVector2> contour;
|
std::vector<IfcVector2> contour;
|
||||||
for (size_t f = 0, vi_total = 0, fend = profile_vertcnts.size(); f < fend; ++f) {
|
for (size_t f = 0, vi_total = 0, fend = profile_vertcnts.size(); f < fend; ++f) {
|
||||||
|
|
||||||
const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
|
const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
|
||||||
(profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize();
|
(profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize();
|
||||||
|
|
||||||
|
@ -1429,6 +1445,12 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) {
|
for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) {
|
||||||
const IfcVector3& x = profile_verts[vi_total];
|
const IfcVector3& x = profile_verts[vi_total];
|
||||||
|
|
||||||
|
if(check_intersection) {
|
||||||
|
const IfcFloat vert_d = -(x * nor);
|
||||||
|
dmin = std::min(dmin, vert_d);
|
||||||
|
dmax = std::max(dmax, vert_d);
|
||||||
|
}
|
||||||
|
|
||||||
const IfcVector3& v = m * x;
|
const IfcVector3& v = m * x;
|
||||||
IfcVector2 vv(v.x, v.y);
|
IfcVector2 vv(v.x, v.y);
|
||||||
|
|
||||||
|
@ -1447,6 +1469,12 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: This epsilon may be too large
|
||||||
|
const IfcFloat epsilon = fabs(dmax-dmin) * 0.01;
|
||||||
|
if (check_intersection && (base_d < dmin-epsilon || base_d > dmax+epsilon)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BoundingBox bb = BoundingBox(vpmin,vpmax);
|
BoundingBox bb = BoundingBox(vpmin,vpmax);
|
||||||
|
|
||||||
// Skip over very small openings - these are likely projection errors
|
// Skip over very small openings - these are likely projection errors
|
||||||
|
@ -1461,8 +1489,8 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
for (std::vector<BoundingBox>::iterator it = bbs.begin(); it != bbs.end();) {
|
for (std::vector<BoundingBox>::iterator it = bbs.begin(); it != bbs.end();) {
|
||||||
const BoundingBox& ibb = *it;
|
const BoundingBox& ibb = *it;
|
||||||
|
|
||||||
if (ibb.first.x <= bb.second.x && ibb.second.x >= bb.first.x &&
|
if (ibb.first.x < bb.second.x && ibb.second.x > bb.first.x &&
|
||||||
ibb.first.y <= bb.second.y && ibb.second.y >= bb.second.x) {
|
ibb.first.y < bb.second.y && ibb.second.y > bb.second.x) {
|
||||||
|
|
||||||
// Take these two contours and try to merge them. If they overlap (which
|
// Take these two contours and try to merge them. If they overlap (which
|
||||||
// should not happen, but in fact happens-in-the-real-world [tm] ),
|
// should not happen, but in fact happens-in-the-real-world [tm] ),
|
||||||
|
@ -1472,7 +1500,7 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
ClipperLib::ExPolygons poly;
|
ClipperLib::ExPolygons poly;
|
||||||
MergeWindowContours(contour, other, poly);
|
MergeWindowContours(contour, other, poly);
|
||||||
|
|
||||||
if (poly.size() > 1) {
|
if (false && poly.size() > 1) {
|
||||||
IFCImporter::LogWarn("cannot use quadrify algorithm to generate wall openings due to "
|
IFCImporter::LogWarn("cannot use quadrify algorithm to generate wall openings due to "
|
||||||
"bounding box overlaps, using poly2tri fallback method");
|
"bounding box overlaps, using poly2tri fallback method");
|
||||||
return TryAddOpenings_Poly2Tri(openings, nors, curmesh);
|
return TryAddOpenings_Poly2Tri(openings, nors, curmesh);
|
||||||
|
@ -1502,7 +1530,9 @@ bool TryAddOpenings_Quadrulate(std::vector<TempOpening>& openings,
|
||||||
|
|
||||||
contours_to_openings.erase(contours_to_openings.begin() + std::distance(bbs.begin(),it));
|
contours_to_openings.erase(contours_to_openings.begin() + std::distance(bbs.begin(),it));
|
||||||
contours.erase(contours.begin() + std::distance(bbs.begin(),it));
|
contours.erase(contours.begin() + std::distance(bbs.begin(),it));
|
||||||
it = bbs.erase(it);
|
bbs.erase(it);
|
||||||
|
|
||||||
|
it = bbs.begin();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue