// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <Poly.hxx>
+#include <gp_Ax1.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_XY.hxx>
-#include <Poly.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_ListOfTriangulation.hxx>
#include <Poly_Polygon2D.hxx>
}
}
+//=======================================================================
+//function : Intersect
+//purpose :
+//=======================================================================
+Standard_Boolean Poly::Intersect (const Handle(Poly_Triangulation)& theTri,
+ const gp_Ax1& theAxis,
+ const Standard_Boolean theIsClosest,
+ Poly_Triangle& theTriangle,
+ Standard_Real& theDistance)
+{
+ const Standard_Real aConf = 1E-15;
+ const gp_XYZ& aLoc = theAxis.Location().XYZ();
+ const gp_Dir& aDir = theAxis.Direction();
+
+ Standard_Real aResult = theIsClosest ? RealLast() : 0.0;
+ Standard_Real aParam = 0.0;
+ Standard_Integer aTriNodes[3] = {};
+ for (Standard_Integer aTriIter = 1; aTriIter <= theTri->NbTriangles(); ++aTriIter)
+ {
+ const Poly_Triangle& aTri = theTri->Triangle (aTriIter);
+ aTri.Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
+ if (IntersectTriLine (aLoc, aDir,
+ theTri->Node (aTriNodes[0]).XYZ(),
+ theTri->Node (aTriNodes[1]).XYZ(),
+ theTri->Node (aTriNodes[2]).XYZ(),
+ aParam))
+ {
+ if (aParam > aConf)
+ {
+ if (theIsClosest)
+ {
+ if (aParam < aResult)
+ {
+ aResult = aParam;
+ theTriangle = aTri;
+ }
+ }
+ else if (aParam > aResult)
+ {
+ aResult = aParam;
+ theTriangle = aTri;
+ }
+ }
+ }
+ }
+
+ if (aConf < aResult && aResult < RealLast())
+ {
+ theDistance = aResult;
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+//! Calculate the minor of the given matrix, defined by the columns specified by values c1, c2, c3.
+static double Determinant (const double a[3][4],
+ const int c1,
+ const int c2,
+ const int c3)
+{
+ return a[0][c1]*a[1][c2]*a[2][c3] +
+ a[0][c2]*a[1][c3]*a[2][c1] +
+ a[0][c3]*a[1][c1]*a[2][c2] -
+ a[0][c3]*a[1][c2]*a[2][c1] -
+ a[0][c2]*a[1][c1]*a[2][c3] -
+ a[0][c1]*a[1][c3]*a[2][c2];
+}
+
+//=======================================================================
+//function : IntersectTriLine
+//purpose : Intersect a triangle with a line
+//=======================================================================
+Standard_Integer Poly::IntersectTriLine (const gp_XYZ& theStart,
+ const gp_Dir& theDir,
+ const gp_XYZ& theV0,
+ const gp_XYZ& theV1,
+ const gp_XYZ& theV2,
+ Standard_Real& theParam)
+{
+ int aRes = 0;
+ const double aConf = 1E-15;
+
+ const double aMat34[3][4] =
+ {
+ { -theDir.X(),
+ theV1.X() - theV0.X(), theV2.X() - theV0.X(), theStart.X() - theV0.X() },
+ { -theDir.Y(),
+ theV1.Y() - theV0.Y(), theV2.Y() - theV0.Y(), theStart.Y() - theV0.Y() },
+ { -theDir.Z(),
+ theV1.Z() - theV0.Z(), theV2.Z() - theV0.Z(), theStart.Z() - theV0.Z() }
+ };
+
+ const double aD = Determinant (aMat34, 0, 1, 2);
+ const double aDt = Determinant (aMat34, 3, 1, 2);
+ if (aD > aConf)
+ {
+ const double aDa = Determinant (aMat34, 0, 3, 2);
+ if (aDa > -aConf)
+ {
+ const double aDb = Determinant (aMat34, 0, 1, 3);
+ aRes = ((aDb > -aConf) && (aDa + aDb <= aD + aConf));
+ }
+ }
+ else if (aD < -aConf)
+ {
+ const double aDa = Determinant (aMat34, 0, 3, 2);
+ if (aDa < aConf)
+ {
+ const double aDb = Determinant (aMat34, 0, 1, 3);
+ aRes = ((aDb < aConf) && (aDa + aDb >= aD - aConf));
+ }
+ }
+ if (aRes != 0)
+ {
+ theParam = aDt / aD;
+ }
+
+ return aRes;
+}
//! point is inside).
Standard_EXPORT static Standard_Real PointOnTriangle (const gp_XY& P1, const gp_XY& P2, const gp_XY& P3, const gp_XY& P, gp_XY& UV);
+ //! Computes the intersection between axis and triangulation.
+ //! @param theTri [in] input triangulation
+ //! @param theAxis [in] intersecting ray
+ //! @param theIsClosest [in] finds the closest intersection when TRUE, finds the farthest otherwise
+ //! @param theTriangle [out] intersected triangle
+ //! @param theDistance [out] distance along ray to intersection point
+ //! @return TRUE if intersection takes place, FALSE otherwise.
+ Standard_EXPORT static Standard_Boolean Intersect (const Handle(Poly_Triangulation)& theTri,
+ const gp_Ax1& theAxis,
+ const Standard_Boolean theIsClosest,
+ Poly_Triangle& theTriangle,
+ Standard_Real& theDistance);
+
+ //! Computes the intersection between a triangle defined by three vertexes and a line.
+ //! @param theStart [in] picking ray origin
+ //! @param theDir [in] picking ray direction
+ //! @param theV0 [in] first triangle node
+ //! @param theV1 [in] second triangle node
+ //! @param theV2 [in] third triangle node
+ //! @param theParam [out] param on line of the intersection point
+ //! @return 1 if intersection was found, 0 otherwise.
+ Standard_EXPORT static Standard_Integer IntersectTriLine (const gp_XYZ& theStart,
+ const gp_Dir& theDir,
+ const gp_XYZ& theV0,
+ const gp_XYZ& theV1,
+ const gp_XYZ& theV2,
+ Standard_Real& theParam);
//! Returns area and perimeter of 2D-polygon given by its vertices.
//! theArea will be negative if the polygon is bypassed clockwise
return Standard_True;
}
-
-protected:
-
-
-
-
-
private:
-
-
-
friend class Poly_Triangle;
friend class Poly_Triangulation;
friend class Poly_Polygon3D;
};
-
-
-
-
-
-
#endif // _Poly_HeaderFile
const Standard_Integer ip1(aTri.Node(ind[i+1]));
// Disconnect from both neighbours
- Poly_CoherentTriangle * pTriConn[2] = {
- const_cast<Poly_CoherentTriangle *>(aTri.GetConnectedTri(ind[i-1])),
- const_cast<Poly_CoherentTriangle *>(aTri.GetConnectedTri(ind[i+1]))
- };
RemoveTriangle(aTri);
// Reconnect all triangles from Node(ind[i+1]) to Node(ind[i-1])
- Poly_CoherentTriPtr::Iterator anIterConn =
- pNode[ind[i+1]]->TriangleIterator();
- for (; anIterConn.More(); anIterConn.Next()) {
+ for (;;)
+ {
+ Poly_CoherentTriPtr::Iterator anIterConn = pNode[ind[i+1]]->TriangleIterator();
+ if (!anIterConn.More())
+ {
+ break;
+ }
+
Poly_CoherentTriangle& aTriConn = anIterConn.ChangeValue();
- if (&aTriConn != &aTri) {
- if (aTriConn.Node(0) == ip1)
- aTriConn.myNodes[0] = im1;
- else if (aTriConn.Node(1) == ip1)
- aTriConn.myNodes[1] = im1;
- else if (aTriConn.Node(2) == ip1)
- aTriConn.myNodes[2] = im1;
- pNode[ind[i+1]]->RemoveTriangle(aTriConn, myAlloc);
- pNode[ind[i-1]]->AddTriangle(aTriConn, myAlloc);
+ Standard_Integer aNewTriConn[] = {aTriConn.Node(0), aTriConn.Node(1), aTriConn.Node(2)};
+ if (&aTriConn != &aTri)
+ {
+ if (aNewTriConn[0] == ip1)
+ aNewTriConn[0] = im1;
+ else if (aNewTriConn[1] == ip1)
+ aNewTriConn[1] = im1;
+ else if (aNewTriConn[2] == ip1)
+ aNewTriConn[2] = im1;
+
+ RemoveTriangle (aTriConn);
+ AddTriangle (aNewTriConn[0], aNewTriConn[1], aNewTriConn[2]);
+ }
+ else
+ {
+ anIterConn.Next();
+ if (!anIterConn.More())
+ {
+ break;
+ }
}
}
- // Set the new mutual connection between the neighbours of the
- // removed degenerated triangle.
- if (pTriConn[0] && pTriConn[1]) {
- pTriConn[0]->SetConnection(* pTriConn[1]);
- }
- if (pLstRemovedNode) {
+ if (pLstRemovedNode)
+ {
pLstRemovedNode->Append(TwoIntegers(ip1, im1));
}
aResult = Standard_True;
for (Standard_Integer i = 0; i < 3; i++) {
if (theTriangle.Node(i) >= 0) {
Poly_CoherentNode& aNode = myNodes(theTriangle.Node(i));
- if (aNode.RemoveTriangle(theTriangle, myAlloc)) {
- theTriangle.myNodes[i] = -1;
- aResult = Standard_True;
- }
// If Links exist in this Triangulation, remove or update a Link
Poly_CoherentLink * aLink =
const_cast<Poly_CoherentLink *>(theTriangle.mypLink[i]);
for (Standard_Integer j = 0; j < 3; j++) {
if (aLink == pTriOpp->GetLink(j)) {
if (aLink->OppositeNode(0) == theTriangle.Node(i)) {
- aLink->myOppositeNode[0] = 0L;
+ aLink->myOppositeNode[0] = -1;
toRemoveLink = Standard_False;
} else if (aLink->OppositeNode(1) == theTriangle.Node(i)) {
- aLink->myOppositeNode[1] = 0L;
+ aLink->myOppositeNode[1] = -1;
toRemoveLink = Standard_False;
}
break;
if (toRemoveLink)
RemoveLink(* aLink);
}
+ if (aNode.RemoveTriangle(theTriangle, myAlloc))
+ {
+ theTriangle.myNodes[i] = -1;
+ aResult = Standard_True;
+ }
}
theTriangle.RemoveConnection(i);
}
toAddLink = Standard_False;
}
}
- break;
}
}
}