1 // Created on: 1998-11-25
2 // Created by: Prestataire Xuan PHAM PHU
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <TopOpeBRepTool.hxx>
23 #include <TopOpeBRepTool_TOOL.hxx>
24 #include <TopOpeBRepTool_CORRISO.ixx>
25 #include <TopOpeBRepTool_define.hxx>
26 #include <TopOpeBRepTool_EXPORT.hxx>
27 #include <TopOpeBRepTool_PURGE.hxx>
28 #include <TopOpeBRepTool_2d.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRep_Builder.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopTools_Array1OfShape.hxx>
33 #include <Geom2dAdaptor_Curve.hxx>
34 #include <Geom2d_TrimmedCurve.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36 #include <BndLib_Add2dCurve.hxx>
39 #include <BRep_TEdge.hxx>
40 #include <BRep_ListOfCurveRepresentation.hxx>
41 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
42 #include <BRep_GCurve.hxx>
45 extern Standard_Boolean TopOpeBRepTool_GettraceCORRISO();
46 Standard_EXPORT TopTools_IndexedMapOfShape STATIC_PURGE_mapv;
47 Standard_EXPORT TopTools_IndexedMapOfOrientedShape STATIC_PURGE_mapeds;
50 static void FUN_RaiseError()
53 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
55 // if (trc) cout <<"*********failure in CORRISO***********\n";
58 static void FUN_Raise()
61 // cout <<"*********failure in CORRISO***********\n";
66 #include <TopOpeBRepTool_DRAW.hxx>
69 #define M_FORWARD(sta) (sta == TopAbs_FORWARD)
70 #define M_REVERSED(sta) (sta == TopAbs_REVERSED)
71 #define M_INTERNAL(sta) (sta == TopAbs_INTERNAL)
72 #define M_EXTERNAL(sta) (sta == TopAbs_EXTERNAL)
74 //=======================================================================
75 //function : TopOpeBRepTool_CORRISO
77 //=======================================================================
79 TopOpeBRepTool_CORRISO::TopOpeBRepTool_CORRISO()
83 //=======================================================================
84 //function : TopOpeBRepTool_CORRISO
86 //=======================================================================
88 TopOpeBRepTool_CORRISO::TopOpeBRepTool_CORRISO(const TopoDS_Face& Fref)
92 FUN_tool_closedS(myFref,myUclosed,myUper,myVclosed,myVper);
94 const Handle(Geom_Surface)& SU = BRep_Tool::Surface(myFref);
95 myGAS = GeomAdaptor_Surface(SU);
98 //=======================================================================
101 //=======================================================================
103 const TopoDS_Face& TopOpeBRepTool_CORRISO::Fref() const
108 //=======================================================================
111 //=======================================================================
113 const GeomAdaptor_Surface& TopOpeBRepTool_CORRISO::GASref() const
119 //=======================================================================
120 //function : Refclosed
122 //=======================================================================
124 Standard_Boolean TopOpeBRepTool_CORRISO::Refclosed(const Standard_Integer x, Standard_Real& xperiod) const
126 if (x==1) {xperiod = myUper; return myUclosed;}
127 if (x==2) {xperiod = myVper; return myVclosed;}
128 return Standard_False;
133 //=======================================================================
136 //=======================================================================
138 Standard_Boolean TopOpeBRepTool_CORRISO::Init(const TopoDS_Shape& S)
141 Standard_Integer ie = 0;
142 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
143 Standard_Boolean INIT = Standard_True;
144 if (INIT) FUN_REINIT();
151 if (S.IsNull()) return Standard_False;
154 TopExp_Explorer ex(S, TopAbs_EDGE);
155 for (; ex.More(); ex.Next()){
156 const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
158 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
160 if (trc) {TCollection_AsciiString aa = TCollection_AsciiString("e"); FUN_tool_draw(aa,E,iE);}
168 // Standard_Real f,l,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,myFref,f,l,tol);
169 Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
170 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,myFref,PC);
171 PC = FC2D_EditableCurveOnSurface(E,myFref,f,l,tol);
172 if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,myFref,f,l,tol);
173 if (PC.IsNull()) return Standard_False;
174 TopOpeBRepTool_C2DF C2DF(PC,f,l,tol,myFref);
175 myERep2d.Bind(E,C2DF);
178 TopExp_Explorer exv(E, TopAbs_VERTEX);
179 for (; exv.More(); exv.Next()){
180 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
182 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
184 if (trc) {TCollection_AsciiString bb = TCollection_AsciiString("v"); FUN_tool_draw(bb,v,iv);}
187 Standard_Boolean isb = myVEds.IsBound(v);
188 if (isb) myVEds.ChangeFind(v).Append(E);
189 else {TopTools_ListOfShape loe; loe.Append(E); myVEds.Bind(v,loe);}
192 return Standard_True;
195 //=======================================================================
198 //=======================================================================
200 const TopoDS_Shape& TopOpeBRepTool_CORRISO::S() const
205 //=======================================================================
208 //=======================================================================
210 const TopTools_ListOfShape& TopOpeBRepTool_CORRISO::Eds() const
215 //=======================================================================
218 //=======================================================================
220 Standard_Boolean TopOpeBRepTool_CORRISO::UVRep(const TopoDS_Edge& E, TopOpeBRepTool_C2DF& C2DF) const
222 Standard_Boolean isb = myERep2d.IsBound(E);
223 if (!isb) return Standard_False;
225 C2DF = myERep2d.Find(E);
226 return Standard_True;
229 //=======================================================================
230 //function : SetUVRep
232 //=======================================================================
234 Standard_Boolean TopOpeBRepTool_CORRISO::SetUVRep(const TopoDS_Edge& E, const TopOpeBRepTool_C2DF& C2DF)
236 Standard_Boolean isb = myERep2d.IsBound(E);
237 if (!isb) return Standard_False;
239 myERep2d.ChangeFind(E) = C2DF;
240 return Standard_True;
243 //=======================================================================
244 //function : Connexity
246 //=======================================================================
248 Standard_Boolean TopOpeBRepTool_CORRISO::Connexity(const TopoDS_Vertex& V, TopTools_ListOfShape& Eds) const
250 Standard_Boolean isb = myVEds.IsBound(V);
251 if (!isb) return Standard_False;
253 Eds = myVEds.Find(V);
254 return Standard_True;
257 //=======================================================================
258 //function : SetConnexity
260 //=======================================================================
262 Standard_Boolean TopOpeBRepTool_CORRISO::SetConnexity(const TopoDS_Vertex& V, const TopTools_ListOfShape& Eds)
264 Standard_Boolean isb = myVEds.IsBound(V);
265 if (!isb) return Standard_False;
267 myVEds.ChangeFind(V) = Eds;
268 return Standard_True;
271 //=======================================================================
272 //function : UVClosed
274 //=======================================================================
276 Standard_Boolean TopOpeBRepTool_CORRISO::UVClosed() const
279 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
280 if (trc) cout<<"** UVClosed"<<endl;
282 TopTools_DataMapOfOrientedShapeInteger lfyE; Standard_Integer nfybounds=3; Standard_Boolean stopatfirst = Standard_True;
283 Standard_Boolean foundfaulty = EdgesWithFaultyUV(myEds,nfybounds,lfyE,stopatfirst);
287 //=======================================================================
290 //=======================================================================
292 Standard_Real TopOpeBRepTool_CORRISO::Tol(const Standard_Integer I, const Standard_Real tol3d) const
294 Standard_Real tol = (I==1) ? myGAS.UResolution(tol3d) : myGAS.VResolution(tol3d);
298 //static Standard_Real FUN_getx(const TopoDS_Edge& E,
299 static Standard_Real FUN_getx(const TopoDS_Edge& ,
300 const TopOpeBRepTool_C2DF& c2df,
301 const Standard_Boolean uiso,
302 const Standard_Real par)
303 { // prequesitory : E is uviso
304 gp_Pnt2d uv = TopOpeBRepTool_TOOL::UVF(par,c2df);
305 Standard_Real x = (uiso) ? uv.Y() : uv.X();
309 //=======================================================================
310 //function : PurgeFyClosingE
312 //=======================================================================
314 Standard_Boolean TopOpeBRepTool_CORRISO::PurgeFyClosingE(const TopTools_ListOfShape& ClEds, TopTools_ListOfShape& fyClEds) const
318 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
319 if (trc) cout<<"* PurgeFyClosingE"<<endl;
321 // Standard_Real xperiod = myUclosed ? myUper : myVper;
322 Standard_Real tttol = 1.e-8;
323 Standard_Real tttolS = BRep_Tool::Tolerance(myFref);
324 Standard_Real tolu = Tol(1,tttolS), tolv = Tol(2,tttolS);
325 Standard_Real tttuvF = Max(tolu,tolv);
327 TopTools_IndexedMapOfOrientedShape mapcl;
328 TopTools_ListIteratorOfListOfShape itce(ClEds);
329 for (; itce.More(); itce.Next()) mapcl.Add(itce.Value());
331 //* one closing edge should be removed
332 itce.Initialize(ClEds);
333 TopTools_DataMapOfOrientedShapeInteger fyceds; Standard_Boolean found = EdgesWithFaultyUV(ClEds,3,fyceds);
334 if (!found) return Standard_False;
336 if (fyceds.Extent() == 1) {// ivf == 3 : cto016G*
337 TopTools_DataMapOfOrientedShapeInteger fyeds;
339 EdgesWithFaultyUV(myEds,3,fyeds);
340 Standard_Integer nfy = fyeds.Extent();
342 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(fyceds);
343 const TopoDS_Edge& cE = TopoDS::Edge(itm.Key());
345 TopAbs_Orientation OocE = TopAbs::Complement(cE.Orientation());
346 Standard_Boolean isoncE = mapcl.Contains(cE.Oriented(OocE));
348 TopTools_Array1OfShape vcE(1,2); TopOpeBRepTool_TOOL::Vertices(cE,vcE);
349 TopAbs_Orientation ocE = cE.Orientation();
350 Standard_Real tttolcE = BRep_Tool::Tolerance(cE);
351 Standard_Real tttuvcE = Max(Tol(1,tttolcE),Tol(2,tttolcE));
352 TopOpeBRepTool_C2DF cE2d; Standard_Boolean isb = UVRep(cE,cE2d);
353 if (!isb) return Standard_False; // NYIRAISE
356 // OcE (closing edge with complemented orientation):
357 TopAbs_Orientation oOcE = TopAbs::Complement(ocE);
358 TopoDS_Shape alocalShape = cE.Oriented(oOcE);
359 TopoDS_Edge OcE = TopoDS::Edge(alocalShape);
360 // TopoDS_Edge OcE = TopoDS::Edge(cE.Oriented(oOcE));
361 TopTools_Array1OfShape vOcE(1,2); TopOpeBRepTool_TOOL::Vertices(OcE,vOcE);
362 Standard_Real tttolOcE = BRep_Tool::Tolerance(OcE);
363 Standard_Real tttuvOcE = Max(Tol(1,tttolOcE),Tol(2,tttolOcE));
364 TopOpeBRepTool_C2DF OcE2d; Standard_Boolean isOb = UVRep(OcE,OcE2d);
365 if (!isOb) return Standard_False; // NYIRAISE
367 Standard_Real parvce1 = TopOpeBRepTool_TOOL::ParE(1,cE); gp_Pnt2d UVvce1 = TopOpeBRepTool_TOOL::UVF(parvce1,cE2d);
369 Standard_Real parvOcE2 = TopOpeBRepTool_TOOL::ParE(2,OcE); gp_Pnt2d UVvOcE2 = TopOpeBRepTool_TOOL::UVF(parvOcE2,OcE2d);
370 Standard_Real tol = Max(tttuvcE,tttuvOcE);
371 isoncE = (UVvce1.Distance(UVvOcE2) < tol);
372 if (isoncE && (nfy != 1)) {// cto009L2
373 return Standard_False;
377 Standard_Integer ivf = itm.Value();
380 return Standard_True;
383 else if (fyceds.Extent() > 1) {// ivf == 1,2 : cto016E*
384 // if {edges of fyceds} describe a closing edge with its first and last
385 // uvbounds non connexed -> we do remove these edges
386 Standard_Boolean hasinit=Standard_False; Standard_Boolean isou=Standard_False,isov=Standard_False;
387 gp_Pnt2d o2d; gp_Dir2d d2d;
388 Standard_Real xinf=1.e7, xsup=-1.e7; // faulty inf and sup bounds
389 Standard_Boolean infdef=Standard_False, supdef=Standard_False;
390 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(fyceds);
391 for (; itm.More(); itm.Next()){
392 const TopoDS_Edge& cE = TopoDS::Edge(itm.Key());
393 TopOpeBRepTool_C2DF c2df; Standard_Boolean isb = UVRep(cE,c2df);
394 if (!isb) return Standard_False; // NYIRAISE
396 Standard_Integer ivf = itm.Value();
397 Standard_Boolean isoux,isovx; gp_Pnt2d o2dx; gp_Dir2d d2dx;
398 Standard_Boolean uvisox = TopOpeBRepTool_TOOL::UVISO(c2df,isoux,isovx, d2dx, o2dx);
399 if (!uvisox) return Standard_False;
402 Standard_Boolean onsamline = (isou && isoux) || (isov && isovx);
403 if (!onsamline) return Standard_False;
406 isou=isoux; isov=isovx;
408 hasinit = Standard_True;
411 Standard_Boolean onsamline = Standard_False;
413 Standard_Real du = o2d.X()-o2dx.X();
414 onsamline = (Abs(du) < tolu);
417 Standard_Real dv = o2d.Y()-o2dx.Y();
418 onsamline = (Abs(dv) < tolv);
420 if (!onsamline) return Standard_False;
422 for (Standard_Integer i = 1; i <=2; i++) {
423 Standard_Real pari = TopOpeBRepTool_TOOL::ParE(i,cE);
424 Standard_Real xi = FUN_getx(cE,c2df,isou,pari);
425 Standard_Boolean vifaulty = (ivf == i || ivf == 3);
426 Standard_Boolean inff = (xi < xinf);
427 Standard_Boolean supl = (xi > xsup);
428 // if (inff) xinf = (ivf == i || ivf == 3) ? xi : 1.e7;
429 // if (supl) xsup = (ivf == i || ivf == 3) ? xi : -1.e7;
430 if (inff) {xinf = xi; infdef = vifaulty;}
431 if (supl) {xsup = xi; supdef = vifaulty;}
435 Standard_Boolean toremove = infdef && supdef; // ie infx,supx are not "uv-connexed"
436 if (!toremove) fyClEds.Clear();
438 if (!fyClEds.IsEmpty()) return Standard_True; // keeping only one closing edge
440 //* the 2 closing edges have they 2drep "confunded"
441 itce.Initialize(ClEds);
442 for (; itce.More(); itce.Next()){
444 const TopoDS_Edge& cE = TopoDS::Edge(itce.Value());
445 TopTools_Array1OfShape vcE(1,2); TopOpeBRepTool_TOOL::Vertices(cE,vcE);
446 TopAbs_Orientation ocE = cE.Orientation();
448 Standard_Real tttolcE = BRep_Tool::Tolerance(cE);
449 Standard_Real tttuvcE = Max(Tol(1,tttolcE),Tol(2,tttolcE));
450 TopOpeBRepTool_C2DF cE2d; Standard_Boolean isb = UVRep(cE,cE2d);
451 if (!isb) return Standard_False; // NYIRAISE
453 Standard_Integer icE = STATIC_PURGE_mapeds.Add(cE);
454 if (trc) cout<<"? e"<<icE<<" :"<<endl;
458 Standard_Boolean isonOcE2d = Standard_False;
460 // OcE (closing edge with complemented orientation):
461 TopAbs_Orientation oOcE = TopAbs::Complement(ocE);
462 TopoDS_Shape aLocalShape = cE.Oriented(oOcE);
463 TopoDS_Edge OcE = TopoDS::Edge(aLocalShape);
464 // TopoDS_Edge OcE = TopoDS::Edge(cE.Oriented(oOcE));
465 TopTools_Array1OfShape vOcE(1,2); TopOpeBRepTool_TOOL::Vertices(OcE,vOcE);
466 Standard_Boolean hasOcE = mapcl.Contains(OcE);
467 if (!hasOcE) continue; // closing edge appears twice
468 Standard_Real tttolOcE = BRep_Tool::Tolerance(OcE);
469 Standard_Real tttuvOcE = Max(Tol(1,tttolOcE),Tol(2,tttolOcE));
470 TopOpeBRepTool_C2DF OcE2d; Standard_Boolean isOb = UVRep(OcE,OcE2d);
471 if (!isOb) return Standard_False; // NYIRAISE
473 Standard_Real parvce1 = TopOpeBRepTool_TOOL::ParE(1,cE); gp_Pnt2d UVvce1 = TopOpeBRepTool_TOOL::UVF(parvce1,cE2d);
475 Standard_Real parvOcE2 = TopOpeBRepTool_TOOL::ParE(2,OcE); gp_Pnt2d UVvOcE2 = TopOpeBRepTool_TOOL::UVF(parvOcE2,OcE2d);
476 Standard_Real tol = Max(tttuvcE,tttuvOcE);
477 isonOcE2d = (UVvce1.Distance(UVvOcE2) < tol);
481 if (trc) cout<<"-> valid edge"<<endl;
486 Standard_Integer nvcEok = 0;
487 for (Standard_Integer ivce = 1; ivce <=2; ivce++) {
488 // <vce> (boundary of <cE>):
489 const TopoDS_Vertex& vce = TopoDS::Vertex(vcE(ivce));
490 TopTools_ListOfShape loe; isb = Connexity(vce,loe);
492 if (!isb) return Standard_False; // NYIRAISE
494 Standard_Real parvce = TopOpeBRepTool_TOOL::ParE(ivce,cE); gp_Pnt2d UVvce = TopOpeBRepTool_TOOL::UVF(parvce,cE2d);
496 // recall in one wire, there are 2 vertices for one non-degenerated closing edge
497 Standard_Integer ivmapv = STATIC_PURGE_mapv.Add(vce);
498 if (trc) {cout<<" connexity for v("<<ivce<<")=v"<<ivmapv;FUN_tool_trace(UVvce);}
500 if (trc) {TCollection_AsciiString bb("uv_");bb += TCollection_AsciiString(ivmapv);FUN_tool_draw(bb,UVvce);}
503 Standard_Real tttolvce = BRep_Tool::Tolerance(vce);
504 Standard_Real tttuvvce = Max(Tol(1,tttolvce),Tol(2,tttolvce));
506 Standard_Boolean vceok = Standard_False;
507 for (TopTools_ListIteratorOfListOfShape ite(loe); ite.More(); ite.Next()) {
508 const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
511 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
512 if (trc) {cout<<" : on e"<<iE<<endl;}
514 // if (E.IsSame(cE)) continue;
515 if (mapcl.Contains(E)) continue; // do NOT check connexity on closing edges
516 // xpu090399 cto016E1
518 TopOpeBRepTool_C2DF E2d; Standard_Boolean isb = UVRep(E,E2d);
519 if (!isb) return Standard_False; // NYIRAISE
521 Standard_Real tttolE = BRep_Tool::Tolerance(E);
522 Standard_Real tttuvE = Max(Tol(1,tttolE),Tol(2,tttolE));
524 TopTools_Array1OfShape vE(1,2); TopOpeBRepTool_TOOL::Vertices(E,vE);
525 for (Standard_Integer ive = 1; ive <=2; ive++) {
527 const TopoDS_Vertex& ve = TopoDS::Vertex(vE(ive));
528 Standard_Boolean samev = ve.IsSame(vce);
529 if (!samev) continue;
530 Standard_Real parve = TopOpeBRepTool_TOOL::ParE(ive,E); gp_Pnt2d UVve = TopOpeBRepTool_TOOL::UVF(parve,E2d);
532 if (trc) {cout<<" ve("<<ive<<")";FUN_tool_trace(UVve);}
534 if (ive == ivce) continue; // vertex FORWARD connexed to REVERSED one
535 Standard_Real tttolve = BRep_Tool::Tolerance(ve);
536 Standard_Real tttuvve = Max(Tol(1,tttolve),Tol(2,tttolve));
538 tttol = Max(tttol,Max(tttuvF,Max(tttuvE,Max(tttuvcE,Max(tttuvve,tttuvvce)))));
539 // Standard_Real dd = myUclosed ? (UVve.X()-UVvce.X()) : (UVve.Y()-UVvce.Y());
540 // Standard_Boolean xok = (Abs(dd)<tttol) || (Abs(Abs(dd)-xperiod)<tttol);
542 Standard_Real dd = UVve.Distance(UVvce);
543 Standard_Boolean sameuv = (dd < tttol);
545 Standard_Real xperiod = myUper;
546 dd = (UVve.X()-UVvce.X());
547 sameuv = sameuv || (Abs(Abs(dd)-xperiod)<tttol);
550 Standard_Real xperiod = myVper;
551 dd = (UVve.Y()-UVvce.Y());
552 sameuv = sameuv || (Abs(Abs(dd)-xperiod)<tttol);
555 vceok = Standard_True;
557 if (trc){cout<<" connexity->ok"<<endl;}
566 if (trc && !vceok) {cout<<" connexity->KO"<<endl;}
571 Standard_Boolean isfycE = (nvcEok == 0); // each bound is not connexed to any non-closed edge
575 {if (isfycE) cout<<"-> faulty edge"<<endl;
576 else cout<<"-> valid edge"<<endl;}
578 if (isfycE) fyClEds.Append(cE);
580 return (!fyClEds.IsEmpty());
583 #define SPLITEDGE (0)
585 #define DECREASE (-1)
587 static Standard_Integer FUN_tool_recadre(const Standard_Real minx,const Standard_Real maxx,
588 const Standard_Real xfirst,const Standard_Real xlast,const Standard_Real tolx,
589 Standard_Boolean& maxsup)
591 Standard_Integer recadre = 10; // INIT
592 Standard_Boolean maxinf = (maxx < xfirst+tolx); // permissive
593 Standard_Boolean mininf = (minx < xfirst-tolx);//
594 maxsup = (maxx > xlast+tolx); //
595 Standard_Boolean minsup = (minx > xlast-tolx); // permissive
596 Standard_Boolean maxok = (xfirst-tolx < maxx) && (maxx < xlast+tolx);// permissive
597 Standard_Boolean minok = (xfirst-tolx < minx) && (minx < xlast+tolx); // permissive
599 if (maxinf) recadre = INCREASE;
600 else if (minsup) recadre = DECREASE;
601 else if (mininf && maxok) recadre = SPLITEDGE;
602 else if (minok && maxsup) recadre = SPLITEDGE;
606 //=======================================================================
607 //function : EdgeOUTofBoundsUV
609 //=======================================================================
611 Standard_Integer TopOpeBRepTool_CORRISO::EdgeOUTofBoundsUV(const TopoDS_Edge& E, const Standard_Boolean onU, const Standard_Real tolx,
612 Standard_Real& parspE) const
614 Standard_Integer recadre = 10; parspE = -1.e7; // INIT
615 Standard_Integer isb = myERep2d.IsBound(E);
616 if (!isb) return Standard_False;
618 const TopOpeBRepTool_C2DF& C2DF = myERep2d.Find(E);
619 Standard_Real f,l,tol; const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
621 Standard_Real xfirst = onU ? myGAS.FirstUParameter() : myGAS.FirstVParameter();
622 Standard_Real xlast = onU ? myGAS.LastUParameter() : myGAS.LastVParameter(); // xlast=xfirst+xperiod
623 Standard_Real xperiod = onU ? myUper : myVper;
625 Standard_Boolean isou,isov; gp_Pnt2d o2d; gp_Dir2d d2d;
626 Standard_Boolean iso = TopOpeBRepTool_TOOL::UVISO(PC,isou,isov,d2d,o2d);
628 if (iso) { // 2drep(E,myFref) is an ISO
629 // -------------------------
630 Standard_Boolean inX = (onU && isou) || ((!onU) && isov);
632 // faulty u-iso : upar out of ubound
633 Standard_Real xpar = onU ? o2d.X() : o2d.Y();
634 Standard_Boolean toosmall = (xpar < xfirst-tolx);
635 Standard_Boolean tobig = (xpar > xfirst+xperiod+tolx);
637 if (toosmall) recadre = INCREASE;
638 if (tobig) recadre = DECREASE;
641 Standard_Boolean inY = (onU && isov) || ((!onU) && isou); // inY = !inX
643 // faulty u-iso : vpar describes (minv,maxv) out of vbounds
644 // PC describes [minx,maxx] in x-space
645 // recadre = INCREASE : maxx < 0.
646 // DECREASE : minx > 2PI
647 // SPLITEDGE : minx<0.<maxx || minx<2PI<maxx
648 Standard_Real d2ddir = onU? d2d.Y(): d2d.X();
649 Standard_Boolean reverse = (d2ddir < 0.); Standard_Real xfactor = reverse? -1.: 1.;
650 Standard_Real max = reverse? f: l;
651 Standard_Real min = reverse? l: f;
652 gp_Pnt2d maxuv = PC->Value(max);
653 gp_Pnt2d minuv = PC->Value(min);
655 Standard_Real maxx = onU? maxuv.X(): maxuv.Y();
656 Standard_Real minx = onU? minuv.X(): minuv.Y();
658 Standard_Boolean maxsup;
659 recadre = FUN_tool_recadre(minx,maxx,xfirst,xlast,tolx,
661 if (recadre == SPLITEDGE) {
662 Standard_Real xbound = maxsup? xperiod: 0.;
663 parspE = max - xfactor*(maxx-xbound);
668 else { // 2drep(E, myFref) is NOT an iso
669 // ------------------------------
671 Geom2dAdaptor_Curve GC2d(PC,f,l);
672 Standard_Real tolE = BRep_Tool::Tolerance(E);
673 Standard_Real toladd = Max(tolE,tol);
674 BndLib_Add2dCurve::Add(GC2d,toladd,Bn2d);
675 Standard_Real umin,vmin,umax,vmax; Bn2d.Get(umin,vmin,umax,vmax);
676 Standard_Real xmin = onU ? umin : vmin;
677 Standard_Real xmax = onU ? umax : vmax;
678 Standard_Boolean maxsup;
679 recadre = FUN_tool_recadre(xmin,xmax,xfirst,xlast,tolx,
681 if (recadre == SPLITEDGE) {
682 // ================================================================
683 //NYIxpu271198 : intersection PC avec xiso (x= maxsup? xperiod: 0.)
684 // ================================================================
692 //=======================================================================
693 //function : EdgesOUTofBoundsUV
695 //=======================================================================
697 Standard_Boolean TopOpeBRepTool_CORRISO::EdgesOUTofBoundsUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Boolean onU, const Standard_Real tolx,
698 TopTools_DataMapOfOrientedShapeInteger & FyEds) const
701 TopTools_ListIteratorOfListOfShape it(EdsToCheck);
702 for (; it.More(); it.Next()){
703 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
704 Standard_Real sspar = -1.e7;
705 Standard_Integer recadre = EdgeOUTofBoundsUV(E,onU,tolx,sspar);
706 if (recadre == SPLITEDGE) FUN_Raise();
707 if (recadre == INCREASE) FyEds.Bind(E,1);
708 if (recadre == DECREASE) FyEds.Bind(E,-1);
710 return (!FyEds.IsEmpty());
714 //=======================================================================
715 //function : EdgeWithFaultyUV
717 //=======================================================================
719 Standard_Boolean TopOpeBRepTool_CORRISO::EdgeWithFaultyUV(const TopoDS_Edge& E, Standard_Integer& Ivfaulty) const
722 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
723 Standard_Integer iE = STATIC_PURGE_mapeds.Add(E);
724 if (trc) cout<<"? e"<<iE<<" :"<<endl;
727 Standard_Real tttol = 1.e-8;
728 Standard_Real tttolF = BRep_Tool::Tolerance(TopoDS::Face(myFref));
729 Standard_Real tttuvF = Max(Tol(1,tttolF),Tol(2,tttolF));
730 Standard_Real tttolE = BRep_Tool::Tolerance(E);
731 Standard_Real tttuvE = Max(Tol(1,tttolE),Tol(2,tttolE));
733 TopAbs_Orientation oE = E.Orientation();
734 if (M_INTERNAL(oE) || M_EXTERNAL(oE)) return Standard_False;
736 TopTools_Array1OfShape vEs(1,2); TopOpeBRepTool_TOOL::Vertices(E, vEs);
737 Standard_Boolean closed = vEs(1).IsSame(vEs(2));
740 if (trc) {cout<<"closed -> valid edge"<<endl;}
742 return Standard_False; // closed edge is assumed valid
745 Standard_Integer nfyv = 0;
746 for (Standard_Integer ivE = 1; ivE <=2; ivE++) {
748 // <vE> (boundary of <E>):
749 const TopoDS_Vertex& vE = TopoDS::Vertex(vEs(ivE));
750 Standard_Real parvE = TopOpeBRepTool_TOOL::ParE(ivE,E);
751 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
752 if (!isb) return Standard_False; //NYIRAISE
753 gp_Pnt2d UVvE = TopOpeBRepTool_TOOL::UVF(parvE,C2DF);
755 // recall in one wire, there are 2 vertices for one non-degenerated closing edge
756 Standard_Integer ivmapv = STATIC_PURGE_mapv.Add(vE);
757 if (trc) {cout<<" connexity for v("<<ivE<<")=v"<<ivmapv;FUN_tool_trace(UVvE);}
759 if (trc) {TCollection_AsciiString bb("uv_");bb += TCollection_AsciiString(ivmapv);FUN_tool_draw(bb,UVvE);}
763 Standard_Real tttolvE = BRep_Tool::Tolerance(vE);
764 Standard_Real tttuvvE = Max(Tol(1,tttolvE),Tol(2,tttolvE));
766 Standard_Boolean isbound = myVEds.IsBound(vE);
767 if (!isbound) {FUN_RaiseError(); return Standard_False;}
770 Standard_Boolean vEok = Standard_False;
771 const TopTools_ListOfShape& loe = myVEds.Find(vE);
773 for (TopTools_ListIteratorOfListOfShape ite(loe); ite.More(); ite.Next()) {
774 const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
775 TopAbs_Orientation oe = e.Orientation();
778 Standard_Integer ie = STATIC_PURGE_mapeds.Add(e);
779 if (trc) {cout<<" : on e"<<ie<<endl;}
782 if (e.IsSame(E)) continue;
783 if (M_INTERNAL(oe) || M_EXTERNAL(oe)) continue;
785 Standard_Boolean isb = myERep2d.IsBound(e);
786 if (!isb) {FUN_RaiseError(); return Standard_False;}
787 const TopOpeBRepTool_C2DF& C2DF = myERep2d.Find(e);
789 TopTools_Array1OfShape ves(1,2); TopOpeBRepTool_TOOL::Vertices(e,ves);
790 for (Standard_Integer ive = 1; ive <=2; ive++) {
791 const TopoDS_Vertex& ve = TopoDS::Vertex(ves(ive));
792 Standard_Boolean samev = ve.IsSame(vE);
793 if (!samev) continue;
795 Standard_Real pare = TopOpeBRepTool_TOOL::ParE(ive,e); gp_Pnt2d UVve = TopOpeBRepTool_TOOL::UVF(pare,C2DF);
797 if (trc) {cout<<" ve("<<ive<<")";FUN_tool_trace(UVve);}
799 if (ive == ivE) continue;
801 Standard_Real tttolve = BRep_Tool::Tolerance(ve);
802 Standard_Real tttuvve = Max(Tol(1,tttolve),Tol(2, tttolve));
804 tttol = Max(tttol,Max(tttuvF,Max(tttuvE,Max(tttuvE,Max(tttuvve,tttuvvE)))));
805 Standard_Boolean isequal = UVvE.IsEqual(UVve,tttol);
807 vEok = Standard_True;
809 if (trc){cout<<" connexity->ok"<<endl;}
817 if (!vEok) {nfyv++; Ivfaulty = ivE;}
819 if (trc && !vEok) {cout<<" connexity->KO"<<endl;}
823 if (nfyv == 2) Ivfaulty = 3;
825 if (trc) {if (Ivfaulty == 0) cout<<"-> valid edge"<<endl; else cout<<"-> faulty edge"<<endl;}
827 return (Ivfaulty != 0);
830 //=======================================================================
831 //function : EdgesWithFaultyUV
833 //=======================================================================
835 Standard_Boolean TopOpeBRepTool_CORRISO::EdgesWithFaultyUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Integer nfybounds,
836 TopTools_DataMapOfOrientedShapeInteger& FyEds, const Standard_Boolean stopatfirst) const
840 Standard_Integer ifault = 0;
841 Standard_Boolean trc = TopOpeBRepTool_GettraceCORRISO();
842 if (trc) cout<<endl<<"* EdgesWithFaultyUV"<<endl;
847 // An edge is valid if the first and last vertices are valid:
848 // vertex <vEchk> is valid if there is an edge with bound <ve> such that :
849 // <vEchk> and <ve> share same UV geometry
850 // <vEchk> and <ve> are of opposite orientation.
851 TopTools_ListIteratorOfListOfShape itchk(EdsToCheck);
852 for (; itchk.More(); itchk.Next()) {
854 const TopoDS_Edge& Echk = TopoDS::Edge(itchk.Value());
855 Standard_Integer Ivfaulty=0; Standard_Boolean faulty = EdgeWithFaultyUV(Echk,Ivfaulty);
856 if (!faulty) continue;
857 Standard_Integer nfyv = (Ivfaulty == 3)? 2 : 1;
861 if (trc) cout<<"e"<<STATIC_PURGE_mapeds.FindIndex(Echk)<<" has ifyv="<<Ivfaulty<<endl;
863 if (trc) {TCollection_AsciiString aa("fault"); FUN_tool_draw(aa,Echk,ifault);}
867 Standard_Boolean found = Standard_False;
868 if (nfybounds == 1) found = (nfyv == nfybounds);
869 else if (nfybounds == 2) found = (nfyv == nfybounds);
870 else if (nfybounds == 3) found = (nfyv > 0);
873 FyEds.Bind(Echk,Ivfaulty);
874 if (stopatfirst) return Standard_True;
877 Standard_Integer n = FyEds.Extent(); // DEB
881 //=======================================================================
882 //function : EdgeWithFaultyUV
884 //=======================================================================
886 Standard_Boolean TopOpeBRepTool_CORRISO::EdgeWithFaultyUV(const TopTools_ListOfShape& EdsToCheck, const Standard_Integer nfybounds,
887 TopoDS_Shape& fyE, Standard_Integer& Ifaulty) const
889 TopTools_DataMapOfOrientedShapeInteger FyEds;
890 Standard_Boolean found = EdgesWithFaultyUV(EdsToCheck,nfybounds,FyEds,Standard_True);
891 if (!found) return Standard_False;
893 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(FyEds);
895 Ifaulty = itm.Value();
896 return Standard_True;
899 //=======================================================================
902 //=======================================================================
904 Standard_Boolean TopOpeBRepTool_CORRISO::TrslUV(const Standard_Boolean onU, const TopTools_DataMapOfOrientedShapeInteger& FyEds)
907 if (onU) {Standard_Real uper;
909 if (!uper) return Standard_False;
910 tt2d = gp_Vec2d(uper,0.);}
911 else {Standard_Real vper;
913 if (!vper) return Standard_False;
914 tt2d = gp_Vec2d(0.,vper);}
915 TopTools_DataMapIteratorOfDataMapOfOrientedShapeInteger itm(FyEds);
916 for (; itm.More(); itm.Next()){
917 const TopoDS_Edge& E = TopoDS::Edge(itm.Key());
918 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
919 if (!isb) return Standard_False;
921 Standard_Integer itt = itm.Value();
922 if (itt == SPLITEDGE) return Standard_False;
923 else if (itt == INCREASE) TopOpeBRepTool_TOOL::TrslUV(tt2d,C2DF);
924 else if (itt == DECREASE) TopOpeBRepTool_TOOL::TrslUV(tt2d.Multiplied(-1.),C2DF);
925 else return Standard_False;
928 return Standard_True;
931 // modif in BRep_Builder031298
932 /*static void FUN_tool_correctdgE(const TopoDS_Edge& E)
934 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &E.TShape());
935 BRep_ListOfCurveRepresentation& lcr = TE->ChangeCurves();
936 BRep_ListIteratorOfListOfCurveRepresentation itcr(lcr);
937 while (itcr.More()) {
938 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
940 if (GC->IsCurve3D()) lcr.Remove(itcr);
946 //=======================================================================
949 //=======================================================================
951 Standard_Boolean TopOpeBRepTool_CORRISO::GetnewS(TopoDS_Face& newS) const
954 if (myS.ShapeType() != TopAbs_FACE) return Standard_False;
956 newS = TopoDS::Face(myS);
959 TopTools_ListIteratorOfListOfShape it(myEds);
960 for (; it.More(); it.Next()){
961 TopoDS_Edge E = TopoDS::Edge(it.Value());
962 TopAbs_Orientation oriE = E.Orientation();
963 TopOpeBRepTool_C2DF C2DF; Standard_Boolean isb = UVRep(E,C2DF);
964 if (!isb) return Standard_False;
966 Standard_Real f,l,tol;const Handle(Geom2d_Curve)& PC = C2DF.PC(f,l,tol);
967 Handle(Geom2d_TrimmedCurve) cu = new Geom2d_TrimmedCurve(PC,f,l);
969 TopoDS_Shape aLocalShape = E.Oriented(TopAbs::Complement(oriE));
970 TopoDS_Edge Err = TopoDS::Edge(aLocalShape);
971 // TopoDS_Edge Err = TopoDS::Edge(E.Oriented(TopAbs::Complement(oriE)));
972 TopOpeBRepTool_C2DF C2DFrr; Standard_Boolean isclo = UVRep(Err,C2DFrr);
974 // Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
975 // !BUC60380 : degenerated edge has a 3d curve !!, remove it
976 // if (isdgE) {FUN_tool_correctdgE(E);}
979 Standard_Real frr,lrr,tolrr;const Handle(Geom2d_Curve)& PCrr = C2DFrr.PC(frr,lrr,tolrr);
980 Handle(Geom2d_TrimmedCurve) curr = new Geom2d_TrimmedCurve(PCrr,frr,lrr);
981 if (M_FORWARD(oriE)) BB.UpdateEdge(E,cu,curr,newS,tol);
983 else BB.UpdateEdge(E,cu,newS,tol);
985 return Standard_True;
988 //=======================================================================
989 //function : AddNewConnexity
991 //=======================================================================
993 //Standard_Boolean TopOpeBRepTool_CORRISO::AddNewConnexity(const TopoDS_Vertex& V,
994 Standard_Boolean TopOpeBRepTool_CORRISO::AddNewConnexity(const TopoDS_Vertex& ,
995 const TopoDS_Edge& E)
998 Standard_Boolean isb = myERep2d.IsBound(E);
1000 Handle(Geom2d_Curve) PC; Standard_Real f,l,tol;
1001 Standard_Boolean hasold = FC2D_HasOldCurveOnSurface(E,myFref,PC);
1002 PC = FC2D_EditableCurveOnSurface(E,myFref,f,l,tol);
1003 if (!hasold) FC2D_AddNewCurveOnSurface(PC,E,myFref,f,l,tol);
1004 if (PC.IsNull()) return Standard_False;
1005 TopOpeBRepTool_C2DF C2DF(PC,f,l,tol,myFref);
1006 myERep2d.Bind(E,C2DF);
1010 if (!isb) myEds.Append(E);
1013 TopExp_Explorer exv(E, TopAbs_VERTEX);
1014 for (; exv.More(); exv.Next()){
1015 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
1016 Standard_Boolean isbb = myVEds.IsBound(v);
1017 if (isbb) myVEds.ChangeFind(v).Append(E);
1018 else {TopTools_ListOfShape loe; loe.Append(E); myVEds.Bind(v,loe);}
1020 return Standard_True;
1024 //=======================================================================
1025 //function : RemoveOldConnexity
1027 //=======================================================================
1029 //Standard_Boolean TopOpeBRepTool_CORRISO::RemoveOldConnexity(const TopoDS_Vertex& V,
1030 Standard_Boolean TopOpeBRepTool_CORRISO::RemoveOldConnexity(const TopoDS_Vertex& ,
1031 const TopoDS_Edge& E)
1034 Standard_Boolean isb = myERep2d.IsBound(E);
1035 if (isb) myERep2d.UnBind(E);
1039 TopTools_ListIteratorOfListOfShape it(myEds);
1041 if (it.Value().IsEqual(E)) {myEds.Remove(it);break;}
1047 Standard_Boolean done = Standard_False;
1048 TopExp_Explorer exv(E, TopAbs_VERTEX);
1049 for (; exv.More(); exv.Next()){
1050 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
1051 Standard_Boolean isb = myVEds.IsBound(v);
1052 if (!isb) return Standard_False;
1053 TopTools_ListOfShape& loe = myVEds.ChangeFind(v);
1054 TopTools_ListIteratorOfListOfShape ite(loe);
1055 while (ite.More()) {
1056 if (ite.Value().IsEqual(E)) {done = Standard_True; loe.Remove(ite);break;}