+ fixes #0001499: Mesh trim loses some triangles

This commit is contained in:
wmayer 2014-07-15 18:42:42 +02:00
parent b8772df79c
commit d456cd21f9
3 changed files with 89 additions and 24 deletions

View File

@ -225,6 +225,28 @@ bool Line2D::Intersect (const Line2D& rclLine, Vector2D &rclV) const
return true; /*** RETURN TRUE (intersection) **********/
}
bool Line2D::Intersect (const Vector2D &rclV, double eps) const
{
double dxc = rclV.fX - clV1.fX;
double dyc = rclV.fY - clV1.fY;
double dxl = clV2.fX - clV1.fX;
double dyl = clV2.fY - clV1.fY;
double cross = dxc * dyl - dyc * dxl;
// is point on the infinite line?
if (fabs(cross) > eps)
return false;
// point is on line but it is also between V1 and V2?
double dot = dxc * dxl + dyc * dyl;
double len = dxl * dxl + dyl * dyl;
if (dot < -eps || dot > len + eps)
return false;
return true;
}
Vector2D Line2D::FromPos (double fDistance) const
{
Vector2D clDir(clV2 - clV1);

View File

@ -124,6 +124,7 @@ public:
// misc
inline bool Contains (const Vector2D &rclV) const;
bool Intersect (const Line2D& rclLine, Vector2D &rclV) const;
bool Intersect (const Vector2D &rclV, double eps) const;
bool IntersectAndContain (const Line2D& rclLine, Vector2D &rclV) const;
Vector2D FromPos (double fDistance) const;
};

View File

@ -202,6 +202,7 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
Base::Line2D clFacLine, clPolyLine;
int iIntersections=0;
int iIntsctWithEdge0=0, iIntsctWithEdge1=0, iIntsctWithEdge2=0;
// Edge with no intersection
iSide = -1;
@ -222,7 +223,15 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
clFacLine.clV1 = P1;
clFacLine.clV2 = P2;
if (clPolyLine.Intersect(clFacLine, S)) {
if (clPolyLine.Intersect(P1, MESH_MIN_PT_DIST)) {
// do not pick up corner points
iIntersections++;
}
else if (clPolyLine.Intersect(P2, MESH_MIN_PT_DIST)) {
// do not pick up corner points
iIntersections++;
}
else if (clPolyLine.Intersect(clFacLine, S)) {
bool bPushBack=true;
float fP1P2 = (float)(P2-P1).Length();
float fSP1 = (float)(P1-S).Length();
@ -242,20 +251,6 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
if ((fabs(l+m-1.0f) < 0.001) && (fabs(r+s-1.0f) < 0.001)) {
Base::Vector3f clIntersection(m*clFac._aclPoints[j]+l*clFac._aclPoints[(j+1)%3]);
// in case the triangle is intersected at a corner point then don't allow this point twice
bool duplicate = false;
for (std::vector<Base::Vector3f>::iterator it = raclPoints.begin(); it != raclPoints.end(); ++it) {
if (Base::DistanceP2(*it, clIntersection) < MESH_MIN_PT_DIST) {
duplicate = true;
break;
}
}
#if 1
if (duplicate)
continue; // ignore this point
#endif
iIntersections++;
// only two intersections points per edge allowed
@ -348,14 +343,61 @@ bool MeshTrimming::CreateFacets(unsigned long ulFacetPos, int iSide, const std::
if (iSide == -1)
return false;
// one point found => triangle is only touch at a corner point
// in this case we can use the original triangle
if (raclPoints.size() == 1) {
#if 1
aclNewFacets.push_back(myMesh.GetFacet(ulFacetPos));
#endif
// no intersection point found => triangle is only touched at a corner point
if (raclPoints.size() == 0) {
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
int iCtPts=0;
Base::Vector3f clFacPnt;
Base::Vector2D clProjPnt;
for (int i=0; i<3; i++) {
clFacPnt = (*myProj)(myMesh._aclPointArray[facet._aulPoints[i]]);
clProjPnt = Base::Vector2D(clFacPnt.x, clFacPnt.y);
if (myPoly.Contains(clProjPnt) == myInner)
++iCtPts;
}
// in this case we can use the original triangle
if (iCtPts < 2)
aclNewFacets.push_back(myMesh.GetFacet(ulFacetPos));
}
// two points found
// one intersection point found => triangle is also touched at a corner point
else if (raclPoints.size() == 1) {
Base::Vector3f clP(raclPoints[0]);
clP = ((*myProj)(clP));
Base::Vector2D P(clP.x, clP.y);
MeshGeomFacet clFac(myMesh.GetFacet(ulFacetPos));
// determine the edge containing the intersection point
Base::Line2D clFacLine;
for (int j=0; j<3; j++) {
Base::Vector3f clP1((*myProj)(clFac._aclPoints[j]));
Base::Vector3f clP2((*myProj)(clFac._aclPoints[(j+1)%3]));
Base::Vector2D P1(clP1.x, clP1.y);
Base::Vector2D P2(clP2.x, clP2.y);
clFacLine.clV1 = P1;
clFacLine.clV2 = P2;
if (clFacLine.Intersect(P, MESH_MIN_PT_DIST)) {
if (myPoly.Contains(P1) == myInner) {
MeshGeomFacet clNew;
clNew._aclPoints[0] = raclPoints[0];
clNew._aclPoints[1] = clFac._aclPoints[(j+1)%3];
clNew._aclPoints[2] = clFac._aclPoints[(j+2)%3];
aclNewFacets.push_back(clNew);
break;
}
else if (myPoly.Contains(P2) == myInner) {
MeshGeomFacet clNew;
clNew._aclPoints[0] = raclPoints[0];
clNew._aclPoints[1] = clFac._aclPoints[(j+2)%3];
clNew._aclPoints[2] = clFac._aclPoints[j];
aclNewFacets.push_back(clNew);
break;
}
}
}
}
// two intersection points found
else if (raclPoints.size() == 2) {
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
AdjustFacet(facet, iSide);
@ -400,7 +442,7 @@ bool MeshTrimming::CreateFacets(unsigned long ulFacetPos, int iSide, const std::
else
return false;
}
// four points found
// four intersection points found
else if (raclPoints.size() == 4) {
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
AdjustFacet(facet, iSide);