// File: TopOpeBRepTool_REGUS.cxx // Created: Mon Jan 4 15:34:02 1999 // Author: Xuan PHAM PHU // #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DRAW #include #endif #define M_FORWARD(ori) (ori == TopAbs_FORWARD) #define M_REVERSED(ori) (ori == TopAbs_REVERSED) #define M_INTERNAL(ori) (ori == TopAbs_INTERNAL) #define M_EXTERNAL(ori) (ori == TopAbs_EXTERNAL) #define FORWARD (1) #define REVERSED (2) #define INTERNAL (3) #define EXTERNAL (4) #define CLOSING (5) #ifdef DEB Standard_IMPORT Standard_Boolean TopOpeBRepTool_GettraceREGUSO(); static TopTools_IndexedMapOfShape STATIC_mape, STATIC_mapf, STATIC_mapw, STATIC_mapsh; static Standard_Integer FUN_adds(const TopoDS_Shape& s) { TopAbs_ShapeEnum typ = s.ShapeType(); TCollection_AsciiString aa; Standard_Integer is = 0; if (typ == TopAbs_SHELL) {aa = TCollection_AsciiString("s"); is = STATIC_mapsh.Add(s);} if (typ == TopAbs_WIRE) {aa = TCollection_AsciiString("w"); is = STATIC_mapw.Add(s); } if (typ == TopAbs_FACE) {aa = TCollection_AsciiString("f"); is = STATIC_mapf.Add(s); } if (typ == TopAbs_EDGE) {aa = TCollection_AsciiString("e"); is = STATIC_mape.Add(s); } #ifdef DRAW Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); if (trc) FUN_tool_draw(aa,s,is); #endif return is; } #endif static void FUN_Raise() { #ifdef DEB Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); if (trc) cout<<"***** Failure in REGUS **********"< 2) mymapemult.Add(e); #ifdef DEB if (trc) { cout <<"co(e"< are INTERNAL edges of // their 2 bounds are of connexity > 1. // if (eIs.IsEmpty()) {nWs.Append(w); continue;} TopTools_ListOfShape spW; // -------- Standard_Boolean spok = REGUW.REGU(); // only first step if (!spok) {FUN_Raise(); return Standard_False;} REGUW.GetSplits(spW); if (!spW.IsEmpty()) {nWs.Append(spW); hassp = Standard_True;} }//exw if (!hassp) return Standard_False; TopTools_ListOfShape nFs; Standard_Boolean ok = TopOpeBRepTool_REGUS::WireToFace(aFace, nWs,nFs); if (!ok) {FUN_Raise(); return Standard_False;} TopTools_ListIteratorOfListOfShape itf(nFs); for (; itf.More(); itf.Next()) FSplits.Append(itf.Value().Oriented(oAnc)); return Standard_True; } //======================================================================= //function : SplitFaces //purpose : //======================================================================= Standard_Boolean TopOpeBRepTool_REGUS::SplitFaces() { #ifdef DEB Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); Standard_Integer ish = FUN_adds(S()); if (trc) cout<<"** SPLITTING FACES ** shape"< lfsp = {fsp} mynF--; TopTools_ListIteratorOfListOfShape itf(lfsp); for (; itf.More(); itf.Next()){ const TopoDS_Shape& fsp = itf.Value(); mynF++; TopExp_Explorer exe(fsp, TopAbs_EDGE); for (; exe.More(); exe.Next()) { // fsp -> {e} const TopoDS_Shape& e = exe.Current(); Standard_Boolean isb = mymapeFs.IsBound(e); if (!isb) {FUN_Raise(); return Standard_False;} // TopTools_ListOfShape& lof = mymapeFs.ChangeFind(e); TopOpeBRepTool_TOOL::Remove(lof,f); lof.Append(fsp); // Standard_Integer nf = lof.Extent(); if (nf > 2) mymapemult.Add(e); }//exe(fsp) }//itf(lfsp) #ifdef DEB if (trc) { cout <<"split(f"< edge of // 1. is INTERNAL or EXTERNAL -> nothing is done // 2. is closing edge of -> nothing is done // 3. is already bound in -> remove it from the map // (then has 2 ancestor faces stored in the current Block) // 4. elsewhere, add it in the map. // // !! if is INTERNAL/EXTERNAL -> nothing is done { TopAbs_Orientation ofcur = fcur.Orientation(); if (M_INTERNAL(ofcur) || M_EXTERNAL(ofcur)) return; TopExp_Explorer exe(fcur, TopAbs_EDGE); for (; exe.More(); exe.Next()){ const TopoDS_Shape& e = exe.Current(); TopAbs_Orientation oe = e.Orientation(); if (M_INTERNAL(oe) || M_EXTERNAL(oe)) continue; Standard_Boolean isclo = TopOpeBRepTool_TOOL::IsClosingE(TopoDS::Edge(e),TopoDS::Face(fcur)); if (isclo) continue; Standard_Boolean isb = edstoconnect.Contains(e); if (isb) edstoconnect.Remove(e); else edstoconnect.Add(e); }//exe } //======================================================================= //function : REGU //purpose : //======================================================================= Standard_Boolean TopOpeBRepTool_REGUS::REGU() { #ifdef DEB Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); Standard_Integer ishe = FUN_adds(myS); if (trc) cout<<"** REGU **"< {Blocks}, // a Block is a closed shell with "valid" edges. // - a valid edge in a Block has at most two ancestor faces - // // Give us the starting couple (, ) : // * If has only one untouched ancestor face left, fj+1 <- fj // Else among the untouched ancestors faces, we choose the one for which // angle (, ) is the smallest; providing face reduces // the matter described by . // * update for ( as touched). // * Update for 's bound edges : // - if bound edge is not in the map, add it. // - else if bound edge has two ancestor faces in current list , // delete it form the map. // // TopTools_ListOfShape lFinBlock; // describes a valid closed shell when is emptied. mylFinBlock.Clear(); Standard_Integer nite = 0; while (nite <= mynF) { Standard_Boolean startBlock = mylFinBlock.IsEmpty(); Standard_Boolean endBlock = myedstoconnect.IsEmpty() && (!startBlock); #ifdef DEB Standard_Boolean tr=Standard_False; if (tr) { TopTools_MapIteratorOfMapOfShape it(myedstoconnect); cout<<"still to connect : "; for (; it.More(); it.Next()) cout<<" e"< Standard_Integer nFcur = mylFinBlock.Extent(); Standard_Boolean unchanged = (nFcur==myoldnF) && (mynF==myoldnF); if (unchanged) { #ifdef DEB if (trc) cout<<"#** shell"< are stored in Blocks TopOpeBRepTool_TOOL::Remove(mymapeFs.ChangeFind(e),myf); }//exe mylFinBlock.Append(myf); nite++; }//nite <= mynF myOshNsh.Bind(S(), Splits); return Standard_True; } //======================================================================= //function : InitBlock //purpose : //======================================================================= Standard_Boolean TopOpeBRepTool_REGUS::InitBlock() { Standard_Integer nec = myedstoconnect.Extent(); if (nec != 0) return Standard_False; // should be empty TopTools_ListOfShape eds; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(mymapeFs); for (; itm.More(); itm.Next()) eds.Append(itm.Key()); TopTools_ListIteratorOfListOfShape ite(eds); for (; ite.More(); ite.Next()){ const TopoDS_Shape& e = ite.Value(); const TopTools_ListOfShape& lof = mymapeFs.Find(e); if (lof.IsEmpty()) {mymapeFs.UnBind(e); continue;} myf = lof.First(); #ifdef DEB Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); if (trc) cout<<"* Block : first face = f"< bound in TopTools_ListOfShape eds; TopExp_Explorer exe(myf, TopAbs_EDGE); for (; exe.More(); exe.Next()){ const TopoDS_Shape& e = exe.Current(); Standard_Boolean isb = myedstoconnect.Contains(e); if (isb) eds.Append(e); }//exe Standard_Boolean alleftouched = eds.IsEmpty(); if (alleftouched) { TopTools_MapIteratorOfMapOfShape itc(myedstoconnect); for (; itc.More(); itc.Next()){ const TopoDS_Shape& e = itc.Key(); Standard_Boolean isb = mymapeFs.IsBound(e); // all ancestor faces of have been stored if (!isb) {myedstoconnect.Remove(e); continue;} const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent(); if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e); continue;} // myf = lof.First(); 130499 if (lof.Extent() == 1) myf = lof.First(); else { // looking for first face stored in the current block // connexed to e TopTools_ListIteratorOfListOfShape itff(mylFinBlock); TopTools_MapOfShape mapf;for (; itff.More(); itff.Next()) mapf.Add(itff.Value()); // lofc : the list of faces connexed to e in // lof : the list of untouched faces connexed to e in const TopTools_ListOfShape& lofc = mymapeFsstatic.Find(e); itff.Initialize(lofc); TopoDS_Face fref; for (; itff.More(); itff.Next()) { const TopoDS_Face& fc = TopoDS::Face(itff.Value()); Standard_Boolean isb = mapf.Contains(fc); if (isb) {fref = fc; break;} } // itff(lofc) if (fref.IsNull()) { return Standard_False; // !!!!!!!!!! a revoir 130499 } else { myf = fref; TopoDS_Face ffound; Standard_Boolean ok = NearestF(TopoDS::Edge(e),lof,ffound); if (!ok) return Standard_False; myf = ffound; } } return Standard_True; } return Standard_False; } TopTools_ListIteratorOfListOfShape ite(eds); for (; ite.More(); ite.Next()){ const TopoDS_Shape& e = ite.Value(); Standard_Boolean isb = mymapeFs.IsBound(e); // all ancestor faces of have been stored if (!isb) {myedstoconnect.Remove(e); continue;} const TopTools_ListOfShape& lof = mymapeFs.Find(e); Standard_Integer nf = lof.Extent(); if (nf == 0) {myedstoconnect.Remove(e); mymapeFs.UnBind(e); continue;} #ifdef DEB if (trc) {cout<<"e"<myf = f"< : if (approx) { Standard_Boolean ok = TopOpeBRepTool_TOOL::tryNgApp(pare,e,f,tola,nt); if (!ok) return Standard_False; } else { gp_Vec tmp; Standard_Boolean ok = FUN_tool_nggeomF(pare,e,f,tmp); if (!ok) return Standard_False; nt = gp_Dir(tmp); } if (M_REVERSED(f.Orientation())) nt.Reverse(); // : Standard_Boolean ok = FUN_tool_getxx(f,e,pare,xx); if (!ok) return Standard_False; return Standard_True; } //======================================================================= //function : NearestF //purpose : //======================================================================= Standard_Boolean TopOpeBRepTool_REGUS::NearestF(const TopoDS_Edge& e, const TopTools_ListOfShape& lof, TopoDS_Face& ffound) const // prequesitory : is shared by and faces of . // // NYIXPU!!!!!!!! if (xx1 tg xx2) -> use curvatures // { #ifdef DEB Standard_Boolean trc = TopOpeBRepTool_GettraceREGUSO(); #endif ffound.Nullify(); TopoDS_Face fref = TopoDS::Face(myf); // Give us egde , and a reference face (= ) // - parameter on = . // - xxi = tangent fo face fi at pnt(e,pare) oriented INSIDE 2d(fi) // normal to tge = tg(e,pare). // purpose : looking for ffound / // MatterAng(xxref, xxfound) = Min{ MatterAng(xxref, xxi), xxi for fi in // providing fi reduces 3d(fref) } // : Standard_Real f,l; FUN_tool_bounds(e,f,l); Standard_Real eps = 0.45678; Standard_Real pare = (1-eps)*f+eps*l; // RONd (x,y,z) = (xxref,ntref,x^y) Standard_Real tola = Precision::Angular()*1.e3; //gp_Dir xapp,yapp; Standard_Boolean refapp = Standard_False; gp_Dir x,y; Standard_Boolean ok = ::FUN_vectors(fref,e,pare,y,x,tola,Standard_False); if (!ok) {FUN_Raise(); return Standard_False;} // initializing // ------------ Standard_Real angfound = 0; TopTools_ListIteratorOfListOfShape itf(lof); for (; itf.More(); itf.Next()){ ffound = TopoDS::Face(itf.Value()); gp_Dir ntfound,xxfound; ok = ::FUN_vectors(ffound,e,pare,ntfound,xxfound,tola,Standard_False); if (!ok) {FUN_Raise(); return Standard_False;} Standard_Boolean oppo = TopOpeBRepTool_TOOL::Matter(x,y,xxfound,ntfound,tola, angfound); #ifdef DEB if (trc&&!oppo) cout<<" f"<