ca817bc2896052facddaf22edca3577e886461a9
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_PURGE.cxx
1 // File:        TopOpeBRepTool_PURGE.cxx
2 // Created:     Thu Nov 13 13:45:48 1997
3 // Author:      Xuan PHAM PHU
4 //              <xpu@poulopox.paris1.matra-dtv.fr>
5
6 #include <TopOpeBRepTool.hxx>
7 #include <TopOpeBRepTool_TOOL.hxx>
8 #include <TopOpeBRepTool_CORRISO.hxx>
9 #include <TopOpeBRepTool_C2DF.hxx>
10 #include <gp_Pnt2d.hxx>
11 #include <gp_Vec2d.hxx>
12 #include <GeomAdaptor_Surface.hxx>
13 #include <Geom2d_Curve.hxx>
14 #include <Geom2d_TrimmedCurve.hxx>
15 #include <Geom2d_Line.hxx>
16 #include <Geom_Surface.hxx>
17 #include <TopoDS.hxx>
18 #include <TopoDS_Wire.hxx>
19 #include <TopTools_Array1OfShape.hxx>
20
21 #include <BRep_Tool.hxx>
22 #include <Precision.hxx>
23 #include <TopExp.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <BRep_Builder.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <TopOpeBRepTool_define.hxx>
28 #include <TopOpeBRepTool_EXPORT.hxx>
29 #include <TopOpeBRepTool_2d.hxx>
30 #include <Standard_Failure.hxx>
31 #include <TopOpeBRepTool_PURGE.hxx>
32
33 #ifdef DEB
34 //Standard_EXPORT Standard_Integer STATIC_PURGE_iwi = 0;
35 //Standard_EXPORT TopTools_IndexedMapOfShape STATIC_PURGE_mapw, STATIC_PURGE_mapv;
36 //Standard_EXPORT TopTools_IndexedMapOfOrientedShape STATIC_PURGE_mapeds, STATIC_CORR_mapeds;
37
38 Standard_EXPORT void debcorrUV(){};
39 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettracePURGE();
40 Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceCORRISO();
41 #endif
42 // DEB
43
44 // Unused :
45 #ifdef DEB
46 static void FUN_RaiseError()
47 {
48 #ifdef DEB
49   Standard_Boolean trc = TopOpeBRepTool_GettracePURGE();
50   //  Standard_Failure::Raise("TopOpeBRepTool::PurgeClosingEdges");
51   FUN_REINIT(); 
52   if (trc) cout <<"*********failure in TopOpeBRepTool::PurgeClosingEdges***********\n";
53 #endif
54 }
55 static void FUN_Raise()
56 {
57 #ifdef DEB
58   //  cout <<"*********failure in TopOpeBRepTool::CorrectONUVISO***********\n";
59   //  Standard_Failure::Raise("TopOpeBRepTool::CorrectONUVISO");
60 #endif
61 }
62 #endif
63
64 #define SPLITEDGE (0)
65 #define INCREASE  (1)
66 #define DECREASE (-1)
67
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 static void FUN_addtomap(TopTools_DataMapOfShapeListOfShape& map, const TopoDS_Shape& key, const TopoDS_Shape& item)
74 {
75   if (map.IsBound(key))               map.ChangeFind(key).Append(item);
76   else {TopTools_ListOfShape los; los.Append(item); map.Bind(key,los);}
77 }
78
79 static Standard_Boolean FUN_getv(const TopAbs_Orientation& orivine, const TopoDS_Shape& e, TopoDS_Shape& v)
80 {
81   v.Nullify();
82   // gets <v> oriented <orivine> in <e>
83   TopAbs_Orientation oe = e.Orientation();
84   Standard_Boolean isnonO = M_INTERNAL(oe) || M_EXTERNAL(oe);
85   TopoDS_Shape eO;
86   if (isnonO) {
87     eO = e.Oriented(TopAbs_FORWARD);
88   }
89   else {
90     eO = e;
91   }
92   TopExp_Explorer exv(eO, TopAbs_VERTEX);
93   for (; exv.More(); exv.Next()) {      
94     const TopoDS_Shape& vcur = exv.Current();
95     if (vcur.Orientation() == orivine) {v = vcur; return Standard_True;}    
96   } // exv
97   return Standard_False;
98 }
99
100 Standard_EXPORT Standard_Boolean FUN_tool_ClosedW(const TopoDS_Wire& W)
101 {
102   // !! an edge oriented INTERNAL/EXTERNAL has all its vertices
103   // oriented INTERNAL/EXTERNAL.
104
105   // <mapvedsO> = {(v,loe)} / e is oriented :
106   // <mapvedsO> = {(v,loe)} / e is not oriented (INTERNAL/EXTERNAL) :
107   TopTools_DataMapOfShapeListOfShape mapvFine,mapvRine, mapvIine;
108
109   TopExp_Explorer exe(W, TopAbs_EDGE);
110   for (; exe.More(); exe.Next()){
111     const TopoDS_Shape& e = exe.Current();
112     TopAbs_Orientation oe = e.Orientation();
113     Standard_Boolean isnonO = M_INTERNAL(oe) || M_EXTERNAL(oe);
114     TopoDS_Shape eO;
115     if (isnonO) {
116       eO = e.Oriented(TopAbs_FORWARD);
117     }
118     else {
119       eO = e;
120     }
121
122     TopExp_Explorer exv(eO, TopAbs_VERTEX); 
123     for (; exv.More(); exv.Next()) {    
124       const TopoDS_Shape& v = exv.Current();
125       TopAbs_Orientation oriv = v.Orientation();
126       if (M_FORWARD(oriv))  FUN_addtomap(mapvFine,v,e);
127       if (M_REVERSED(oriv)) FUN_addtomap(mapvRine,v,e);
128       if (M_INTERNAL(oriv)) FUN_addtomap(mapvIine,v,e);
129     }      
130   }
131
132   if (mapvFine.Extent() == 0) return Standard_False;   // empty wire  
133
134   TopTools_MapOfShape mapvok;    
135   // a vertex is found valid if is - an internal vertex
136   //                               - found FORWARD and REVERSED. 
137   TopTools_MapOfShape mapvonlyFine; // {(v,e)} v F in e, v belongs to only one e
138   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itvFine(mapvFine);
139   for (; itvFine.More(); itvFine.Next()){
140     const TopoDS_Shape& vFine = itvFine.Key();
141 #ifdef DEB
142     const TopTools_ListOfShape& edsvFine =
143 #endif
144                              itvFine.Value();
145     Standard_Boolean vIine = mapvIine.IsBound(vFine);
146     if (vIine) {mapvok.Add(vFine); continue;}
147     Standard_Boolean vRine = mapvRine.IsBound(vFine);
148     if (vRine) {mapvok.Add(vFine); continue;}
149     mapvonlyFine.Add(vFine);
150   }  
151   // <mapvRinonee> = {(v,e)} v R in e, v belongs to only one e
152   TopTools_MapOfShape mapvonlyRine; 
153   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itvRine(mapvRine);
154   for (; itvRine.More(); itvRine.Next()){
155     const TopoDS_Shape& vRine = itvRine.Key();
156 #ifdef DEB
157     const TopTools_ListOfShape& edsvRine =
158 #endif
159                              itvRine.Value();
160     Standard_Boolean vok = mapvok.Contains(vRine);
161     if (vok) continue;
162     Standard_Boolean vIine = mapvIine.IsBound(vRine);
163     if (vIine) {mapvok.Add(vRine); continue;}    
164     mapvonlyRine.Add(vRine);
165   }
166   
167   // checking vertices <mapvonlyFine> and <mapvonlyRine>
168   TopTools_MapIteratorOfMapOfShape itvonlyFRine;
169   Standard_Integer nmap = 0;
170   while (nmap <= 2) {
171     nmap++;
172     Standard_Boolean vFine = (nmap == 1);
173     if (vFine) itvonlyFRine.Initialize(mapvonlyFine);
174     else       itvonlyFRine.Initialize(mapvonlyRine);
175
176     for (; itvonlyFRine.More(); itvonlyFRine.Next()){
177       const TopoDS_Shape& vtocheck = itvonlyFRine.Key();
178       TopTools_ListOfShape edsvFRine;
179       if (vFine) edsvFRine = mapvFine.Find(vtocheck);
180       else       edsvFRine = mapvRine.Find(vtocheck);
181        
182       if (edsvFRine.Extent() > 1) return Standard_False; // faulty wire
183       const TopoDS_Shape& e = edsvFRine.First();
184
185       TopAbs_Orientation ovori = vFine? TopAbs_REVERSED: TopAbs_FORWARD;
186       TopoDS_Shape ov; Standard_Boolean ovfound = FUN_getv(ovori,e,ov);
187       if (!ovfound) return Standard_False; // faulty edge
188
189       // <vtocheck> is on only one edge <e>,
190       // <vtocheck> is FORWARD/REVERSED in <e>,
191       // <ovfound> is REVERSED/FORWARD in <e>.
192       // <vtocheck> is ok if : - <ovfound> is INTERNAL in another edge
193       //                       - <ovfound> is FORWARD and REVERSED in 
194       //                         one or two other edges.
195       //                      and e is not oriented
196       TopAbs_Orientation oe = e.Orientation();
197       if (M_FORWARD(oe) || M_REVERSED(oe)) return Standard_False;
198       if (!mapvok.Contains(ov)) return Standard_False;
199
200       Standard_Boolean ovIine = mapvIine.IsBound(ov); if (ovIine)  continue;
201       Standard_Boolean ovFine = mapvRine.IsBound(ov); if (!ovFine) return Standard_False;
202       Standard_Boolean ovRine = mapvRine.IsBound(ov); if (!ovRine) return Standard_False;
203     
204       const TopTools_ListOfShape& edsovFine = mapvFine.Find(ov);
205       const TopTools_ListOfShape& edsovRine = mapvRine.Find(ov);
206       if (edsovFine.Extent() > 1) continue;
207       if (edsovRine.Extent() > 1) continue;
208       if (edsovFine.First().IsEqual(e)) return Standard_False;
209       if (edsovRine.First().IsEqual(e)) return Standard_False;
210     }
211   } // nmap
212   return Standard_True; 
213 }
214
215 //=======================================================================
216 //function : PurgeClosingEdges
217 //purpose  : 
218 //=======================================================================
219
220 Standard_Boolean TopOpeBRepTool::PurgeClosingEdges(const TopoDS_Face& Fin, const TopoDS_Face& FF, 
221 //                                    const TopTools_DataMapOfShapeInteger& MWisOld,
222                                       const TopTools_DataMapOfShapeInteger& ,
223                                       TopTools_IndexedMapOfOrientedShape& MshNOK)
224 {
225   // Fin is the original face
226   // FF  is the splitted face
227
228   // prequesitory : splitted edges, of edge ancestor a closing edge
229   //                keep in memory the geometry of the ancestor edge,
230   //                they answer True to BRep_Tool::IsClosed.
231   // elsewhere : we have to get this information using geometric 
232   //             criteriums (TopOpeBRepTool_TOOL::IsonCLO)
233
234 #ifdef DEB
235   Standard_Boolean trc =  TopOpeBRepTool_GettracePURGE();
236   if (trc) cout<<"\n* PurgeClosingEdges:\n\n";
237 #endif
238   TopOpeBRepTool_CORRISO CORRISO(Fin);  
239   Standard_Real tolF = BRep_Tool::Tolerance(Fin);
240   Standard_Real uperiod; Standard_Boolean uclosed = CORRISO.Refclosed(1,uperiod);
241   Standard_Real vperiod; Standard_Boolean vclosed = CORRISO.Refclosed(2,vperiod);
242   if (!uclosed && !vclosed) return Standard_False;
243   Standard_Boolean inU = uclosed ? Standard_True : Standard_False;  
244   Standard_Real xmin = inU ? (CORRISO.GASref().FirstUParameter()) :
245                              (CORRISO.GASref().FirstVParameter());
246   Standard_Real xper = inU ? uperiod : vperiod;
247   Standard_Real tolx = inU ? (CORRISO.Tol(1,tolF)) : (CORRISO.Tol(2,tolF));
248
249   TopExp_Explorer exw(FF, TopAbs_WIRE);
250   for (; exw.More(); exw.Next()){
251     const TopoDS_Shape& W = exw.Current();
252
253     CORRISO.Init(W);
254     Standard_Boolean ok = CORRISO.UVClosed();
255     if (ok) continue;
256
257     TopTools_ListOfShape cEds; 
258     TopTools_ListIteratorOfListOfShape ite(CORRISO.Eds());
259     for (; ite.More(); ite.Next()){
260       const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
261       Standard_Boolean closing = BRep_Tool::IsClosed(E,Fin); 
262       if (!closing) {// xpu231198 : pcurve modified, the information is lost
263         TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = CORRISO.UVRep(E,C2DF);
264         if (!isb) return Standard_False;//NYIRAISE
265         Standard_Boolean onclo = TopOpeBRepTool_TOOL::IsonCLO(C2DF,inU,xmin,xper,tolx);
266         if (onclo) closing=Standard_True;
267       }
268       if (closing) cEds.Append(E);
269     }          
270     Standard_Integer ncE = cEds.Extent();
271     Standard_Boolean nopurge = (ncE <= 1);
272     if (nopurge) return Standard_True;
273     
274     // Checking <W>
275     TopTools_ListOfShape fyEds; Standard_Boolean topurge = CORRISO.PurgeFyClosingE(cEds,fyEds);
276     if (topurge) {
277       TopTools_ListIteratorOfListOfShape it(fyEds);
278       for (; it.More(); it.Next()) MshNOK.Add(it.Value()); 
279       MshNOK.Add(W); 
280       MshNOK.Add(FF);
281     }
282     
283 #ifdef DEB
284     if (trc && topurge) cout<<"found FAULTY edge = ed"<<endl;
285 #endif
286   } // exw
287   return Standard_True;
288 }
289
290 //=======================================================================
291 //function : PurgeClosingEdges
292 //purpose  : 
293 //=======================================================================
294
295 Standard_Boolean TopOpeBRepTool::PurgeClosingEdges(const TopoDS_Face& Fin, const TopTools_ListOfShape& LOF, 
296                                       const TopTools_DataMapOfShapeInteger& MWisOld,
297                                       TopTools_IndexedMapOfOrientedShape& MshNOK)
298 {  
299   Standard_Boolean uvclosed = FUN_tool_closedS(Fin);
300   if (!uvclosed) return Standard_True;
301   
302   TopTools_ListIteratorOfListOfShape it(LOF);
303   for (; it.More(); it.Next()){
304     const TopoDS_Face& FF = TopoDS::Face(it.Value());
305     Standard_Boolean ok = TopOpeBRepTool::PurgeClosingEdges(Fin,FF,MWisOld,MshNOK);
306     if (!ok) return Standard_False;    
307   }
308   return Standard_True;
309 }
310
311 /*static Standard_Boolean FUN_correctClosingE(TopoDS_Edge& newfE, TopoDS_Face& Fsp)
312 {    
313   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(newfE,Fsp,f,l,tol);
314   gp_Dir2d d2d; gp_Pnt2d O2d; Standard_Boolean isuiso,isviso; 
315   Standard_Boolean uviso = FUN_tool_IsUViso(PC,isuiso,isviso,d2d,O2d);
316   if (!uviso) return Standard_False;
317
318   Standard_Real period = 2*M_PI;
319   Standard_Real piso = isuiso? O2d.X(): O2d.Y();
320   Standard_Real tol2d = 1.e-6;
321   Standard_Boolean is0   = Abs(piso) < tol2d;
322   Standard_Boolean is2PI = Abs(period-piso) < tol2d;
323   // --------------------------------------------------
324   //  prequesitory :  Closed Surfaces have period 2PI
325   if (!is0 && !is2PI) return Standard_False;
326   // -------------------------------------------------- 
327   Standard_Real factor = is0? period: -period;
328   gp_Vec2d transl(1.,0.); if (isviso) transl = gp_Vec2d(0.,1.);
329   transl.Multiply(factor);
330   
331   Standard_Integer ok = FUN_tool_translate(transl,Fsp,newfE);
332   return Standard_True;   
333 }
334
335 static Standard_Boolean FUN_correctDegeneratedE
336 (const TopTools_IndexedDataMapOfShapeListOfShape& mve,TopoDS_Edge& Ein,TopoDS_Face& Fsp)
337 {
338   TopoDS_Vertex v1,v2; TopExp::Vertices(Ein,v1,v2);
339   TopAbs_Orientation ov1 = v1.Orientation();
340   TopAbs_Orientation ov2 = v2.Orientation();
341   Standard_Boolean ok1 = mve.Contains(v1); if (!ok1) return Standard_False;
342   Standard_Boolean ok2 = mve.Contains(v2); if (!ok2) return Standard_False;
343
344   const TopTools_ListOfShape& le= mve.FindFromKey(v1);
345
346   TopoDS_Edge e1,e2; Standard_Boolean fe1 = Standard_False; Standard_Boolean fe2 = Standard_False;
347   TopoDS_Vertex vfe1,vfe2;
348   Standard_Boolean fEin = Standard_False;
349   for(TopTools_ListIteratorOfListOfShape itle(le);itle.More();itle.Next()) {
350     const TopoDS_Shape& ecx = TopoDS::Edge(itle.Value());
351     if (ecx.IsEqual(Ein)) {
352       fEin = Standard_True;
353     }
354     else {
355       TopExp_Explorer exv;
356       for (exv.Init(ecx,TopAbs_VERTEX);exv.More();exv.Next()) {
357 //      for (TopExp_Explorer exv(ecx,TopAbs_VERTEX);exv.More();exv.Next()) {
358         const TopoDS_Vertex& vecx = TopoDS::Vertex(exv.Current());
359         Standard_Boolean issam = vecx.IsSame(v1);
360         if (issam) { 
361           Standard_Boolean iseq1 = vecx.IsEqual(v1);
362           Standard_Boolean iseq2 = vecx.IsEqual(v2);
363           if (!iseq1) {
364             e1 = TopoDS::Edge(ecx);
365             vfe1 = TopoDS::Vertex(vecx); 
366             fe1 = Standard_True;
367           }
368           if (!iseq2) {
369             e2 = TopoDS::Edge(ecx);
370             vfe2 = TopoDS::Vertex(vecx); 
371             fe2 = Standard_True;
372           }
373         }
374         if (fe1 && fe2) break;
375       }
376       if (fe1 && fe2) break;
377     }
378     if (fEin && fe1 && fe2) break;
379   } // itle.More()
380
381   Standard_Boolean ok = (fEin && fe1 && fe2);
382   if (!ok) return Standard_False;
383   
384 #ifdef DEB
385   debcorrUV(); // call Draw_Call("av2d;dy fyf;fit;ppcu fyf")
386 #endif
387
388   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(Ein,Fsp,f,l,tol);
389   gp_Dir2d d2d; gp_Pnt2d O2d; Standard_Boolean isuiso = 0,isviso = 0; 
390   Standard_Boolean uviso = FUN_tool_IsUViso(PC,isuiso,isviso,d2d,O2d);
391   if (!uviso) return Standard_False;
392
393   Standard_Real pfEin,plEin,tolEin; Handle(Geom2d_Curve) PCEin = FUNTOOLC2D_CurveOnSurface(Ein,Fsp,pfEin,plEin,tolEin); 
394   if (PCEin.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve Ein");
395   Standard_Real pf1,pl1,tol1; Handle(Geom2d_Curve) PC1 = FUNTOOLC2D_CurveOnSurface(e1,Fsp,pf1,pl1,tol1); 
396   if (PC1.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve e1");
397   Standard_Real pf2,pl2,tol2; Handle(Geom2d_Curve) PC2 = FUNTOOLC2D_CurveOnSurface(e2,Fsp,pf2,pl2,tol2); 
398   if (PC2.IsNull()) Standard_Failure::Raise(" FUN_correctDegeneratedE : no 2d curve e2");
399   
400   Standard_Real parv1 = BRep_Tool::Parameter(v1,Ein,Fsp);
401   Standard_Real parv2 = BRep_Tool::Parameter(v2,Ein,Fsp);
402   gp_Pnt2d  pv1; PCEin->D0(parv1,pv1);
403   gp_Pnt2d  pv2; PCEin->D0(parv2,pv2);
404
405   Standard_Real par1 = BRep_Tool::Parameter(vfe1,e1,Fsp);
406   Standard_Real par2 = BRep_Tool::Parameter(vfe2,e2,Fsp);
407   gp_Pnt2d  p1; PC1->D0(par1,p1);
408   gp_Pnt2d  p2; PC2->D0(par2,p2);
409
410   Standard_Real cv1 = (isuiso) ? pv1.Y() : pv1.X();
411   Standard_Real cv2 = (isuiso) ? pv2.Y() : pv2.X();
412   Standard_Real c1 = (isuiso) ? p1.Y() : p1.X();
413   Standard_Real c2 = (isuiso) ? p2.Y() : p2.X();
414
415   Standard_Real d1 = (c1 - cv1);
416   Standard_Real d2 = (c2 - cv2);
417   Standard_Real adc = Abs(c1 - c2);
418   Standard_Real adcv = Abs(cv1 - cv2);
419
420   Standard_Real tol2d = 1.e-6;
421   Standard_Boolean mmd = (Abs(adc-adcv) < tol2d);
422   if (mmd) { // correction de CTS20973
423     gp_Vec2d transl(0.,1.); if (isviso) transl = gp_Vec2d(1.,0.);
424     transl.Multiply(d1); // ou d2
425     ok = FUN_tool_translate(transl,Fsp,Ein);
426   }
427   else {
428     // redefinition des parametres de v1,v2 de Ein tels que des parametres de 
429 #ifdef DEB
430     if (TopOpeBRepTool_GettraceCORRISO()) {
431       cout<<"FUN_correctDegeneratedE : !mmd NYI"<<endl;
432     }
433 #endif
434     ok = Standard_False;
435   }
436   
437   return ok;   
438 } //FUN_correctDegeneratedE*/
439
440 /*static Standard_Boolean FUN_tool_reguUV(const TopoDS_Face& FF, TopoDS_Face& fF)
441 {  
442
443   const TopoDS_Face& F = TopoDS::Face(FF);
444   Standard_Boolean uclosed,vclosed; Standard_Real uperiod,vperiod;
445   Standard_Boolean closed = FUN_tool_closedS(F,uclosed,uperiod,vclosed,vperiod);
446   if (!closed) return Standard_False;    
447   Standard_Real tolu,tolv; FUN_tool_tolUV(TopoDS::Face(fF),tolu,tolv);
448
449   TopTools_ListOfShape leko;
450   // --------
451   TopTools_IndexedMapOfOrientedShape mape;
452   TopExp_Explorer ex(fF, TopAbs_EDGE);
453   for (; ex.More(); ex.Next()){
454     const TopoDS_Edge& ee = TopoDS::Edge(ex.Current());
455     TopAbs_Orientation oee = ee.Orientation();
456     TopAbs_Orientation oe = TopAbs::Complement(oee);
457     TopoDS_Edge e = TopoDS::Edge(ee.Oriented(oe));
458     Standard_Boolean hasoppo = mape.Contains(e); // e with complement ori was added to mape
459     if (hasoppo) {
460       // ee :
461       Standard_Real ff,ll; Handle(Geom2d_Curve) PCee = BRep_Tool::CurveOnSurface(ee,F,ff,ll);
462       Standard_Boolean uisoee,visoee; gp_Dir2d d2dee; gp_Pnt2d O2dee; 
463       Standard_Boolean uvisoee = FUN_tool_IsUViso(PCee,uisoee,visoee,d2dee,O2dee);
464       // e :
465       Standard_Real f,l; Handle(Geom2d_Curve) PCe = BRep_Tool::CurveOnSurface(e,F,f,l);
466       Standard_Boolean uisoe,visoe; gp_Dir2d d2de; gp_Pnt2d O2de; 
467       Standard_Boolean uvisoe = FUN_tool_IsUViso(PCe,uisoe,visoe,d2de,O2de);
468
469       // isfaulty :
470       Standard_Boolean isfaulty = Standard_False;
471       Standard_Real dd = O2dee.Distance(O2de);
472       if (uisoee && uisoe) isfaulty = (dd < tolu);
473       if (visoee && visoe) isfaulty = (dd < tolv);
474
475       if (isfaulty) leko.Append(ee);
476     }
477     else mape.Add(ee);
478   }
479   
480   Standard_Integer nko = leko.Extent();
481   if (nko != 1) return Standard_False;
482
483   // eko = edge with faulty pcurve :
484   const TopoDS_Shape& eko = leko.First();
485   TopAbs_Orientation oeko = eko.Orientation();
486   TopTools_ListOfShape edges; ex.Init(fF, TopAbs_EDGE);
487   for (; ex.More(); ex.Next()){
488     const TopoDS_Shape& ee = ex.Current();
489     if (!ee.IsSame(eko)) edges.Append(ee);
490   }    
491   // fe = edge with vfe = vertex(ivfe) not uv-connexed :
492   TopoDS_Shape fe; Standard_Integer ivfe=0; 
493   Standard_Boolean det = ::FUN_DetectEdgewithfaultyUV(FF,fF,edges,Standard_False,fe,ivfe);
494   if (!det) return Standard_False;
495
496   TopTools_Array1OfShape Vfe(1,2); FUN_Vertices(TopoDS::Edge(fe),Vfe); 
497   TopAbs_Orientation ofe = fe.Orientation(); 
498   const TopoDS_Vertex& vfe = TopoDS::Vertex(Vfe(ivfe));
499   Standard_Real parfe = BRep_Tool::Parameter(vfe,TopoDS::Edge(fe));
500   gp_Pnt2d uvfe; Standard_Boolean ok = FUN_tool_paronEF(TopoDS::Edge(fe),parfe,F,uvfe);
501   if (!ok) return Standard_False;
502   // ivconnex :
503   Standard_Integer ivconnex = (ivfe == 1) ? 2 : 1;
504 //  if (ofe == TopAbs_REVERSED) ivconnex = (ivconnex == 1) ? 2 : 1;
505   
506   // vertex(ivconnex) of eko FORWARD
507   TopoDS_Edge ekoFOR = TopoDS::Edge(eko.Oriented(TopAbs_FORWARD));
508   TopTools_Array1OfShape Veko(1,2); FUN_Vertices(TopoDS::Edge(ekoFOR),Veko);  
509   const TopoDS_Vertex& veko1 = TopoDS::Vertex(Veko(1));
510   const TopoDS_Vertex& veko2 = TopoDS::Vertex(Veko(2));
511   Standard_Integer iveko = 0;
512   if (veko1.IsSame(vfe)) iveko = 1;
513   if (veko2.IsSame(vfe)) iveko = 2;
514   if (iveko == 0) return Standard_False;
515
516   // ett : edge same eko with pcurve to translate
517   // isekoFOR=true : vfe should be connexed to vertex(ivconnex) of ekoFOR
518   Standard_Boolean isekoFOR = (iveko == ivconnex); 
519   TopAbs_Orientation oett = isekoFOR ? TopAbs_FORWARD : TopAbs_REVERSED; 
520   TopoDS_Edge ett = TopoDS::Edge(eko.Oriented(oett));
521   const TopoDS_Vertex& vtt = TopoDS::Vertex(Veko(iveko));
522
523   Standard_Real parett = BRep_Tool::Parameter(vtt,ett);
524   gp_Pnt2d uvtt; ok = FUN_tool_paronEF(ett,parett,F,uvtt);
525   if (!ok) return Standard_False;
526   
527   Standard_Real du = uvfe.X()-uvtt.X(); 
528   Standard_Real dv = uvfe.Y()-uvtt.Y(); 
529   Standard_Boolean tru=Standard_False, trv=Standard_False;
530   if (uclosed) tru = (Abs(Abs(du)-uperiod) < tolu);
531   if (vclosed) trv = (Abs(Abs(dv)-vperiod) < tolv);
532   if (!tru && !trv) return Standard_False;
533
534   gp_Vec2d tt;
535   if (tru) tt = gp_Vec2d(du,0.);
536   if (trv) tt = gp_Vec2d(0.,dv);
537   Standard_Real f,l; Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface(ett,F,f,l);
538   Standard_Boolean uisoett,visoett; gp_Dir2d d2dett; gp_Pnt2d o2dett; 
539   Standard_Boolean uvisoett = FUN_tool_IsUViso(PC1,uisoett,visoett,d2dett,o2dett);o2dett.Translate(tt);
540   Handle(Geom2d_Line) L2d = new Geom2d_Line(o2dett,d2dett);
541   Handle(Geom2d_TrimmedCurve) PC2 = new Geom2d_TrimmedCurve(L2d,f,l);
542
543   BRep_Builder BB;
544   Standard_Real toltt = BRep_Tool::Tolerance(ett);
545 //  BB.UpdateEdge(TopoDS::Edge(ett),PC2,PC1,fF,toltt);
546   // xpu220998 : cto cylcong A1
547   Handle(Geom2d_Curve) nullc2d;
548   BB.UpdateEdge(TopoDS::Edge(ekoFOR),nullc2d,nullc2d,fF,toltt); // clear
549   if (isekoFOR) BB.UpdateEdge(TopoDS::Edge(ekoFOR),PC2,PC1,fF,toltt);
550   else          BB.UpdateEdge(TopoDS::Edge(ekoFOR),PC1,PC2,fF,toltt);
551
552   return Standard_True;
553 }*/
554
555 static Standard_Boolean FUN_connexX(const Standard_Boolean onU, TopOpeBRepTool_CORRISO& CORRISO, 
556                        const TopTools_ListOfShape& EdstoCheck, TopTools_DataMapOfOrientedShapeInteger& fyEds)
557 // purpose : Fref is x-periodic, 
558 //           <fyEds>={(fye,recadre)}, recadre = INCREASE,DECREASE
559 //                                    fye has its 2 bounds faulty
560 {
561   fyEds.Clear();
562   Standard_Real tolF = BRep_Tool::Tolerance(CORRISO.Fref());
563   Standard_Integer Index = onU ? 1 : 2;
564   Standard_Real xperiod; Standard_Boolean xclosed = CORRISO.Refclosed(Index,xperiod);
565   if (!xclosed) return Standard_False;
566   Standard_Real xtol = CORRISO.Tol(Index,tolF);
567   
568   // fy has its 2 uvbounds non-connexed       
569   //nyixpu300998 : iterative (while ko) + map of "static" edges
570   TopoDS_Shape fy; Standard_Integer Ify=0; Standard_Boolean hasfy = CORRISO.EdgeWithFaultyUV(EdstoCheck,2,fy,Ify); 
571   if (!hasfy) return Standard_False;
572   TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = CORRISO.UVRep(TopoDS::Edge(fy),C2DF);
573   if (!isb) return Standard_False; // NYIRAISE
574
575   TopTools_Array1OfShape vfy(1,2); TopOpeBRepTool_TOOL::Vertices(TopoDS::Edge(fy),vfy);
576   for (Standard_Integer ii = 1; ii <=2; ii++) {
577     // vff = vertex[ii] of fy
578     const TopoDS_Vertex& vff = TopoDS::Vertex(vfy(ii));
579     Standard_Real parvff = TopOpeBRepTool_TOOL::ParE(ii,TopoDS::Edge(fy));gp_Pnt2d uvff = TopOpeBRepTool_TOOL::UVF(parvff,C2DF);
580     // loe list of edges connexed to faultE
581     TopTools_ListOfShape loe; isb = CORRISO.Connexity(vff,loe);
582     if (!isb) return Standard_False; // FUNRAISE
583
584     TopTools_ListIteratorOfListOfShape ite(loe); // iteration on connex edges of vff
585     for (; ite.More(); ite.Next()){
586       const TopoDS_Edge& ee = TopoDS::Edge(ite.Value());
587       TopTools_Array1OfShape vee(1,2); TopOpeBRepTool_TOOL::Vertices(ee,vee);
588       for (Standard_Integer ive = 1; ive <=2; ive++) {    
589         // ve = vertex[ive] of ee
590         const TopoDS_Vertex& ve = TopoDS::Vertex(vee(ive));       
591         Standard_Boolean samev = ve.IsSame(vff);
592         if (!samev) continue;   
593         if (ive == ii) continue;
594         TopOpeBRepTool_C2DF C2DFe; isb = CORRISO.UVRep(ee,C2DFe);
595         if (!isb) return Standard_False; // FUNRAISE
596         Standard_Real paree = TopOpeBRepTool_TOOL::ParE(ive,ee); gp_Pnt2d uve = TopOpeBRepTool_TOOL::UVF(paree,C2DFe);  
597         
598         // xxtrsl :
599         Standard_Real dxx = onU ? uve.X()-uvff.X() : uve.Y()-uvff.Y();
600         Standard_Boolean isper =( Abs(xperiod-Abs(dxx)) < xtol);
601         if (!isper) continue;
602         
603         Standard_Integer recadre = (dxx > 0) ? INCREASE : DECREASE; 
604         fyEds.Bind(fy,recadre);
605       } //ive=1..2
606     }//ite(loe)
607   }//ii=1..2    
608   return !fyEds.IsEmpty();
609 } // FUN_connexX
610  
611 //=======================================================================
612 //function : CorrectONUVISO
613 //purpose  :  
614 //=======================================================================
615
616 Standard_Boolean TopOpeBRepTool::CorrectONUVISO(const TopoDS_Face& Fin, TopoDS_Face& Fsp)
617 // <Fref> is x-periodic 
618 {
619 #ifdef DEB
620   Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
621   if (trc) cout<<"\n####    CorrectONUVISO    ####\n\n";
622   debcorrUV();
623 #endif
624
625   Standard_Real tolF = BRep_Tool::Tolerance(Fin);
626
627   TopOpeBRepTool_CORRISO CORRISO(Fin);
628   Standard_Real uperiod,vperiod;
629   Standard_Boolean uclosed = CORRISO.Refclosed(1,uperiod);
630   Standard_Boolean vclosed = CORRISO.Refclosed(2,vperiod);
631   if (!uclosed && !vclosed) return Standard_False;
632   
633   CORRISO.Init(Fsp);
634   Standard_Boolean ok = CORRISO.UVClosed();
635   if (ok) return Standard_True; // Fsp is valid
636
637   // 1. We check connexity among all edges of <Fsp>
638   // if we find on edge with 2 faulty UVbounds, we try to UVconnect it.
639 //  for (Standard_Integer i=1; i<=2; i++) {
640   Standard_Integer i ;
641   for ( i=1; i<=2; i++) {
642     Standard_Boolean onU = (i==1) ? Standard_True : Standard_False; 
643     const TopTools_ListOfShape& Tocheck = CORRISO.Eds();
644     TopTools_DataMapOfOrientedShapeInteger fyEds; ok =::FUN_connexX(onU,CORRISO,Tocheck,fyEds);
645     if (!ok) continue;
646     ok = CORRISO.TrslUV(onU,fyEds);
647     if (!ok) continue;
648     ok = CORRISO.UVClosed();
649     if (!ok) continue;
650     ok = CORRISO.GetnewS(Fsp);
651     if (!ok) return Standard_False; //NYIRAISE
652     return Standard_True;
653   }
654
655   // 2. x-2drep(edges) are in [xfirst,xfirst+xperiod]
656   for (i = 1; i <=2; i++) {
657     Standard_Boolean onU = (i==1);     
658     Standard_Real xper=0.; Standard_Boolean xclosed = CORRISO.Refclosed(i,xper);
659     if (!xclosed) continue;
660     Standard_Real tolx = CORRISO.Tol(i,tolF);
661     tolx *= 1.e2; // BUC60380
662     TopTools_DataMapOfOrientedShapeInteger FyEds; Standard_Boolean hasfy = CORRISO.EdgesOUTofBoundsUV(CORRISO.Eds(),onU,tolx,FyEds);
663     if (!hasfy) continue;
664     ok = CORRISO.TrslUV(onU,FyEds);
665     if (!ok) return Standard_False;
666     ok = CORRISO.UVClosed();
667     if (!ok) continue;
668     ok = CORRISO.GetnewS(Fsp);
669     if (!ok) return Standard_False; //NYIRAISE
670     return Standard_True;
671   }
672   return Standard_False;
673
674   /*// xpu310898 : eC closing ff, ff sdm F(reference face), proj(eC,F) gives ee with
675   //             !closing(ee,Fsp) -> 2drep(Fsp) is not closed.
676   //             purpose : translate pceCFOR or pceCREV
677   //   cto902B7 (ff=f7,eC=e9,F=f14)
678   ok = ::FUN_tool_reguUV(Fin,Fsp);*/
679
680   /*// JYL 980909 : reecriture complete
681   // 1/ traitement de TOUTES les aretes
682   //    isou et isov fautives (et non la premiere trouvee);
683   // 2/ traitement des aretes degenerees fautives : CTS20973
684
685   TopTools_ListOfShape lisoe,ldege;
686   TopExp_Explorer exe(Fsp, TopAbs_EDGE);
687   for (; exe.More(); exe.Next()){
688     const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
689     Standard_Boolean degen = BRep_Tool::Degenerated(E);
690     if ( degen ) {
691       ldege.Append(E);
692     }
693     else {
694       Standard_Real f,l; Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(E,Fin,f,l);
695       Standard_Boolean uiso,viso; gp_Dir2d d2d; gp_Pnt2d O2d; 
696       Standard_Boolean uviso = FUN_tool_IsUViso(PC,uiso,viso,d2d,O2d);
697       Standard_Boolean onclosing = (uiso && uclosed) || (viso && vclosed);
698       if      ( onclosing) {
699         lisoe.Append(E);
700       }
701     }
702   }
703   
704   Standard_Integer nisoe = lisoe.Extent();
705   Standard_Integer ndege = ldege.Extent();
706   if (nisoe ==0 && ndege == 0) return Standard_False;
707
708   Standard_Integer tmpisoe;
709   Standard_Integer tmpdege;
710
711   TopTools_ListOfShape lfyisoe; Standard_Boolean tocorrectisoe = Standard_False;
712   tocorrectisoe = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lisoe,Standard_True,lfyisoe,tmpisoe);
713
714   TopTools_ListOfShape lfydege; Standard_Boolean tocorrectdege = Standard_False;
715   tocorrectdege = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,ldege,Standard_True,lfydege,tmpdege);
716
717   tocorrect = (tocorrectisoe || tocorrectdege);
718   if (!tocorrect) {
719     return Standard_True;
720   }
721   
722 #ifdef DEB
723   if (trc) {
724     cout<<"CorrectONUVISO ";
725     cout<<"iso faulty "<<tocorrectisoe<<" deg faulty "<<tocorrectdege<<endl;;
726   }
727   debcorrUV();
728 #endif
729   
730   if (tocorrectisoe) {
731     for (TopTools_ListIteratorOfListOfShape itiso(lfyisoe);itiso.More();itiso.Next()) {
732       TopoDS_Edge& fyisoe = TopoDS::Edge(itiso.Value());
733       
734       // !! if the faulty edge ON closing appears twice in <Eds>, NOTHING is done!
735       // -> see processing ::PurgeClosingEdges later called in WESMakeFaces    
736       Standard_Integer nfoundisoe = 0;
737       for (exe.Init(Fsp, TopAbs_EDGE); exe.More(); exe.Next()) {
738         if (exe.Current().IsSame(fyisoe)) {
739           nfoundisoe++; 
740         }
741       }
742       if (nfoundisoe > 1) {
743         continue;
744       }
745       
746 #ifdef DRAW
747       if (trc) { 
748         cout<<"TopOpeBRepTool correctONUVISO : faulty iso edge"<<endl;
749         FUN_tool_draw("fyf",Fsp);FUN_tool_draw("fyisoe",fyisoe);
750       }
751 #endif
752       
753       Standard_Boolean ok = ::FUN_correctClosingE(fyisoe,Fsp);
754       if (!ok) {
755         FUN_Raise();
756         continue;
757       }
758     }
759     
760     Standard_Integer tmpisoe;
761     TopTools_ListOfShape lffyisoe; tocorrectisoe = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lfyisoe,Standard_False,lffyisoe,tmpisoe);
762   } // end lffyisoe process
763   
764   if (tocorrectdege) {
765     TopTools_IndexedDataMapOfShapeListOfShape mve;
766     TopExp::MapShapesAndAncestors(Fsp,TopAbs_VERTEX,TopAbs_EDGE,mve);
767     
768     for (TopTools_ListIteratorOfListOfShape itdeg(lfydege);itdeg.More();itdeg.Next()) {
769       TopoDS_Edge& fydege = TopoDS::Edge(itdeg.Value());
770       
771 #ifdef DRAW
772       if (trc) { 
773         cout<<"TopOpeBRepTool correctONUVISO : faulty deg edge"<<endl;
774         FUN_tool_draw("fyf",Fsp);FUN_tool_draw("fydege",fydege);
775       }
776 #endif
777       
778       Standard_Boolean ok = ::FUN_correctDegeneratedE(mve,fydege,Fsp);
779       if (!ok) {
780         FUN_Raise();
781         continue;
782       }
783     } // itdeg
784     
785     TopTools_ListOfShape lffydege; tocorrectdege = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,lfydege,Standard_False,lffydege,tmpdege);
786   } // end lfydege process
787
788   TopTools_ListOfShape eFsp; FUN_tool_shapes(Fsp,TopAbs_EDGE,eFsp);
789   TopTools_ListOfShape lffydege; tocorrect = FUN_DetectEdgeswithfaultyUV(Fsp,Fsp,eFsp,Standard_False,lffydege,tmpdege);
790   Standard_Boolean done = !tocorrect;
791   return done;*/
792
793 } // correctONUVISO
794
795 //=======================================================================
796 //function : MakeFaces
797 //purpose  : 
798 //=======================================================================
799
800 Standard_Boolean TopOpeBRepTool::MakeFaces(const TopoDS_Face& Fin, const TopTools_ListOfShape& LOF, 
801                               const TopTools_IndexedMapOfOrientedShape& MshNOK,
802                               TopTools_ListOfShape& LOFF)
803 {
804 //  TopOpeBRepDS_BuildTool BT;
805   BRep_Builder BB;
806   LOFF.Clear();
807   TopTools_ListIteratorOfListOfShape it(LOF);
808   for (; it.More(); it.Next()){
809     const TopoDS_Face& FF = TopoDS::Face(it.Value());
810     Standard_Boolean valid = !MshNOK.Contains(FF);
811     if (valid) {LOFF.Append(FF); continue;}
812     
813     TopoDS_Shape aLocalShape = Fin.EmptyCopied();
814     TopoDS_Face newFace = TopoDS::Face(aLocalShape);// BT.CopyFace(Fin,newFace);
815 //    TopoDS_Face newFace = TopoDS::Face(Fin.EmptyCopied());// BT.CopyFace(Fin,newFace);
816     TopExp_Explorer exw(FF, TopAbs_WIRE);
817     
818     for (; exw.More(); exw.Next()){
819       const TopoDS_Wire& W = TopoDS::Wire(exw.Current());
820       valid = !MshNOK.Contains(W);
821       //      if (valid) {BT.AddFaceWire(newFace,W); continue;}
822       if (valid) {BB.Add(newFace,W); continue;}
823
824       TopoDS_Wire newWire; //BT.MakeWire(newWire);
825       BB.MakeWire(newWire);
826       TopExp_Explorer exe(W, TopAbs_EDGE);
827       Standard_Integer ne = 0;
828       for (; exe.More(); exe.Next()){
829         const TopoDS_Edge& E = TopoDS::Edge(exe.Current());
830         valid = !MshNOK.Contains(E);
831         if (!valid) continue;
832         //      BT.AddWireEdge(newWire,E);
833         BB.Add(newWire,E);
834         ne++;
835       } // exe
836       if (ne == 0) continue;
837       Standard_Boolean closed = FUN_tool_ClosedW(newWire);
838       //      BT.Closed(newWire,closed); 
839       //      BT.AddFaceWire(newFace,newWire);
840       newWire.Closed(closed);
841       BB.Add(newFace,newWire);
842     } // exw
843     LOFF.Append(newFace);
844   }
845   return Standard_True;
846 }
847
848 /*static Handle(Geom2d_TrimmedCurve) FUN_translate(const gp_Vec2d& tvector, const TopoDS_Face& fF, TopoDS_Edge& fyE)
849 {
850   Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FUNTOOLC2D_CurveOnSurface(fyE,fF,f,l,tol);
851   Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d;
852   Standard_Boolean isouv = FUN_tool_IsUViso(PC,isou,isov,d2d,o2d); o2d.Translate(tvector);
853   Handle(Geom2d_Line) L2d = new Geom2d_Line(o2d,d2d);
854   Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(L2d,f,l);
855   return C2d;
856 }
857 Standard_EXPORT void FUN_tool_ttranslate(const gp_Vec2d& tvector, const TopoDS_Face& fF, TopoDS_Edge& fyE)
858 {  
859   Handle(Geom2d_TrimmedCurve) C2d = ::FUN_translate(tvector,fF,fyE);
860   Standard_Real tole = BRep_Tool::Tolerance(fyE);
861   BRep_Builder BB;
862 //  Handle(Geom2d_Curve) toclear; BB.UpdateEdge(fyE,toclear,fF,tole);
863   BB.UpdateEdge(fyE,C2d,fF,tole);
864 }
865
866 static Standard_Boolean FUN_tool_translate(const gp_Vec2d& tvector, TopoDS_Face& fF, TopoDS_Edge& fyE)
867      // prequesitory : <fF> is on periodic surface, translates edge 
868      //  <fyE>'s uorviso to have its uorvpar bounded in [0.,2PI].
869 {
870   Handle(Geom2d_TrimmedCurve) C2d = ::FUN_translate(tvector,fF,fyE);
871   Standard_Real tole = BRep_Tool::Tolerance(fyE);
872   
873   //xpu040598 : CTS20280 f37 modified when its split is modified!
874   TopoDS_Face newf; Standard_Boolean ok = FUN_tool_pcurveonF(fF,fyE,C2d,newf);
875   if (ok) fF = newf;
876   return ok;
877   //xpu040598
878 }
879 */