1 // Created on: 1993-06-15
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepMesh_CircleTool.hxx>
18 #include <BRepMesh_GeomTool.hxx>
19 #include <gp_Circ2d.hxx>
20 #include <Precision.hxx>
21 #include <BRepMesh_Circle.hxx>
22 #include <BRepMesh_CircleInspector.hxx>
24 //=======================================================================
27 //=======================================================================
28 NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect(
29 const Standard_Integer theTargetIndex)
31 const BRepMesh_Circle& aCircle = myCircles(theTargetIndex);
32 Standard_Real aRadius = aCircle.Radius();
34 return CellFilter_Purge;
36 const gp_XY& aLoc = aCircle.Location();
38 if ((myPoint - aLoc).SquareModulus() - (aRadius * aRadius) <= myTolerance)
39 myResIndices.Append(theTargetIndex);
41 return CellFilter_Keep;
45 //=======================================================================
46 //function : BRepMesh_CircleTool
48 //=======================================================================
49 BRepMesh_CircleTool::BRepMesh_CircleTool(
50 const Handle(NCollection_IncAllocator)& theAllocator)
51 : myTolerance (Precision::PConfusion() * Precision::PConfusion()),
52 myAllocator (theAllocator),
53 myCellFilter(10.0, theAllocator),
54 mySelector (myTolerance, 64, theAllocator)
58 //=======================================================================
59 //function : BRepMesh_CircleTool
61 //=======================================================================
62 BRepMesh_CircleTool::BRepMesh_CircleTool(
63 const Standard_Integer theReservedSize,
64 const Handle(NCollection_IncAllocator)& theAllocator)
65 : myTolerance (Precision::PConfusion() * Precision::PConfusion()),
66 myAllocator (theAllocator),
67 myCellFilter(10.0, theAllocator),
68 mySelector (myTolerance, Max(theReservedSize, 64), theAllocator)
72 //=======================================================================
75 //=======================================================================
76 void BRepMesh_CircleTool::bind(const Standard_Integer theIndex,
77 const gp_XY& theLocation,
78 const Standard_Real theRadius)
80 BRepMesh_Circle aCirle(theLocation, theRadius);
83 Standard_Real aMaxX = Min(theLocation.X() + theRadius, myFaceMax.X());
84 Standard_Real aMinX = Max(theLocation.X() - theRadius, myFaceMin.X());
85 Standard_Real aMaxY = Min(theLocation.Y() + theRadius, myFaceMax.Y());
86 Standard_Real aMinY = Max(theLocation.Y() - theRadius, myFaceMin.Y());
88 gp_XY aMinPnt(aMinX, aMinY);
89 gp_XY aMaxPnt(aMaxX, aMaxY);
91 myCellFilter.Add(theIndex, aMinPnt, aMaxPnt);
92 mySelector.Bind(theIndex, aCirle);
95 //=======================================================================
98 //=======================================================================
99 void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
100 const gp_Circ2d& theCircle)
102 gp_XY aCoord = theCircle.Location().Coord();
103 Standard_Real aRadius = theCircle.Radius();
104 bind(theIndex, aCoord, aRadius);
107 //=======================================================================
108 //function : MakeCircle
110 //=======================================================================
111 Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1,
112 const gp_XY& thePoint2,
113 const gp_XY& thePoint3,
115 Standard_Real& theRadius)
117 static const Standard_Real aPrecision = Precision::PConfusion();
118 static const Standard_Real aSqPrecision = aPrecision * aPrecision;
120 if ((thePoint1 - thePoint3).SquareModulus() < aSqPrecision)
121 return Standard_False;
123 gp_XY aLink1(thePoint2 - thePoint1);
124 if (aLink1.SquareModulus() < aSqPrecision)
125 return Standard_False;
127 gp_XY aLink2(thePoint3 - thePoint2);
128 if (aLink2.SquareModulus() < aSqPrecision)
129 return Standard_False;
131 gp_XY aMidPnt1 = (thePoint1 + thePoint2) / 2.;
132 gp_XY aNorm1 = gp_XY(aLink1.Y(), -aLink1.X());
133 aNorm1.Add(aMidPnt1);
135 if (aLink2.SquareModulus() < aSqPrecision)
136 return Standard_False;
138 gp_XY aMidPnt2 = (thePoint2 + thePoint3) / 2.;
139 gp_XY aNorm2 = gp_XY(aLink2.Y(), -aLink2.X());
140 aNorm2.Add(aMidPnt2);
143 Standard_Real aParam[2];
144 BRepMesh_GeomTool::IntFlag aIntFlag =
145 BRepMesh_GeomTool::IntLinLin(aMidPnt1, aNorm1,
146 aMidPnt2, aNorm2, aIntPnt, aParam);
148 if (aIntFlag != BRepMesh_GeomTool::Cross)
149 return Standard_False;
151 theLocation = aIntPnt;
153 theRadius = Sqrt(Max(Max((thePoint1 - aIntPnt).SquareModulus(),
154 (thePoint2 - aIntPnt).SquareModulus()),
155 (thePoint3 - aIntPnt).SquareModulus())) + 2 * RealEpsilon();
157 return Standard_True;
160 //=======================================================================
163 //=======================================================================
164 Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
165 const gp_XY& thePoint1,
166 const gp_XY& thePoint2,
167 const gp_XY& thePoint3)
170 Standard_Real aRadius;
171 if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius))
172 return Standard_False;
174 bind(theIndex, aLocation, aRadius);
175 return Standard_True;
178 //=======================================================================
181 //=======================================================================
182 void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
184 BRepMesh_Circle& aCircle = mySelector.Circle(theIndex);
185 if(aCircle.Radius() > 0.)
186 aCircle.SetRadius(-1);
189 //=======================================================================
192 //=======================================================================
193 BRepMesh::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
195 mySelector.SetPoint(thePoint);
196 myCellFilter.Inspect(thePoint, mySelector);
197 return mySelector.GetShotCircles();
200 //=======================================================================
203 //=======================================================================
204 void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex)
206 BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.);
207 mySelector.Bind(theIndex, aNullCir);