Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-06-15 |
2 | // Created by: Didier PIFFAULT | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
0d88155b | 16 | |
fc9b36d6 | 17 | #include <BRepMesh_CircleTool.hxx> |
18 | #include <BRepMesh_GeomTool.hxx> | |
19 | #include <gp_Circ2d.hxx> | |
0d88155b | 20 | #include <Precision.hxx> |
fc9b36d6 | 21 | #include <BRepMesh_Circle.hxx> |
0d88155b | 22 | #include <BRepMesh_CircleInspector.hxx> |
0d88155b | 23 | |
0d88155b O |
24 | //======================================================================= |
25 | //function : BRepMesh_CircleTool | |
26 | //purpose : | |
27 | //======================================================================= | |
fc9b36d6 | 28 | BRepMesh_CircleTool::BRepMesh_CircleTool( |
848fa7e3 | 29 | const Handle(NCollection_IncAllocator)& theAllocator) |
7bd071ed | 30 | : myTolerance (Precision::PConfusion()), |
fc9b36d6 | 31 | myAllocator (theAllocator), |
7c4740f8 | 32 | myCellFilter(10.0, theAllocator), |
fc9b36d6 | 33 | mySelector (myTolerance, 64, theAllocator) |
0d88155b | 34 | { |
0d88155b O |
35 | } |
36 | ||
37 | //======================================================================= | |
38 | //function : BRepMesh_CircleTool | |
39 | //purpose : | |
40 | //======================================================================= | |
fc9b36d6 | 41 | BRepMesh_CircleTool::BRepMesh_CircleTool( |
848fa7e3 | 42 | const Standard_Integer theReservedSize, |
43 | const Handle(NCollection_IncAllocator)& theAllocator) | |
7bd071ed | 44 | : myTolerance (Precision::PConfusion()), |
fc9b36d6 | 45 | myAllocator (theAllocator), |
7c4740f8 | 46 | myCellFilter(10.0, theAllocator), |
fc9b36d6 | 47 | mySelector (myTolerance, Max(theReservedSize, 64), theAllocator) |
0d88155b | 48 | { |
0d88155b O |
49 | } |
50 | ||
0d88155b | 51 | //======================================================================= |
fc9b36d6 | 52 | //function : bind |
0d88155b O |
53 | //purpose : |
54 | //======================================================================= | |
fc9b36d6 | 55 | void BRepMesh_CircleTool::bind(const Standard_Integer theIndex, |
56 | const gp_XY& theLocation, | |
57 | const Standard_Real theRadius) | |
0d88155b | 58 | { |
fc9b36d6 | 59 | BRepMesh_Circle aCirle(theLocation, theRadius); |
0d88155b | 60 | |
fc9b36d6 | 61 | //compute coords |
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()); | |
0d88155b | 66 | |
fc9b36d6 | 67 | gp_XY aMinPnt(aMinX, aMinY); |
68 | gp_XY aMaxPnt(aMaxX, aMaxY); | |
0d88155b | 69 | |
fc9b36d6 | 70 | myCellFilter.Add(theIndex, aMinPnt, aMaxPnt); |
71 | mySelector.Bind(theIndex, aCirle); | |
0d88155b O |
72 | } |
73 | ||
74 | //======================================================================= | |
fc9b36d6 | 75 | //function : Bind |
0d88155b O |
76 | //purpose : |
77 | //======================================================================= | |
fc9b36d6 | 78 | void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex, |
79 | const gp_Circ2d& theCircle) | |
0d88155b | 80 | { |
fc9b36d6 | 81 | gp_XY aCoord = theCircle.Location().Coord(); |
82 | Standard_Real aRadius = theCircle.Radius(); | |
83 | bind(theIndex, aCoord, aRadius); | |
0d88155b O |
84 | } |
85 | ||
86 | //======================================================================= | |
ec26bf88 | 87 | //function : MakeCircle |
0d88155b O |
88 | //purpose : |
89 | //======================================================================= | |
ec26bf88 | 90 | Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1, |
91 | const gp_XY& thePoint2, | |
92 | const gp_XY& thePoint3, | |
93 | gp_XY& theLocation, | |
94 | Standard_Real& theRadius) | |
0d88155b | 95 | { |
ec26bf88 | 96 | static const Standard_Real aPrecision = Precision::PConfusion(); |
97 | static const Standard_Real aSqPrecision = aPrecision * aPrecision; | |
0d88155b | 98 | |
7bd071ed | 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)); | |
ec26bf88 | 101 | if (aLink1.SquareModulus() < aSqPrecision) |
102 | return Standard_False; | |
0d88155b | 103 | |
7bd071ed | 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)); | |
ec26bf88 | 106 | if (aLink2.SquareModulus() < aSqPrecision) |
107 | return Standard_False; | |
108 | ||
7bd071ed | 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) | |
ec26bf88 | 112 | return Standard_False; |
0d88155b | 113 | |
7bd071ed | 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()); | |
0d88155b | 117 | |
7bd071ed | 118 | if (Abs(aD) < gp::Resolution()) |
fc9b36d6 | 119 | return Standard_False; |
0d88155b | 120 | |
7bd071ed | 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; | |
128 | ||
129 | theLocation.ChangeCoord(2) = (aSqMod1 * aLink1.X() + | |
130 | aSqMod2 * aLink2.X() + | |
131 | aSqMod3 * aLink3.X()) * aInvD; | |
ec26bf88 | 132 | |
7bd071ed | 133 | theRadius = Sqrt(Max(Max((thePoint1 - theLocation).SquareModulus(), |
134 | (thePoint2 - theLocation).SquareModulus()), | |
135 | (thePoint3 - theLocation).SquareModulus())) + 2 * RealEpsilon(); | |
ec26bf88 | 136 | |
137 | return Standard_True; | |
138 | } | |
139 | ||
140 | //======================================================================= | |
141 | //function : Bind | |
142 | //purpose : | |
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) | |
148 | { | |
149 | gp_XY aLocation; | |
150 | Standard_Real aRadius; | |
151 | if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius)) | |
152 | return Standard_False; | |
153 | ||
154 | bind(theIndex, aLocation, aRadius); | |
0d88155b O |
155 | return Standard_True; |
156 | } | |
157 | ||
158 | //======================================================================= | |
159 | //function : Delete | |
160 | //purpose : | |
161 | //======================================================================= | |
fc9b36d6 | 162 | void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex) |
0d88155b | 163 | { |
fc9b36d6 | 164 | BRepMesh_Circle& aCircle = mySelector.Circle(theIndex); |
165 | if(aCircle.Radius() > 0.) | |
166 | aCircle.SetRadius(-1); | |
0d88155b O |
167 | } |
168 | ||
169 | //======================================================================= | |
170 | //function : Select | |
171 | //purpose : | |
172 | //======================================================================= | |
7bd071ed | 173 | IMeshData::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint) |
0d88155b | 174 | { |
fc9b36d6 | 175 | mySelector.SetPoint(thePoint); |
176 | myCellFilter.Inspect(thePoint, mySelector); | |
177 | return mySelector.GetShotCircles(); | |
0d88155b O |
178 | } |
179 | ||
fc9b36d6 | 180 | //======================================================================= |
181 | //function : MocBind | |
182 | //purpose : | |
183 | //======================================================================= | |
184 | void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex) | |
0d88155b | 185 | { |
fc9b36d6 | 186 | BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.); |
187 | mySelector.Bind(theIndex, aNullCir); | |
0d88155b | 188 | } |