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 O |
23 | |
24 | //======================================================================= | |
25 | //function : Inspect | |
26 | //purpose : | |
0d88155b | 27 | //======================================================================= |
fc9b36d6 | 28 | NCollection_CellFilter_Action BRepMesh_CircleInspector::Inspect( |
29 | const Standard_Integer theTargetIndex) | |
0d88155b | 30 | { |
fc9b36d6 | 31 | const BRepMesh_Circle& aCircle = myCircles(theTargetIndex); |
32 | Standard_Real aRadius = aCircle.Radius(); | |
33 | if(aRadius < 0.) | |
0d88155b | 34 | return CellFilter_Purge; |
fc9b36d6 | 35 | |
36 | const gp_XY& aLoc = aCircle.Location(); | |
37 | ||
38 | if ((myPoint - aLoc).SquareModulus() - (aRadius * aRadius) <= myTolerance) | |
39 | myResIndices.Append(theTargetIndex); | |
40 | ||
0d88155b O |
41 | return CellFilter_Keep; |
42 | } | |
43 | ||
44 | ||
45 | //======================================================================= | |
46 | //function : BRepMesh_CircleTool | |
47 | //purpose : | |
48 | //======================================================================= | |
fc9b36d6 | 49 | BRepMesh_CircleTool::BRepMesh_CircleTool( |
848fa7e3 | 50 | const Handle(NCollection_IncAllocator)& theAllocator) |
fc9b36d6 | 51 | : myTolerance (Precision::PConfusion() * Precision::PConfusion()), |
52 | myAllocator (theAllocator), | |
a7653f4f | 53 | myCellFilter(10, theAllocator), |
fc9b36d6 | 54 | mySelector (myTolerance, 64, theAllocator) |
0d88155b | 55 | { |
0d88155b O |
56 | } |
57 | ||
58 | //======================================================================= | |
59 | //function : BRepMesh_CircleTool | |
60 | //purpose : | |
61 | //======================================================================= | |
fc9b36d6 | 62 | BRepMesh_CircleTool::BRepMesh_CircleTool( |
848fa7e3 | 63 | const Standard_Integer theReservedSize, |
64 | const Handle(NCollection_IncAllocator)& theAllocator) | |
fc9b36d6 | 65 | : myTolerance (Precision::PConfusion() * Precision::PConfusion()), |
66 | myAllocator (theAllocator), | |
a7653f4f | 67 | myCellFilter(10, theAllocator), |
fc9b36d6 | 68 | mySelector (myTolerance, Max(theReservedSize, 64), theAllocator) |
0d88155b | 69 | { |
0d88155b O |
70 | } |
71 | ||
0d88155b | 72 | //======================================================================= |
fc9b36d6 | 73 | //function : bind |
0d88155b O |
74 | //purpose : |
75 | //======================================================================= | |
fc9b36d6 | 76 | void BRepMesh_CircleTool::bind(const Standard_Integer theIndex, |
77 | const gp_XY& theLocation, | |
78 | const Standard_Real theRadius) | |
0d88155b | 79 | { |
fc9b36d6 | 80 | BRepMesh_Circle aCirle(theLocation, theRadius); |
0d88155b | 81 | |
fc9b36d6 | 82 | //compute coords |
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()); | |
0d88155b | 87 | |
fc9b36d6 | 88 | gp_XY aMinPnt(aMinX, aMinY); |
89 | gp_XY aMaxPnt(aMaxX, aMaxY); | |
0d88155b | 90 | |
fc9b36d6 | 91 | myCellFilter.Add(theIndex, aMinPnt, aMaxPnt); |
92 | mySelector.Bind(theIndex, aCirle); | |
0d88155b O |
93 | } |
94 | ||
95 | //======================================================================= | |
fc9b36d6 | 96 | //function : Bind |
0d88155b O |
97 | //purpose : |
98 | //======================================================================= | |
fc9b36d6 | 99 | void BRepMesh_CircleTool::Bind(const Standard_Integer theIndex, |
100 | const gp_Circ2d& theCircle) | |
0d88155b | 101 | { |
fc9b36d6 | 102 | gp_XY aCoord = theCircle.Location().Coord(); |
103 | Standard_Real aRadius = theCircle.Radius(); | |
104 | bind(theIndex, aCoord, aRadius); | |
0d88155b O |
105 | } |
106 | ||
107 | //======================================================================= | |
ec26bf88 | 108 | //function : MakeCircle |
0d88155b O |
109 | //purpose : |
110 | //======================================================================= | |
ec26bf88 | 111 | Standard_Boolean BRepMesh_CircleTool::MakeCircle(const gp_XY& thePoint1, |
112 | const gp_XY& thePoint2, | |
113 | const gp_XY& thePoint3, | |
114 | gp_XY& theLocation, | |
115 | Standard_Real& theRadius) | |
0d88155b | 116 | { |
ec26bf88 | 117 | static const Standard_Real aPrecision = Precision::PConfusion(); |
118 | static const Standard_Real aSqPrecision = aPrecision * aPrecision; | |
0d88155b | 119 | |
ec26bf88 | 120 | if ((thePoint1 - thePoint3).SquareModulus() < aSqPrecision) |
121 | return Standard_False; | |
0d88155b | 122 | |
ec26bf88 | 123 | gp_XY aLink1(thePoint2 - thePoint1); |
124 | if (aLink1.SquareModulus() < aSqPrecision) | |
125 | return Standard_False; | |
0d88155b | 126 | |
ec26bf88 | 127 | gp_XY aLink2(thePoint3 - thePoint2); |
128 | if (aLink2.SquareModulus() < aSqPrecision) | |
129 | return Standard_False; | |
130 | ||
131 | gp_XY aMidPnt1 = (thePoint1 + thePoint2) / 2.; | |
132 | gp_XY aNorm1 = gp_XY(aLink1.Y(), -aLink1.X()); | |
133 | aNorm1.Add(aMidPnt1); | |
0d88155b | 134 | |
ec26bf88 | 135 | if (aLink2.SquareModulus() < aSqPrecision) |
136 | return Standard_False; | |
0d88155b | 137 | |
ec26bf88 | 138 | gp_XY aMidPnt2 = (thePoint2 + thePoint3) / 2.; |
139 | gp_XY aNorm2 = gp_XY(aLink2.Y(), -aLink2.X()); | |
140 | aNorm2.Add(aMidPnt2); | |
0d88155b | 141 | |
fc9b36d6 | 142 | gp_XY aIntPnt; |
143 | Standard_Real aParam[2]; | |
144 | BRepMesh_GeomTool::IntFlag aIntFlag = | |
ec26bf88 | 145 | BRepMesh_GeomTool::IntLinLin(aMidPnt1, aNorm1, |
146 | aMidPnt2, aNorm2, aIntPnt, aParam); | |
0d88155b | 147 | |
fc9b36d6 | 148 | if (aIntFlag != BRepMesh_GeomTool::Cross) |
149 | return Standard_False; | |
0d88155b | 150 | |
ec26bf88 | 151 | theLocation = aIntPnt; |
152 | ||
153 | theRadius = Sqrt(Max(Max((thePoint1 - aIntPnt).SquareModulus(), | |
154 | (thePoint2 - aIntPnt).SquareModulus()), | |
155 | (thePoint3 - aIntPnt).SquareModulus())) + aPrecision; | |
156 | ||
157 | return Standard_True; | |
158 | } | |
159 | ||
160 | //======================================================================= | |
161 | //function : Bind | |
162 | //purpose : | |
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) | |
168 | { | |
169 | gp_XY aLocation; | |
170 | Standard_Real aRadius; | |
171 | if (!MakeCircle(thePoint1, thePoint2, thePoint3, aLocation, aRadius)) | |
172 | return Standard_False; | |
173 | ||
174 | bind(theIndex, aLocation, aRadius); | |
0d88155b O |
175 | return Standard_True; |
176 | } | |
177 | ||
178 | //======================================================================= | |
179 | //function : Delete | |
180 | //purpose : | |
181 | //======================================================================= | |
fc9b36d6 | 182 | void BRepMesh_CircleTool::Delete(const Standard_Integer theIndex) |
0d88155b | 183 | { |
fc9b36d6 | 184 | BRepMesh_Circle& aCircle = mySelector.Circle(theIndex); |
185 | if(aCircle.Radius() > 0.) | |
186 | aCircle.SetRadius(-1); | |
0d88155b O |
187 | } |
188 | ||
189 | //======================================================================= | |
190 | //function : Select | |
191 | //purpose : | |
192 | //======================================================================= | |
848fa7e3 | 193 | BRepMesh::ListOfInteger& BRepMesh_CircleTool::Select(const gp_XY& thePoint) |
0d88155b | 194 | { |
fc9b36d6 | 195 | mySelector.SetPoint(thePoint); |
196 | myCellFilter.Inspect(thePoint, mySelector); | |
197 | return mySelector.GetShotCircles(); | |
0d88155b O |
198 | } |
199 | ||
fc9b36d6 | 200 | //======================================================================= |
201 | //function : MocBind | |
202 | //purpose : | |
203 | //======================================================================= | |
204 | void BRepMesh_CircleTool::MocBind(const Standard_Integer theIndex) | |
0d88155b | 205 | { |
fc9b36d6 | 206 | BRepMesh_Circle aNullCir(gp::Origin2d().Coord(), -1.); |
207 | mySelector.Bind(theIndex, aNullCir); | |
0d88155b | 208 | } |