1 // Created on: 1998-11-26
2 // Created by: Xuan PHAM PHU
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 
18 #include <Bnd_Box.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepBndLib.hxx>
24 #include <BRepLProp_CLProps.hxx>
25 #include <ElCLib.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
29 #include <GeomLProp_SLProps.hxx>
30 #include <gp_Circ.hxx>
31 #include <gp_Cone.hxx>
32 #include <gp_Cylinder.hxx>
33 #include <gp_Dir.hxx>
34 #include <gp_Dir2d.hxx>
35 #include <gp_Elips.hxx>
36 #include <gp_Hypr.hxx>
37 #include <gp_Lin.hxx>
38 #include <gp_Parab.hxx>
39 #include <gp_Pln.hxx>
40 #include <gp_Pnt.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <gp_Sphere.hxx>
43 #include <gp_Torus.hxx>
44 #include <gp_Vec.hxx>
45 #include <gp_Vec2d.hxx>
46 #include <NCollection_Array1.hxx>
47 #include <Precision.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_IndexedMapOfReal.hxx>
50 #include <TopExp.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopoDS.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Iterator.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopOpeBRepTool.hxx>
59 #include <TopOpeBRepTool_2d.hxx>
60 #include <TopOpeBRepTool_C2DF.hxx>
61 #include <TopOpeBRepTool_define.hxx>
62 #include <TopOpeBRepTool_EXPORT.hxx>
63 #include <TopOpeBRepTool_ShapeTool.hxx>
64 #include <TopOpeBRepTool_TOOL.hxx>
65 #include <TopTools_DataMapOfIntegerShape.hxx>
66 
67 #include <algorithm>
68 #define M_FORWARD(sta)  (sta == TopAbs_FORWARD)
69 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
70 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
71 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
72 
73 #define FORWARD  (1)
74 #define REVERSED (2)
75 #define INTERNAL (3)
76 #define EXTERNAL (4)
77 #define CLOSING  (5)
78 
FUN_nullprodv(const Standard_Real prodv)79 static Standard_Boolean FUN_nullprodv(const Standard_Real prodv)
80 {
81 //  Standard_Real tola = Precision::Angular()*1.e+1; // NYI
82   Standard_Real tola = 1.e-6; // NYI NYI NYI : for case cto 012 I2
83   return (Abs(prodv) < tola);
84 }
85 
86 //modified by NIZNHY-PKV Fri Aug  4 11:22:57 2000 from
87 
88 //=======================================================================
89 //function : CheckEdgeLength
90 //purpose  :
91 //=======================================================================
CheckEdgeLength(const TopoDS_Edge & E)92 static Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
93 {
94   BRepAdaptor_Curve BC(E);
95 
96   TopTools_IndexedMapOfShape aM;
97   TopExp::MapShapes(E, TopAbs_VERTEX, aM);
98   Standard_Integer i, anExtent, aN=10;
99   Standard_Real ln=0., d, t, f, l, dt;
100   anExtent=aM.Extent();
101 
102   if (anExtent!=1)
103     return Standard_True;
104 
105   gp_Pnt p1, p2;
106   f = BC.FirstParameter();
107   l = BC.LastParameter();
108   dt=(l-f)/aN;
109 
110   BC.D0(f, p1);
111   for (i=1; i<=aN; i++) {
112     t=f+i*dt;
113 
114     if (i==aN)
115       BC.D0(l, p2);
116       else
117 	BC.D0(t, p2);
118 
119     d=p1.Distance(p2);
120     ln+=d;
121     p1=p2;
122   }
123 
124   return (ln > Precision::Confusion());
125 }
126 
127 //modified by NIZNHY-PKV Fri Aug  4 11:23:07 2000 to
128 
129 //=======================================================================
130 //function : OriinSor
131 //purpose  :
132 //=======================================================================
133 
OriinSor(const TopoDS_Shape & sub,const TopoDS_Shape & S,const Standard_Boolean checkclo)134 Standard_Integer TopOpeBRepTool_TOOL::OriinSor(const TopoDS_Shape& sub, const TopoDS_Shape& S, const Standard_Boolean checkclo)
135 {
136   if (checkclo) {
137     Standard_Boolean Sclosed = Standard_False;
138     if      (S.ShapeType() == TopAbs_EDGE) {
139       if (sub.ShapeType() != TopAbs_VERTEX) return 0;
140 
141       TopoDS_Vertex vclo; Sclosed = TopOpeBRepTool_TOOL::ClosedE(TopoDS::Edge(S),vclo);
142       if (Sclosed)
143 	if (sub.IsSame(vclo)) return CLOSING;
144     }
145     else if (S.ShapeType() == TopAbs_FACE) {
146       if (sub.ShapeType() != TopAbs_EDGE) return 0;
147 
148       Sclosed = ClosedS(TopoDS::Face(S));
149       if (Sclosed)
150 	if (IsClosingE(TopoDS::Edge(sub),TopoDS::Face(S))) return CLOSING;
151     }
152   }
153 
154   TopExp_Explorer ex(S,sub.ShapeType());
155   for(; ex.More(); ex.Next()) {
156     const TopoDS_Shape& ssub = ex.Current();
157     Standard_Boolean same = ssub.IsSame(sub);
158     if (!same) continue;
159     TopAbs_Orientation osub = ssub.Orientation();
160     if      (M_FORWARD(osub))  return FORWARD;
161     else if (M_REVERSED(osub)) return REVERSED;
162     else if (M_INTERNAL(osub)) return INTERNAL;
163     else if (M_EXTERNAL(osub)) return EXTERNAL;
164   }
165   return 0;
166 }
167 
168 //=======================================================================
169 //function : OriinSorclosed
170 //purpose  :
171 //=======================================================================
172 
OriinSorclosed(const TopoDS_Shape & sub,const TopoDS_Shape & S)173 Standard_Integer TopOpeBRepTool_TOOL::OriinSorclosed(const TopoDS_Shape& sub, const TopoDS_Shape& S)
174 {
175   if (S.ShapeType() == TopAbs_EDGE)
176     {if (sub.ShapeType() != TopAbs_VERTEX) return 0;}
177   else if (S.ShapeType() == TopAbs_FACE)
178     {if (sub.ShapeType() != TopAbs_EDGE) return 0;}
179   TopoDS_Iterator it(S);
180   for(; it.More(); it.Next()) {
181     const TopoDS_Shape& ssub = it.Value();
182     Standard_Boolean equal = ssub.IsEqual(sub);
183     if (!equal) continue;
184     TopAbs_Orientation osub = ssub.Orientation();
185     if      (M_FORWARD(osub))  return FORWARD;
186     else if (M_REVERSED(osub)) return REVERSED;
187   }
188   return 0;
189 }
190 
191 
192 
193 //=======================================================================
194 //function : ClosedE
195 //purpose  :
196 //=======================================================================
197 
ClosedE(const TopoDS_Edge & E,TopoDS_Vertex & vclo)198 Standard_Boolean TopOpeBRepTool_TOOL::ClosedE(const TopoDS_Edge& E, TopoDS_Vertex& vclo)
199 {
200    // returns true if <E> has a closing vertex <vclosing>
201 //  return E.IsClosed();
202   Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
203   if (isdgE) return Standard_False;
204 
205   TopoDS_Shape vv; vclo.Nullify();
206   TopExp_Explorer ex(E,TopAbs_VERTEX);
207   for (; ex.More(); ex.Next()) {
208     const TopoDS_Shape& v = ex.Current();
209     if (M_INTERNAL(v.Orientation())) continue;
210     if (vv.IsNull()) vv = v;
211     else if (v.IsSame(vv))
212       {vclo = TopoDS::Vertex(vv); return Standard_True;}
213   }
214   return Standard_False;
215 }
216 
217 //=======================================================================
218 //function : ClosedS
219 //purpose  :
220 //=======================================================================
221 
ClosedS(const TopoDS_Face & F)222 Standard_Boolean TopOpeBRepTool_TOOL::ClosedS(const TopoDS_Face& F)
223 {
224   Handle(Geom_Surface) S =TopOpeBRepTool_ShapeTool::BASISSURFACE(TopoDS::Face(F));
225   if (S.IsNull()) return Standard_False;
226   Standard_Boolean uclosed = S->IsUClosed(); if (uclosed) uclosed = S->IsUPeriodic();
227   Standard_Boolean vclosed = S->IsVClosed(); if (vclosed) vclosed = S->IsVPeriodic();
228   return (uclosed || vclosed);
229 }
230 
231 //=======================================================================
232 //function : IsClosingE
233 //purpose  :
234 //=======================================================================
235 
IsClosingE(const TopoDS_Edge & E,const TopoDS_Face & F)236 Standard_Boolean TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E, const TopoDS_Face& F)
237 {
238   Standard_Integer nbocc = 0;
239   TopExp_Explorer exp(F,TopAbs_EDGE);
240   for (;exp.More();exp.Next())
241     if (exp.Current().IsSame(E)) nbocc++;
242   if (nbocc != 2) return Standard_False;
243   return BRep_Tool::IsClosed(E,F);
244 }
245 
246 //=======================================================================
247 //function : IsClosingE
248 //purpose  :
249 //=======================================================================
250 
IsClosingE(const TopoDS_Edge & E,const TopoDS_Shape & W,const TopoDS_Face & F)251 Standard_Boolean TopOpeBRepTool_TOOL::IsClosingE(const TopoDS_Edge& E, const TopoDS_Shape& W, const TopoDS_Face& F)
252 {
253   Standard_Integer nbocc = 0;
254   TopExp_Explorer exp(W,TopAbs_EDGE);
255   for (;exp.More();exp.Next())
256     if (exp.Current().IsSame(E)) nbocc++;
257   if (nbocc != 2) return Standard_False;
258   return BRep_Tool::IsClosed(E,F);
259 }
260 
261 //=======================================================================
262 //function : Vertices
263 //purpose  :
264 //=======================================================================
265 
Vertices(const TopoDS_Edge & E,TopTools_Array1OfShape & Vces)266 void TopOpeBRepTool_TOOL::Vertices(const TopoDS_Edge& E, TopTools_Array1OfShape& Vces)
267 {
268   // Returns vertices (F,R) if E is FORWARD
269   //                  (R,V) if E is REVERSED
270   TopAbs_Orientation oriE = E.Orientation();
271   TopoDS_Vertex v1, v2; TopExp::Vertices(E,v1,v2);
272 
273   if (M_INTERNAL(oriE) || M_EXTERNAL(oriE))
274     {Vces.ChangeValue(1)=v1;Vces.ChangeValue(2)=v2;}
275 
276   Standard_Real par1 = BRep_Tool::Parameter(v1,E);
277   Standard_Real par2 = BRep_Tool::Parameter(v2,E);
278 #ifdef OCCT_DEBUG
279 //  if (par1>par2) std::cout<<"TopOpeBRepTool_TOOL::Vertices ERROR"<<std::endl;
280 #endif
281   Standard_Integer ivparSMA = (par1<par2) ? FORWARD : REVERSED;
282   Standard_Integer ivparSUP = (par1<par2) ? REVERSED : FORWARD;
283   if (M_REVERSED(oriE)) {
284     ivparSMA = (ivparSMA == FORWARD) ? REVERSED : FORWARD;
285     ivparSUP = (ivparSUP == REVERSED) ? FORWARD : REVERSED;
286   }
287   Vces.ChangeValue(ivparSMA) = v1;
288   Vces.ChangeValue(ivparSUP) = v2;
289 }
290 
291 //=======================================================================
292 //function : Vertex
293 //purpose  :
294 //=======================================================================
295 
Vertex(const Standard_Integer Iv,const TopoDS_Edge & E)296 TopoDS_Vertex TopOpeBRepTool_TOOL::Vertex(const Standard_Integer Iv, const TopoDS_Edge& E)
297 {
298   TopTools_Array1OfShape Vces(1,2); Vertices(E,Vces);
299   TopoDS_Vertex V = TopoDS::Vertex(Vces(Iv));
300   return V;
301 }
302 
303 //=======================================================================
304 //function : ParE
305 //purpose  :
306 //=======================================================================
307 
ParE(const Standard_Integer Iv,const TopoDS_Edge & E)308 Standard_Real TopOpeBRepTool_TOOL::ParE(const Standard_Integer Iv, const TopoDS_Edge& E)
309 {
310   const TopoDS_Vertex& v = Vertex(Iv,E);
311   return (BRep_Tool::Parameter(v,E));
312 }
313 
314 //=======================================================================
315 //function : OnBoundary
316 //purpose  :
317 //=======================================================================
318 
OnBoundary(const Standard_Real par,const TopoDS_Edge & e)319 Standard_Integer TopOpeBRepTool_TOOL::OnBoundary(const Standard_Real par, const TopoDS_Edge& e)
320 {
321   BRepAdaptor_Curve bc(e);
322   Standard_Boolean closed = bc.IsClosed();
323   Standard_Real first = bc.FirstParameter();
324   Standard_Real last = bc.LastParameter();
325   Standard_Real tole = bc.Tolerance(); Standard_Real tolp = bc.Resolution(tole);
326 
327   Standard_Boolean onf = Abs(par-first)<tolp;
328   Standard_Boolean onl = Abs(par-last)<tolp;
329   Standard_Boolean onfl =  (onf || onl);
330   if (onfl && closed) return CLOSING;
331   if (onf) return FORWARD;
332   if (onl) return REVERSED;
333   if ((first < par)&&(par < last)) return INTERNAL;
334   return EXTERNAL;
335 }
336 
337 
338 
FUN_tool_sortVonE(TopTools_ListOfShape & lov,const TopoDS_Edge E)339 static void FUN_tool_sortVonE(TopTools_ListOfShape& lov, const TopoDS_Edge E)
340 {
341   TopTools_DataMapOfIntegerShape mapiv;// mapiv.Find(iV) = V
342   TColStd_IndexedMapOfReal mappar;     // mappar.FindIndex(parV) = iV
343 
344   for (TopTools_ListIteratorOfListOfShape itlove(lov); itlove.More(); itlove.Next()){
345     const TopoDS_Vertex& v = TopoDS::Vertex(itlove.Value());
346     Standard_Real par = BRep_Tool::Parameter(v,E);
347     Standard_Integer iv = mappar.Add(par);
348     mapiv.Bind(iv,v);
349   }
350   Standard_Integer nv = mapiv.Extent();
351   NCollection_Array1<Standard_Real> tabpar(1,nv);
352 //  for (Standard_Integer i = 1; i <= nv; i++) {
353   Standard_Integer i ;
354   for ( i = 1; i <= nv; i++) {
355     Standard_Real p = mappar.FindKey(i);
356     tabpar.SetValue(i,p);
357   }
358 
359   TopTools_ListOfShape newlov;
360   std::sort (tabpar.begin(), tabpar.end());
361   for (i = 1; i <= nv; i++) {
362     Standard_Real par = tabpar.Value(i);
363     Standard_Integer iv = mappar.FindIndex(par);
364     const TopoDS_Shape& v = mapiv.Find(iv);
365     newlov.Append(v);
366   }
367   lov.Clear(); lov.Append(newlov);
368 }
369 
370 //=======================================================================
371 //function : SplitE
372 //purpose  :
373 //=======================================================================
374 
SplitE(const TopoDS_Edge & Eanc,TopTools_ListOfShape & Splits)375 Standard_Boolean TopOpeBRepTool_TOOL::SplitE(const TopoDS_Edge& Eanc, TopTools_ListOfShape& Splits)
376 {
377   // prequesitory : <Eanc> is a valid edge.
378   TopAbs_Orientation oEanc = Eanc.Orientation();
379   TopoDS_Shape aLocalShape = Eanc.Oriented(TopAbs_FORWARD);
380   TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
381 //  TopoDS_Edge EFOR = TopoDS::Edge(Eanc.Oriented(TopAbs_FORWARD));
382   TopTools_ListOfShape lov;
383   TopExp_Explorer exv(EFOR,TopAbs_VERTEX);
384   for (;exv.More(); exv.Next()) {
385     const TopoDS_Shape& v = exv.Current();
386     lov.Append(v);
387   }
388   Standard_Integer nv = lov.Extent();
389   if (nv <= 2) return Standard_False;
390 
391   ::FUN_tool_sortVonE(lov,EFOR);
392 
393   TopoDS_Vertex v0;
394   TopTools_ListIteratorOfListOfShape itlov(lov);
395   if (itlov.More()) {v0 = TopoDS::Vertex(itlov.Value()); itlov.Next();}
396   else return Standard_False;
397 
398   for (; itlov.More(); itlov.Next()) {
399     TopoDS_Vertex v = TopoDS::Vertex(itlov.Value());
400 
401     // prequesitory: par0 < par
402     Standard_Real par0 = BRep_Tool::Parameter(v0, EFOR);
403     Standard_Real par  = BRep_Tool::Parameter(v, EFOR);
404 
405     // here, ed has the same geometries than Ein, but with no subshapes.
406     TopoDS_Edge ed; FUN_ds_CopyEdge(EFOR,ed);
407     BRep_Builder BB;
408     v0.Orientation(TopAbs_FORWARD); BB.Add(ed,v0); FUN_ds_Parameter(ed,v0,par0);
409     v.Orientation(TopAbs_REVERSED); BB.Add(ed,v);  FUN_ds_Parameter(ed,v,par);
410     Splits.Append(ed.Oriented(oEanc));
411     v0 = v;
412   }
413   return Standard_True;
414 }
415 
416 
417 
418 
419 //=======================================================================
420 //function : UVF
421 //purpose  :
422 //=======================================================================
423 
UVF(const Standard_Real par,const TopOpeBRepTool_C2DF & C2DF)424 gp_Pnt2d TopOpeBRepTool_TOOL::UVF(const Standard_Real par, const TopOpeBRepTool_C2DF& C2DF)
425 {
426   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
427   gp_Pnt2d UV; PC->D0(par,UV);
428   return UV;
429 }
430 
431 //=======================================================================
432 //function : ParISO
433 //purpose  :
434 //=======================================================================
435 
ParISO(const gp_Pnt2d & uv,const TopoDS_Edge & E,const TopoDS_Face & F,Standard_Real & par)436 Standard_Boolean TopOpeBRepTool_TOOL::ParISO(const gp_Pnt2d& uv, const TopoDS_Edge& E, const TopoDS_Face& F,
437 				Standard_Real& par)
438 {
439   par = 1.e7;
440   Standard_Boolean isou,isov; gp_Dir2d d2d; gp_Pnt2d o2d;
441   Standard_Boolean uviso = TopOpeBRepTool_TOOL::UVISO(E,F, isou,isov, d2d,o2d);
442   if (!uviso) return Standard_False;
443   if (isou) {par = (uv.Y()-o2d.Y()); if (d2d.Y()<0) par = -par;}
444   if (isov) {par = (uv.X()-o2d.X()); if (d2d.X()<0) par = -par;}
445   return Standard_True;
446 }
447 
448 
449 
450 //=======================================================================
451 //function : ParE2d
452 //purpose  :
453 //=======================================================================
454 
ParE2d(const gp_Pnt2d & p2d,const TopoDS_Edge & E,const TopoDS_Face & F,Standard_Real & par,Standard_Real & dist)455 Standard_Boolean TopOpeBRepTool_TOOL::ParE2d(const gp_Pnt2d& p2d, const TopoDS_Edge& E, const TopoDS_Face& F,
456 				Standard_Real& par, Standard_Real& dist)
457 {
458   // Avoid projections if possible :
459   BRepAdaptor_Curve2d BC2d(E,F);
460   GeomAbs_CurveType CT = BC2d.GetType();
461   const Handle(Geom2d_Curve)& C2d = BC2d.Curve();
462   if (CT == GeomAbs_Line) {
463     Standard_Boolean isoU,isoV; gp_Pnt2d Loc; gp_Dir2d dir2d;
464     TopOpeBRepTool_TOOL::UVISO(C2d,isoU,isoV,dir2d,Loc);
465     if (isoU) {par = p2d.Y()-Loc.Y();dist = Abs(p2d.X()-Loc.X());}
466     if (isoV) {par = p2d.X()-Loc.X();dist = Abs(p2d.Y()-Loc.Y());}
467     if (isoU || isoV) return Standard_True;
468   }
469 
470   Geom2dAPI_ProjectPointOnCurve proj(p2d,C2d);
471   dist = p2d.Distance(proj.NearestPoint());
472   par = proj.LowerDistanceParameter();
473   return Standard_True;
474 }
475 
476 
477 
478 //=======================================================================
479 //function : TgINSIDE
480 //purpose  :
481 //=======================================================================
482 
TgINSIDE(const TopoDS_Vertex & v,const TopoDS_Edge & E,gp_Vec & Tg,Standard_Integer & OvinE)483 Standard_Boolean TopOpeBRepTool_TOOL::TgINSIDE(const TopoDS_Vertex& v, const TopoDS_Edge& E,
484 				  gp_Vec& Tg, Standard_Integer& OvinE)
485 {
486   TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
487   TopoDS_Edge EFOR = TopoDS::Edge(aLocalShape);
488 //  TopoDS_Edge EFOR = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
489   Standard_Integer ovE = TopOpeBRepTool_TOOL::OriinSor(v,EFOR,Standard_True);
490   if (ovE == 0) return Standard_False;
491   OvinE = ovE;
492   Standard_Integer iv = 0;
493   if      (ovE == CLOSING)                      iv = FORWARD;
494   else if ((ovE == FORWARD)||(ovE == REVERSED)) iv = ovE;
495   Standard_Real parE;
496   if (iv == 0) parE = BRep_Tool::Parameter(v,E);
497   else         parE = TopOpeBRepTool_TOOL::ParE(iv,EFOR);
498   Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(parE,EFOR,Tg);
499   if (!ok) return Standard_False;
500   if (ovE == REVERSED) Tg.Reverse();
501   return Standard_True;
502 }
503 
504 //=======================================================================
505 //function : TggeomE
506 //purpose  :
507 //=======================================================================
508 
TggeomE(const Standard_Real par,const BRepAdaptor_Curve & BC,gp_Vec & Tg)509 Standard_Boolean TopOpeBRepTool_TOOL::TggeomE(const Standard_Real par, const BRepAdaptor_Curve& BC,
510 				 gp_Vec& Tg)
511 {
512 //#ifdef OCCT_DEBUG
513 //  GeomAbs_CurveType ct =
514 //#endif
515 //                         BC.GetType();
516 //#ifdef OCCT_DEBUG
517 //  Standard_Boolean apoles = (ct == GeomAbs_BezierCurve)||(ct == GeomAbs_BSplineCurve);
518 //#endif
519 
520   Standard_Real f = BC.FirstParameter(), l = BC.LastParameter();
521   Standard_Real tolE = BC.Tolerance(); Standard_Real tolp = BC.Resolution(tolE);
522 
523   Standard_Boolean onf = Abs(f-par)<tolp; Standard_Boolean onl = Abs(l-par)<tolp;
524   Standard_Boolean inbounds = (f<par)&&(par<l);
525 
526   if ((!inbounds) && (!onf) && (!onl)) return Standard_False;
527   Standard_Real thepar = par;
528 
529   gp_Pnt thepnt; BC.D1(thepar, thepnt, Tg);
530   Tg.Normalize();
531   return Standard_True;
532 
533 }
534 
535 //=======================================================================
536 //function : TggeomE
537 //purpose  :
538 //=======================================================================
539 
TggeomE(const Standard_Real par,const TopoDS_Edge & E,gp_Vec & Tg)540 Standard_Boolean TopOpeBRepTool_TOOL::TggeomE(const Standard_Real par, const TopoDS_Edge& E, gp_Vec& Tg)
541 {
542   Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
543   if (isdgE) return Standard_False;
544 
545   BRepAdaptor_Curve BC(E);
546   //modified by NIZNHY-PKV Fri Aug  4 09:49:31 2000 f
547   if (!CheckEdgeLength(E)) {
548     return Standard_False;
549   }
550   //modified by NIZNHY-PKV Fri Aug  4 09:49:36 2000 t
551 
552   return (TopOpeBRepTool_TOOL::TggeomE(par,BC,Tg));
553 }
554 
555 //=======================================================================
556 //function : Tg2d
557 //purpose  :
558 //=======================================================================
559 
Tg2d(const Standard_Integer iv,const TopoDS_Edge & E,const TopOpeBRepTool_C2DF & C2DF)560 gp_Vec2d TopOpeBRepTool_TOOL::Tg2d(const Standard_Integer iv, const TopoDS_Edge& E,
561 				   const TopOpeBRepTool_C2DF& C2DF)
562 {
563   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
564   Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv,E);
565   gp_Pnt2d UV; gp_Vec2d tg2d; PC->D1(par,UV,tg2d);
566   gp_Dir2d d2d(tg2d);
567   return d2d;
568 }
569 
570 //=======================================================================
571 //function : Tg2dApp
572 //purpose  :
573 //=======================================================================
574 
Tg2dApp(const Standard_Integer iv,const TopoDS_Edge & E,const TopOpeBRepTool_C2DF & C2DF,const Standard_Real factor)575 gp_Vec2d TopOpeBRepTool_TOOL::Tg2dApp(const Standard_Integer iv, const TopoDS_Edge& E,
576 				      const TopOpeBRepTool_C2DF& C2DF,
577 				      const Standard_Real factor)
578 {
579   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
580 
581   Standard_Integer iOOv  = (iv == 1) ? 2 : 1;
582   Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv,E);
583   Standard_Real OOpar = TopOpeBRepTool_TOOL::ParE(iOOv,E);
584   Standard_Real parE = (1-factor)*par + factor*OOpar;
585 
586   gp_Pnt2d UV; gp_Vec2d tg2d; PC->D1(parE,UV,tg2d);
587   gp_Dir2d d2d(tg2d);
588 
589 //modified by NIZHNY-MZV  Wed May 24 12:52:18 2000
590 //  TopAbs_Orientation oE = E.Orientation();
591 //  if (M_REVERSED(oE)) d2d.Reverse();
592 //we remove this line because we want to know original tangent
593   return d2d;
594 }
595 
596 //=======================================================================
597 //function : tryTg2dApp
598 //purpose  :
599 //=======================================================================
600 
tryTg2dApp(const Standard_Integer iv,const TopoDS_Edge & E,const TopOpeBRepTool_C2DF & C2DF,const Standard_Real factor)601 gp_Vec2d TopOpeBRepTool_TOOL::tryTg2dApp(const Standard_Integer iv, const TopoDS_Edge& E,
602 					 const TopOpeBRepTool_C2DF& C2DF,
603 					 const Standard_Real factor)
604 {
605   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
606   Standard_Boolean isquad = FUN_tool_quad(PC);
607   Standard_Boolean line   = FUN_tool_line(PC);
608   if (!isquad || line) return TopOpeBRepTool_TOOL::Tg2d(iv,E,C2DF);
609   return TopOpeBRepTool_TOOL::Tg2dApp(iv,E,C2DF,factor);
610 }
611 
612 //=======================================================================
613 //function : OriEinF
614 //purpose  :
615 //=======================================================================
616 
tryOriEinF(const Standard_Real par,const TopoDS_Edge & e,const TopoDS_Face & f)617 Standard_Integer TopOpeBRepTool_TOOL::tryOriEinF(const Standard_Real par, const TopoDS_Edge& e, const TopoDS_Face& f)
618 {
619   // ------------------------------------------------------------
620   // 1) <e> is a subshape of <f>
621   // 2) else, compute oriEinF, using <e>'s 2d rep on <f>
622   //    PREQUESITORY : <e> must have a pcurve on <f>.
623   // ------------------------------------------------------------
624   Standard_Boolean checkclo = Standard_True; Standard_Integer oeinf = TopOpeBRepTool_TOOL::OriinSor(e,f,checkclo);
625   if (oeinf != 0) return oeinf;
626 
627   Handle(Geom2d_Curve) pc; Standard_Real pf,pl,tol;
628   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(e,f,pc);
629   if (!hasold) return 0;
630   pc = FC2D_EditableCurveOnSurface(e,f,pf,pl,tol);
631 
632   // n2d is such that (p2d,oop2d) is oriented INSIDE F
633   gp_Pnt2d uv; gp_Vec2d tg2d; pc->D1(par,uv,tg2d);
634   gp_Vec2d n2d(gp_Dir2d(-tg2d.Y(), tg2d.X()));
635 
636   Standard_Real delta = TopOpeBRepTool_TOOL::minDUV(f); delta *= 1.e-1;
637   gp_Pnt2d ouv = uv.Translated(delta*n2d);
638   Standard_Boolean outuvbounds = TopOpeBRepTool_TOOL::outUVbounds(ouv,f);
639   oeinf = (outuvbounds) ? 2 : 1;
640   return oeinf;
641 }
642 
643 //=======================================================================
644 //function : NgApp
645 //purpose  :
646 //=======================================================================
647 
NgApp(const Standard_Real par,const TopoDS_Edge & e,const TopoDS_Face & f,const Standard_Real tola,gp_Dir & ngApp)648 Standard_Boolean TopOpeBRepTool_TOOL::NgApp(const Standard_Real par,const TopoDS_Edge& e, const TopoDS_Face& f,const Standard_Real tola,
649 			       gp_Dir& ngApp)
650 {
651   // Give us an edge <e>, a face <f>, <e> has its geometry on <f>.
652   //
653   // P is the point of <par> on <e>
654   // purpose : the compute of <neinsidef>, at a point P' on <F>, near P
655   //           direction pp' is normal to <e>.
656   // return false if the compute fails, or <neinsidef> is closed to <newneinsidef>
657   //
658   // PREQUESITORY : <e> must have a pcurve on <f>.
659   // --------------
660 
661   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
662   if (S.IsNull()) return Standard_False;
663 
664   Standard_Boolean fplane = FUN_tool_plane(f);
665   if (fplane) return Standard_False;
666 
667   // NYI : for bspline surfaces, use a evolutive parameter
668   //       on curve to find out "significant" tangents
669   Standard_Boolean fquad = FUN_tool_quad(f);
670   if (!fquad) return Standard_False;
671   // <pc> :
672   Handle(Geom2d_Curve) pc; Standard_Real pf,pl,tol;
673   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(e,f,pc);
674   if (!hasold) return Standard_False;
675   pc = FC2D_EditableCurveOnSurface(e,f,pf,pl,tol);
676   // <orieinf> :
677   TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD);
678   Standard_Integer orieinf = TopOpeBRepTool_TOOL::tryOriEinF(par,e,TopoDS::Face(aLocalShape));
679 //  Standard_Integer orieinf = TopOpeBRepTool_TOOL::tryOriEinF(par,e,TopoDS::Face(f.Oriented(TopAbs_FORWARD)));
680   if (orieinf == 0) return Standard_False;
681   // <uv> :
682   gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(e,par,f,uv);
683   if (!ok) return Standard_False;
684   // <ng> :
685   gp_Dir ng = FUN_tool_ngS(uv,S);
686   if (!ok) return Standard_False;
687 
688   // <n2dinsideS> :
689   gp_Vec2d tg2d; pc->D1(par,uv,tg2d);
690   gp_Dir2d n2dinsideS = FUN_tool_nC2dINSIDES( gp_Dir2d(tg2d) );
691   if (orieinf == 2)  n2dinsideS.Reverse();
692   //<duv> : '
693   Standard_Real eps = 0.45678;
694   gp_Vec2d duv = gp_Vec2d(n2dinsideS).Multiplied(eps);
695 
696   // cto009S4 : we need an iterative process to get other normal vector
697   Standard_Integer nmax = 5; Standard_Boolean same = Standard_False; Standard_Real delta = 0.45678;
698   for (Standard_Integer i=1; i<=nmax; i++) {
699 
700     gp_Pnt2d newuv = uv.Translated(duv);
701     gp_Vec newng = FUN_tool_ngS(newuv,S);
702     same = ng.IsEqual(newng,tola);
703     Standard_Boolean okk = (newng.Magnitude() > tola);
704     if (!same && okk) {ngApp = gp_Dir(newng); break;}
705     delta *= 1.25; //  NYI
706     duv = gp_Vec2d(n2dinsideS).Multiplied(delta);
707 
708   }//i=1..nmax
709   return !same;
710 }
711 
712 //=======================================================================
713 //function : tryNgApp
714 //purpose  :
715 //=======================================================================
716 
tryNgApp(const Standard_Real par,const TopoDS_Edge & e,const TopoDS_Face & f,const Standard_Real tola,gp_Dir & Ng)717 Standard_Boolean TopOpeBRepTool_TOOL::tryNgApp(const Standard_Real par,const TopoDS_Edge& e, const TopoDS_Face& f,const Standard_Real tola,
718 				  gp_Dir& Ng)
719 {
720   gp_Pnt2d uv; Standard_Boolean ok = FUN_tool_paronEF(e,par,f,uv);
721   if (!ok) return Standard_False;
722   gp_Dir ng( FUN_tool_nggeomF(uv,f) );
723 #ifdef OCCT_DEBUG
724   gp_Dir ngApp;
725 #endif
726   ok = TopOpeBRepTool_TOOL::NgApp(par,e,f,tola,Ng);
727   if (!ok) Ng = ng;
728   return Standard_True;
729 }
730 
731 //=======================================================================
732 //function : IsQuad
733 //purpose  :
734 //=======================================================================
735 
IsQuad(const TopoDS_Edge & E)736 Standard_Boolean TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Edge& E)
737 {
738   BRepAdaptor_Curve bc(E);
739   return ( FUN_quadCT(bc.GetType()) );
740 }
741 
742 
743 //=======================================================================
744 //function : IsQuad
745 //purpose  :
746 //=======================================================================
747 
IsQuad(const TopoDS_Face & F)748 Standard_Boolean TopOpeBRepTool_TOOL::IsQuad(const TopoDS_Face& F)
749 {
750   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);
751   return ( FUN_tool_quad(S) );
752 }
753 
754 
755 
756 //=======================================================================
757 //function : CurvE
758 //purpose  :
759 //=======================================================================
760 
CurvE(const TopoDS_Edge & E,const Standard_Real par,const gp_Dir & tg0,Standard_Real & curv)761 Standard_Boolean TopOpeBRepTool_TOOL::CurvE(const TopoDS_Edge& E,const Standard_Real par,const gp_Dir& tg0,
762 			       Standard_Real& curv)
763 {
764   curv = 0.;
765   BRepAdaptor_Curve BAC(E);
766   GeomAbs_CurveType CT = BAC.GetType();
767   Standard_Boolean line = (CT == GeomAbs_Line);
768   Standard_Real tola = Precision::Angular()*1.e3;//NYITOLXPU
769   if (line) {
770     gp_Dir dir = BAC.Line().Direction();
771     Standard_Real dot = dir.Dot(tg0);
772     if (Abs(1-dot) < tola) return Standard_False;
773     return Standard_True;
774   }
775 
776   BRepLProp_CLProps clprops(BAC,par,2,Precision::Confusion());
777   Standard_Boolean tgdef = clprops.IsTangentDefined();
778   if (!tgdef) return Standard_False;
779   curv = Abs(clprops.Curvature());
780 
781   Standard_Real tol = Precision::Confusion()*1.e+2;//NYITOLXPU
782   Standard_Boolean nullcurv = (curv < tol);
783   if (nullcurv) {curv = 0.; return Standard_True;}
784 
785   gp_Dir N; clprops.Normal(N);
786   gp_Dir T; clprops.Tangent(T);
787   gp_Dir axis = N^T;
788   Standard_Real dot = Abs(axis.Dot(tg0));
789   nullcurv = dot < tola;
790   Standard_Boolean maxcurv  = Abs(1-dot) < tola;
791   if (nullcurv) {
792     curv = 0.;
793     return Standard_True;
794   }
795   if (maxcurv) {
796     return Standard_True;
797   }
798   return Standard_False; // nyi general case
799 }
800 
801 
802 // ================================================================================
803 //   In 3d space, give us a curve <C> and a surface <S>,
804 //   <C> is tangent to <S> at point P0 = <uv0> on <S> ,
805 //   <tgC> = C's tangent at P0,
806 //   <ngS> = <S>'s normal at P0.
807 
808 //   These define a plane thePlane = (O = P0, XY = (<ngS>,<tgC>)),
809 //   the projection of <S> in thePlane describes an apparent contour theContour.
810 
811 //   In thePlane :
812 //   P0 -> p2d0
813 //   <ngS> -> 2d axis x
814 //   <tgC> -> 2d axis y
815 
816 //   <C> -> C2d (same curvature)
817 //   <S>'s contour -> theContour
818 //   - the half3dspace described by (<S>,<ngS>) -> the half2dspace described by (theContour,x)
819 
820 //   if (<tgC>.<ngS> = 0.) : (X,Y) are normal vectors
821 //                           (x,y) are normal vectors
822 // ================================================================================
FUN_analyticcS(const gp_Pnt2d & uv0,const Handle (Geom_Surface)& S,const gp_Dir & ngS,const gp_Dir & tg0,Standard_Real & curv,Standard_Boolean & direct)823 static Standard_Boolean FUN_analyticcS(const gp_Pnt2d& uv0, const Handle(Geom_Surface)& S, const gp_Dir& ngS,
824 			  const gp_Dir& tg0,
825 			  Standard_Real& curv, Standard_Boolean& direct) // dummy if !analyticcontour
826 {
827   curv = 0.; direct = Standard_True;
828   // purpose : Returns true if theContour is analytic, and
829   //           then computes its curvature <curv>.
830   Handle(Geom_Surface) su = TopOpeBRepTool_ShapeTool::BASISSURFACE(S);
831   if (S.IsNull()) return Standard_True;
832   GeomAdaptor_Surface GS(su);
833   GeomAbs_SurfaceType ST = GS.GetType();
834   Standard_Boolean plane = (ST == GeomAbs_Plane);
835   Standard_Boolean cyl   = (ST == GeomAbs_Cylinder);
836   Standard_Boolean cone  = (ST == GeomAbs_Cone);
837   Standard_Boolean sphe  = (ST == GeomAbs_Sphere);
838   Standard_Boolean torus  = (ST == GeomAbs_Torus);
839 
840   Standard_Boolean curvdone = Standard_False;
841   if (plane) {curv = 0.; curvdone = Standard_True;}
842   if (cyl || cone || torus){
843     gp_Dir axis;
844     if (cyl) {
845       const gp_Cylinder& cycy = GS.Cylinder();
846       axis = cycy.Axis().Direction();
847       direct = cycy.Direct();
848     }
849     if (cone) {
850       const gp_Cone& coco = GS.Cone();
851       axis = coco.Axis().Direction();
852       direct = coco.Direct();
853     }
854     if (torus) {
855       const gp_Torus& toto = GS.Torus();
856       axis = toto.Axis().Direction();
857       direct = toto.Direct();
858     }
859     Standard_Real prod = axis.Dot(tg0);
860     Standard_Boolean isMaxAcurv  = FUN_nullprodv(1-Abs(prod));
861     Standard_Boolean nullcurv = FUN_nullprodv(prod);
862 
863     Standard_Real prod2 = ngS.Dot(tg0);
864     if (cyl || cone) nullcurv = nullcurv || FUN_nullprodv(1-Abs(prod2));
865 
866     if (nullcurv) {curv = 0.; curvdone = Standard_True;}
867     if (isMaxAcurv)  {
868       GeomLProp_SLProps slprops(S,uv0.X(),uv0.Y(),2,Precision::Confusion());
869       Standard_Boolean curdef = slprops.IsCurvatureDefined();
870       if (curdef) {
871 	Standard_Real minAcurv = Abs(slprops.MinCurvature());
872 	Standard_Real maxAcurv = Abs(slprops.MaxCurvature());
873 	Standard_Boolean isAmax = (maxAcurv > minAcurv);
874 	curv = isAmax ? maxAcurv : minAcurv;
875       }
876       curvdone = Standard_True;
877     }
878   }
879   if (sphe) {
880     const gp_Sphere& spsp = GS.Sphere();
881     curv = 1./spsp.Radius(); curvdone = Standard_True;
882     direct = spsp.Direct();
883   }
884 
885   return curvdone;
886 }
887 //=======================================================================
888 //function : CurvF
889 //purpose  :
890 //=======================================================================
891 
CurvF(const TopoDS_Face & F,const gp_Pnt2d & uv,const gp_Dir & tg0,Standard_Real & curv,Standard_Boolean & direct)892 Standard_Boolean TopOpeBRepTool_TOOL::CurvF(const TopoDS_Face& F,const gp_Pnt2d& uv,const gp_Dir& tg0,
893 			       Standard_Real& curv,Standard_Boolean& direct)
894 {
895   curv = 0.;
896   gp_Dir ngS = FUN_tool_nggeomF(uv,F);
897   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(F);
898   if (S.IsNull()) return Standard_False;
899   // purpose : Computes theContour's curvature,
900   //          returns false if the compute fails.
901 
902   Standard_Real tola = 1.e-6;//NYITOLXPU
903 
904   Standard_Boolean analyticcontour = FUN_analyticcS(uv,S,ngS,tg0,curv,direct);
905   if (analyticcontour) return Standard_True;
906 
907   GeomLProp_SLProps slprops(S,uv.X(),uv.Y(),2,Precision::Confusion());
908   Standard_Boolean curdef = slprops.IsCurvatureDefined();
909   if (curdef) {
910     gp_Dir npl = tg0;
911 
912     gp_Dir MaxD, MinD; slprops.CurvatureDirections(MaxD, MinD);
913     Standard_Real mincurv = slprops.MinCurvature();
914     Standard_Real maxcurv = slprops.MaxCurvature();
915 
916     gp_Vec Dmax=ngS^MaxD, Dmin=ngS^MinD; //xpu180898 : cto015G2
917     Standard_Real dotmax = Dmax.Dot(npl);//MaxD.Dot(npl); -xpu180898
918     Standard_Boolean iscurmax = Abs(1-dotmax)<tola;
919     if (iscurmax) {direct = (maxcurv < 0.); curv = Abs(maxcurv);}
920     Standard_Real dotmin = Dmin.Dot(npl);//MinD.Dot(npl); -xpu180898
921     Standard_Boolean iscurmin = Abs(1-dotmin)<tola;
922     if (iscurmin) {direct = (mincurv < 0.); curv = Abs(mincurv);}
923     curdef = iscurmax || iscurmin;
924     // -------------
925     // NYI : !curdef
926     // -------------
927   }
928   return curdef;
929 }
930 
931 
932 
933 //=======================================================================
934 //function : UVISO
935 //purpose  :
936 //=======================================================================
937 
UVISO(const Handle (Geom2d_Curve)& PC,Standard_Boolean & isoU,Standard_Boolean & isoV,gp_Dir2d & d2d,gp_Pnt2d & o2d)938 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const Handle(Geom2d_Curve)& PC,
939 			       Standard_Boolean& isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
940 {
941   isoU = isoV = Standard_False;
942   if (PC.IsNull()) return Standard_False;
943   Handle(Geom2d_Curve) LLL = BASISCURVE2D(PC);
944   Handle(Standard_Type) T2 = LLL->DynamicType();
945   Standard_Boolean isline2d = (T2 == STANDARD_TYPE(Geom2d_Line));
946   if (!isline2d) return Standard_False;
947 
948   Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(LLL);
949   d2d = L->Direction();
950   isoU = (Abs(d2d.X()) < Precision::Parametric(Precision::Confusion()));
951   isoV = (Abs(d2d.Y()) < Precision::Parametric(Precision::Confusion()));
952   Standard_Boolean isoUV = isoU || isoV;
953   if (!isoUV) return Standard_False;
954 
955   o2d = L->Location();
956   return Standard_True;
957 }
958 
UVISO(const TopoDS_Edge & E,const TopoDS_Face & F,Standard_Boolean & isoU,Standard_Boolean & isoV,gp_Dir2d & d2d,gp_Pnt2d & o2d)959 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const TopoDS_Edge& E, const TopoDS_Face& F,
960 			       Standard_Boolean & isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
961 {
962   //  Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,f,l,tol);
963   Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
964   Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,F,PC);
965   PC = FC2D_EditableCurveOnSurface(E,F,f,l,tol);
966   if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,F,f,l,tol);
967 
968   Standard_Boolean iso = UVISO(PC,isoU,isoV,d2d,o2d);
969   return iso;
970 }
971 
UVISO(const TopOpeBRepTool_C2DF & C2DF,Standard_Boolean & isoU,Standard_Boolean & isoV,gp_Dir2d & d2d,gp_Pnt2d & o2d)972 Standard_Boolean TopOpeBRepTool_TOOL::UVISO(const TopOpeBRepTool_C2DF& C2DF,
973 			       Standard_Boolean & isoU, Standard_Boolean& isoV, gp_Dir2d& d2d, gp_Pnt2d& o2d)
974 {
975   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
976 //#ifdef OCCT_DEBUG
977 //  const iso = UVISO(PC,isoU,isoV,d2d,o2d);
978 //#else
979   const Standard_Boolean iso = UVISO(PC,isoU,isoV,d2d,o2d);
980 //#endif
981   return iso;
982 }
983 
984 
985 //=======================================================================
986 //function : IsonCLO
987 //purpose  :
988 //=======================================================================
989 
IsonCLO(const Handle (Geom2d_Curve)& PC,const Standard_Boolean onU,const Standard_Real xfirst,const Standard_Real xperiod,const Standard_Real xtol)990 Standard_Boolean TopOpeBRepTool_TOOL::IsonCLO(const Handle(Geom2d_Curve)& PC,
991 				 const Standard_Boolean onU, const Standard_Real xfirst, const Standard_Real xperiod, const Standard_Real xtol)
992 {
993   Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d;
994   Standard_Boolean isouv = UVISO(PC,isou,isov,d2d,o2d);
995   if (!isouv) return Standard_False;
996   Standard_Boolean onX = (onU && isou) || ((!onU) && isov);
997   if (!onX) return Standard_False;
998   Standard_Real dxx=0;
999   if (onU) dxx = Abs(o2d.X()-xfirst);
1000   else     dxx = Abs(o2d.Y()-xfirst);
1001 
1002   Standard_Boolean onclo = (dxx < xtol);
1003   onclo = onclo || (Abs(xperiod-dxx) < xtol);
1004   return onclo;
1005 }
IsonCLO(const TopOpeBRepTool_C2DF & C2DF,const Standard_Boolean onU,const Standard_Real xfirst,const Standard_Real xperiod,const Standard_Real xtol)1006 Standard_Boolean TopOpeBRepTool_TOOL::IsonCLO(const TopOpeBRepTool_C2DF& C2DF,
1007 				 const Standard_Boolean onU, const Standard_Real xfirst, const Standard_Real xperiod, const Standard_Real xtol)
1008 {
1009   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
1010   Standard_Boolean onclo = IsonCLO(PC,onU,xfirst,xperiod,xtol);
1011   return onclo;
1012 }
1013 
1014 //=======================================================================
1015 //function : TrslUV
1016 //purpose  :
1017 //=======================================================================
1018 
TrslUV(const gp_Vec2d & t2d,TopOpeBRepTool_C2DF & C2DF)1019 void TopOpeBRepTool_TOOL::TrslUV(const gp_Vec2d& t2d, TopOpeBRepTool_C2DF& C2DF)
1020 {
1021   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = C2DF.PC(f,l,tol);
1022   PC->Translate(t2d);
1023   C2DF.SetPC(PC,f,l,tol);
1024 }
1025 
TrslUVModifE(const gp_Vec2d & t2d,const TopoDS_Face & F,TopoDS_Edge & E)1026 Standard_Boolean TopOpeBRepTool_TOOL::TrslUVModifE(const gp_Vec2d& t2d, const TopoDS_Face& F, TopoDS_Edge& E)
1027 {
1028   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,f,l,tol);
1029 //  Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
1030 
1031   if (PC.IsNull()) return Standard_False;
1032   PC->Translate(t2d);
1033 //  Handle(Geom2d_Curve) toclear; BB.UpdateEdge(E,toclear,F,tole);
1034   BRep_Builder BB; BB.UpdateEdge(E,PC,F,tol);
1035   return Standard_True;
1036 }
1037 
1038 //=======================================================================
1039 //function : Matter
1040 //purpose  :
1041 //=======================================================================
1042 
Matter(const gp_Vec & d1,const gp_Vec & dR2,const gp_Vec & Ref)1043 Standard_Real TopOpeBRepTool_TOOL::Matter(const gp_Vec& d1, const gp_Vec& dR2, const gp_Vec& Ref)
1044 {
1045   gp_Vec d2 = dR2.Reversed();
1046 
1047   Standard_Real tola = Precision::Angular();
1048   Standard_Real ang = d1.Angle(d2);
1049   Standard_Boolean equal = (ang < tola);
1050   if (equal) return 0.;
1051   Standard_Boolean oppo = ((M_PI-ang) < tola);
1052   if (oppo)  return M_PI;
1053 
1054   ang = d1.AngleWithRef(d2,Ref);
1055   if (ang < 0) ang = 2.*M_PI+ang;
1056   return ang;
1057 }
1058 
1059 //=======================================================================
1060 //function : Matter
1061 //purpose  :
1062 //=======================================================================
1063 
Matter(const gp_Vec2d & d1,const gp_Vec2d & dR2)1064 Standard_Real TopOpeBRepTool_TOOL::Matter(const gp_Vec2d& d1, const gp_Vec2d& dR2)
1065 {
1066   gp_Vec v1 = gp_Vec(d1.X(),d1.Y(),0.);
1067   gp_Vec vR2 = gp_Vec(dR2.X(),dR2.Y(),0.);
1068   gp_Vec Ref(0.,0.,1.);
1069 
1070   Standard_Real ang = TopOpeBRepTool_TOOL::Matter(v1,vR2,Ref);
1071   return ang;
1072 }
1073 
1074 //=======================================================================
1075 //function : Matter
1076 //purpose  :
1077 //=======================================================================
1078 
Matter(const gp_Dir & xx1,const gp_Dir & nt1,const gp_Dir & xx2,const gp_Dir & nt2,const Standard_Real tola,Standard_Real & ang)1079 Standard_Boolean TopOpeBRepTool_TOOL::Matter(const gp_Dir& xx1,const gp_Dir& nt1,
1080 				const gp_Dir& xx2,const gp_Dir& nt2,
1081 				const Standard_Real tola, Standard_Real& ang)
1082 // purpose : the compute of MatterAng(f1,f2)
1083 {
1084   // --------------------------------------------------
1085   // Give us a face f1 and one edge e of f1, pone=pnt(e,pare)
1086   // We project the problem in a plane normal to e, at point pone
1087   // ie we see the problem in space (x,y), with RONd (x,y,z), z tangent to e at pone.
1088   // RONd (x,y,z) = (xx1,nt1,x^y)
1089   //
1090   // Make the analogy :
1091   // f <-> Ef, e <-> Ve,
1092   // In view (x,y), f1 is seen as an edge Ef, e is seen as a vertex Ve,
1093   // the matter delimited by f can be seen as the one delimited by Ef.
1094   // --------------------------------------------------
1095 
1096   // Sign( (v1^nt1).z ) describes Ve's orientation in Ef1
1097   // (v1^nt1).z > 0. => Ve is oriented REVERSED in Ef1.
1098   // - ori(Ve,Ef1) == REVERSED : the matter delimited by <f1>
1099   //                              is (y<=0) in (x,y) 2d space -
1100 
1101   gp_Dir z1 = xx1^nt1;
1102   gp_Dir z2 = xx2^nt2;
1103   Standard_Real dot = z2.Dot(z1);
1104   Standard_Boolean oppo = (dot < 0.);
1105   if (!oppo) return Standard_False;
1106 
1107   // -nti points towards 3dmatter(fi)
1108   // => zi = xxi^nti gives the opposite sense for the compute of the matter angle
1109   z1.Reverse();
1110   ang = xx1.AngleWithRef(xx2,z1);
1111   if (Abs(ang) < tola) {ang = 0.; return Standard_True;}
1112   if (ang < 0) ang = 2.*M_PI+ang;
1113 
1114   return Standard_True;
1115 }
1116 
1117 //=======================================================================
1118 //function : Getduv
1119 //purpose  :
1120 //=======================================================================
1121 
Getduv(const TopoDS_Face & f,const gp_Pnt2d & uv,const gp_Vec & dir,const Standard_Real factor,gp_Dir2d & duv)1122 Standard_Boolean TopOpeBRepTool_TOOL::Getduv(const TopoDS_Face& f,const gp_Pnt2d& uv,const gp_Vec& dir,
1123 				const Standard_Real factor, gp_Dir2d& duv)
1124 {
1125   Standard_Boolean quad = TopOpeBRepTool_TOOL::IsQuad(f);
1126   if (!quad) return Standard_False;
1127   Bnd_Box bndf; BRepBndLib::AddClose(f,bndf);
1128   Standard_Real f1,f2,f3,l1,l2,l3; bndf.Get(f1,f2,f3,l1,l2,l3);
1129   gp_Vec d123(f1-l1, f2-l2, f3-l3);
1130 
1131   gp_Pnt p; FUN_tool_value(uv,f,p); p.Translate(dir.Multiplied(factor));
1132   Standard_Real d; gp_Pnt2d uvtr;
1133   FUN_tool_projPonF(p,f, uvtr,d);
1134   Standard_Real tolf = BRep_Tool::Tolerance(f); tolf *= 1.e2; //NYIXPUTOL
1135   if (d > tolf) return Standard_False;
1136 
1137   gp_Vec2d DUV( uv, uvtr );
1138   Handle(Geom_Surface) S = TopOpeBRepTool_ShapeTool::BASISSURFACE(f);
1139   if ((S->IsUPeriodic()) && (Abs(DUV.X()) > S->UPeriod()/2.))
1140     {
1141       Standard_Real U1 = uv.X(), U2 = uvtr.X(), period = S->UPeriod();
1142       ElCLib::AdjustPeriodic( 0., period, Precision::PConfusion(), U1, U2 );
1143       Standard_Real dx = U2-U1;
1144       if (dx > period/2.)
1145 	dx -= period;
1146       DUV.SetX( dx );
1147     }
1148   if ((S->IsVPeriodic()) && (Abs(DUV.Y()) > S->VPeriod()/2.))
1149     {
1150       Standard_Real V1 = uv.Y(), V2 = uvtr.Y(), period = S->VPeriod();
1151       ElCLib::AdjustPeriodic( 0., period, Precision::PConfusion(), V1, V2 );
1152       Standard_Real dy = V2-V1;
1153       if (dy > period/2.)
1154 	dy -= period;
1155       DUV.SetY( dy );
1156     }
1157   duv = gp_Dir2d( DUV );
1158 
1159   return Standard_True;
1160 }
1161 
1162 
1163 
1164 //=======================================================================
1165 //function : uvApp
1166 //purpose  :
1167 //=======================================================================
1168 
uvApp(const TopoDS_Face & f,const TopoDS_Edge & e,const Standard_Real pare,const Standard_Real eps,gp_Pnt2d & uvapp)1169 Standard_Boolean TopOpeBRepTool_TOOL::uvApp(const TopoDS_Face& f,const TopoDS_Edge& e,const Standard_Real pare,const Standard_Real eps,
1170 			       gp_Pnt2d& uvapp)
1171 {
1172   // uv :
1173   Standard_Boolean ok = FUN_tool_paronEF(e,pare,f,uvapp);
1174   if (!ok) return Standard_False;
1175   gp_Vec2d dxx; ok = FUN_tool_getdxx(f,e,pare,dxx);
1176   if (!ok) return Standard_False;
1177   uvapp.Translate(dxx.Multiplied(eps));
1178   return Standard_True;
1179 }
1180 
1181 //=======================================================================
1182 //function : XX
1183 //purpose  :
1184 //=======================================================================
1185 
XX(const gp_Pnt2d & uv,const TopoDS_Face & f,const Standard_Real par,const TopoDS_Edge & e,gp_Dir & XX)1186 Standard_Boolean TopOpeBRepTool_TOOL::XX(const gp_Pnt2d& uv, const TopoDS_Face& f,
1187 			    const Standard_Real par, const TopoDS_Edge& e,
1188 			    gp_Dir& XX)
1189 {
1190   // ng(uv):
1191   gp_Vec ng = FUN_tool_nggeomF(uv,f);
1192   gp_Vec geomxx = FUN_tool_getgeomxx(f,e,par,ng);
1193 
1194   Standard_Real tol = Precision::Confusion()*1.e2;//NYITOL
1195   Standard_Boolean nullng = (geomxx.Magnitude()<tol);
1196   if (nullng) return Standard_False;
1197 
1198   TopAbs_Orientation oef; Standard_Boolean ok = FUN_tool_orientEinFFORWARD(e,f,oef);
1199   if (!ok) return Standard_False;
1200   XX = gp_Dir(geomxx);
1201   if (M_REVERSED(oef)) XX.Reverse();
1202   return Standard_True;
1203 }
1204 
1205 //=======================================================================
1206 //function : Nt
1207 //purpose  :
1208 //=======================================================================
1209 
Nt(const gp_Pnt2d & uv,const TopoDS_Face & f,gp_Dir & normt)1210 Standard_Boolean TopOpeBRepTool_TOOL::Nt(const gp_Pnt2d& uv, const TopoDS_Face& f,
1211 			    gp_Dir& normt)
1212 {
1213   gp_Vec nggeom; Standard_Boolean ok = TopOpeBRepTool_TOOL::NggeomF(uv,f,nggeom);
1214   if (!ok) return Standard_False;
1215   normt = gp_Dir(nggeom);
1216   if (M_REVERSED(f.Orientation())) normt.Reverse();
1217   return Standard_True;
1218 }
1219 
1220 //=======================================================================
1221 //function : NggeomF
1222 //purpose  :
1223 //=======================================================================
1224 
FUN_ngF(const gp_Pnt2d & uv,const TopoDS_Face & F,gp_Vec & ngF)1225 static Standard_Boolean FUN_ngF(const gp_Pnt2d& uv, const TopoDS_Face& F, gp_Vec& ngF)
1226 {
1227   BRepAdaptor_Surface bs(F);
1228   Standard_Real tol3d = bs.Tolerance();
1229   Standard_Real tolu = bs.UResolution(tol3d);
1230   Standard_Real tolv = bs.VResolution(tol3d);
1231 
1232   // ###############################
1233   // nyi : all geometries are direct
1234   // ###############################
1235   gp_Pnt p; gp_Vec d1u,d1v; bs.D1(uv.X(),uv.Y(),p,d1u,d1v);
1236 
1237   Standard_Real delta = TopOpeBRepTool_TOOL::minDUV(F); delta *= 1.e-1;
1238 
1239   Standard_Real du = d1u.Magnitude();
1240   Standard_Real dv = d1v.Magnitude();
1241   Standard_Boolean kpart = (du < tolu) || (dv < tolv);
1242   if (kpart) {
1243     GeomAbs_SurfaceType ST = bs.GetType();
1244     if (ST == GeomAbs_Cone) {
1245       Standard_Boolean nullx = (Abs(uv.X()) < tolu);
1246       Standard_Boolean apex = nullx && (Abs(uv.Y()) < tolv);
1247       if (apex) {
1248         const gp_Dir axis = bs.Cone().Axis().Direction();
1249         gp_Vec ng(axis);
1250         ng.Reverse();
1251         ngF = ng;
1252         return Standard_True;
1253       }
1254       else if (du < tolu) {
1255 	Standard_Real x = uv.X();
1256 
1257 	Standard_Real y = uv.Y();
1258 	Standard_Real vf = bs.FirstVParameter();
1259 
1260 	if (Abs(vf-y) < tolu) vf += delta;
1261 	else                  vf -= delta;
1262 
1263 	//modified by NIZHNY-MZV  Fri Nov 26 12:38:55 1999
1264 	y = vf;
1265 	bs.D1(x,y,p,d1u,d1v);
1266 	gp_Vec ng = d1u^d1v;
1267 
1268 	ngF = ng; return Standard_True;
1269       }
1270     }
1271     if (ST == GeomAbs_Sphere) {
1272       Standard_Real pisur2 = M_PI*.5;
1273       Standard_Real u = uv.X(),v = uv.Y();
1274       Standard_Boolean vpisur2 = (Abs(v-pisur2) < tolv);
1275       Standard_Boolean vmoinspisur2 = (Abs(v+pisur2) < tolv);
1276       Standard_Boolean apex = vpisur2 || vmoinspisur2;
1277       if (apex) {
1278 	gp_Pnt center = bs.Sphere().Location();
1279 	gp_Pnt value  = bs.Value(u,v);
1280 	gp_Vec ng(center,value);
1281 	ngF = ng; return Standard_True;
1282       }
1283     }
1284 #ifdef OCCT_DEBUG
1285     std::cout<<"FUN_tool_nggeomF NYI"<<std::endl;
1286 #endif
1287     return Standard_False;
1288   } //kpart
1289 
1290   gp_Dir udir(d1u);
1291   gp_Dir vdir(d1v);
1292   ngF = gp_Vec(gp_Dir(udir^vdir));
1293   return Standard_True;
1294 }
1295 
NggeomF(const gp_Pnt2d & uv,const TopoDS_Face & f,gp_Vec & ng)1296 Standard_Boolean TopOpeBRepTool_TOOL::NggeomF(const gp_Pnt2d& uv, const TopoDS_Face& f,
1297 				 gp_Vec& ng)
1298 {
1299   return FUN_ngF(uv,f,ng);
1300 }
1301 
1302 //=======================================================================
1303 //function : Matter
1304 //purpose  :
1305 //=======================================================================
1306 
Matter(const TopoDS_Face & f1,const TopoDS_Face & f2,const TopoDS_Edge & e,const Standard_Real par,const Standard_Real tola,Standard_Real & ang)1307 Standard_Boolean TopOpeBRepTool_TOOL::Matter(const TopoDS_Face& f1,const TopoDS_Face& f2,
1308 				const TopoDS_Edge& e,const Standard_Real par,
1309 				const Standard_Real tola, Standard_Real& ang)
1310 {
1311   gp_Dir xx1,xx2;
1312   gp_Dir nt1,nt2;
1313 
1314   Standard_Real tolf1 = BRep_Tool::Tolerance(f1)*1.e2;//nyitolxpu
1315   gp_Pnt2d uv1; Standard_Boolean ok1 = FUN_tool_paronEF(e,par,f1,uv1,tolf1);
1316   if (!ok1) return Standard_False;
1317   ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1318   if (!ok1) return Standard_False;
1319   ok1 = TopOpeBRepTool_TOOL::XX(uv1,f1,par,e,xx1);
1320   if (!ok1) return Standard_False;
1321 
1322   Standard_Real tolf2 = BRep_Tool::Tolerance(f2)*2.e2;//nyitolxpu
1323   gp_Pnt2d uv2; Standard_Boolean ok2 = FUN_tool_paronEF(e,par,f2,uv2,tolf2);
1324   if (!ok2) return Standard_False;
1325   ok2 = TopOpeBRepTool_TOOL::Nt(uv2,f2,nt2);
1326   if (!ok2) return Standard_False;
1327   ok2 = TopOpeBRepTool_TOOL::XX(uv2,f2,par,e,xx2);
1328   if (!ok2) return Standard_False;
1329 
1330   return (TopOpeBRepTool_TOOL::Matter(xx1,nt1,xx2,nt2,tola,ang));
1331 }
1332 
1333 
1334 
1335 
1336 //=======================================================================
1337 //function : MatterKPtg
1338 //purpose  :
1339 //=======================================================================
1340 
MatterKPtg(const TopoDS_Face & f1,const TopoDS_Face & f2,const TopoDS_Edge & e,Standard_Real & ang)1341 Standard_Boolean TopOpeBRepTool_TOOL::MatterKPtg(const TopoDS_Face& f1,const TopoDS_Face& f2,const TopoDS_Edge& e,
1342 				    Standard_Real& ang)
1343 {
1344   Standard_Real f,l; FUN_tool_bounds(e,f,l);
1345   Standard_Real x = 0.45678; Standard_Real pare = (1-x)*f+x*l;
1346 
1347   Standard_Real eps = 0.123; //NYIXPU190199
1348 
1349   //Standard_Real tola = Precision::Angular()*1.e3;
1350 
1351   gp_Pnt2d uv1; FUN_tool_paronEF(e,pare,f1,uv1);
1352   gp_Dir nt1; Standard_Boolean ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1353   if (!ok1) return Standard_False;
1354   gp_Pnt2d uvapp1; ok1 = TopOpeBRepTool_TOOL::uvApp(f1,e,pare,eps,uvapp1);
1355   if (!ok1) return Standard_False;
1356   gp_Pnt pf1; FUN_tool_value(uvapp1,f1,pf1);
1357 
1358   gp_Pnt2d uv2; Standard_Real d; Standard_Boolean ok2 = FUN_tool_projPonF(pf1,f2,uv2,d);
1359   gp_Pnt pf2; FUN_tool_value(uv2,f2,pf2);
1360   if (!ok2) return Standard_False;
1361 
1362   gp_Dir v12(gp_Vec(pf1,pf2));
1363   Standard_Real dot = v12.Dot(nt1);
1364   ang = (dot < 0.) ? 0. : 2.*M_PI;
1365 
1366 //  gp_Dir nt1; ok1 = TopOpeBRepTool_TOOL::Nt(uv1,f1,nt1);
1367 //  if (!ok1) return Standard_False;
1368 //  gp_Dir xx1; ok1 = TopOpeBRepTool_TOOL::XX(uv1,f1,pare,e,xx1);
1369 //  if (!ok1) return Standard_False;
1370 //  gp_Pnt2d uv2; Standard_Boolean ok2 = TopOpeBRepTool_TOOL::uvApp(f2,e,pare,eps,uv2);
1371 //  if (!ok2) return Standard_False;
1372 //  gp_Dir nt2; ok2 = TopOpeBRepTool_TOOL::Nt(uv2,f2,nt2);
1373 //  if (!ok2) return Standard_False;
1374 //  gp_Dir xx2; ok2 = TopOpeBRepTool_TOOL::XX(uv2,f2,pare,e,xx2);
1375 //  if (!ok2) return Standard_False;
1376 //  Standard_Real angapp; Standard_Boolean ok = TopOpeBRepTool_TOOL::Matter(xx1,nt1, xx2,nt2,tola,angapp);
1377 //  if (!ok) return Standard_False;
1378 //  Standard_Boolean is0 = (Abs(angapp) < Abs(2.*M_PI-angapp));
1379 //  ang = is0 ? 0. : 2.*M_PI;
1380   return Standard_True;
1381 }
1382 
1383 //=======================================================================
1384 //function : Getstp3dF
1385 //purpose  :
1386 //=======================================================================
1387 
Getstp3dF(const gp_Pnt & p,const TopoDS_Face & f,gp_Pnt2d & uv,TopAbs_State & st)1388 Standard_Boolean TopOpeBRepTool_TOOL::Getstp3dF(const gp_Pnt& p, const TopoDS_Face& f, gp_Pnt2d& uv, TopAbs_State& st)
1389 // classification solide de <P> / <F>
1390 {
1391   st = TopAbs_UNKNOWN;
1392   Standard_Real tol3d = BRep_Tool::Tolerance(f);
1393     // EXPENSIVE : calls an extrema
1394   Standard_Real d;  Standard_Boolean ok = FUN_tool_projPonF(p,f,uv,d);
1395   if (!ok) return Standard_False;
1396   if (d < tol3d) {st = TopAbs_ON; return Standard_True;}
1397 
1398   gp_Pnt ppr; ok = FUN_tool_value(uv,f,ppr);
1399   if (!ok) return Standard_False;
1400 
1401   gp_Dir ntf; ok = TopOpeBRepTool_TOOL::Nt(uv,f, ntf);
1402   if (!ok) return Standard_False;
1403 
1404   gp_Dir dppr(gp_Vec(p,ppr));
1405   Standard_Real dot = dppr.Dot(ntf);
1406   Standard_Boolean isOUT = (dot < 0.);
1407   st = (isOUT ? TopAbs_OUT : TopAbs_IN);
1408   return Standard_True;
1409 }
1410 
1411 
1412 
1413 //=======================================================================
1414 //function : MkShell
1415 //purpose  :
1416 //=======================================================================
1417 
MkShell(const TopTools_ListOfShape & lF,TopoDS_Shape & She)1418 void TopOpeBRepTool_TOOL::MkShell(const TopTools_ListOfShape& lF, TopoDS_Shape& She)
1419 {
1420   BRep_Builder BB; BB.MakeShell(TopoDS::Shell(She));
1421   for (TopTools_ListIteratorOfListOfShape li(lF); li.More(); li.Next()) BB.Add(She,li.Value());
1422 }
1423 
1424 //=======================================================================
1425 //function : Remove
1426 //purpose  :
1427 //=======================================================================
1428 
Remove(TopTools_ListOfShape & loS,const TopoDS_Shape & toremove)1429 Standard_Boolean TopOpeBRepTool_TOOL::Remove(TopTools_ListOfShape& loS, const TopoDS_Shape& toremove)
1430 {
1431   TopTools_ListIteratorOfListOfShape it(loS);
1432   Standard_Boolean found = Standard_False;
1433   while (it.More()) {
1434     if (it.Value().IsEqual(toremove)) {loS.Remove(it);found = Standard_True;}
1435     else                              it.Next();
1436   }
1437   return found;
1438 }
1439 
1440 //=======================================================================
1441 //function : minDUV
1442 //purpose  :
1443 //=======================================================================
1444 
minDUV(const TopoDS_Face & F)1445 Standard_Real TopOpeBRepTool_TOOL::minDUV(const TopoDS_Face& F)
1446 {
1447   BRepAdaptor_Surface BS(F);
1448   Standard_Real delta = BS.LastUParameter() - BS.FirstUParameter();
1449   Standard_Real tmp = BS.LastVParameter() - BS.FirstVParameter();
1450   delta = (tmp < delta) ? tmp : delta;
1451   return delta;
1452 }
1453 
1454 
1455 //=======================================================================
1456 //function : stuvF
1457 //purpose  :
1458 //=======================================================================
1459 #define INFFIRST (-1)
1460 #define SUPLAST (-2)
1461 #define ONFIRST (1)
1462 #define ONLAST  (2)
stuvF(const gp_Pnt2d & uv,const TopoDS_Face & f,Standard_Integer & onU,Standard_Integer & onV)1463 void TopOpeBRepTool_TOOL::stuvF(const gp_Pnt2d& uv,const TopoDS_Face& f,  Standard_Integer& onU,Standard_Integer& onV)
1464 {
1465   BRepAdaptor_Surface bs(f);
1466   onU = onV = 0;
1467   Standard_Real tolf = bs.Tolerance();
1468   Standard_Real tolu = bs.UResolution(tolf), tolv = bs.VResolution(tolf);
1469   Standard_Real u=uv.X(),v = uv.Y();
1470   Standard_Real uf=bs.FirstUParameter(),ul=bs.LastUParameter(),vf=bs.FirstVParameter(),vl=bs.LastVParameter();
1471   Standard_Boolean onuf = (Abs(uf-u)<tolu), onul = (Abs(ul-u)<tolu);
1472   Standard_Boolean onvf = (Abs(vf-v)<tolv), onvl = (Abs(vl-v)<tolv);
1473   if (onuf) onU = ONFIRST;
1474   if (onul) onU = ONLAST;
1475   if (onvf) onV = ONFIRST;
1476   if (onvl) onV = ONLAST;
1477   if (u < (uf-tolu)) onU = INFFIRST;
1478   if (u > (ul+tolu)) onU = SUPLAST;
1479   if (v < (vf-tolv)) onV = INFFIRST;
1480   if (v > (vl+tolv)) onV = SUPLAST;
1481 }
1482 
1483 //=======================================================================
1484 //function : outUVbounds
1485 //purpose  :
1486 //=======================================================================
1487 
outUVbounds(const gp_Pnt2d & uv,const TopoDS_Face & F)1488 Standard_Boolean TopOpeBRepTool_TOOL::outUVbounds(const gp_Pnt2d& uv, const TopoDS_Face& F)
1489 {
1490   BRepAdaptor_Surface BS(F);
1491   Standard_Boolean outofboundU = (uv.X() > BS.LastUParameter())||(uv.X() < BS.FirstUParameter());
1492   Standard_Boolean outofboundV = (uv.Y() > BS.LastVParameter())||(uv.Y() < BS.FirstVParameter());
1493   return outofboundU || outofboundV;
1494 }
1495 
1496 //=======================================================================
1497 //function : TolUV
1498 //purpose  :
1499 //=======================================================================
1500 
TolUV(const TopoDS_Face & F,const Standard_Real tol3d)1501 Standard_Real TopOpeBRepTool_TOOL::TolUV(const TopoDS_Face& F, const Standard_Real tol3d)
1502 {
1503   BRepAdaptor_Surface bs(F);
1504   Standard_Real tol2d = bs.UResolution(tol3d);
1505   tol2d = Max(tol2d,bs.VResolution(tol3d));
1506   return tol2d;
1507 }
1508 
1509 //=======================================================================
1510 //function : TolP
1511 //purpose  :
1512 //=======================================================================
1513 
TolP(const TopoDS_Edge & E,const TopoDS_Face & F)1514 Standard_Real TopOpeBRepTool_TOOL::TolP(const TopoDS_Edge& E, const TopoDS_Face& F)
1515 {
1516   BRepAdaptor_Curve2d BC2d(E,F);
1517   return ( BC2d.Resolution(BRep_Tool::Tolerance(E)) );
1518 }
1519 
1520 //=======================================================================
1521 //function : WireToFace
1522 //purpose  :
1523 //=======================================================================
1524 
WireToFace(const TopoDS_Face & Fref,const TopTools_DataMapOfShapeListOfShape & mapWlow,TopTools_ListOfShape & lFs)1525 Standard_Boolean TopOpeBRepTool_TOOL::WireToFace(const TopoDS_Face& Fref, const TopTools_DataMapOfShapeListOfShape& mapWlow,
1526 				    TopTools_ListOfShape& lFs)
1527 {
1528   BRep_Builder BB;
1529   TopoDS_Shape aLocalShape = Fref.Oriented(TopAbs_FORWARD);
1530   TopoDS_Face F = TopoDS::Face(aLocalShape);
1531 //  TopoDS_Face F = TopoDS::Face(Fref.Oriented(TopAbs_FORWARD));
1532   Standard_Boolean toreverse = M_REVERSED(Fref.Orientation());
1533   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mapWlow);
1534   for (; itm.More(); itm.Next()) {
1535     TopoDS_Shape FF = F.EmptyCopied();
1536     const TopoDS_Wire& wi = TopoDS::Wire(itm.Key());
1537     BB.Add(FF,wi);
1538     TopTools_ListIteratorOfListOfShape itw(itm.Value());
1539     for (; itw.More(); itw.Next()) {
1540       const TopoDS_Wire& wwi = TopoDS::Wire(itw.Value());
1541       BB.Add(FF,wwi);
1542     }
1543     if (toreverse) FF.Orientation(TopAbs_REVERSED);
1544     lFs.Append(FF);
1545   }
1546   return Standard_True;
1547 }
1548 
1549 //=======================================================================
1550 //function : EdgeONFace
1551 //purpose  :
1552 //=======================================================================
1553 
EdgeONFace(const Standard_Real par,const TopoDS_Edge & ed,const gp_Pnt2d & uv,const TopoDS_Face & fa,Standard_Boolean & isonfa)1554 Standard_Boolean TopOpeBRepTool_TOOL::EdgeONFace(const Standard_Real par,const TopoDS_Edge& ed,
1555 				    const gp_Pnt2d& uv,const TopoDS_Face& fa,
1556 				    Standard_Boolean& isonfa)
1557 {
1558   isonfa = Standard_False;
1559   // prequesitory : pnt(par,ed) = pnt(uv,f)
1560   Standard_Boolean dge = BRep_Tool::Degenerated(ed);
1561   if (dge) {
1562     isonfa = Standard_True;
1563     return Standard_True;
1564   }
1565 
1566   Standard_Real tola = Precision::Angular()*1.e2;//NYITOLXPU
1567   gp_Vec tge; Standard_Boolean ok = TopOpeBRepTool_TOOL::TggeomE(par,ed,tge);
1568   if (!ok) return Standard_False;
1569   gp_Vec ngf = FUN_tool_nggeomF(uv,fa);
1570   Standard_Real aProdDot = tge.Dot(ngf);
1571   Standard_Boolean etgf = Abs(aProdDot) < tola;
1572   if (!etgf) return Standard_True;
1573 
1574   BRepAdaptor_Surface bs(fa);
1575   GeomAbs_SurfaceType st = bs.GetType();
1576   Standard_Boolean plane = (st == GeomAbs_Plane);
1577   Standard_Boolean cylinder = (st == GeomAbs_Cylinder);
1578 
1579   BRepAdaptor_Curve bc(ed);
1580   GeomAbs_CurveType ct = bc.GetType();
1581   Standard_Boolean line = (ct == GeomAbs_Line);
1582   Standard_Boolean circle = (ct == GeomAbs_Circle);
1583 
1584   Standard_Real tole = bc.Tolerance(); Standard_Real tol1de = bc.Resolution(tole);
1585   Standard_Real tolf = bs.Tolerance();
1586   Standard_Real tol3d = Max(tole,tolf)*1.e2;//NYITOLXPU
1587 
1588   // NYIxpu100299 : for other analytic geometries
1589   if (plane && line) {isonfa = Standard_True; return Standard_True;}
1590   if       (plane) {
1591     gp_Dir ne;
1592     Standard_Boolean det = Standard_True;
1593     if      (circle)  ne = bc.Circle().Axis().Direction();
1594     else if (ct == GeomAbs_Ellipse) ne = bc.Ellipse().Axis().Direction();
1595     else if (ct == GeomAbs_Hyperbola)    ne = bc.Hyperbola().Axis().Direction();
1596     else if (ct == GeomAbs_Parabola)ne = bc.Parabola().Axis().Direction();
1597     else                            det = Standard_False;
1598     if (det) {
1599       Standard_Real prod = ne.Dot(ngf);
1600       isonfa = ( Abs(1-Abs(prod)) < tola );
1601       return Standard_True;
1602     }
1603   }//plane
1604   else if (cylinder) {
1605     gp_Dir ne; Standard_Boolean det = Standard_True;
1606     if      (line)  ne = tge;
1607     else if (circle)ne = bc.Circle().Axis().Direction();
1608     else            det = Standard_False;
1609     gp_Dir axicy = bs.Cylinder().Axis().Direction();
1610 
1611     if (det) {
1612       Standard_Real prod = ne.Dot(axicy);
1613       isonfa = ( Abs(1-Abs(prod)) < tola );
1614       if (isonfa && circle) {
1615 	Standard_Real radci = bc.Circle().Radius();
1616 	Standard_Real radcy = bs.Cylinder().Radius();
1617 	isonfa = ( Abs(radci-radcy)<tol3d );
1618       }
1619       return Standard_True;
1620     }
1621   }//cylinder
1622 
1623   // !!!!!!!!!!!!!!!! NOT STILL OK !!!!!!!!!!!!!!
1624   // projecting point of <ed> on <fa>
1625   Standard_Real x = 0.12345;
1626   Standard_Real f,l; FUN_tool_bounds(ed,f,l);
1627   Standard_Boolean onf = ( Abs(par-f)<tol1de );
1628   Standard_Real opar = onf ?  ((1-x)*f+x*l) : ((1-x)*f+x*par);
1629   gp_Pnt opc = bc.Value(opar);
1630 
1631   gp_Pnt2d ouv; ok = FUN_tool_parF(ed,opar,fa,ouv,tolf);
1632   if (!ok) return Standard_False;
1633   gp_Pnt ops = bs.Value(ouv.X(),ouv.Y());
1634 
1635   Standard_Real dd = opc.Distance(ops);
1636   isonfa = (dd < tol3d);
1637   return Standard_True;
1638 }
1639