1 // Created on: 1998-12-08
2 // Created by: Xuan PHAM PHU
3 // Copyright (c) 1997-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 <BRep_Tool.hxx>
19 #include <Geom2d_Curve.hxx>
20 #include <Precision.hxx>
21 #include <TopExp_Explorer.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopOpeBRepTool_C2DF.hxx>
28 #include <TopOpeBRepTool_connexity.hxx>
29 #include <TopOpeBRepTool_define.hxx>
30 #include <TopOpeBRepTool_EXPORT.hxx>
31 #include <TopOpeBRepTool_REGUW.hxx>
32 #include <TopOpeBRepTool_TOOL.hxx>
35 #include <TopOpeBRepTool_DRAW.hxx>
44 #define M_FORWARD(ori) (ori == TopAbs_FORWARD)
45 #define M_REVERSED(ori) (ori == TopAbs_REVERSED)
46 #define M_INTERNAL(ori) (ori == TopAbs_INTERNAL)
47 #define M_EXTERNAL(ori) (ori == TopAbs_EXTERNAL)
50 extern Standard_Boolean TopOpeBRepTool_GettraceREGUFA();
51 static TopTools_IndexedMapOfShape STATIC_mapf, STATIC_mapw, STATIC_mapv;
52 static TopTools_IndexedMapOfOrientedShape STATIC_mapeds;
53 void FUN_tro(const Standard_Integer i)
55 if (i==1) std::cout<<"FORWARD";
56 else if (i==2) std::cout<<"REVERSED";
57 else if (i==3) std::cout<<"INTERNAL";
58 else if (i==4) std::cout<<"EXTERNAL";
59 else if (i==5) std::cout<<"CLOSING";
61 Standard_EXPORT Standard_Integer FUN_adds(const TopoDS_Shape& s) {
62 TopAbs_ShapeEnum typ = s.ShapeType();
63 TCollection_AsciiString aa; Standard_Integer is = 0;
64 if (typ == TopAbs_VERTEX) {aa = TCollection_AsciiString("v"); is = STATIC_mapv.Add(s);}
65 if (typ == TopAbs_EDGE) {aa = TCollection_AsciiString("e"); is = STATIC_mapeds.Add(s);}
66 if (typ == TopAbs_WIRE) {aa = TCollection_AsciiString("wi"); is = STATIC_mapw.Add(s);}
67 if (typ == TopAbs_FACE) {aa = TCollection_AsciiString("f"); is = STATIC_mapf.Add(s);}
69 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
70 if (trc) FUN_tool_draw(aa,s,is);
76 extern void FUN_tool_tori(const TopAbs_Orientation Or);
78 void FUN_tool_Add(TopTools_DataMapOfShapeListOfShape& map,const TopoDS_Shape& key, const TopoDS_Shape& subitem)
80 if (map.IsBound(key)) map.ChangeFind(key).Append(subitem);
81 else {TopTools_ListOfShape los; los.Append(subitem); map.Bind(key,los);}
83 static void FUN_Raise() {
85 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
86 if (trc) std::cout<<"*** Raise REGUW"<<std::endl;
87 // throw Standard_Failure("REGUW");
91 //=======================================================================
94 //=======================================================================
96 TopOpeBRepTool_REGUW::TopOpeBRepTool_REGUW(const TopoDS_Face& Fref)
100 hasnewsplits = Standard_False;
106 mymapvmultiple.Clear();
107 myListVmultiple.Clear();
112 //=======================================================================
115 //=======================================================================
117 const TopoDS_Face& TopOpeBRepTool_REGUW::Fref() const
119 return (myCORRISO.Fref());
122 //=======================================================================
123 //function : SetEsplits
125 //=======================================================================
127 void TopOpeBRepTool_REGUW::SetEsplits(TopTools_DataMapOfShapeListOfShape& Esplits)
131 //=======================================================================
132 //function : GetEsplits
134 //=======================================================================
136 void TopOpeBRepTool_REGUW::GetEsplits(TopTools_DataMapOfShapeListOfShape& Esplits) const
138 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
142 //=======================================================================
145 //=======================================================================
147 void TopOpeBRepTool_REGUW::SetOwNw(TopTools_DataMapOfShapeListOfShape& OwNw)
151 //=======================================================================
154 //=======================================================================
156 void TopOpeBRepTool_REGUW::GetOwNw(TopTools_DataMapOfShapeListOfShape& OwNw) const
158 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
162 //=======================================================================
163 //function : SplitEds
165 //=======================================================================
167 Standard_Boolean TopOpeBRepTool_REGUW::SplitEds()
169 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
171 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
172 if (trc) std::cout<<"** SPLITTING EDGES **"<<std::endl;
175 TopTools_IndexedMapOfShape mehasIv;
177 for (i = 1; i <= mymapvEds.Extent(); i++) {
178 const TopOpeBRepTool_connexity& co = mymapvEds(i);
179 TopTools_ListOfShape loe; Standard_Integer ni = co.IsInternal(loe);
180 if (ni == 0) continue;
181 TopTools_ListIteratorOfListOfShape ite(loe);
182 for (; ite.More(); ite.Next()) mehasIv.Add(ite.Value());
185 for (i = 1; i <= mehasIv.Extent(); i++) {
186 const TopoDS_Edge& e = TopoDS::Edge(mehasIv.FindKey(i));
187 TopTools_ListOfShape splits; Standard_Boolean issp = Standard_False;
188 Standard_Boolean isdone = myEsplits.IsBound(e);
189 if (isdone) splits.Assign(myEsplits.Find(e));
190 else issp = TopOpeBRepTool_TOOL::SplitE(e,splits);
191 if (issp) hasnewsplits = Standard_True;
193 if (trc) std::cout<<"e"<<FUN_adds(e)<<" gives splits ="<<std::endl;
195 if (!(issp || isdone)) continue; //nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnyi
197 // e gives splits = {esp has vertices {vv}}
198 TopTools_ListIteratorOfListOfShape ite(splits);
199 for (; ite.More(); ite.Next()){
200 const TopoDS_Shape& esp = ite.Value();
202 if (trc) {std::cout<<" e"<<FUN_adds(esp);}
204 TopExp_Explorer exvv(esp, TopAbs_VERTEX);
205 for (; exvv.More(); exvv.Next()){
206 const TopoDS_Shape& vv = exvv.Current();
207 TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(vv);
208 Standard_Boolean isb = co.RemoveItem(INTERNAL,e);
210 Standard_Integer ivv = TopOpeBRepTool_TOOL::OriinSorclosed(vv,esp);
215 if (trc) std::cout<<std::endl;
218 return Standard_True;
222 //=======================================================================
225 //=======================================================================
227 const TopoDS_Shape& TopOpeBRepTool_REGUW::S() const
229 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
233 //=======================================================================
236 //=======================================================================
238 void TopOpeBRepTool_REGUW::Init(const TopoDS_Shape& S)
244 //=======================================================================
247 //=======================================================================
249 Standard_Boolean TopOpeBRepTool_REGUW::HasInit() const
251 return (!myS.IsNull());
256 //=======================================================================
257 //function : InitStep
259 //=======================================================================
261 void TopOpeBRepTool_REGUW::InitStep(const TopoDS_Shape& S)
263 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
264 TopoDS_Shape null;myCORRISO.Init(null); myCORRISO.Init(S);
267 mymapvmultiple.Clear();
268 myListVmultiple.Clear();
273 //=======================================================================
276 //=======================================================================
278 Standard_Boolean TopOpeBRepTool_REGUW::MapS()
280 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
282 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
283 if (trc) std::cout<<"** MAPPING **"<<std::endl;
287 // 0) an edge with an INTERNAL vertex binded in <mapVedges> must be
289 // After splitting such edges, we deal only with FORWARD and
290 // REVERSED vertices.
291 // 1) a vertex belonging to a CLOSING edge is represented by 2 distinct
292 // 2d points in the UV space.
293 // 2) a vertex belonging to a DEGENERATED edge has at least 2 UV rep.
294 // (if the original degenerated edge has been splitted).
295 // the bounds of the degenerated edge share the same TShape.
296 // 3) a CLOSED edge binds the same vertex oriented FORWARD and REVERSED.
298 // For each vertex get non-"singular" edges in which the vertex is oriented
299 // FORWARD and REVERSED.
300 // <mymapvmultiple(1)> binds v and ed if :
301 // v is FORWARD in ed FORWARD : oriFF(v,ed) = FORWARD
302 // v is REVERSED in ed REVERSED : oriFF(v,ed) = FORWARD
303 // oriFF(v,ed) = (ori(ed) == FORWARD) ? ori(ed) : ori(ed).Reverse.
305 // A "singular" edge is a closed, a closing or a degenerated edge.
306 // In <mymapvmultiple(5)>, we bind with the key <v>:
307 // - the FORWARD and the REVERSED CLOSING ancestor edges of <v>
308 // - the DEGENERATED ancestor edge of <v>
309 // - the CLOSED edge ancestor edge of <v>
311 // A MULTIPLE vertex has its single UV representation's connexity > 2
313 const TopoDS_Shape& CS = myCORRISO.S();
314 TopExp_Explorer exe(CS, TopAbs_EDGE);
315 for (; exe.More(); exe.Next()){
316 const TopoDS_Edge& ed = TopoDS::Edge(exe.Current());
318 Standard_Boolean isdgE = BRep_Tool::Degenerated(ed);
319 Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(ed,myCORRISO.S(),Fref());
320 iscE = iscE && !isdgE; // closing ed
321 TopoDS_Shape vcl; Standard_Boolean isvcl = TopOpeBRepTool_TOOL::ClosedE(ed,TopoDS::Vertex(vcl)); isvcl = isvcl && !isdgE;
323 TopExp_Explorer exv(ed, TopAbs_VERTEX);
324 for (; exv.More(); exv.Next()){
325 const TopoDS_Vertex& v = TopoDS::Vertex(exv.Current());
326 Standard_Boolean isb = mymapvEds.Contains(v);
327 TopOpeBRepTool_connexity theconnexity(v);
328 if (!isb) mymapvEds.Add(v, theconnexity);
329 TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
332 // avoid adding it twice
333 co.RemoveItem(CLOSING,ed);
334 co.AddItem(CLOSING,ed);
338 // FORWARD and REVERSED edge is added
339 co.AddItem(CLOSING,ed);
341 else if (isvcl && (v.IsSame(vcl))) {
342 // avoid adding it twice
343 co.RemoveItem(CLOSING,ed);
344 co.AddItem(CLOSING,ed);
347 Standard_Integer iov = TopOpeBRepTool_TOOL::OriinSor(v,ed,Standard_False); //iov != 0
356 for (Standard_Integer iv = 1; iv <= mymapvEds.Extent(); iv++) {
357 const TopoDS_Vertex& v = TopoDS::Vertex(mymapvEds.FindKey(iv));
358 std::cout <<"#v"<<FUN_adds(v)<<" :\n";
359 const TopOpeBRepTool_connexity& co = mymapvEds(iv);
360 for (Standard_Integer i=1; i<=5; i++) {
361 TopTools_ListOfShape eds; Standard_Integer ieds = co.Item(i,eds);
362 if (ieds == 0) continue;
363 std::cout<<" is ";FUN_tro(i);std::cout<<" in ";
364 TopTools_ListIteratorOfListOfShape ite(eds);
365 for (; ite.More(); ite.Next())
366 {const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
367 std::cout<<"e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
368 TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) std::cout<<"closed";
369 Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) std::cout<<"degenerated";
370 Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(e,myCORRISO.S(),Fref());
371 if (iscE) std::cout<<"closing";
373 std::cout<<std::endl;
379 Standard_Integer nV = mymapvEds.Extent();
380 if (nV < 1) return Standard_False;
383 for (i = 1; i <= mymapvEds.Extent(); i++) {
384 const TopoDS_Shape& v = mymapvEds.FindKey(i);
385 const TopOpeBRepTool_connexity& co = mymapvEds(i);
386 Standard_Boolean faulty = co.IsFaulty();
387 if (faulty) return Standard_False;
388 Standard_Boolean multiple = co.IsMultiple();
390 if (mymapvmultiple.Add(v))
391 myListVmultiple.Append(v);
393 return Standard_True;
396 static void FUN_nextdata(const Standard_Integer iStep,const TopoDS_Edge& e,const Handle(Geom2d_Curve)& pc,
397 TopoDS_Vertex& v,gp_Pnt2d& p2d,gp_Dir2d& tg)
398 // prequesitory : pc = 2drep(e),
399 // ori(v,e)=iv1e1 -> v, p2d=pt2d(v,e), tg=tg2d(v,e).
401 Standard_Integer iv1e1 = (iStep == 1) ? FORWARD : REVERSED;
402 TopoDS_Shape aLocalShape = TopOpeBRepTool_TOOL::Vertex(iv1e1,e);
403 v = TopoDS::Vertex(aLocalShape);
404 // v = TopoDS::Vertex(TopOpeBRepTool_TOOL::Vertex(iv1e1,e));
405 Standard_Real par1 = TopOpeBRepTool_TOOL::ParE(iv1e1,e);
406 Standard_Boolean line = FUN_tool_line(pc);
407 Standard_Boolean quad = FUN_tool_quad(pc);// mytg2d is reapproximated if PCquad
408 Standard_Boolean approx = quad && (!line);
412 p2d = pc->Value(par1);
414 Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
415 Standard_Real par0 = TopOpeBRepTool_TOOL::ParE(iv0e1,e);
416 // Getting a point near point<Index> of <E>
417 Standard_Real x = 0.2345; Standard_Real par = (1-x)*par1+x*par0;
418 gp_Pnt2d pmil; pc->D1(par,pmil,tg2d);
421 pc->D1(par1,p2d,tg2d);
424 if (M_REVERSED(e.Orientation())) tg.Reverse();
427 //=======================================================================
428 //function : InitBlock
430 //=======================================================================
432 Standard_Boolean TopOpeBRepTool_REGUW::InitBlock()
434 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
436 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
439 myv0.Nullify(); myp2d0=gp_Pnt2d(1.e7,1.e7);
441 Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
443 // updating <mymapvmultiple> and myListVmultiple
444 TopTools_ListIteratorOfListOfShape itmu(myListVmultiple);
445 while (itmu.More()) {
446 const TopoDS_Shape& vmu = itmu.Value();
447 const TopOpeBRepTool_connexity& cmu = mymapvEds.FindFromKey(vmu);
448 Standard_Boolean mult = cmu.IsMultiple();
450 myListVmultiple.Remove(itmu);
451 mymapvmultiple.Remove(vmu);
457 if (myListVmultiple.IsEmpty()) {
459 for (i = 1; i <= mymapvEds.Extent(); i++) {
460 const TopoDS_Vertex& v = TopoDS::Vertex(mymapvEds.FindKey(i));
461 const TopOpeBRepTool_connexity& co = mymapvEds(i);
462 TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
463 TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
464 TopTools_ListOfShape le; le.Append(lea); le.Append(leb); Standard_Integer ne = nea+neb;
465 if (ne != 0) {myv0 = v; break;}
469 myv0 = TopoDS::Vertex(myListVmultiple.First());
471 if (myv0.IsNull()) return Standard_False;
473 const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(myv0);
475 TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
476 TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
477 TopTools_ListOfShape le; le.Append(lea); le.Append(leb); Standard_Integer ne = nea+neb;
478 if (ne == 0) return Standard_False;
480 if (nea > 0) myed = TopoDS::Edge(le.First());
481 else {// <myv0> CLOSING in <myed>
482 TopTools_ListIteratorOfListOfShape itb(le);
483 for (; itb.More(); itb.Next()){
484 const TopoDS_Edge& eb = TopoDS::Edge(itb.Value());
485 Standard_Boolean iscE = TopOpeBRepTool_TOOL::IsClosingE(myed,myCORRISO.S(),Fref());
486 if (!iscE) {myed = eb; break;}
487 Standard_Integer iov0 = TopOpeBRepTool_TOOL::OriinSorclosed(myv0,myed);
488 if (iov0 != iv0e1) continue;
491 if (myed.IsNull()) return Standard_False;
493 TopExp_Explorer exv(myed, TopAbs_VERTEX);
494 for (; exv.More(); exv.Next()){
495 const TopoDS_Shape& vcur = exv.Current();
496 TopOpeBRepTool_connexity& cco = mymapvEds.ChangeFromKey(vcur);
498 // Standard_Boolean ok =
500 cco.RemoveItem(myed);
501 // if (!ok) return Standard_False; see for closing vertices
505 TopOpeBRepTool_C2DF c2df;Standard_Boolean bound = myCORRISO.UVRep(myed,c2df);
506 if (!bound) return Standard_False;
507 Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
508 Standard_Real par0 = TopOpeBRepTool_TOOL::ParE(iv0e1,myed);
511 // myv, myp2d, mytg2d :
512 ::FUN_nextdata(iStep,myed,pc, myv,myp2d,mytg2d);
516 std::cout<<std::endl<<" v0 = v"<<FUN_adds(myv0)<<" p2d0 = ("<<myp2d0.X()<<" "<<myp2d0.Y()<<")"<<std::endl;
517 std::cout<<" vcur = v"<<FUN_adds(myv)<<" p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<std::endl;
518 std::cout<<" ecur = e"<<FUN_adds(myed)<<std::endl;
521 return Standard_True;
524 //=======================================================================
525 //function : NearestE
527 //=======================================================================
529 Standard_Boolean TopOpeBRepTool_REGUW::NearestE(const TopTools_ListOfShape& loe, TopoDS_Edge& efound) const
532 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
535 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
537 Standard_Real fac = 0.45678;
538 Standard_Real tola = Precision::Angular();
539 Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
542 TopTools_ListIteratorOfListOfShape ite(loe);
543 efound = TopoDS::Edge(ite.Value());
544 if (ite.More()) ite.Next();
545 else return Standard_True;
547 TopOpeBRepTool_C2DF c2defound;Standard_Boolean isbfound = myCORRISO.UVRep(efound,c2defound);
548 if (!isbfound) return Standard_False;
550 gp_Vec2d tg2dfound = TopOpeBRepTool_TOOL::tryTg2dApp(iv0e1,efound,c2defound,fac);
551 if (M_REVERSED(efound.Orientation())) tg2dfound.Reverse();
552 Standard_Real angfound = 1.e7;
553 if (iStep == 1) angfound = TopOpeBRepTool_TOOL::Matter(mytg2d,tg2dfound);
554 else angfound = 2.*M_PI - TopOpeBRepTool_TOOL::Matter(tg2dfound,mytg2d);
556 if (trc) std::cout<<"ang(e"<<FUN_adds(myed)<<",e"<<FUN_adds(efound)<<")="<<angfound<<std::endl;
559 // purpose : finding out <efound> /
560 // ecur is given by <tg2d>
562 // iStep=1 : matterang2d(efound,ecur) = min(ei,ecur)
563 // iStep=2 : oppomatterang2d(efound,ecur) = min(ei,ecur)
564 for (; ite.More(); ite.Next()){
565 const TopoDS_Edge& ei = TopoDS::Edge(ite.Value());
566 // for INTERNAL edge eI -> eF+eR
567 if (ei.IsSame(myed)) continue;
569 TopOpeBRepTool_C2DF c2dei;Standard_Boolean isbi = myCORRISO.UVRep(ei,c2dei);
570 if (!isbi) return Standard_False;
571 gp_Vec2d tg2di = TopOpeBRepTool_TOOL::tryTg2dApp(iv0e1,ei,c2dei,fac);
572 if (M_REVERSED(ei.Orientation())) tg2di.Reverse();
574 Standard_Real angi = 1.e7;
575 if (iStep == 1) angi = TopOpeBRepTool_TOOL::Matter(mytg2d,tg2di);
576 else angi = 2.*M_PI - TopOpeBRepTool_TOOL::Matter(tg2di,mytg2d);
577 Standard_Boolean eq = Abs(angi-angfound) < tola;
579 if (trc) std::cout<<"ang(e"<<FUN_adds(myed)<<",e"<<FUN_adds(ei)<<")="<<angi<<std::endl;
583 return Standard_False;
586 if (angi < angfound) {efound = ei; angfound = angi;}
588 return Standard_True;
591 //=======================================================================
592 //function : NextinBlock
594 //=======================================================================
596 Standard_Boolean TopOpeBRepTool_REGUW::NextinBlock()
598 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
600 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
601 if (trc) std::cout<<std::endl<<" vcur = v"<<FUN_adds(myv)<<" p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<std::endl;
604 Standard_Integer iv0e1 = (iStep == 1) ? REVERSED : FORWARD;
605 const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(myv);
607 // {e} : e is connexed to <myv> && ori(<myv>,e)=iv0e1
608 TopTools_ListOfShape lea; Standard_Integer nea = co.Item(iv0e1,lea);
609 TopTools_ListOfShape leb; Standard_Integer neb = co.Item(CLOSING,leb);
610 TopTools_ListOfShape le; le.Append(lea); le.Append(leb); Standard_Integer ne = nea + neb;
612 TopTools_ListIteratorOfListOfShape ite(le);
614 const TopoDS_Edge& e = TopoDS::Edge(ite.Value());
616 if (trc) std::cout<<" e"<<FUN_adds(e);
619 Standard_Boolean issame = e.IsSame(myed);
620 if (issame) {//xpu240299 FRA60275, fsp4
622 if (trc) std::cout<<" is same : not valid"<<std::endl;
624 le.Remove(ite); continue;
627 TopOpeBRepTool_C2DF c2df;Standard_Boolean bound = myCORRISO.UVRep(e,c2df);
628 if (!bound) {FUN_Raise(); return Standard_False;}
629 Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
630 Standard_Real par = TopOpeBRepTool_TOOL::ParE(iv0e1,e);
631 gp_Pnt2d p2de; pc->D0(par,p2de);
633 // p2d(myv,ed)=p2d(myv,e)
634 Standard_Boolean samep2d = p2de.IsEqual(myp2d,mytol2d);
635 if (!samep2d) le.Remove(ite);
638 if (trc) {if (samep2d) std::cout<<" valid"<<std::endl;
639 else std::cout<<" not valid"<<std::endl;}
643 if (ne == 0) {FUN_Raise(); return Standard_False;}
647 if (ne == 1) myed = TopoDS::Edge(le.First());
649 TopoDS_Edge efound; Standard_Boolean found = NearestE(le,efound);
650 if (!found) {FUN_Raise(); return Standard_False;}
654 TopExp_Explorer exv(myed, TopAbs_VERTEX);
655 for (; exv.More(); exv.Next()){
656 TopOpeBRepTool_connexity& cco = mymapvEds.ChangeFromKey(exv.Current());
658 // Standard_Boolean ok =
660 cco.RemoveItem(myed);
661 // if (!ok) {FUN_Raise(); return Standard_False;} closed edges
664 TopOpeBRepTool_C2DF c2df; myCORRISO.UVRep(myed,c2df);
665 Standard_Real f,l,tol; const Handle(Geom2d_Curve)& pc = c2df.PC(f,l,tol);
666 ::FUN_nextdata(iStep,myed,pc, myv,myp2d,mytg2d);
670 std::cout<<" vcur = v"<<FUN_adds(myv)<<" p2d = ("<<myp2d.X()<<" "<<myp2d.Y()<<")"<<std::endl;
671 std::cout<<" ecur = e"<<FUN_adds(myed)<<std::endl;
674 return Standard_True;
677 //=======================================================================
679 //purpose : step <iStep> for regularization
680 //=======================================================================
682 Standard_Boolean TopOpeBRepTool_REGUW::REGU(const Standard_Integer istep,
684 const TopoDS_Shape& Scur,
686 const TopoDS_Shape& ,
688 TopTools_ListOfShape& Splits)
690 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
693 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
694 if (trc) std::cout<<std::endl<<"** REGU istep=**"<<iStep<<std::endl;
698 // A valid face is built on "valid" wires.
699 // A valid wire has for UV representation a set of 2d edges of connexity = 2.
701 // Starting element is a vertex of single UV representation with connexity greater
703 // Given <v0m>, we get :
704 // - <e1> an edge where <v0m> is oriented REVERSED(step1)/FORWARD(step2)
705 // - <v1> the other vertex of <e1> oriented FORWARD(step1)/REVERSED(step2)
706 // - <p2d1> is <v1>'s UV representation attached to <e1>,
707 // - tg2d<e1> = Tgt(p2d1,e1) if <e1> FORWARD(step1)
708 // = -Tgt(p2d1,e1) if <e1> is REVERSED(step1) in the face with
709 // Tgt(p2d1,e1) = tangent to <e1>'s pcurve at point <p2d1>
713 // Given a starting couple (<vi>, <p2di>, tg2d<e1>, <ei>) with :
714 // - <vi> oriented FORWARD in <ei>,
715 // - <vi>'s 2d representation falling on an UV bound of <ei>'s pcurve (if <vi> is
716 // on a closing edge),
717 // We get the edge <ei+1> such that :
718 // - <ei+1> is not already touched,
719 // - <vi> is oriented REVERSED(step1) in <ei+1>,
720 // - <ei+1> has an UV bound falling into geometry <p2di>.
721 // - The oriented angle (-tg2d<ei>, tg2d<ei+1>) is the lowest,
722 // ( The angle is computed in the anti-trigonometric sense;
723 // the tangents's orientation are reversed if the edge is oriented REVERSED in the face )
724 // = Smaller oriented (following trigonometric sense) angle (tg2d<ei+1>, -tg2d<ei>)
726 // step2 : reverse the orientations and the angle describes non-matter.
729 // tol2d = 1.e-2*(lowest distance (p2df,p2dl) between all non-closed
730 // and non-degenerated pcurves seen during the regularization).
731 // This value is updated in method chkp2dFORinE.
732 // The comparision of p2d points is coupled with comparision of vertices
733 // We should in fact use bounding boxes on pcurves but this is too expensive!!!
735 isinit0 = Standard_True;
736 TopTools_ListOfShape loEcur, loW;
738 Standard_Integer nite = 0;
739 Standard_Integer nE = myCORRISO.Eds().Extent();// recall myCORRISO.Init(myS);
740 TopTools_ListIteratorOfListOfShape ite(myCORRISO.Eds());
741 for (; ite.More(); ite.Next()) {
742 TopAbs_Orientation oe = ite.Value().Orientation();
743 if (M_INTERNAL(oe) || M_EXTERNAL(oe)) nE--;
747 Standard_Boolean FINI = (nite == nE);
749 //*** Getting starts elements if not defined
750 // -----------------------------------------
751 if (isinit0 && !FINI) {
752 Standard_Boolean ok = InitBlock();
755 if (trc) std::cout<<"** InitBlock fails"<<std::endl;
757 {FUN_Raise(); return Standard_False;}
759 loEcur.Append(myed);// add it to the current wire
760 nite++; // increment nite
761 isinit0 = Standard_False;
765 //*** Checking the wire is not already closed
766 // ------------------------------------------
767 // If last vertex <v> is the first one <v0> and <p2d> == <p2d0>, the wire is closed
768 Standard_Boolean wireisclosed = myp2d.IsEqual(myp2d0,mytol2d);
771 //* Adding INTERNAL/EXTERNAL edges to wires
772 // ----------------------------------------
773 TopTools_ListIteratorOfListOfShape ite1(loEcur);
774 for (; ite1.More(); ite1.Next()){
775 const TopoDS_Shape& e = ite1.Value();
776 TopExp_Explorer exv(e, TopAbs_VERTEX);
777 for (; exv.More(); exv.Next()){
778 const TopoDS_Shape& v = exv.Current();
779 TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
780 TopTools_ListOfShape& le = co.ChangeItem(INTERNAL);
781 TopTools_ListIteratorOfListOfShape itte(le);
782 while (itte.More()) {
783 const TopoDS_Shape& ee = itte.Value();
784 TopAbs_Orientation oe = ee.Orientation();
785 if (M_INTERNAL(oe) || M_EXTERNAL(oe)) {loEcur.Append(ee);le.Remove(itte);}
792 // if Scur = <currentW> gives only one new wire, and has no new splitted edges, <currentW>
793 // is valid and unchanged.
794 Standard_Boolean onewok = FINI && loW.IsEmpty() && !hasnewsplits;
797 if (trc) std::cout<<"wire "<<FUN_adds(Scur)<<" is found valid\n";
799 return Standard_True;
802 TopoDS_Wire newW; Standard_Boolean wiok = FUN_tool_MakeWire(loEcur, newW);
803 if (wiok) loW.Append(newW);
806 if (trc) std::cout<<"** FUN_tool_MakeWire fails"<<std::endl;
808 {FUN_Raise(); return Standard_False;}
811 if (trc) {std::cout<<"#->new wire = wi"<<FUN_adds(newW)<<" = ";
812 for (TopTools_ListIteratorOfListOfShape it(loEcur); it.More(); it.Next())
813 std::cout<<" e"<<FUN_adds(it.Value());
816 isinit0 = Standard_True;
821 return Standard_True;
826 //*** Iteration on UV connexed edges
827 // ---------------------------------
828 // <v> is in <ed>, <p2d> = <v> current UV representation
829 Standard_Boolean gotonext = NextinBlock();
832 if (trc) std::cout<<"** NextinBlock fails"<<std::endl;
834 {FUN_Raise(); return Standard_False;}
840 return Standard_True;
843 //=======================================================================
845 //purpose : complete regularization
846 //=======================================================================
848 Standard_Boolean TopOpeBRepTool_REGUW::REGU()
850 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
851 TopTools_ListOfShape null;
853 Standard_Boolean toregu = !myListVmultiple.IsEmpty();
854 toregu = toregu || hasnewsplits;
855 TopTools_ListOfShape Splits;
857 myOwNw.Bind(S(),Splits);
858 return Standard_True;
862 TopTools_ListOfShape loS; Standard_Boolean ok = REGU(1,S(),loS);
863 if (!ok) {FUN_Raise(); return Standard_False;}
866 if (loS.IsEmpty()) loS.Append(S());// no new shape
868 TopTools_ListIteratorOfListOfShape it(loS);
869 for (; it.More(); it.Next()){
870 const TopoDS_Shape& Scur = it.Value();
873 Standard_Boolean toregu1 = !myListVmultiple.IsEmpty();
874 if (!toregu1) {Splits.Append(Scur); continue;}
876 TopTools_ListOfShape sp; ok = REGU(2,Scur,sp);
877 if (!ok) {FUN_Raise(); return Standard_False;}
878 if (sp.IsEmpty()) sp.Append(Scur);// no new shape
881 myOwNw.Bind(S(),Splits);
882 return Standard_True;
885 //=======================================================================
886 //function : GetSplits
888 //=======================================================================
890 Standard_Boolean TopOpeBRepTool_REGUW::GetSplits(TopTools_ListOfShape& Splits) const
892 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
893 Standard_Boolean isb = myOwNw.IsBound(S());
894 if (!isb) return Standard_False;
895 Splits = myOwNw.Find(S());
896 return Standard_True;
899 //=======================================================================
900 //function : Connexity
902 //=======================================================================
904 Standard_Boolean TopOpeBRepTool_REGUW::Connexity(const TopoDS_Vertex& v, TopOpeBRepTool_connexity& co) const
906 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
907 Standard_Boolean isb = mymapvEds.Contains(v);
908 if (!isb) return Standard_False;
909 co = mymapvEds.FindFromKey(v);
910 return Standard_True;
913 //=======================================================================
914 //function : AddNewConnexity
916 //=======================================================================
918 Standard_Boolean TopOpeBRepTool_REGUW::AddNewConnexity(const TopoDS_Vertex& v, const Standard_Integer OriKey,const TopoDS_Edge& e)
920 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
921 Standard_Boolean isb = mymapvEds.Contains(v);
922 if (!isb) return Standard_False;
924 Standard_Boolean ok = myCORRISO.AddNewConnexity(v,e);
925 if (!ok) return Standard_False;
927 TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
928 co.AddItem(OriKey,e);
931 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
933 {std::cout<<"** setting new connexity : v"<<FUN_adds(v)<<" is ";FUN_tro(OriKey);
934 std::cout<<" in e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
935 TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) std::cout<<" closed";
936 Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) std::cout<<" degenerated";std::cout<<std::endl;}
938 return Standard_True;
941 //=======================================================================
942 //function : RemoveOldConnexity
944 //=======================================================================
946 Standard_Boolean TopOpeBRepTool_REGUW::RemoveOldConnexity(const TopoDS_Vertex& v, const Standard_Integer OriKey,const TopoDS_Edge& e)
948 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
949 Standard_Boolean isb = mymapvEds.Contains(v);
950 if (!isb) return Standard_False;
952 Standard_Boolean ok = myCORRISO.RemoveOldConnexity(v,e);
953 // if (!ok) return Standard_False;
955 TopOpeBRepTool_connexity& co = mymapvEds.ChangeFromKey(v);
956 ok = co.RemoveItem(OriKey,e);
957 if (!ok) return Standard_False;
960 Standard_Boolean trc = TopOpeBRepTool_GettraceREGUFA();
962 {std::cout<<"** removing old connexity : v"<<FUN_adds(v)<<" for e"<<FUN_adds(e);FUN_tool_tori(e.Orientation());
963 TopoDS_Vertex vclo; Standard_Boolean cloE = TopOpeBRepTool_TOOL::ClosedE(e,vclo); if (cloE) std::cout<<" closed";
964 Standard_Boolean dgE = BRep_Tool::Degenerated(e); if (dgE) std::cout<<" degenerated";std::cout<<std::endl;}
966 return Standard_True;
969 //=======================================================================
970 //function : UpdateMultiple
972 //=======================================================================
974 Standard_Boolean TopOpeBRepTool_REGUW::UpdateMultiple(const TopoDS_Vertex& v)
976 if (!HasInit()) throw Standard_Failure("TopOpeBRepTool_REGUW : NO INIT");
977 Standard_Boolean isb = mymapvEds.Contains(v);
978 if (!isb) return Standard_False;
979 const TopOpeBRepTool_connexity& co = mymapvEds.FindFromKey(v);
980 Standard_Boolean ismult = co.IsMultiple();
982 if (mymapvmultiple.Add(v))
983 myListVmultiple.Append(v);
984 return Standard_True;