#include <BRepMesh_Circle.hxx>
#include <BRepMesh_CircleInspector.hxx>
-//=======================================================================
-//function : Inspect
-//purpose :
-//=======================================================================
-NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect(
- const Standard_Integer theTargetIndex)
-{
- const BRepMesh_Circle& aCircle = myCircles(theTargetIndex);
- Standard_Real aRadius = aCircle.Radius();
- if(aRadius < 0.)
- return CellFilter_Purge;
-
- const gp_XY& aLoc = aCircle.Location();
-
- if ((myPoint - aLoc).SquareModulus() - (aRadius * aRadius) <= myTolerance)
- myResIndices.Append(theTargetIndex);
-
- return CellFilter_Keep;
-}
-
-
//=======================================================================
//function : BRepMesh_CircleTool
//purpose :
//=======================================================================
BRepMesh_CircleTool::BRepMesh_CircleTool(
- const BRepMeshCol::Allocator& theAllocator)
-: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
+ const Handle(NCollection_IncAllocator)& theAllocator)
+: myTolerance (Precision::PConfusion()),
myAllocator (theAllocator),
- myCellFilter(10, theAllocator),
+ myCellFilter(10.0, theAllocator),
mySelector (myTolerance, 64, theAllocator)
{
}
//purpose :
//=======================================================================
BRepMesh_CircleTool::BRepMesh_CircleTool(
- const Standard_Integer theReservedSize,
- const BRepMeshCol::Allocator& theAllocator)
-: myTolerance (Precision::PConfusion() * Precision::PConfusion()),
+ const Standard_Integer theReservedSize,
+ const Handle(NCollection_IncAllocator)& theAllocator)
+: myTolerance (Precision::PConfusion()),
myAllocator (theAllocator),
- myCellFilter(10, theAllocator),
+ myCellFilter(10.0, theAllocator),
mySelector (myTolerance, Max(theReservedSize, 64), theAllocator)
{
}
}
//=======================================================================
-//function : Bind
+//function : MakeCircle
//purpose :
//=======================================================================
-Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
- const gp_XY& thePoint1,
- const gp_XY& thePoint2,
- const gp_XY& thePoint3)
+Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1,
+ const gp_XY& thePoint2,
+ const gp_XY& thePoint3,
+ gp_XY& theLocation,
+ Standard_Real& theRadius)
{
- const Standard_Real aPrecision = Precision::PConfusion();
- const Standard_Real aSqPrecision = aPrecision * aPrecision;
+ static const Standard_Real aPrecision = Precision::PConfusion();
+ static const Standard_Real aSqPrecision = aPrecision * aPrecision;
- const gp_XY aPoints[3] = { thePoint1, thePoint2, thePoint3 };
+ gp_XY aLink1(const_cast<gp_XY&>(thePoint3).ChangeCoord(1) - const_cast<gp_XY&>(thePoint2).ChangeCoord(1),
+ const_cast<gp_XY&>(thePoint2).ChangeCoord(2) - const_cast<gp_XY&>(thePoint3).ChangeCoord(2));
+ if (aLink1.SquareModulus() < aSqPrecision)
+ return Standard_False;
- gp_XY aNorm[3];
- gp_XY aMidPnt[3];
- for (Standard_Integer i = 0; i < 3; ++i)
- {
- const gp_XY& aPnt1 = aPoints[i];
- const gp_XY& aPnt2 = aPoints[(i + 1) % 3];
+ gp_XY aLink2(const_cast<gp_XY&>(thePoint1).ChangeCoord(1) - const_cast<gp_XY&>(thePoint3).ChangeCoord(1),
+ const_cast<gp_XY&>(thePoint3).ChangeCoord(2) - const_cast<gp_XY&>(thePoint1).ChangeCoord(2));
+ if (aLink2.SquareModulus() < aSqPrecision)
+ return Standard_False;
- aMidPnt[i] = (aPnt1 + aPnt2) / 2.;
+ gp_XY aLink3(const_cast<gp_XY&>(thePoint2).ChangeCoord(1) - const_cast<gp_XY&>(thePoint1).ChangeCoord(1),
+ const_cast<gp_XY&>(thePoint1).ChangeCoord(2) - const_cast<gp_XY&>(thePoint2).ChangeCoord(2));
+ if (aLink3.SquareModulus() < aSqPrecision)
+ return Standard_False;
+
+ const Standard_Real aD = 2 * (const_cast<gp_XY&>(thePoint1).ChangeCoord(1) * aLink1.Y() +
+ const_cast<gp_XY&>(thePoint2).ChangeCoord(1) * aLink2.Y() +
+ const_cast<gp_XY&>(thePoint3).ChangeCoord(1) * aLink3.Y());
+
+ if (Abs(aD) < gp::Resolution())
+ return Standard_False;
- gp_XY aLink(aPnt2 - aPnt1);
- if (aLink.SquareModulus() < aSqPrecision)
- return Standard_False;
+ const Standard_Real aInvD = 1. / aD;
+ const Standard_Real aSqMod1 = thePoint1.SquareModulus();
+ const Standard_Real aSqMod2 = thePoint2.SquareModulus();
+ const Standard_Real aSqMod3 = thePoint3.SquareModulus();
+ theLocation.ChangeCoord(1) = (aSqMod1 * aLink1.Y() +
+ aSqMod2 * aLink2.Y() +
+ aSqMod3 * aLink3.Y()) * aInvD;
- aNorm[i] = gp_XY(aLink.Y(), -aLink.X());
- aNorm[i].Add(aMidPnt[i]);
- }
+ theLocation.ChangeCoord(2) = (aSqMod1 * aLink1.X() +
+ aSqMod2 * aLink2.X() +
+ aSqMod3 * aLink3.X()) * aInvD;
- gp_XY aIntPnt;
- Standard_Real aParam[2];
- BRepMesh_GeomTool::IntFlag aIntFlag =
- BRepMesh_GeomTool::IntLinLin(aMidPnt[0], aNorm[0],
- aMidPnt[1], aNorm[1], aIntPnt, aParam);
+ theRadius = Sqrt(Max(Max((thePoint1 - theLocation).SquareModulus(),
+ (thePoint2 - theLocation).SquareModulus()),
+ (thePoint3 - theLocation).SquareModulus())) + 2 * RealEpsilon();
- if (aIntFlag != BRepMesh_GeomTool::Cross)
+ return Standard_True;
+}
+
+//=======================================================================
+//function : Bind
+//purpose :
+//=======================================================================
+Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
+ const gp_XY& thePoint1,
+ const gp_XY& thePoint2,
+ const gp_XY& thePoint3)
+{
+ gp_XY aLocation;
+ Standard_Real aRadius;
+ if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius))
return Standard_False;
- Standard_Real aRadius = (aPoints[0] - aIntPnt).Modulus();
- bind(theIndex, aIntPnt, aRadius);
+ bind(theIndex, aLocation, aRadius);
return Standard_True;
}
//function : Select
//purpose :
//=======================================================================
-BRepMeshCol::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
+IMeshData::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
{
mySelector.SetPoint(thePoint);
myCellFilter.Inspect(thePoint, mySelector);