0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_REGUW.cxx
1 // File:        TopOpeBRepTool_REGUW.cxx
2 // Created:     Tue Dec  8 18:07:24 1998
3 // Author:      Xuan PHAM PHU
4 //              <xpu@poulopox.paris1.matra-dtv.fr>
5
6
7 #include <Geom2d_Curve.hxx>
8 #include <TopoDS.hxx>
9 #include <BRep_Tool.hxx>
10 #include <Precision.hxx>
11 #include <TopExp_Explorer.hxx>
12 #include <TopOpeBRepTool_C2DF.hxx>
13 #include <TopOpeBRepTool_REGUW.ixx>
14 #include <TopOpeBRepTool_EXPORT.hxx>
15 #include <TopOpeBRepTool_TOOL.hxx>
16 #include <TopOpeBRepTool_define.hxx>
17
18 #ifdef DRAW
19 #include <TopOpeBRepTool_DRAW.hxx>
20 #endif
21
22 #define FORWARD  (1)
23 #define REVERSED (2)
24 #define INTERNAL (3)
25 #define EXTERNAL (4)
26 #define CLOSING  (5)
27
28 #define M_FORWARD(ori)  (ori == TopAbs_FORWARD) 
29 #define M_REVERSED(ori) (ori == TopAbs_REVERSED) 
30 #define M_INTERNAL(ori) (ori == TopAbs_INTERNAL) 
31 #define M_EXTERNAL(ori) (ori == TopAbs_EXTERNAL) 
32
33 #ifdef DEB
34 Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceREGUFA(); 
35 static TopTools_IndexedMapOfShape STATIC_mapf, STATIC_mapw, STATIC_mapv;
36 static TopTools_IndexedMapOfOrientedShape STATIC_mapeds;
37 void FUN_tro(const Standard_Integer i)
38 {
39   if      (i==1) cout<<"FORWARD";
40   else if (i==2) cout<<"REVERSED";
41   else if (i==3) cout<<"INTERNAL";
42   else if (i==4) cout<<"EXTERNAL";
43   else if (i==5) cout<<"CLOSING";
44 }
45 Standard_EXPORT Standard_Integer FUN_adds(const TopoDS_Shape& s) {
46   TopAbs_ShapeEnum typ = s.ShapeType();
47   TCollection_AsciiString aa; Standard_Integer is = 0;
48   if (typ == TopAbs_VERTEX) {aa = TCollection_AsciiString("v"); is = STATIC_mapv.Add(s);}
49   if (typ == TopAbs_EDGE)   {aa = TCollection_AsciiString("e"); is = STATIC_mapeds.Add(s);}
50   if (typ == TopAbs_WIRE)   {aa = TCollection_AsciiString("wi"); is = STATIC_mapw.Add(s);}
51   if (typ == TopAbs_FACE)   {aa = TCollection_AsciiString("f"); is = STATIC_mapf.Add(s);}
52 #ifdef DRAW
53   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); 
54   if (trc) FUN_tool_draw(aa,s,is);
55 #endif
56   return is;
57 }
58 #endif
59
60 Standard_IMPORT void FUN_tool_tori(const TopAbs_Orientation Or);
61
62 void FUN_tool_Add(TopTools_DataMapOfShapeListOfShape& map,const TopoDS_Shape& key, const TopoDS_Shape& subitem)
63 {
64   if (map.IsBound(key)) map.ChangeFind(key).Append(subitem);
65   else {TopTools_ListOfShape los; los.Append(subitem); map.Bind(key,los);}
66 }
67 static void FUN_Raise() {
68 #ifdef DEB
69   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
70   if (trc) cout<<"*** Raise REGUW"<<endl;
71 //  Standard_Failure::Raise("REGUW");
72 #endif  
73 }
74
75 //=======================================================================
76 //function : CORRISO
77 //purpose  : 
78 //=======================================================================
79
80 TopOpeBRepTool_REGUW::TopOpeBRepTool_REGUW(const TopoDS_Face& Fref)
81  : myCORRISO(Fref)
82 {  
83   myS.Nullify(); 
84   hasnewsplits = Standard_False;
85
86   myEsplits.Clear();
87   myOwNw.Clear();
88
89   mymapvEds.Clear();
90   mymapvmultiple.Clear();
91   myListVmultiple.Clear();
92
93   iStep = 0;
94 }
95
96 //=======================================================================
97 //function : Fref
98 //purpose  : 
99 //=======================================================================
100
101 const TopoDS_Face& TopOpeBRepTool_REGUW::Fref() const
102 {
103   return (myCORRISO.Fref());
104 }
105
106 //=======================================================================
107 //function : SetEsplits
108 //purpose  : 
109 //=======================================================================
110
111 void TopOpeBRepTool_REGUW::SetEsplits(TopTools_DataMapOfShapeListOfShape& Esplits)
112 {
113   myEsplits = Esplits;
114 }
115 //=======================================================================
116 //function : GetEsplits
117 //purpose  : 
118 //=======================================================================
119
120 void TopOpeBRepTool_REGUW::GetEsplits(TopTools_DataMapOfShapeListOfShape& Esplits) const 
121 {
122   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
123   Esplits = myEsplits;
124 }
125
126 //=======================================================================
127 //function : SetOwNw
128 //purpose  : 
129 //=======================================================================
130
131 void TopOpeBRepTool_REGUW::SetOwNw(TopTools_DataMapOfShapeListOfShape& OwNw)
132 {
133   myOwNw = OwNw;
134 }
135 //=======================================================================
136 //function : GetOwNw
137 //purpose  : 
138 //=======================================================================
139
140 void TopOpeBRepTool_REGUW::GetOwNw(TopTools_DataMapOfShapeListOfShape& OwNw) const
141 {
142   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
143   OwNw = myOwNw;
144 }
145
146 //=======================================================================
147 //function : SplitEds
148 //purpose  : 
149 //=======================================================================
150
151 Standard_Boolean TopOpeBRepTool_REGUW::SplitEds()
152 {
153   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
154 #ifdef DEB
155   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
156   if (trc) cout<<"**    SPLITTING EDGES    **"<<endl;
157 #endif
158
159   TopTools_IndexedMapOfShape mehasIv;
160   Standard_Integer i;
161   for (i = 1; i <= mymapvEds.Extent(); i++) {
162     const TopOpeBRepTool_connexity& co = mymapvEds(i);
163     TopTools_ListOfShape loe; Standard_Integer ni = co.IsInternal(loe);
164     if (ni == 0) continue;
165     TopTools_ListIteratorOfListOfShape ite(loe);
166     for (; ite.More(); ite.Next()) mehasIv.Add(ite.Value());
167   }
168
169   for (i = 1; i <= mehasIv.Extent(); i++) {
170     const TopoDS_Edge& e = TopoDS::Edge(mehasIv.FindKey(i));
171     TopTools_ListOfShape splits; Standard_Boolean issp = Standard_False;
172     Standard_Boolean isdone = myEsplits.IsBound(e);
173     if (isdone) splits.Assign(myEsplits.Find(e));
174     else        issp = TopOpeBRepTool_TOOL::SplitE(e,splits);
175     if (issp) hasnewsplits = Standard_True;
176 #ifdef DEB
177     if (trc) cout<<"e"<<FUN_adds(e)<<" gives splits ="<<endl;
178 #endif
179     if (!(issp || isdone)) continue; //nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnyi
180
181     // e gives splits = {esp has vertices {vv}}
182     TopTools_ListIteratorOfListOfShape ite(splits);
183     for (; ite.More(); ite.Next()){
184       const TopoDS_Shape& esp = ite.Value();
185 #ifdef DEB
186       if (trc) {cout<<" e"<<FUN_adds(esp);}
187 #endif
188       TopExp_Explorer exvv(esp, TopAbs_VERTEX);
189       for (; exvv.More(); exvv.Next()){
190         const TopoDS_Shape& vv = exvv.Current();
191         TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(vv);
192         Standard_Boolean isb = co.RemoveItem(INTERNAL,e);
193         if (!isb) continue;
194         Standard_Integer ivv = TopOpeBRepTool_TOOL::OriinSorclosed(vv,esp);
195         co.AddItem(ivv,esp);
196       }//exvv(exvv,VERTEX)
197     }//ite(splits)
198 #ifdef DEB
199     if (trc) cout<<endl;
200 #endif
201   }
202   return Standard_True;
203 }
204
205
206 //=======================================================================
207 //function : S
208 //purpose  : 
209 //=======================================================================
210
211 const TopoDS_Shape& TopOpeBRepTool_REGUW::S() const
212 {
213   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
214   return myS;
215 }
216
217 //=======================================================================
218 //function : Init
219 //purpose  : 
220 //=======================================================================
221
222 void TopOpeBRepTool_REGUW::Init(const TopoDS_Shape& S)
223 {
224   myS = S;
225   InitStep(S);
226 }
227
228 //=======================================================================
229 //function : HasInit
230 //purpose  : 
231 //=======================================================================
232
233 Standard_Boolean TopOpeBRepTool_REGUW::HasInit() const
234 {
235   return (!myS.IsNull());
236 }
237
238
239
240 //=======================================================================
241 //function : InitStep
242 //purpose  : 
243 //=======================================================================
244
245 void TopOpeBRepTool_REGUW::InitStep(const TopoDS_Shape& S)
246 {  
247   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
248   TopoDS_Shape null;myCORRISO.Init(null); myCORRISO.Init(S);
249
250   mymapvEds.Clear();
251   mymapvmultiple.Clear();
252   myListVmultiple.Clear();
253 }
254
255
256
257 //=======================================================================
258 //function : MapS
259 //purpose  : 
260 //=======================================================================
261
262 Standard_Boolean TopOpeBRepTool_REGUW::MapS()
263 {
264   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
265 #ifdef DEB
266   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
267   if (trc) cout<<"**    MAPPING    **"<<endl;
268 #endif
269   
270   // Prequesitories :
271   //        0) an edge with an INTERNAL vertex binded in <mapVedges> must be
272   //           splitted 
273   //           After splitting such edges, we deal only with FORWARD and       
274   //           REVERSED vertices.
275   //        1) a vertex belonging to a CLOSING edge is represented by 2 distinct
276   //          2d points in the UV space.
277   //        2) a vertex belonging to a  DEGENERATED edge has at least 2 UV rep.
278   //          (if the original degenerated edge has been splitted).
279   //          the bounds of the degenerated edge share the same TShape.
280   //        3) a CLOSED edge binds the same vertex oriented FORWARD and REVERSED. 
281   
282   // For each vertex get non-"singular" edges in which the vertex is oriented 
283   // FORWARD and REVERSED.
284   // <mymapvmultiple(1)> binds v and ed if : 
285   //            v is FORWARD in ed FORWARD   : oriFF(v,ed) = FORWARD
286   //            v is REVERSED in ed REVERSED : oriFF(v,ed) = FORWARD
287   // oriFF(v,ed) = (ori(ed) == FORWARD) ? ori(ed) : ori(ed).Reverse.
288   
289   // A "singular" edge is a closed, a closing or a degenerated edge.
290   // In <mymapvmultiple(5)>, we bind with the key <v>:
291   // - the FORWARD and the REVERSED CLOSING ancestor edges of <v>
292   // - the DEGENERATED ancestor edge of <v> 
293   // - the CLOSED edge ancestor edge of <v>   
294   
295   // A MULTIPLE vertex has its single UV representation's connexity > 2
296   
297   const TopoDS_Shape& CS = myCORRISO.S();
298   TopExp_Explorer exe(CS, TopAbs_EDGE);
299   for (; exe.More(); exe.Next()){
300     const TopoDS_Edge& ed = TopoDS::Edge(exe.Current());
301
302     Standard_Boolean isdgE = BRep_Tool::Degenerated(ed); 
303     Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(ed,myCORRISO.S(),Fref()); 
304     iscE = iscE && !isdgE; // closing ed
305     TopoDS_Shape vcl; Standard_Boolean isvcl = TopOpeBRepTool_TOOL::ClosedE(ed,TopoDS::Vertex(vcl)); isvcl = isvcl && !isdgE; 
306
307     TopExp_Explorer exv(ed, TopAbs_VERTEX);
308     for (; exv.More(); exv.Next()){
309       const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
310       Standard_Boolean isb = mymapvEds.Contains(v);
311       TopOpeBRepTool_connexity theconnexity(v);
312       if (!isb) mymapvEds.Add(v, theconnexity);
313       TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
314
315       if      (isdgE)                   {
316         // avoid adding it twice        
317         co.RemoveItem(CLOSING,ed);
318         co.AddItem(CLOSING,ed);   
319         break;
320       }
321       else if (iscE) {
322         // FORWARD and REVERSED edge is added
323         co.AddItem(CLOSING,ed);
324       }
325       else if (isvcl && (v.IsSame(vcl))) {              
326         // avoid adding it twice        
327         co.RemoveItem(CLOSING,ed);
328         co.AddItem(CLOSING,ed);
329       }
330       else {
331         Standard_Integer iov = TopOpeBRepTool_TOOL::OriinSor(v,ed,Standard_False); //iov != 0
332         co.AddItem(iov,ed);
333       }
334
335     }//exv    
336   }//exe
337
338 #ifdef DEB
339   if (trc) {
340     for (Standard_Integer iv = 1; iv <= mymapvEds.Extent(); iv++) {
341       const TopoDS_Vertex& v = TopoDS::Vertex(mymapvEds.FindKey(iv));
342       cout <<"#v"<<FUN_adds(v)<<" :\n";
343       const TopOpeBRepTool_connexity& co = mymapvEds(iv);
344       for (Standard_Integer i=1; i<=5; i++)    {
345         TopTools_ListOfShape eds; Standard_Integer ieds = co.Item(i,eds);
346         if (ieds == 0) continue;
347         cout<<" is ";FUN_tro(i);cout<<" in ";
348         TopTools_ListIteratorOfListOfShape ite(eds);
349         for (; ite.More(); ite.Next())
350           {const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
351            cout<<"e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
352            TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) cout<<"closed";
353            Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) cout<<"degenerated";
354            Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(e,myCORRISO.S(),Fref()); 
355            if (iscE) cout<<"closing";
356            cout<<" ";}
357         cout<<endl;     
358       }//i=1..5
359     }
360   }//trc
361 #endif
362
363   Standard_Integer nV = mymapvEds.Extent();
364   if (nV < 1) return Standard_False;
365
366   Standard_Integer i;
367   for (i = 1; i <= mymapvEds.Extent(); i++) {
368     const TopoDS_Shape& v = mymapvEds.FindKey(i);
369     const TopOpeBRepTool_connexity& co = mymapvEds(i);
370     Standard_Boolean faulty = co.IsFaulty();
371     if (faulty) return Standard_False;
372     Standard_Boolean multiple = co.IsMultiple();
373     if (multiple)
374       if (mymapvmultiple.Add(v))
375         myListVmultiple.Append(v);
376   } 
377   return Standard_True;    
378 }//MapS
379
380 static void FUN_nextdata(const Standard_Integer iStep,const TopoDS_Edge& e,const Handle(Geom2d_Curve)& pc,
381                          TopoDS_Vertex& v,gp_Pnt2d& p2d,gp_Dir2d& tg)
382 // prequesitory : pc = 2drep(e),
383 // ori(v,e)=iv1e1 -> v, p2d=pt2d(v,e), tg=tg2d(v,e).
384 {  
385   Standard_Integer iv1e1 = (iStep == 1) ? FORWARD : REVERSED;
386   TopoDS_Shape aLocalShape = TopOpeBRepTool_TOOL::Vertex(iv1e1,e);
387   v = TopoDS::Vertex(aLocalShape);
388 //  v = TopoDS::Vertex(TopOpeBRepTool_TOOL::Vertex(iv1e1,e));
389   Standard_Real par1 = TopOpeBRepTool_TOOL::ParE(iv1e1,e);
390   Standard_Boolean line = FUN_tool_line(pc);
391   Standard_Boolean quad = FUN_tool_quad(pc);// mytg2d is reapproximated if PCquad
392   Standard_Boolean approx = quad && (!line);
393   
394   gp_Vec2d tg2d; 
395   if (approx) {
396     p2d = pc->Value(par1);
397
398     Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
399     Standard_Real par0 = TopOpeBRepTool_TOOL::ParE(iv0e1,e);
400     // Getting a point near point<Index> of <E>
401     Standard_Real x = 0.2345; Standard_Real par = (1-x)*par1+x*par0;
402     gp_Pnt2d pmil; pc->D1(par,pmil,tg2d);     
403   }
404   else {
405     pc->D1(par1,p2d,tg2d);  
406   }
407   tg = gp_Dir2d(tg2d); 
408   if (M_REVERSED(e.Orientation())) tg.Reverse();
409 }
410
411 //=======================================================================
412 //function : InitBlock
413 //purpose  : 
414 //=======================================================================
415
416 Standard_Boolean TopOpeBRepTool_REGUW::InitBlock()
417 {  
418   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
419 #ifdef DEB
420   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
421 #endif
422
423   myv0.Nullify(); myp2d0=gp_Pnt2d(1.e7,1.e7); 
424   myed.Nullify();
425   Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
426
427   // updating <mymapvmultiple> and myListVmultiple
428   TopTools_ListIteratorOfListOfShape itmu(myListVmultiple);
429   while (itmu.More()) {
430     const TopoDS_Shape& vmu = itmu.Value(); 
431     const TopOpeBRepTool_connexity& cmu = mymapvEds.FindFromKey(vmu);
432     Standard_Boolean mult = cmu.IsMultiple();
433     if (!mult) {
434       myListVmultiple.Remove(itmu);
435       mymapvmultiple.Remove(vmu);
436     }
437     else itmu.Next();
438   }
439   
440   // myv0 :
441   if (myListVmultiple.IsEmpty()) {
442     Standard_Integer i;
443     for (i = 1; i <= mymapvEds.Extent(); i++) {
444       const TopoDS_Vertex& v = TopoDS::Vertex(mymapvEds.FindKey(i));
445       const TopOpeBRepTool_connexity& co = mymapvEds(i);
446       TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
447       TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
448       TopTools_ListOfShape le;  le.Append(lea); le.Append(leb); Standard_Integer ne = nea+neb;
449       if (ne != 0) {myv0 = v; break;}
450     }
451   }
452   else {
453     myv0 = TopoDS::Vertex(myListVmultiple.First());  
454   }
455   if (myv0.IsNull()) return Standard_False;
456   // myed : 
457   const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(myv0);
458    
459   TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
460   TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
461   TopTools_ListOfShape le;  le.Append(lea); le.Append(leb); Standard_Integer ne = nea+neb;
462   if (ne == 0) return Standard_False;
463
464   if (nea > 0) myed = TopoDS::Edge(le.First());
465   else {// <myv0> CLOSING in <myed>
466     TopTools_ListIteratorOfListOfShape itb(le);
467     for (; itb.More(); itb.Next()){
468       const TopoDS_Edge& eb = TopoDS::Edge(itb.Value());
469       Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(myed,myCORRISO.S(),Fref()); 
470       if (!iscE) {myed = eb; break;}
471       Standard_Integer iov0 = TopOpeBRepTool_TOOL::OriinSorclosed(myv0,myed);
472       if (iov0 != iv0e1) continue;
473     }//itb(leb)
474   }
475   if (myed.IsNull()) return Standard_False;
476
477   TopExp_Explorer exv(myed, TopAbs_VERTEX);
478   for (; exv.More(); exv.Next()){
479     const TopoDS_Shape& vcur = exv.Current();
480     TopOpeBRepTool_connexity& cco = mymapvEds.ChangeFromKey(vcur);
481 //#ifdef DEB
482 //    Standard_Boolean ok =
483 //#endif
484              cco.RemoveItem(myed);
485 //    if (!ok) return Standard_False; see for closing vertices
486   }
487
488   // myp2d0 :
489   TopOpeBRepTool_C2DF c2df;Standard_Boolean bound = myCORRISO.UVRep(myed,c2df);
490   if (!bound) return Standard_False;
491   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
492   Standard_Real par0 = TopOpeBRepTool_TOOL::ParE(iv0e1,myed);
493   pc->D0(par0,myp2d0);
494
495   // myv, myp2d, mytg2d :
496   ::FUN_nextdata(iStep,myed,pc, myv,myp2d,mytg2d);  
497
498 #ifdef DEB
499   if (trc) {
500     cout<<endl<<" v0   = v"<<FUN_adds(myv0)<<" p2d0 = ("<<myp2d0.X()<<" "<<myp2d0.Y()<<")"<<endl;
501     cout<<" vcur = v"<<FUN_adds(myv)<<"  p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<endl;
502     cout<<" ecur = e"<<FUN_adds(myed)<<endl;
503   }
504 #endif
505   return Standard_True;
506 }
507
508 //=======================================================================
509 //function : NearestE
510 //purpose  : 
511 //=======================================================================
512
513 Standard_Boolean TopOpeBRepTool_REGUW::NearestE(const TopTools_ListOfShape& loe, TopoDS_Edge& efound) const
514 {
515 #ifdef DEB
516   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
517 #endif
518
519   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
520   efound.Nullify();
521   Standard_Real fac = 0.45678;
522   Standard_Real tola = Precision::Angular();
523   Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
524
525   // initializing 
526   TopTools_ListIteratorOfListOfShape ite(loe);
527   efound = TopoDS::Edge(ite.Value());  
528   if (ite.More()) ite.Next();
529   else            return Standard_True;
530
531   TopOpeBRepTool_C2DF c2defound;Standard_Boolean isbfound = myCORRISO.UVRep(efound,c2defound);
532   if (!isbfound) return Standard_False;
533   
534   gp_Vec2d tg2dfound = TopOpeBRepTool_TOOL::tryTg2dApp(iv0e1,efound,c2defound,fac);
535   if (M_REVERSED(efound.Orientation())) tg2dfound.Reverse();
536   Standard_Real angfound = 1.e7;
537   if (iStep == 1) angfound = TopOpeBRepTool_TOOL::Matter(mytg2d,tg2dfound);
538   else            angfound = 2.*M_PI - TopOpeBRepTool_TOOL::Matter(tg2dfound,mytg2d);
539 #ifdef DEB
540   if (trc) cout<<"ang(e"<<FUN_adds(myed)<<",e"<<FUN_adds(efound)<<")="<<angfound<<endl;
541 #endif
542
543   // purpose : finding out <efound> /
544   //     ecur is given by <tg2d>
545   //     le = {ei}
546   //     iStep=1 : matterang2d(efound,ecur) = min(ei,ecur)
547   //     iStep=2 : oppomatterang2d(efound,ecur) = min(ei,ecur)
548   for (; ite.More(); ite.Next()){
549     const TopoDS_Edge& ei = TopoDS::Edge(ite.Value());
550     // for INTERNAL edge eI -> eF+eR
551     if (ei.IsSame(myed)) continue; 
552
553     TopOpeBRepTool_C2DF c2dei;Standard_Boolean isbi = myCORRISO.UVRep(ei,c2dei);
554     if (!isbi) return Standard_False;
555     gp_Vec2d tg2di = TopOpeBRepTool_TOOL::tryTg2dApp(iv0e1,ei,c2dei,fac);
556     if (M_REVERSED(ei.Orientation())) tg2di.Reverse();
557     
558     Standard_Real angi = 1.e7;
559     if (iStep == 1) angi = TopOpeBRepTool_TOOL::Matter(mytg2d,tg2di);
560     else            angi = 2.*M_PI - TopOpeBRepTool_TOOL::Matter(tg2di,mytg2d);
561     Standard_Boolean eq = Abs(angi-angfound) < tola;
562 #ifdef DEB
563     if (trc) cout<<"ang(e"<<FUN_adds(myed)<<",e"<<FUN_adds(ei)<<")="<<angi<<endl;
564 #endif
565     if (eq) {
566       FUN_Raise(); 
567       return Standard_False;
568     }
569     
570     if (angi < angfound) {efound = ei; angfound = angi;}
571   }  
572   return Standard_True;
573 }
574
575 //=======================================================================
576 //function : NextinBlock
577 //purpose  : 
578 //=======================================================================
579
580 Standard_Boolean TopOpeBRepTool_REGUW::NextinBlock()
581 {
582   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
583 #ifdef DEB
584   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
585   if (trc) cout<<endl<<" vcur = v"<<FUN_adds(myv)<<"   p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<endl;
586 #endif
587
588   Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
589   const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(myv);
590
591   // {e} : e is connexed to <myv> && ori(<myv>,e)=iv0e1
592   TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
593   TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
594   TopTools_ListOfShape le; le.Append(lea); le.Append(leb); Standard_Integer ne = nea + neb;
595
596   TopTools_ListIteratorOfListOfShape ite(le);
597   while (ite.More()) {
598     const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
599 #ifdef DEB
600     if (trc) cout<<" e"<<FUN_adds(e);
601 #endif
602
603     Standard_Boolean issame = e.IsSame(myed);
604     if (issame) {//xpu240299 FRA60275, fsp4
605 #ifdef DEB
606       if (trc) cout<<" is same : not valid"<<endl;
607 #endif
608       le.Remove(ite); continue;
609     }
610
611     TopOpeBRepTool_C2DF c2df;Standard_Boolean bound = myCORRISO.UVRep(e,c2df);
612     if (!bound) {FUN_Raise(); return Standard_False;}
613     Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
614     Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv0e1,e);
615     gp_Pnt2d p2de; pc->D0(par,p2de);
616     
617     // p2d(myv,ed)=p2d(myv,e)
618     Standard_Boolean samep2d = p2de.IsEqual(myp2d,mytol2d);
619     if (!samep2d) le.Remove(ite); 
620     else ite.Next();
621 #ifdef DEB
622     if (trc) {if (samep2d) cout<<" valid"<<endl;
623     else         cout<<" not valid"<<endl;}
624 #endif
625   }//ite(le)
626   ne = le.Extent();
627   if (ne == 0) {FUN_Raise(); return Standard_False;}
628   
629   // myed :
630   ne = le.Extent();
631   if (ne == 1) myed = TopoDS::Edge(le.First());
632   else {
633     TopoDS_Edge efound; Standard_Boolean found = NearestE(le,efound);
634     if (!found) {FUN_Raise(); return Standard_False;}
635     myed = efound;
636   }
637
638   TopExp_Explorer exv(myed, TopAbs_VERTEX);
639   for (; exv.More(); exv.Next()){
640     TopOpeBRepTool_connexity& cco = mymapvEds.ChangeFromKey(exv.Current());
641 //#ifdef DEB
642 //    Standard_Boolean ok =
643 //#endif
644              cco.RemoveItem(myed);
645 //    if (!ok) {FUN_Raise(); return Standard_False;} closed edges
646   }
647
648   TopOpeBRepTool_C2DF c2df; myCORRISO.UVRep(myed,c2df);
649   Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
650   ::FUN_nextdata(iStep,myed,pc, myv,myp2d,mytg2d);
651
652 #ifdef DEB
653   if (trc) {
654     cout<<" vcur = v"<<FUN_adds(myv)<<"  p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<endl;
655     cout<<" ecur = e"<<FUN_adds(myed)<<endl;
656   }
657 #endif
658   return Standard_True;
659 }//NextinBlock
660
661 //=======================================================================
662 //function : REGU
663 //purpose  : step <iStep> for regularization 
664 //=======================================================================
665
666 Standard_Boolean TopOpeBRepTool_REGUW::REGU(const Standard_Integer istep,
667 #ifdef DEB
668                                             const TopoDS_Shape& Scur,
669 #else
670                                             const TopoDS_Shape& ,
671 #endif
672                                             TopTools_ListOfShape& Splits)
673 {   
674   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
675   iStep = istep;
676 #ifdef DEB
677   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
678   if (trc) cout<<endl<<"**    REGU    istep=**"<<iStep<<endl;
679 #endif
680
681   Splits.Clear();
682   // A valid face is built on "valid" wires.
683   // A valid wire has for UV representation a set of 2d edges of connexity = 2.
684   
685   // Starting element is a vertex of single UV representation with connexity greater
686   // than 2.
687   // Given <v0m>, we get :
688   //  - <e1> an edge where <v0m> is oriented REVERSED(step1)/FORWARD(step2)
689   //  - <v1> the other vertex of <e1> oriented FORWARD(step1)/REVERSED(step2)
690   //  - <p2d1> is <v1>'s UV representation attached to <e1>, 
691   //  - tg2d<e1> = Tgt(p2d1,e1)  if <e1> FORWARD(step1)
692   //             = -Tgt(p2d1,e1) if <e1> is REVERSED(step1) in the face with
693   //    Tgt(p2d1,e1) = tangent to <e1>'s pcurve at point <p2d1>
694   
695   // step1 :
696   // -------
697   // Given a starting couple (<vi>, <p2di>, tg2d<e1>, <ei>) with :
698   //  - <vi> oriented FORWARD in <ei>,  
699   //  - <vi>'s 2d representation falling on an UV bound of <ei>'s pcurve (if <vi> is 
700   //    on a closing edge),
701   // We get the edge <ei+1> such that :
702   //  - <ei+1> is not already touched,
703   //  - <vi> is oriented REVERSED(step1) in <ei+1>,
704   //  - <ei+1> has an UV bound falling into geometry <p2di>.
705   //  - The oriented angle (-tg2d<ei>, tg2d<ei+1>) is the lowest,
706   // ( The angle is computed in the anti-trigonometric sense; 
707   //   the tangents's orientation are reversed if the edge is oriented REVERSED in the face )
708   //   = Smaller oriented (following trigonometric sense) angle (tg2d<ei+1>, -tg2d<ei>) 
709   //
710   // step2 :  reverse the orientations and the angle describes non-matter.
711   // -------
712   
713   // tol2d = 1.e-2*(lowest distance (p2df,p2dl) between all non-closed  
714   //                and non-degenerated pcurves seen during the regularization).
715   // This value is updated in method chkp2dFORinE.
716   // The comparision of p2d points is coupled with comparision of vertices
717   // We should in fact use bounding boxes on pcurves but this is too expensive!!!
718   mytol2d = 1.e-5;
719   isinit0 = Standard_True;
720   TopTools_ListOfShape loEcur, loW;
721
722   Standard_Integer nite = 0; 
723   Standard_Integer nE = myCORRISO.Eds().Extent();// recall myCORRISO.Init(myS);
724   TopTools_ListIteratorOfListOfShape ite(myCORRISO.Eds());
725   for (; ite.More(); ite.Next()) {
726     TopAbs_Orientation oe = ite.Value().Orientation();
727     if (M_INTERNAL(oe) || M_EXTERNAL(oe)) nE--;
728   }
729
730   while (nite <= nE) {       
731     Standard_Boolean FINI = (nite == nE);    
732
733     //*** Getting starts elements if not defined 
734     // -----------------------------------------
735     if (isinit0 && !FINI) {
736       Standard_Boolean ok = InitBlock();
737       if (!ok) {
738 #ifdef DEB
739       if (trc) cout<<"** InitBlock fails"<<endl;
740 #endif    
741         {FUN_Raise(); return Standard_False;}      
742       }
743       loEcur.Append(myed);// add it to the current wire
744       nite++;             // increment nite  
745       isinit0 = Standard_False;
746       continue;
747     } 
748
749     //*** Checking the wire is not already closed
750     // ------------------------------------------
751     // If last vertex <v> is the first one <v0> and <p2d> == <p2d0>, the wire is closed
752     Standard_Boolean wireisclosed = myp2d.IsEqual(myp2d0,mytol2d);
753     if (wireisclosed) {
754
755       //* Adding INTERNAL/EXTERNAL edges to wires
756       // ----------------------------------------      
757       TopTools_ListIteratorOfListOfShape ite1(loEcur);
758       for (; ite1.More(); ite1.Next()){
759         const TopoDS_Shape& e = ite1.Value();
760         TopExp_Explorer exv(e, TopAbs_VERTEX);
761         for (; exv.More(); exv.Next()){
762           const TopoDS_Shape& v = exv.Current();
763           TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
764           TopTools_ListOfShape& le = co.ChangeItem(INTERNAL);
765           TopTools_ListIteratorOfListOfShape itte(le);
766           while (itte.More()) {
767             const TopoDS_Shape& ee = itte.Value();
768             TopAbs_Orientation oe = ee.Orientation();
769             if (M_INTERNAL(oe) || M_EXTERNAL(oe)) {loEcur.Append(ee);le.Remove(itte);}
770             else                                  itte.Next();
771           }//itte(le)
772         }//exv(e)
773       }//ite(loEcur)
774       FINI = (nite == nE);
775             
776       // if Scur = <currentW> gives only one new wire, and has no new splitted edges, <currentW>
777       // is valid and unchanged.
778       Standard_Boolean onewok = FINI && loW.IsEmpty() && !hasnewsplits;
779       if (onewok){
780 #ifdef DEB      
781         if (trc) cout<<"wire "<<FUN_adds(Scur)<<" is found valid\n";
782 #endif
783         return Standard_True;
784       }//onewok
785
786       TopoDS_Wire newW; Standard_Boolean wiok = FUN_tool_MakeWire(loEcur, newW);
787       if (wiok) loW.Append(newW);
788       else      {
789 #ifdef DEB
790       if (trc) cout<<"** FUN_tool_MakeWire fails"<<endl;
791 #endif   
792         {FUN_Raise(); return Standard_False;} 
793       }
794 #ifdef DEB
795       if (trc) {cout<<"#->new wire = wi"<<FUN_adds(newW)<<" = ";
796                 for (TopTools_ListIteratorOfListOfShape it(loEcur); it.More(); it.Next())
797                   cout<<" e"<<FUN_adds(it.Value());
798                 cout<<"\n\n";}  
799 #endif      
800       isinit0 = Standard_True; 
801       loEcur.Clear(); 
802
803       if (FINI) {
804         Splits.Append(loW);
805         return Standard_True;
806       }
807       continue;
808     } // wireisclosed            
809     
810     //*** Iteration on UV connexed edges 
811     // ---------------------------------
812     // <v> is in <ed>, <p2d> = <v> current UV representation
813     Standard_Boolean gotonext = NextinBlock();
814     if (!gotonext) {
815 #ifdef DEB
816       if (trc) cout<<"** NextinBlock fails"<<endl;
817 #endif   
818       {FUN_Raise(); return Standard_False;}
819     }
820     loEcur.Append(myed);
821     nite++;
822   } // nite
823
824   return Standard_True;   
825 }
826
827 //=======================================================================
828 //function : REGU
829 //purpose  : complete regularization
830 //=======================================================================
831
832 Standard_Boolean TopOpeBRepTool_REGUW::REGU() 
833 {  
834   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
835   TopTools_ListOfShape null;
836
837   Standard_Boolean toregu = !myListVmultiple.IsEmpty();
838   toregu = toregu || hasnewsplits;
839   TopTools_ListOfShape Splits;
840   if (!toregu) {
841     myOwNw.Bind(S(),Splits); 
842     return Standard_True;
843   }
844
845   // iStep = 1;
846   TopTools_ListOfShape loS; Standard_Boolean ok = REGU(1,S(),loS);
847   if (!ok) {FUN_Raise(); return Standard_False;}
848
849   // iStep = 2;
850   if (loS.IsEmpty()) loS.Append(S());// no new shape
851
852   TopTools_ListIteratorOfListOfShape it(loS);
853   for (; it.More(); it.Next()){
854     const TopoDS_Shape& Scur = it.Value();
855     InitStep(Scur);
856     MapS();
857     Standard_Boolean toregu1 = !myListVmultiple.IsEmpty();
858     if (!toregu1) {Splits.Append(Scur); continue;}
859
860     TopTools_ListOfShape sp; ok = REGU(2,Scur,sp);
861     if (!ok) {FUN_Raise(); return Standard_False;}
862     if (sp.IsEmpty()) sp.Append(Scur);// no new shape
863     Splits.Append(sp);
864   }
865   myOwNw.Bind(S(),Splits);
866   return Standard_True;
867 }
868
869 //=======================================================================
870 //function : GetSplits
871 //purpose  : 
872 //=======================================================================
873
874 Standard_Boolean TopOpeBRepTool_REGUW::GetSplits(TopTools_ListOfShape& Splits) const
875 {
876   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
877   Standard_Boolean isb = myOwNw.IsBound(S());
878   if (!isb) return Standard_False;
879   Splits = myOwNw.Find(S());
880   return Standard_True;
881 }
882
883 //=======================================================================
884 //function : Connexity
885 //purpose  : 
886 //=======================================================================
887
888 Standard_Boolean TopOpeBRepTool_REGUW::Connexity(const TopoDS_Vertex& v, TopOpeBRepTool_connexity& co) const
889 {
890   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
891   Standard_Boolean isb = mymapvEds.Contains(v);
892   if (!isb) return Standard_False;
893   co = mymapvEds.FindFromKey(v);
894   return Standard_True;
895 }
896
897 //=======================================================================
898 //function : AddNewConnexity
899 //purpose  : 
900 //=======================================================================
901
902 Standard_Boolean TopOpeBRepTool_REGUW::AddNewConnexity(const TopoDS_Vertex& v, const Standard_Integer OriKey,const TopoDS_Edge& e)
903 {
904   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
905   Standard_Boolean isb = mymapvEds.Contains(v);
906   if (!isb) return Standard_False;
907
908   Standard_Boolean ok = myCORRISO.AddNewConnexity(v,e);
909   if (!ok) return Standard_False;
910
911   TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
912   co.AddItem(OriKey,e);
913
914 #ifdef DEB
915   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); 
916   if (trc) 
917     {cout<<"** setting new connexity : v"<<FUN_adds(v)<<" is ";FUN_tro(OriKey);
918      cout<<" in "<<" e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
919      TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) cout<<" closed";
920      Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) cout<<" degenerated";cout<<endl;}
921 #endif
922   return Standard_True;  
923 }
924
925 //=======================================================================
926 //function : RemoveOldConnexity
927 //purpose  : 
928 //=======================================================================
929
930 Standard_Boolean TopOpeBRepTool_REGUW::RemoveOldConnexity(const TopoDS_Vertex& v, const Standard_Integer OriKey,const TopoDS_Edge& e)
931 {
932   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
933   Standard_Boolean isb = mymapvEds.Contains(v);
934   if (!isb) return Standard_False;
935
936   Standard_Boolean ok = myCORRISO.RemoveOldConnexity(v,e);
937 //  if (!ok) return Standard_False;
938
939   TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
940   ok = co.RemoveItem(OriKey,e);
941   if (!ok) return Standard_False;
942
943 #ifdef DEB
944   Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA(); 
945   if (trc) 
946     {cout<<"** removing old connexity : v"<<FUN_adds(v)<<" for e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
947      TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) cout<<" closed";
948      Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) cout<<" degenerated";cout<<endl;}
949 #endif
950   return Standard_True;  
951 }
952   
953 //=======================================================================
954 //function : UpdateMultiple
955 //purpose  : 
956 //=======================================================================
957
958 Standard_Boolean TopOpeBRepTool_REGUW::UpdateMultiple(const TopoDS_Vertex& v)
959 {
960   if (!HasInit()) Standard_Failure::Raise("TopOpeBRepTool_REGUW : NO INIT");
961   Standard_Boolean isb = mymapvEds.Contains(v);
962   if (!isb) return Standard_False;
963   const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(v);
964   Standard_Boolean ismult = co.IsMultiple();
965   if (ismult)
966     if (mymapvmultiple.Add(v))
967       myListVmultiple.Append(v);
968   return Standard_True;
969   
970 }