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