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 //=======================================================================
25 //function : BRepMesh_CircleTool
27 //=======================================================================
28 BRepMesh_CircleTool::BRepMesh_CircleTool(
29 const Handle(NCollection_IncAllocator)& theAllocator)
30 : myTolerance (Precision::PConfusion()),
31 myAllocator (theAllocator),
32 myCellFilter(10.0, theAllocator),
33 mySelector (myTolerance, 64, theAllocator)
37 //=======================================================================
38 //function : BRepMesh_CircleTool
40 //=======================================================================
41 BRepMesh_CircleTool::BRepMesh_CircleTool(
42 const Standard_Integer theReservedSize,
43 const Handle(NCollection_IncAllocator)& theAllocator)
44 : myTolerance (Precision::PConfusion()),
45 myAllocator (theAllocator),
46 myCellFilter(10.0, theAllocator),
47 mySelector (myTolerance, Max(theReservedSize, 64), theAllocator)
51 //=======================================================================
54 //=======================================================================
55 void BRepMesh_CircleTool::bind(const Standard_Integer theIndex,
56 const gp_XY& theLocation,
57 const Standard_Real theRadius)
59 BRepMesh_Circle aCirle(theLocation, theRadius);
62 Standard_Real aMaxX = Min(theLocation.X() + theRadius, myFaceMax.X());
63 Standard_Real aMinX = Max(theLocation.X() - theRadius, myFaceMin.X());
64 Standard_Real aMaxY = Min(theLocation.Y() + theRadius, myFaceMax.Y());
65 Standard_Real aMinY = Max(theLocation.Y() - theRadius, myFaceMin.Y());
67 gp_XY aMinPnt(aMinX, aMinY);
68 gp_XY aMaxPnt(aMaxX, aMaxY);
70 myCellFilter.Add(theIndex, aMinPnt, aMaxPnt);
71 mySelector.Bind(theIndex, aCirle);
74 //=======================================================================
77 //=======================================================================
78 void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
79 const gp_Circ2d& theCircle)
81 gp_XY aCoord = theCircle.Location().Coord();
82 Standard_Real aRadius = theCircle.Radius();
83 bind(theIndex, aCoord, aRadius);
86 //=======================================================================
87 //function : MakeCircle
89 //=======================================================================
90 Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1,
91 const gp_XY& thePoint2,
92 const gp_XY& thePoint3,
94 Standard_Real& theRadius)
96 static const Standard_Real aPrecision = Precision::PConfusion();
97 static const Standard_Real aSqPrecision = aPrecision * aPrecision;
99 gp_XY aLink1(const_cast<gp_XY&>(thePoint3).ChangeCoord(1) - const_cast<gp_XY&>(thePoint2).ChangeCoord(1),
100 const_cast<gp_XY&>(thePoint2).ChangeCoord(2) - const_cast<gp_XY&>(thePoint3).ChangeCoord(2));
101 if (aLink1.SquareModulus() < aSqPrecision)
102 return Standard_False;
104 gp_XY aLink2(const_cast<gp_XY&>(thePoint1).ChangeCoord(1) - const_cast<gp_XY&>(thePoint3).ChangeCoord(1),
105 const_cast<gp_XY&>(thePoint3).ChangeCoord(2) - const_cast<gp_XY&>(thePoint1).ChangeCoord(2));
106 if (aLink2.SquareModulus() < aSqPrecision)
107 return Standard_False;
109 gp_XY aLink3(const_cast<gp_XY&>(thePoint2).ChangeCoord(1) - const_cast<gp_XY&>(thePoint1).ChangeCoord(1),
110 const_cast<gp_XY&>(thePoint1).ChangeCoord(2) - const_cast<gp_XY&>(thePoint2).ChangeCoord(2));
111 if (aLink3.SquareModulus() < aSqPrecision)
112 return Standard_False;
114 const Standard_Real aD = 2 * (const_cast<gp_XY&>(thePoint1).ChangeCoord(1) * aLink1.Y() +
115 const_cast<gp_XY&>(thePoint2).ChangeCoord(1) * aLink2.Y() +
116 const_cast<gp_XY&>(thePoint3).ChangeCoord(1) * aLink3.Y());
118 if (Abs(aD) < gp::Resolution())
119 return Standard_False;
121 const Standard_Real aInvD = 1. / aD;
122 const Standard_Real aSqMod1 = thePoint1.SquareModulus();
123 const Standard_Real aSqMod2 = thePoint2.SquareModulus();
124 const Standard_Real aSqMod3 = thePoint3.SquareModulus();
125 theLocation.ChangeCoord(1) = (aSqMod1 * aLink1.Y() +
126 aSqMod2 * aLink2.Y() +
127 aSqMod3 * aLink3.Y()) * aInvD;
129 theLocation.ChangeCoord(2) = (aSqMod1 * aLink1.X() +
130 aSqMod2 * aLink2.X() +
131 aSqMod3 * aLink3.X()) * aInvD;
133 theRadius = Sqrt(Max(Max((thePoint1 - theLocation).SquareModulus(),
134 (thePoint2 - theLocation).SquareModulus()),
135 (thePoint3 - theLocation).SquareModulus())) + 2 * RealEpsilon();
137 return Standard_True;
140 //=======================================================================
143 //=======================================================================
144 Standard_Boolean BRepMesh_CircleTool::Bind(const Standard_Integer theIndex,
145 const gp_XY& thePoint1,
146 const gp_XY& thePoint2,
147 const gp_XY& thePoint3)
150 Standard_Real aRadius;
151 if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius))
152 return Standard_False;
154 bind(theIndex, aLocation, aRadius);
155 return Standard_True;
158 //=======================================================================
161 //=======================================================================
162 void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex)
164 BRepMesh_Circle& aCircle = mySelector.Circle(theIndex);
165 if(aCircle.Radius() > 0.)
166 aCircle.SetRadius(-1);
169 //=======================================================================
172 //=======================================================================
173 IMeshData::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint)
175 mySelector.SetPoint(thePoint);
176 myCellFilter.Inspect(thePoint, mySelector);
177 return mySelector.GetShotCircles();
180 //=======================================================================
183 //=======================================================================
184 void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex)
186 BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.);
187 mySelector.Bind(theIndex, aNullCir);