Integration of OCCT 6.5.0 from SVN
[occt.git] / src / TopOpeBRepTool / TopOpeBRepTool_PURGE.cxx
CommitLineData
7fd59977 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
38Standard_EXPORT void debcorrUV(){};
39Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettracePURGE();
40Standard_EXPORT Standard_Boolean TopOpeBRepTool_GettraceCORRISO();
41#endif
42// DEB
43
44// Unused :
45#ifdef DEB
46static 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}
55static 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
73static 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
79static 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
100Standard_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
220Standard_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
295Standard_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*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
335static 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
555static 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
616Standard_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
800Standard_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}
857Standard_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
866static 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*/