d25dd566535aac6702747f70a3dd654420ade00d
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_PROJECT.cxx
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
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                                                    const Extrema_ExtFlag anExtFlag,
207                                                    const Extrema_ExtAlgo anExtAlgo)
208
209   Standard_Real UMin, UMax, VMin, VMax;
210   GeomAPI_ProjectPointOnSurf PonS;
211   //
212   S->Bounds(UMin, UMax, VMin, VMax);
213   PonS.Init(S, UMin, UMax, VMin, VMax, anExtAlgo);
214   Extrema_ExtPS& anExtPS = const_cast<Extrema_ExtPS&>(PonS.Extrema());
215   anExtPS.SetFlag(anExtFlag);
216   //
217   PonS.Perform(P);
218   //
219   if (!PonS.Extrema().IsDone()) return Standard_False;
220   if (PonS.NbPoints() == 0) return Standard_False;
221   dist = PonS.LowerDistance();
222   Standard_Real U,V; PonS.LowerDistanceParameters(U,V); UV.SetCoord(U,V);
223   return Standard_True;
224 }
225
226 // ----------------------------------------------------------------------
227 //  projecting point <P> on topologies (edge <E>,face <F>)
228 // ----------------------------------------------------------------------
229
230 // ----------------------------------------------------------------------
231 Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const Standard_Real tole,const TopoDS_Edge& E,
232                                       Standard_Real& param,Standard_Real& dist)
233 {
234   dist = 1.;
235   BRepAdaptor_Curve BAC(E);
236   Standard_Real first = BAC.FirstParameter();
237   Standard_Real last = BAC.LastParameter();
238   Standard_Boolean ok = FUN_tool_projPonC(P,tole,BAC,first,last,param,dist);
239   if (!ok) return Standard_False;
240
241   Standard_Real f,l; FUN_tool_bounds(E,f,l);
242   Standard_Real tolp = Precision::Parametric(Precision::Confusion());
243   Standard_Boolean onf = Abs(f-param) < tolp; if (onf) param = f;
244   Standard_Boolean onl = Abs(l-param) < tolp; if (onl) param = l;
245   return Standard_True;
246 }
247
248 // ----------------------------------------------------------------------
249 Standard_EXPORT Standard_Boolean FUN_tool_projPonE(const gp_Pnt& P,const TopoDS_Edge& E,
250                                       Standard_Real& param,Standard_Real& dist)
251 {
252   Standard_Real tole = BRep_Tool::Tolerance(E);
253   Standard_Boolean ok = FUN_tool_projPonE(P,tole,E,param,dist);
254   return ok;
255 }
256
257 // ----------------------------------------------------------------------
258 Standard_EXPORT Standard_Boolean FUN_tool_projPonboundedF(const gp_Pnt& P,const TopoDS_Face& F,
259                                              gp_Pnt2d& UV,Standard_Real& dist)
260 {
261   dist = 1.;
262   // ! projecting point on surf does not take into account the face's 
263   // restriction
264   BRepLib_MakeVertex mv(P); TopoDS_Vertex V = mv.Vertex();
265   BRepExtrema_ExtPF PonF(V,F);
266   if (!PonF.IsDone()) return Standard_False;
267   Standard_Integer npt = PonF.NbExt();
268   if (npt == 0) return Standard_False;
269
270   // tri
271   Standard_Real dmin2 = 1.e14; Standard_Integer imin = 0;
272   for (Standard_Integer i=1; i <=npt; i++){
273     Standard_Real d2 = PonF.SquareDistance(i);
274     if (d2 < dmin2) {imin = i; dmin2 = d2;}
275   }
276   if (imin == 0) return Standard_False;
277   
278   Standard_Real u,v; PonF.Parameter(imin,u,v);
279   dist = sqrt (dmin2);
280   UV = gp_Pnt2d(u,v);
281   return Standard_True;
282 }
283
284 // ----------------------------------------------------------------------
285 Standard_EXPORT Standard_Boolean FUN_tool_projPonF(const gp_Pnt& P,const TopoDS_Face& F,
286                                                    gp_Pnt2d& UV,Standard_Real& dist,
287                                                    const Extrema_ExtFlag anExtFlag,
288                                                    const Extrema_ExtAlgo anExtAlgo)
289 {
290   dist = 1.;
291   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
292   Standard_Boolean ok = FUN_tool_projPonS(P,S,UV,dist, anExtFlag, anExtAlgo);
293   return ok;
294 }