+ fixes #0001499: Mesh trim loses some triangles
This commit is contained in:
parent
b8772df79c
commit
d456cd21f9
|
@ -225,6 +225,28 @@ bool Line2D::Intersect (const Line2D& rclLine, Vector2D &rclV) const
|
||||||
return true; /*** RETURN TRUE (intersection) **********/
|
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 Line2D::FromPos (double fDistance) const
|
||||||
{
|
{
|
||||||
Vector2D clDir(clV2 - clV1);
|
Vector2D clDir(clV2 - clV1);
|
||||||
|
|
|
@ -124,6 +124,7 @@ public:
|
||||||
// misc
|
// misc
|
||||||
inline bool Contains (const Vector2D &rclV) const;
|
inline bool Contains (const Vector2D &rclV) const;
|
||||||
bool Intersect (const Line2D& rclLine, 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;
|
bool IntersectAndContain (const Line2D& rclLine, Vector2D &rclV) const;
|
||||||
Vector2D FromPos (double fDistance) const;
|
Vector2D FromPos (double fDistance) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -202,6 +202,7 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
|
||||||
Base::Line2D clFacLine, clPolyLine;
|
Base::Line2D clFacLine, clPolyLine;
|
||||||
int iIntersections=0;
|
int iIntersections=0;
|
||||||
int iIntsctWithEdge0=0, iIntsctWithEdge1=0, iIntsctWithEdge2=0;
|
int iIntsctWithEdge0=0, iIntsctWithEdge1=0, iIntsctWithEdge2=0;
|
||||||
|
|
||||||
// Edge with no intersection
|
// Edge with no intersection
|
||||||
iSide = -1;
|
iSide = -1;
|
||||||
|
|
||||||
|
@ -222,7 +223,15 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
|
||||||
clFacLine.clV1 = P1;
|
clFacLine.clV1 = P1;
|
||||||
clFacLine.clV2 = P2;
|
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;
|
bool bPushBack=true;
|
||||||
float fP1P2 = (float)(P2-P1).Length();
|
float fP1P2 = (float)(P2-P1).Length();
|
||||||
float fSP1 = (float)(P1-S).Length();
|
float fSP1 = (float)(P1-S).Length();
|
||||||
|
@ -242,22 +251,8 @@ bool MeshTrimming::GetIntersectionPointsOfPolygonAndFacet(unsigned long ulIndex,
|
||||||
if ((fabs(l+m-1.0f) < 0.001) && (fabs(r+s-1.0f) < 0.001)) {
|
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]);
|
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++;
|
iIntersections++;
|
||||||
|
|
||||||
// only two intersections points per edge allowed
|
// only two intersections points per edge allowed
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
if (iIntsctWithEdge0 == 2)
|
if (iIntsctWithEdge0 == 2)
|
||||||
|
@ -348,14 +343,61 @@ bool MeshTrimming::CreateFacets(unsigned long ulFacetPos, int iSide, const std::
|
||||||
if (iSide == -1)
|
if (iSide == -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// one point found => triangle is only touch at a corner point
|
// no intersection point found => triangle is only touched at a corner point
|
||||||
// in this case we can use the original triangle
|
if (raclPoints.size() == 0) {
|
||||||
if (raclPoints.size() == 1) {
|
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
|
||||||
#if 1
|
int iCtPts=0;
|
||||||
aclNewFacets.push_back(myMesh.GetFacet(ulFacetPos));
|
Base::Vector3f clFacPnt;
|
||||||
#endif
|
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) {
|
else if (raclPoints.size() == 2) {
|
||||||
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
|
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
|
||||||
AdjustFacet(facet, iSide);
|
AdjustFacet(facet, iSide);
|
||||||
|
@ -400,7 +442,7 @@ bool MeshTrimming::CreateFacets(unsigned long ulFacetPos, int iSide, const std::
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// four points found
|
// four intersection points found
|
||||||
else if (raclPoints.size() == 4) {
|
else if (raclPoints.size() == 4) {
|
||||||
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
|
MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos];
|
||||||
AdjustFacet(facet, iSide);
|
AdjustFacet(facet, iSide);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user