1 // Created on: 1998-11-25
2 // Created by: Prestataire Xuan PHAM PHU
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BndLib_Add2dCurve.hxx>
19 #include <BRep_Builder.hxx>
20 #include <BRep_GCurve.hxx>
21 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
22 #include <BRep_ListOfCurveRepresentation.hxx>
23 #include <BRep_TEdge.hxx>
24 #include <BRep_Tool.hxx>
25 #include <Geom2d_TrimmedCurve.hxx>
26 #include <Geom2dAdaptor_Curve.hxx>
27 #include <GeomAdaptor_Surface.hxx>
28 #include <TopExp_Explorer.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Vertex.hxx>
34 #include <TopOpeBRepTool.hxx>
35 #include <TopOpeBRepTool_2d.hxx>
36 #include <TopOpeBRepTool_C2DF.hxx>
37 #include <TopOpeBRepTool_CORRISO.hxx>
38 #include <TopOpeBRepTool_define.hxx>
39 #include <TopOpeBRepTool_EXPORT.hxx>
40 #include <TopOpeBRepTool_PURGE.hxx>
41 #include <TopOpeBRepTool_TOOL.hxx>
42 #include <TopTools_Array1OfShape.hxx>
45 extern Standard_Boolean TopOpeBRepTool_GettraceCORRISO();
46 Standard_EXPORT TopTools_IndexedMapOfShape STATIC_PURGE_mapv;
47 Standard_EXPORT TopTools_IndexedMapOfOrientedShape STATIC_PURGE_mapeds;
48 extern void FUN_tool_trace(const Standard_Integer Index);
49 extern void FUN_tool_trace(const gp_Pnt2d p2d);
52 static void FUN_RaiseError()
55 // Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
57 // if (trc) std::cout <<"*********failure in CORRISO***********\n";
60 static void FUN_Raise()
63 // std::cout <<"*********failure in CORRISO***********\n";
68 #include <TopOpeBRepTool_DRAW.hxx>
71 #define M_FORWARD(sta) (sta == TopAbs_FORWARD)
72 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
73 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
74 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
76 //=======================================================================
77 //function : TopOpeBRepTool_CORRISO
79 //=======================================================================
81 TopOpeBRepTool_CORRISO::TopOpeBRepTool_CORRISO()
85 //=======================================================================
86 //function : TopOpeBRepTool_CORRISO
88 //=======================================================================
90 TopOpeBRepTool_CORRISO::TopOpeBRepTool_CORRISO(const TopoDS_Face& Fref)
94 FUN_tool_closedS(myFref,myUclosed,myUper,myVclosed,myVper);
96 const Handle(Geom_Surface)& SU = BRep_Tool::Surface(myFref);
97 myGAS = GeomAdaptor_Surface(SU);
100 //=======================================================================
103 //=======================================================================
105 const TopoDS_Face& TopOpeBRepTool_CORRISO::Fref() const
110 //=======================================================================
113 //=======================================================================
115 const GeomAdaptor_Surface& TopOpeBRepTool_CORRISO::GASref() const
121 //=======================================================================
122 //function : Refclosed
124 //=======================================================================
126 Standard_Boolean TopOpeBRepTool_CORRISO::Refclosed(const Standard_Integer x, Standard_Real& xperiod) const
128 if (x==1) {xperiod = myUper; return myUclosed;}
129 if (x==2) {xperiod = myVper; return myVclosed;}
130 return Standard_False;
135 //=======================================================================
138 //=======================================================================
140 Standard_Boolean TopOpeBRepTool_CORRISO::Init(const TopoDS_Shape& S)
143 Standard_Integer ie = 0;
144 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
145 Standard_Boolean INIT = Standard_True;
146 if (INIT) FUN_REINIT();
153 if (S.IsNull()) return Standard_False;
156 TopExp_Explorer ex(S, TopAbs_EDGE);
157 for (; ex.More(); ex.Next()){
158 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
160 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
161 (void)iE; // avoid warning
163 if (trc) {TCollection_AsciiString aa = TCollection_AsciiString("e"); FUN_tool_draw(aa,E,iE);}
171 // Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,myFref,f,l,tol);
172 Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
173 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,myFref,PC);
174 PC = FC2D_EditableCurveOnSurface(E,myFref,f,l,tol);
175 if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,myFref,f,l,tol);
176 if (PC.IsNull()) return Standard_False;
177 TopOpeBRepTool_C2DF C2DF(PC,f,l,tol,myFref);
178 myERep2d.Bind(E,C2DF);
181 TopExp_Explorer exv(E, TopAbs_VERTEX);
182 for (; exv.More(); exv.Next()){
183 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
185 Standard_Integer aniE = STATIC_PURGE_mapeds.Add(E);
186 (void)aniE; // avoid warning
188 if (trc) {TCollection_AsciiString bb = TCollection_AsciiString("v"); FUN_tool_draw(bb,v,iv);}
191 Standard_Boolean isb = myVEds.IsBound(v);
192 if (isb) myVEds.ChangeFind(v).Append(E);
193 else {TopTools_ListOfShape loe; loe.Append(E); myVEds.Bind(v,loe);}
196 return Standard_True;
199 //=======================================================================
202 //=======================================================================
204 const TopoDS_Shape& TopOpeBRepTool_CORRISO::S() const
209 //=======================================================================
212 //=======================================================================
214 const TopTools_ListOfShape& TopOpeBRepTool_CORRISO::Eds() const
219 //=======================================================================
222 //=======================================================================
224 Standard_Boolean TopOpeBRepTool_CORRISO::UVRep(const TopoDS_Edge& E, TopOpeBRepTool_C2DF& C2DF) const
226 Standard_Boolean isb = myERep2d.IsBound(E);
227 if (!isb) return Standard_False;
229 C2DF = myERep2d.Find(E);
230 return Standard_True;
233 //=======================================================================
234 //function : SetUVRep
236 //=======================================================================
238 Standard_Boolean TopOpeBRepTool_CORRISO::SetUVRep(const TopoDS_Edge& E, const TopOpeBRepTool_C2DF& C2DF)
240 Standard_Boolean isb = myERep2d.IsBound(E);
241 if (!isb) return Standard_False;
243 myERep2d.ChangeFind(E) = C2DF;
244 return Standard_True;
247 //=======================================================================
248 //function : Connexity
250 //=======================================================================
252 Standard_Boolean TopOpeBRepTool_CORRISO::Connexity(const TopoDS_Vertex& V, TopTools_ListOfShape& Eds) const
254 Standard_Boolean isb = myVEds.IsBound(V);
255 if (!isb) return Standard_False;
257 Eds = myVEds.Find(V);
258 return Standard_True;
261 //=======================================================================
262 //function : SetConnexity
264 //=======================================================================
266 Standard_Boolean TopOpeBRepTool_CORRISO::SetConnexity(const TopoDS_Vertex& V, const TopTools_ListOfShape& Eds)
268 Standard_Boolean isb = myVEds.IsBound(V);
269 if (!isb) return Standard_False;
271 myVEds.ChangeFind(V) = Eds;
272 return Standard_True;
275 //=======================================================================
276 //function : UVClosed
278 //=======================================================================
280 Standard_Boolean TopOpeBRepTool_CORRISO::UVClosed() const
283 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
284 if (trc) std::cout<<"** UVClosed"<<std::endl;
286 TopTools_DataMapOfOrientedShapeInteger lfyE; Standard_Integer nfybounds=3; Standard_Boolean stopatfirst = Standard_True;
287 Standard_Boolean foundfaulty = EdgesWithFaultyUV(myEds,nfybounds,lfyE,stopatfirst);
291 //=======================================================================
294 //=======================================================================
296 Standard_Real TopOpeBRepTool_CORRISO::Tol(const Standard_Integer I, const Standard_Real tol3d) const
298 Standard_Real tol = (I==1) ? myGAS.UResolution(tol3d) : myGAS.VResolution(tol3d);
302 //static Standard_Real FUN_getx(const TopoDS_Edge& E,
303 static Standard_Real FUN_getx(const TopoDS_Edge& ,
304 const TopOpeBRepTool_C2DF& c2df,
305 const Standard_Boolean uiso,
306 const Standard_Real par)
307 { // prequesitory : E is uviso
308 gp_Pnt2d uv = TopOpeBRepTool_TOOL::UVF(par,c2df);
309 Standard_Real x = (uiso) ? uv.Y() : uv.X();
313 //=======================================================================
314 //function : PurgeFyClosingE
316 //=======================================================================
318 Standard_Boolean TopOpeBRepTool_CORRISO::PurgeFyClosingE(const TopTools_ListOfShape& ClEds, TopTools_ListOfShape& fyClEds) const
322 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
323 if (trc) std::cout<<"* PurgeFyClosingE"<<std::endl;
325 // Standard_Real xperiod = myUclosed ? myUper : myVper;
326 Standard_Real tttol = 1.e-8;
327 Standard_Real tttolS = BRep_Tool::Tolerance(myFref);
328 Standard_Real tolu = Tol(1,tttolS), tolv = Tol(2,tttolS);
329 Standard_Real tttuvF = Max(tolu,tolv);
331 TopTools_IndexedMapOfOrientedShape mapcl;
332 TopTools_ListIteratorOfListOfShape itce(ClEds);
333 for (; itce.More(); itce.Next()) mapcl.Add(itce.Value());
335 //* one closing edge should be removed
336 itce.Initialize(ClEds);
337 TopTools_DataMapOfOrientedShapeInteger fyceds; Standard_Boolean found = EdgesWithFaultyUV(ClEds,3,fyceds);
338 if (!found) return Standard_False;
340 if (fyceds.Extent() == 1) {// ivf == 3 : cto016G*
341 TopTools_DataMapOfOrientedShapeInteger fyeds;
343 EdgesWithFaultyUV(myEds,3,fyeds);
344 Standard_Integer nfy = fyeds.Extent();
346 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(fyceds);
347 const TopoDS_Edge& cE = TopoDS::Edge(itm.Key());
349 TopAbs_Orientation OocE = TopAbs::Complement(cE.Orientation());
350 Standard_Boolean isoncE = mapcl.Contains(cE.Oriented(OocE));
352 TopTools_Array1OfShape vcE(1,2); TopOpeBRepTool_TOOL::Vertices(cE,vcE);
353 TopAbs_Orientation ocE = cE.Orientation();
354 Standard_Real tttolcE = BRep_Tool::Tolerance(cE);
355 Standard_Real tttuvcE = Max(Tol(1,tttolcE),Tol(2,tttolcE));
356 TopOpeBRepTool_C2DF cE2d; Standard_Boolean isb = UVRep(cE,cE2d);
357 if (!isb) return Standard_False; // NYIRAISE
360 // OcE (closing edge with complemented orientation):
361 TopAbs_Orientation oOcE = TopAbs::Complement(ocE);
362 TopoDS_Shape alocalShape = cE.Oriented(oOcE);
363 TopoDS_Edge OcE = TopoDS::Edge(alocalShape);
364 // TopoDS_Edge OcE = TopoDS::Edge(cE.Oriented(oOcE));
365 TopTools_Array1OfShape vOcE(1,2); TopOpeBRepTool_TOOL::Vertices(OcE,vOcE);
366 Standard_Real tttolOcE = BRep_Tool::Tolerance(OcE);
367 Standard_Real tttuvOcE = Max(Tol(1,tttolOcE),Tol(2,tttolOcE));
368 TopOpeBRepTool_C2DF OcE2d; Standard_Boolean isOb = UVRep(OcE,OcE2d);
369 if (!isOb) return Standard_False; // NYIRAISE
371 Standard_Real parvce1 = TopOpeBRepTool_TOOL::ParE(1,cE); gp_Pnt2d UVvce1 = TopOpeBRepTool_TOOL::UVF(parvce1,cE2d);
373 Standard_Real parvOcE2 = TopOpeBRepTool_TOOL::ParE(2,OcE); gp_Pnt2d UVvOcE2 = TopOpeBRepTool_TOOL::UVF(parvOcE2,OcE2d);
374 Standard_Real tol = Max(tttuvcE,tttuvOcE);
375 isoncE = (UVvce1.Distance(UVvOcE2) < tol);
376 if (isoncE && (nfy != 1)) {// cto009L2
377 return Standard_False;
381 Standard_Integer ivf = itm.Value();
384 return Standard_True;
387 else if (fyceds.Extent() > 1) {// ivf == 1,2 : cto016E*
388 // if {edges of fyceds} describe a closing edge with its first and last
389 // uvbounds non connexed -> we do remove these edges
390 Standard_Boolean hasinit=Standard_False; Standard_Boolean isou=Standard_False,isov=Standard_False;
391 gp_Pnt2d o2d; gp_Dir2d d2d;
392 Standard_Real xinf=1.e7, xsup=-1.e7; // faulty inf and sup bounds
393 Standard_Boolean infdef=Standard_False, supdef=Standard_False;
394 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(fyceds);
395 for (; itm.More(); itm.Next()){
396 const TopoDS_Edge& cE = TopoDS::Edge(itm.Key());
397 TopOpeBRepTool_C2DF c2df; Standard_Boolean isb = UVRep(cE,c2df);
398 if (!isb) return Standard_False; // NYIRAISE
400 Standard_Integer ivf = itm.Value();
401 Standard_Boolean isoux,isovx; gp_Pnt2d o2dx; gp_Dir2d d2dx;
402 Standard_Boolean uvisox = TopOpeBRepTool_TOOL::UVISO(c2df,isoux,isovx, d2dx, o2dx);
403 if (!uvisox) return Standard_False;
406 Standard_Boolean onsamline = (isou && isoux) || (isov && isovx);
407 if (!onsamline) return Standard_False;
410 isou=isoux; isov=isovx;
412 hasinit = Standard_True;
415 Standard_Boolean onsamline = Standard_False;
417 Standard_Real du = o2d.X()-o2dx.X();
418 onsamline = (Abs(du) < tolu);
421 Standard_Real dv = o2d.Y()-o2dx.Y();
422 onsamline = (Abs(dv) < tolv);
424 if (!onsamline) return Standard_False;
426 for (Standard_Integer i = 1; i <=2; i++) {
427 Standard_Real pari = TopOpeBRepTool_TOOL::ParE(i,cE);
428 Standard_Real xi = FUN_getx(cE,c2df,isou,pari);
429 Standard_Boolean vifaulty = (ivf == i || ivf == 3);
430 Standard_Boolean inff = (xi < xinf);
431 Standard_Boolean supl = (xi > xsup);
432 // if (inff) xinf = (ivf == i || ivf == 3) ? xi : 1.e7;
433 // if (supl) xsup = (ivf == i || ivf == 3) ? xi : -1.e7;
434 if (inff) {xinf = xi; infdef = vifaulty;}
435 if (supl) {xsup = xi; supdef = vifaulty;}
439 Standard_Boolean toremove = infdef && supdef; // ie infx,supx are not "uv-connexed"
440 if (!toremove) fyClEds.Clear();
442 if (!fyClEds.IsEmpty()) return Standard_True; // keeping only one closing edge
444 //* the 2 closing edges have they 2drep "confunded"
445 itce.Initialize(ClEds);
446 for (; itce.More(); itce.Next()){
448 const TopoDS_Edge& cE = TopoDS::Edge(itce.Value());
449 TopTools_Array1OfShape vcE(1,2); TopOpeBRepTool_TOOL::Vertices(cE,vcE);
450 TopAbs_Orientation ocE = cE.Orientation();
452 Standard_Real tttolcE = BRep_Tool::Tolerance(cE);
453 Standard_Real tttuvcE = Max(Tol(1,tttolcE),Tol(2,tttolcE));
454 TopOpeBRepTool_C2DF cE2d; Standard_Boolean isb = UVRep(cE,cE2d);
455 if (!isb) return Standard_False; // NYIRAISE
457 Standard_Integer icE = STATIC_PURGE_mapeds.Add(cE);
458 if (trc) std::cout<<"? e"<<icE<<" :"<<std::endl;
462 Standard_Boolean isonOcE2d = Standard_False;
464 // OcE (closing edge with complemented orientation):
465 TopAbs_Orientation oOcE = TopAbs::Complement(ocE);
466 TopoDS_Shape aLocalShape = cE.Oriented(oOcE);
467 TopoDS_Edge OcE = TopoDS::Edge(aLocalShape);
468 // TopoDS_Edge OcE = TopoDS::Edge(cE.Oriented(oOcE));
469 TopTools_Array1OfShape vOcE(1,2); TopOpeBRepTool_TOOL::Vertices(OcE,vOcE);
470 Standard_Boolean hasOcE = mapcl.Contains(OcE);
471 if (!hasOcE) continue; // closing edge appears twice
472 Standard_Real tttolOcE = BRep_Tool::Tolerance(OcE);
473 Standard_Real tttuvOcE = Max(Tol(1,tttolOcE),Tol(2,tttolOcE));
474 TopOpeBRepTool_C2DF OcE2d; Standard_Boolean isOb = UVRep(OcE,OcE2d);
475 if (!isOb) return Standard_False; // NYIRAISE
477 Standard_Real parvce1 = TopOpeBRepTool_TOOL::ParE(1,cE); gp_Pnt2d UVvce1 = TopOpeBRepTool_TOOL::UVF(parvce1,cE2d);
479 Standard_Real parvOcE2 = TopOpeBRepTool_TOOL::ParE(2,OcE); gp_Pnt2d UVvOcE2 = TopOpeBRepTool_TOOL::UVF(parvOcE2,OcE2d);
480 Standard_Real tol = Max(tttuvcE,tttuvOcE);
481 isonOcE2d = (UVvce1.Distance(UVvOcE2) < tol);
485 if (trc) std::cout<<"-> valid edge"<<std::endl;
490 Standard_Integer nvcEok = 0;
491 for (Standard_Integer ivce = 1; ivce <=2; ivce++) {
492 // <vce> (boundary of <cE>):
493 const TopoDS_Vertex& vce = TopoDS::Vertex(vcE(ivce));
494 TopTools_ListOfShape loe; isb = Connexity(vce,loe);
496 if (!isb) return Standard_False; // NYIRAISE
498 Standard_Real parvce = TopOpeBRepTool_TOOL::ParE(ivce,cE); gp_Pnt2d UVvce = TopOpeBRepTool_TOOL::UVF(parvce,cE2d);
500 // recall in one wire, there are 2 vertices for one non-degenerated closing edge
501 Standard_Integer ivmapv = STATIC_PURGE_mapv.Add(vce);
502 if (trc) {std::cout<<" connexity for v("<<ivce<<")=v"<<ivmapv;FUN_tool_trace(UVvce);}
504 if (trc) {TCollection_AsciiString bb("uv_");bb += TCollection_AsciiString(ivmapv);FUN_tool_draw(bb,UVvce);}
507 Standard_Real tttolvce = BRep_Tool::Tolerance(vce);
508 Standard_Real tttuvvce = Max(Tol(1,tttolvce),Tol(2,tttolvce));
510 Standard_Boolean vceok = Standard_False;
511 for (TopTools_ListIteratorOfListOfShape ite(loe); ite.More(); ite.Next()) {
512 const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
515 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
516 if (trc) {std::cout<<" : on e"<<iE<<std::endl;}
518 // if (E.IsSame(cE)) continue;
519 if (mapcl.Contains(E)) continue; // do NOT check connexity on closing edges
520 // xpu090399 cto016E1
522 TopOpeBRepTool_C2DF E2d; Standard_Boolean isB2 = UVRep(E,E2d);
523 if (!isB2) return Standard_False; // NYIRAISE
525 Standard_Real tttolE = BRep_Tool::Tolerance(E);
526 Standard_Real tttuvE = Max(Tol(1,tttolE),Tol(2,tttolE));
528 TopTools_Array1OfShape vE(1,2); TopOpeBRepTool_TOOL::Vertices(E,vE);
529 for (Standard_Integer ive = 1; ive <=2; ive++) {
531 const TopoDS_Vertex& ve = TopoDS::Vertex(vE(ive));
532 Standard_Boolean samev = ve.IsSame(vce);
533 if (!samev) continue;
534 Standard_Real parve = TopOpeBRepTool_TOOL::ParE(ive,E); gp_Pnt2d UVve = TopOpeBRepTool_TOOL::UVF(parve,E2d);
536 if (trc) {std::cout<<" ve("<<ive<<")";FUN_tool_trace(UVve);}
538 if (ive == ivce) continue; // vertex FORWARD connexed to REVERSED one
539 Standard_Real tttolve = BRep_Tool::Tolerance(ve);
540 Standard_Real tttuvve = Max(Tol(1,tttolve),Tol(2,tttolve));
542 tttol = Max(tttol,Max(tttuvF,Max(tttuvE,Max(tttuvcE,Max(tttuvve,tttuvvce)))));
543 // Standard_Real dd = myUclosed ? (UVve.X()-UVvce.X()) : (UVve.Y()-UVvce.Y());
544 // Standard_Boolean xok = (Abs(dd)<tttol) || (Abs(Abs(dd)-xperiod)<tttol);
546 Standard_Real dd = UVve.Distance(UVvce);
547 Standard_Boolean sameuv = (dd < tttol);
549 Standard_Real xperiod = myUper;
550 dd = (UVve.X()-UVvce.X());
551 sameuv = sameuv || (Abs(Abs(dd)-xperiod)<tttol);
554 Standard_Real xperiod = myVper;
555 dd = (UVve.Y()-UVvce.Y());
556 sameuv = sameuv || (Abs(Abs(dd)-xperiod)<tttol);
559 vceok = Standard_True;
561 if (trc){std::cout<<" connexity->ok"<<std::endl;}
570 if (trc && !vceok) {std::cout<<" connexity->KO"<<std::endl;}
575 Standard_Boolean isfycE = (nvcEok == 0); // each bound is not connexed to any non-closed edge
579 {if (isfycE) std::cout<<"-> faulty edge"<<std::endl;
580 else std::cout<<"-> valid edge"<<std::endl;}
582 if (isfycE) fyClEds.Append(cE);
584 return (!fyClEds.IsEmpty());
587 #define SPLITEDGE (0)
589 #define DECREASE (-1)
591 static Standard_Integer FUN_tool_recadre(const Standard_Real minx,const Standard_Real maxx,
592 const Standard_Real xfirst,const Standard_Real xlast,const Standard_Real tolx,
593 Standard_Boolean& maxsup)
595 Standard_Integer recadre = 10; // INIT
596 Standard_Boolean maxinf = (maxx < xfirst+tolx); // permissive
597 Standard_Boolean mininf = (minx < xfirst-tolx);//
598 maxsup = (maxx > xlast+tolx); //
599 Standard_Boolean minsup = (minx > xlast-tolx); // permissive
600 Standard_Boolean maxok = (xfirst-tolx < maxx) && (maxx < xlast+tolx);// permissive
601 Standard_Boolean minok = (xfirst-tolx < minx) && (minx < xlast+tolx); // permissive
603 if (maxinf) recadre = INCREASE;
604 else if (minsup) recadre = DECREASE;
605 else if (mininf && maxok) recadre = SPLITEDGE;
606 else if (minok && maxsup) recadre = SPLITEDGE;
610 //=======================================================================
611 //function : EdgeOUTofBoundsUV
613 //=======================================================================
615 Standard_Integer TopOpeBRepTool_CORRISO::EdgeOUTofBoundsUV(const TopoDS_Edge& E, const Standard_Boolean onU, const Standard_Real tolx,
616 Standard_Real& parspE) const
618 Standard_Integer recadre = 10; parspE = -1.e7; // INIT
619 Standard_Integer isb = myERep2d.IsBound(E);
620 if (!isb) return Standard_False;
622 const TopOpeBRepTool_C2DF& C2DF = myERep2d.Find(E);
623 Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
625 Standard_Real xfirst = onU ? myGAS.FirstUParameter() : myGAS.FirstVParameter();
626 Standard_Real xlast = onU ? myGAS.LastUParameter() : myGAS.LastVParameter(); // xlast=xfirst+xperiod
627 Standard_Real xperiod = onU ? myUper : myVper;
629 Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d;
630 Standard_Boolean iso = TopOpeBRepTool_TOOL::UVISO(PC,isou,isov,d2d,o2d);
632 if (iso) { // 2drep(E,myFref) is an ISO
633 // -------------------------
634 Standard_Boolean inX = (onU && isou) || ((!onU) && isov);
636 // faulty u-iso : upar out of ubound
637 Standard_Real xpar = onU ? o2d.X() : o2d.Y();
638 Standard_Boolean toosmall = (xpar < xfirst-tolx);
639 Standard_Boolean tobig = (xpar > xfirst+xperiod+tolx);
641 if (toosmall) recadre = INCREASE;
642 if (tobig) recadre = DECREASE;
645 Standard_Boolean inY = (onU && isov) || ((!onU) && isou); // inY = !inX
647 // faulty u-iso : vpar describes (minv,maxv) out of vbounds
648 // PC describes [minx,maxx] in x-space
649 // recadre = INCREASE : maxx < 0.
650 // DECREASE : minx > 2PI
651 // SPLITEDGE : minx<0.<maxx || minx<2PI<maxx
652 Standard_Real d2ddir = onU? d2d.Y(): d2d.X();
653 Standard_Boolean reverse = (d2ddir < 0.); Standard_Real xfactor = reverse? -1.: 1.;
654 Standard_Real max = reverse? f: l;
655 Standard_Real min = reverse? l: f;
656 gp_Pnt2d maxuv = PC->Value(max);
657 gp_Pnt2d minuv = PC->Value(min);
659 Standard_Real maxx = onU? maxuv.X(): maxuv.Y();
660 Standard_Real minx = onU? minuv.X(): minuv.Y();
662 Standard_Boolean maxsup;
663 recadre = FUN_tool_recadre(minx,maxx,xfirst,xlast,tolx,
665 if (recadre == SPLITEDGE) {
666 Standard_Real xbound = maxsup? xperiod: 0.;
667 parspE = max - xfactor*(maxx-xbound);
672 else { // 2drep(E, myFref) is NOT an iso
673 // ------------------------------
675 Geom2dAdaptor_Curve GC2d(PC,f,l);
676 Standard_Real tolE = BRep_Tool::Tolerance(E);
677 Standard_Real toladd = Max(tolE,tol);
678 BndLib_Add2dCurve::Add(GC2d,toladd,Bn2d);
679 Standard_Real umin,vmin,umax,vmax; Bn2d.Get(umin,vmin,umax,vmax);
680 Standard_Real xmin = onU ? umin : vmin;
681 Standard_Real xmax = onU ? umax : vmax;
682 Standard_Boolean maxsup;
683 recadre = FUN_tool_recadre(xmin,xmax,xfirst,xlast,tolx,
685 if (recadre == SPLITEDGE) {
686 // ================================================================
687 //NYIxpu271198 : intersection PC avec xiso (x= maxsup? xperiod: 0.)
688 // ================================================================
696 //=======================================================================
697 //function : EdgesOUTofBoundsUV
699 //=======================================================================
701 Standard_Boolean TopOpeBRepTool_CORRISO::EdgesOUTofBoundsUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Boolean onU, const Standard_Real tolx,
702 TopTools_DataMapOfOrientedShapeInteger & FyEds) const
705 TopTools_ListIteratorOfListOfShape it(EdsToCheck);
706 for (; it.More(); it.Next()){
707 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
708 Standard_Real sspar = -1.e7;
709 Standard_Integer recadre = EdgeOUTofBoundsUV(E,onU,tolx,sspar);
710 if (recadre == SPLITEDGE) FUN_Raise();
711 if (recadre == INCREASE) FyEds.Bind(E,1);
712 if (recadre == DECREASE) FyEds.Bind(E,-1);
714 return (!FyEds.IsEmpty());
718 //=======================================================================
719 //function : EdgeWithFaultyUV
721 //=======================================================================
723 Standard_Boolean TopOpeBRepTool_CORRISO::EdgeWithFaultyUV(const TopoDS_Edge& E, Standard_Integer& Ivfaulty) const
726 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
727 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
728 if (trc) std::cout<<"? e"<<iE<<" :"<<std::endl;
731 Standard_Real tttol = 1.e-8;
732 Standard_Real tttolF = BRep_Tool::Tolerance(TopoDS::Face(myFref));
733 Standard_Real tttuvF = Max(Tol(1,tttolF),Tol(2,tttolF));
734 Standard_Real tttolE = BRep_Tool::Tolerance(E);
735 Standard_Real tttuvE = Max(Tol(1,tttolE),Tol(2,tttolE));
737 TopAbs_Orientation oE = E.Orientation();
738 if (M_INTERNAL(oE) || M_EXTERNAL(oE)) return Standard_False;
740 TopTools_Array1OfShape vEs(1,2); TopOpeBRepTool_TOOL::Vertices(E, vEs);
741 Standard_Boolean closed = vEs(1).IsSame(vEs(2));
744 if (trc) {std::cout<<"closed -> valid edge"<<std::endl;}
746 return Standard_False; // closed edge is assumed valid
749 Standard_Integer nfyv = 0;
750 for (Standard_Integer ivE = 1; ivE <=2; ivE++) {
752 // <vE> (boundary of <E>):
753 const TopoDS_Vertex& vE = TopoDS::Vertex(vEs(ivE));
754 Standard_Real parvE = TopOpeBRepTool_TOOL::ParE(ivE,E);
755 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
756 if (!isb) return Standard_False; //NYIRAISE
757 gp_Pnt2d UVvE = TopOpeBRepTool_TOOL::UVF(parvE,C2DF);
759 // recall in one wire, there are 2 vertices for one non-degenerated closing edge
760 Standard_Integer ivmapv = STATIC_PURGE_mapv.Add(vE);
761 if (trc) {std::cout<<" connexity for v("<<ivE<<")=v"<<ivmapv;FUN_tool_trace(UVvE);}
763 if (trc) {TCollection_AsciiString bb("uv_");bb += TCollection_AsciiString(ivmapv);FUN_tool_draw(bb,UVvE);}
767 Standard_Real tttolvE = BRep_Tool::Tolerance(vE);
768 Standard_Real tttuvvE = Max(Tol(1,tttolvE),Tol(2,tttolvE));
770 Standard_Boolean isbound = myVEds.IsBound(vE);
771 if (!isbound) {FUN_RaiseError(); return Standard_False;}
774 Standard_Boolean vEok = Standard_False;
775 const TopTools_ListOfShape& loe = myVEds.Find(vE);
777 for (TopTools_ListIteratorOfListOfShape ite(loe); ite.More(); ite.Next()) {
778 const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
779 TopAbs_Orientation oe = e.Orientation();
782 Standard_Integer ie = STATIC_PURGE_mapeds.Add(e);
783 if (trc) {std::cout<<" : on e"<<ie<<std::endl;}
786 if (e.IsSame(E)) continue;
787 if (M_INTERNAL(oe) || M_EXTERNAL(oe)) continue;
789 Standard_Boolean isBound = myERep2d.IsBound(e);
790 if (!isBound) {FUN_RaiseError(); return Standard_False;}
791 const TopOpeBRepTool_C2DF& aC2DF = myERep2d.Find(e);
793 TopTools_Array1OfShape ves(1,2); TopOpeBRepTool_TOOL::Vertices(e,ves);
794 for (Standard_Integer ive = 1; ive <=2; ive++) {
795 const TopoDS_Vertex& ve = TopoDS::Vertex(ves(ive));
796 Standard_Boolean samev = ve.IsSame(vE);
797 if (!samev) continue;
799 Standard_Real pare = TopOpeBRepTool_TOOL::ParE(ive,e); gp_Pnt2d UVve = TopOpeBRepTool_TOOL::UVF(pare,aC2DF);
801 if (trc) {std::cout<<" ve("<<ive<<")";FUN_tool_trace(UVve);}
803 if (ive == ivE) continue;
805 Standard_Real tttolve = BRep_Tool::Tolerance(ve);
806 Standard_Real tttuvve = Max(Tol(1,tttolve),Tol(2, tttolve));
808 tttol = Max(tttol,Max(tttuvF,Max(tttuvE,Max(tttuvE,Max(tttuvve,tttuvvE)))));
809 Standard_Boolean isequal = UVvE.IsEqual(UVve,tttol);
811 vEok = Standard_True;
813 if (trc){std::cout<<" connexity->ok"<<std::endl;}
821 if (!vEok) {nfyv++; Ivfaulty = ivE;}
823 if (trc && !vEok) {std::cout<<" connexity->KO"<<std::endl;}
827 if (nfyv == 2) Ivfaulty = 3;
829 if (trc) {if (Ivfaulty == 0) std::cout<<"-> valid edge"<<std::endl; else std::cout<<"-> faulty edge"<<std::endl;}
831 return (Ivfaulty != 0);
834 //=======================================================================
835 //function : EdgesWithFaultyUV
837 //=======================================================================
839 Standard_Boolean TopOpeBRepTool_CORRISO::EdgesWithFaultyUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Integer nfybounds,
840 TopTools_DataMapOfOrientedShapeInteger& FyEds, const Standard_Boolean stopatfirst) const
844 Standard_Integer ifault = 0;
845 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
846 if (trc) std::cout<<std::endl<<"* EdgesWithFaultyUV"<<std::endl;
851 // An edge is valid if the first and last vertices are valid:
852 // vertex <vEchk> is valid if there is an edge with bound <ve> such that :
853 // <vEchk> and <ve> share same UV geometry
854 // <vEchk> and <ve> are of opposite orientation.
855 TopTools_ListIteratorOfListOfShape itchk(EdsToCheck);
856 for (; itchk.More(); itchk.Next()) {
858 const TopoDS_Edge& Echk = TopoDS::Edge(itchk.Value());
859 Standard_Integer Ivfaulty=0; Standard_Boolean faulty = EdgeWithFaultyUV(Echk,Ivfaulty);
860 if (!faulty) continue;
861 Standard_Integer nfyv = (Ivfaulty == 3)? 2 : 1;
865 if (trc) std::cout<<"e"<<STATIC_PURGE_mapeds.FindIndex(Echk)<<" has ifyv="<<Ivfaulty<<std::endl;
867 if (trc) {TCollection_AsciiString aa("fault"); FUN_tool_draw(aa,Echk,ifault);}
871 Standard_Boolean found = Standard_False;
872 if (nfybounds == 1) found = (nfyv == nfybounds);
873 else if (nfybounds == 2) found = (nfyv == nfybounds);
874 else if (nfybounds == 3) found = (nfyv > 0);
877 FyEds.Bind(Echk,Ivfaulty);
878 if (stopatfirst) return Standard_True;
881 Standard_Integer n = FyEds.Extent(); // DEB
885 //=======================================================================
886 //function : EdgeWithFaultyUV
888 //=======================================================================
890 Standard_Boolean TopOpeBRepTool_CORRISO::EdgeWithFaultyUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Integer nfybounds,
891 TopoDS_Shape& fyE, Standard_Integer& Ifaulty) const
893 TopTools_DataMapOfOrientedShapeInteger FyEds;
894 Standard_Boolean found = EdgesWithFaultyUV(EdsToCheck,nfybounds,FyEds,Standard_True);
895 if (!found) return Standard_False;
897 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(FyEds);
899 Ifaulty = itm.Value();
900 return Standard_True;
903 //=======================================================================
906 //=======================================================================
908 Standard_Boolean TopOpeBRepTool_CORRISO::TrslUV(const Standard_Boolean onU, const TopTools_DataMapOfOrientedShapeInteger& FyEds)
911 if (onU) {Standard_Real uper;
913 if (!uper) return Standard_False;
914 tt2d = gp_Vec2d(uper,0.);}
915 else {Standard_Real vper;
917 if (!vper) return Standard_False;
918 tt2d = gp_Vec2d(0.,vper);}
919 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(FyEds);
920 for (; itm.More(); itm.Next()){
921 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
922 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
923 if (!isb) return Standard_False;
925 Standard_Integer itt = itm.Value();
926 if (itt == SPLITEDGE) return Standard_False;
927 else if (itt == INCREASE) TopOpeBRepTool_TOOL::TrslUV(tt2d,C2DF);
928 else if (itt == DECREASE) TopOpeBRepTool_TOOL::TrslUV(tt2d.Multiplied(-1.),C2DF);
929 else return Standard_False;
932 return Standard_True;
935 // modif in BRep_Builder031298
936 /*static void FUN_tool_correctdgE(const TopoDS_Edge& E)
938 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
939 BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
940 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
941 while (itcr.More()) {
942 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
944 if (GC->IsCurve3D()) lcr.Remove(itcr);
950 //=======================================================================
953 //=======================================================================
955 Standard_Boolean TopOpeBRepTool_CORRISO::GetnewS(TopoDS_Face& newS) const
958 if (myS.ShapeType() != TopAbs_FACE) return Standard_False;
960 newS = TopoDS::Face(myS);
963 TopTools_ListIteratorOfListOfShape it(myEds);
964 for (; it.More(); it.Next()){
965 TopoDS_Edge E = TopoDS::Edge(it.Value());
966 TopAbs_Orientation oriE = E.Orientation();
967 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
968 if (!isb) return Standard_False;
970 Standard_Real f,l,tol;const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
971 Handle(Geom2d_TrimmedCurve) cu = new Geom2d_TrimmedCurve(PC,f,l);
973 TopoDS_Shape aLocalShape = E.Oriented(TopAbs::Complement(oriE));
974 TopoDS_Edge Err = TopoDS::Edge(aLocalShape);
975 // TopoDS_Edge Err = TopoDS::Edge(E.Oriented(TopAbs::Complement(oriE)));
976 TopOpeBRepTool_C2DF C2DFrr; Standard_Boolean isclo = UVRep(Err,C2DFrr);
978 // Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
979 // !BUC60380 : degenerated edge has a 3d curve !!, remove it
980 // if (isdgE) {FUN_tool_correctdgE(E);}
983 Standard_Real frr,lrr,tolrr;const Handle(Geom2d_Curve)& PCrr = C2DFrr.PC(frr,lrr,tolrr);
984 Handle(Geom2d_TrimmedCurve) curr = new Geom2d_TrimmedCurve(PCrr,frr,lrr);
985 if (M_FORWARD(oriE)) BB.UpdateEdge(E,cu,curr,newS,tol);
987 else BB.UpdateEdge(E,cu,newS,tol);
989 return Standard_True;
992 //=======================================================================
993 //function : AddNewConnexity
995 //=======================================================================
997 //Standard_Boolean TopOpeBRepTool_CORRISO::AddNewConnexity(const TopoDS_Vertex& V,
998 Standard_Boolean TopOpeBRepTool_CORRISO::AddNewConnexity(const TopoDS_Vertex& ,
999 const TopoDS_Edge& E)
1002 Standard_Boolean isb = myERep2d.IsBound(E);
1004 Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
1005 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,myFref,PC);
1006 PC = FC2D_EditableCurveOnSurface(E,myFref,f,l,tol);
1007 if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,myFref,f,l,tol);
1008 if (PC.IsNull()) return Standard_False;
1009 TopOpeBRepTool_C2DF C2DF(PC,f,l,tol,myFref);
1010 myERep2d.Bind(E,C2DF);
1014 if (!isb) myEds.Append(E);
1017 TopExp_Explorer exv(E, TopAbs_VERTEX);
1018 for (; exv.More(); exv.Next()){
1019 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
1020 Standard_Boolean isbb = myVEds.IsBound(v);
1021 if (isbb) myVEds.ChangeFind(v).Append(E);
1022 else {TopTools_ListOfShape loe; loe.Append(E); myVEds.Bind(v,loe);}
1024 return Standard_True;
1028 //=======================================================================
1029 //function : RemoveOldConnexity
1031 //=======================================================================
1033 //Standard_Boolean TopOpeBRepTool_CORRISO::RemoveOldConnexity(const TopoDS_Vertex& V,
1034 Standard_Boolean TopOpeBRepTool_CORRISO::RemoveOldConnexity(const TopoDS_Vertex& ,
1035 const TopoDS_Edge& E)
1038 Standard_Boolean isb = myERep2d.IsBound(E);
1039 if (isb) myERep2d.UnBind(E);
1043 TopTools_ListIteratorOfListOfShape it(myEds);
1045 if (it.Value().IsEqual(E)) {myEds.Remove(it);break;}
1051 Standard_Boolean done = Standard_False;
1052 TopExp_Explorer exv(E, TopAbs_VERTEX);
1053 for (; exv.More(); exv.Next()){
1054 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
1055 Standard_Boolean isBoundV = myVEds.IsBound(v);
1056 if (!isBoundV) return Standard_False;
1057 TopTools_ListOfShape& loe = myVEds.ChangeFind(v);
1058 TopTools_ListIteratorOfListOfShape ite(loe);
1059 while (ite.More()) {
1060 if (ite.Value().IsEqual(E)) {done = Standard_True; loe.Remove(ite);break;}