b311480e |
1 | // Created on: 1997-11-24 |
2 | // Created by: Xuan PHAM PHU |
3 | // Copyright (c) 1997-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | #include <TopOpeBRepTool_PROJECT.hxx> |
23 | |
24 | #include <Geom2d_Curve.hxx> |
25 | #include <Geom_Curve.hxx> |
26 | #include <Geom_Surface.hxx> |
27 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
28 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
29 | #include <BRepLib_MakeVertex.hxx> |
30 | #include <BRepExtrema_ExtPF.hxx> |
31 | #include <Bnd_Box2d.hxx> |
32 | #include <Bnd_Box.hxx> |
33 | #include <BRepBndLib.hxx> |
34 | #include <BndLib_Add2dCurve.hxx> |
35 | #include <BRepAdaptor_Curve.hxx> |
36 | #include <BRepAdaptor_Curve2d.hxx> |
37 | #include <gp_Pnt.hxx> |
38 | #include <gp_Dir2d.hxx> |
39 | #include <BRep_Tool.hxx> |
40 | #include <Precision.hxx> |
41 | |
42 | #include <TopOpeBRepTool_GEOMETRY.hxx> |
43 | |
44 | // ---------------------------------------------------------------------- |
45 | Standard_EXPORT void FUN_tool_bounds(const TopoDS_Edge& E,Standard_Real& f,Standard_Real& l) |
46 | { |
47 | BRepAdaptor_Curve BAC(E); |
48 | f = BAC.FirstParameter(); |
49 | l = BAC.LastParameter(); |
50 | } |
51 | |
52 | // ---------------------------------------------------------------------- |
53 | Standard_EXPORT Standard_Integer FUN_tool_getindex(const Extrema_ExtPC& ponc) |
54 | { |
55 | Standard_Real Dist2,Dist2Min = ponc.SquareDistance(1); |
56 | Standard_Integer myIndex = 1,n = ponc.NbExt(); |
57 | |
58 | for ( Standard_Integer i = 2; i <= n; i++) { |
59 | Dist2 = ponc.SquareDistance(i); |
60 | if ( Dist2 < Dist2Min) { |
61 | Dist2Min = Dist2; |
62 | myIndex = i; |
63 | } |
64 | } |
65 | return myIndex; |
66 | } |
67 | |
68 | // ---------------------------------------------------------------------- |
69 | Standard_EXPORT Standard_Integer FUN_tool_getindex(const Extrema_ExtPC2d& ponc) |
70 | { |
71 | Standard_Real Dist2,Dist2Min = ponc.SquareDistance(1); |
72 | Standard_Integer myIndex = 1,n = ponc.NbExt(); |
73 | |
74 | for ( Standard_Integer i = 2; i <= n; i++) { |
75 | Dist2 = ponc.SquareDistance(i); |
76 | if ( Dist2 < Dist2Min) { |
77 | Dist2Min = Dist2; |
78 | myIndex = i; |
79 | } |
80 | } |
81 | return myIndex; |
82 | } |
83 | |
84 | // ---------------------------------------------------------------------- |
85 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC(const gp_Pnt& P, |
86 | const Standard_Real tole,const BRepAdaptor_Curve& BAC, |
87 | const Standard_Real pmin,const Standard_Real pmax, |
88 | Standard_Real& param,Standard_Real& dist) |
89 | { |
90 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
91 | Extrema_ExtPC ponc(P,BAC,pmin,pmax); |
92 | Standard_Boolean ok = ponc.IsDone(); |
93 | Standard_Integer nbext = 0; |
94 | if (ok) {nbext = ponc.NbExt(); ok = (nbext > 0);} |
95 | if (!ok) { |
96 | for (Standard_Integer i = 1; i <= 2; i++) { |
97 | Standard_Real par = (i == 1) ? pmin : pmax; |
98 | gp_Pnt pt = BAC.Value(par); |
99 | Standard_Real d2 = pt.SquareDistance(P); |
100 | Standard_Boolean onpt = (d2 < tole * tole); |
101 | if (onpt) { |
102 | param = par; |
103 | dist = sqrt (d2); |
104 | return Standard_True;} |
105 | } |
106 | return Standard_False; |
107 | } |
108 | Standard_Integer i = FUN_tool_getindex(ponc); |
109 | param = ponc.Point(i).Parameter(); |
110 | dist = sqrt (ponc.SquareDistance(i)); |
111 | return Standard_True; |
112 | } |
113 | |
114 | // ---------------------------------------------------------------------- |
115 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC(const gp_Pnt& P, |
116 | const BRepAdaptor_Curve& BAC, |
117 | const Standard_Real pmin,const Standard_Real pmax, |
118 | Standard_Real& param,Standard_Real& dist) |
119 | { |
120 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
121 | Standard_Real tole = BAC.Tolerance(); |
122 | Standard_Boolean ok = FUN_tool_projPonC(P,tole,BAC,pmin,pmax,param,dist); |
123 | return ok; |
124 | } |
125 | |
126 | // ---------------------------------------------------------------------- |
127 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC(const gp_Pnt& P, |
128 | const BRepAdaptor_Curve& BAC, |
129 | Standard_Real& param,Standard_Real& dist) |
130 | { |
131 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
132 | Standard_Real tole = BAC.Tolerance(); |
133 | Standard_Real pmin = BAC.FirstParameter(); |
134 | Standard_Real pmax = BAC.LastParameter(); |
135 | Standard_Boolean ok = FUN_tool_projPonC(P,tole,BAC,pmin,pmax,param,dist); |
136 | return ok; |
137 | } |
138 | |
139 | // ---------------------------------------------------------------------- |
140 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P, |
141 | const Standard_Real tole,const BRepAdaptor_Curve2d& BAC2D, |
142 | const Standard_Real pmin,const Standard_Real pmax, |
143 | Standard_Real& param,Standard_Real& dist) |
144 | { |
145 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
146 | Standard_Boolean ok = Standard_False; |
147 | |
148 | gp_Pnt2d P2D; |
149 | const TopoDS_Face& F = BAC2D.Face(); |
150 | ok = FUN_tool_projPonF(P,F,P2D,dist); |
151 | if (!ok) return Standard_False; |
152 | |
153 | Extrema_ExtPC2d ponc2d(P2D,BAC2D,pmin,pmax); |
154 | ok = ponc2d.IsDone(); |
155 | Standard_Integer nbext = ponc2d.NbExt(); |
156 | if (ok) ok = (nbext > 0); |
157 | if (!ok) { |
158 | for (Standard_Integer i = 1; i <= 2; i++) { |
159 | Standard_Real par = (i == 1) ? pmin : pmax; |
160 | gp_Pnt2d pt2d = BAC2D.Value(par); |
161 | Standard_Real d2 = pt2d.SquareDistance(P2D); |
162 | Standard_Boolean onpt = (d2 < tole * tole); |
163 | if (onpt) { |
164 | param = par; |
165 | dist = sqrt (d2); |
166 | return Standard_True;} |
167 | } |
168 | return Standard_False; |
169 | } |
170 | |
171 | Standard_Integer i = FUN_tool_getindex(ponc2d); |
172 | param = ponc2d.Point(i).Parameter(); |
173 | dist = sqrt (ponc2d.SquareDistance(i)); |
174 | return Standard_True; |
175 | } |
176 | |
177 | // ---------------------------------------------------------------------- |
178 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P, |
179 | const BRepAdaptor_Curve2d& BAC2D, |
180 | const Standard_Real pmin,const Standard_Real pmax, |
181 | Standard_Real& param,Standard_Real& dist) |
182 | { |
183 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
184 | Standard_Real tole = BRep_Tool::Tolerance(BAC2D.Edge()); |
185 | Standard_Boolean ok = FUN_tool_projPonC2D(P,tole,BAC2D,pmin,pmax,param,dist); |
186 | return ok; |
187 | } |
188 | |
189 | // ---------------------------------------------------------------------- |
190 | Standard_EXPORT Standard_Boolean FUN_tool_projPonC2D(const gp_Pnt& P, |
191 | const BRepAdaptor_Curve2d& BAC2D, |
192 | Standard_Real& param,Standard_Real& dist) |
193 | { |
194 | // <True> if projection succeeds,and sets <param> to parameter of <P> on <C>. |
195 | Standard_Real tole = BRep_Tool::Tolerance(BAC2D.Edge()); |
196 | Standard_Real pmin = BAC2D.FirstParameter(); |
197 | Standard_Real pmax = BAC2D.LastParameter(); |
198 | Standard_Boolean ok = FUN_tool_projPonC2D(P,tole,BAC2D,pmin,pmax,param,dist); |
199 | return ok; |
200 | } |
201 | |
202 | // ---------------------------------------------------------------------- |
203 | Standard_EXPORT Standard_Boolean FUN_tool_projPonS(const gp_Pnt& P, |
204 | const Handle(Geom_Surface)& S, |
205 | gp_Pnt2d& UV,Standard_Real& dist) |
206 | { |
207 | GeomAPI_ProjectPointOnSurf PonS(P,S); |
208 | if (!PonS.Extrema().IsDone()) return Standard_False; |
209 | if (PonS.NbPoints() == 0) return Standard_False; |
210 | dist = PonS.LowerDistance(); |
211 | Standard_Real U,V; PonS.LowerDistanceParameters(U,V); UV.SetCoord(U,V); |
212 | return Standard_True; |
213 | } |
214 | |
215 | // ---------------------------------------------------------------------- |
216 | // projecting point <P> on topologies (edge <E>,face <F>) |
217 | // ---------------------------------------------------------------------- |
218 | |
219 | // ---------------------------------------------------------------------- |
220 | Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const Standard_Real tole,const TopoDS_Edge& E, |
221 | Standard_Real& param,Standard_Real& dist) |
222 | { |
223 | dist = 1.; |
224 | BRepAdaptor_Curve BAC(E); |
225 | Standard_Real first = BAC.FirstParameter(); |
226 | Standard_Real last = BAC.LastParameter(); |
227 | Standard_Boolean ok = FUN_tool_projPonC(P,tole,BAC,first,last,param,dist); |
228 | if (!ok) return Standard_False; |
229 | |
230 | Standard_Real f,l; FUN_tool_bounds(E,f,l); |
231 | Standard_Real tolp = Precision::Parametric(Precision::Confusion()); |
232 | Standard_Boolean onf = Abs(f-param) < tolp; if (onf) param = f; |
233 | Standard_Boolean onl = Abs(l-param) < tolp; if (onl) param = l; |
234 | return Standard_True; |
235 | } |
236 | |
237 | // ---------------------------------------------------------------------- |
238 | Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const TopoDS_Edge& E, |
239 | Standard_Real& param,Standard_Real& dist) |
240 | { |
241 | Standard_Real tole = BRep_Tool::Tolerance(E); |
242 | Standard_Boolean ok = FUN_tool_projPonE(P,tole,E,param,dist); |
243 | return ok; |
244 | } |
245 | |
246 | // ---------------------------------------------------------------------- |
247 | Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const TopoDS_Face& F, |
248 | gp_Pnt2d& UV,Standard_Real& dist) |
249 | { |
250 | dist = 1.; |
251 | // ! projecting point on surf does not take into account the face's |
252 | // restriction |
253 | BRepLib_MakeVertex mv(P); TopoDS_Vertex V = mv.Vertex(); |
254 | BRepExtrema_ExtPF PonF(V,F); |
255 | if (!PonF.IsDone()) return Standard_False; |
256 | Standard_Integer npt = PonF.NbExt(); |
257 | if (npt == 0) return Standard_False; |
258 | |
259 | // tri |
260 | Standard_Real dmin2 = 1.e14; Standard_Integer imin = 0; |
261 | for (Standard_Integer i=1; i <=npt; i++){ |
262 | Standard_Real d2 = PonF.SquareDistance(i); |
263 | if (d2 < dmin2) {imin = i; dmin2 = d2;} |
264 | } |
265 | if (imin == 0) return Standard_False; |
266 | |
267 | Standard_Real u,v; PonF.Parameter(imin,u,v); |
268 | dist = sqrt (dmin2); |
269 | UV = gp_Pnt2d(u,v); |
270 | return Standard_True; |
271 | } |
272 | |
273 | // ---------------------------------------------------------------------- |
274 | Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F, |
275 | gp_Pnt2d& UV,Standard_Real& dist) |
276 | { |
277 | dist = 1.; |
278 | Handle(Geom_Surface) S = BRep_Tool::Surface(F); |
279 | Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist); |
280 | return ok; |
281 | } |