// File: TopOpeBRepBuild_KPart.cxx // Created: Tue Aug 30 11:13:16 1994 // Author: Jean Yves LEBEY // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DEB Standard_EXPORT Standard_Boolean TopOpeBRepBuild_GettraceKPB(); #endif static void FUN_Raise() { #ifdef DEB cout<<"******************************ERROR"< and are kpkoletge on faces , // with same oriented with // returns k=1,2 if shi is contained in shk // else returns 0 { SC.SetReference(sh2); TopExp_Explorer exf(sh1,TopAbs_FACE); for (; exf.More(); exf.Next()){ const TopoDS_Face& f1 = TopoDS::Face(exf.Current()); if (f1.IsSame(fkole1)) continue; gp_Pnt pnt1; BRepClass3d_SolidExplorer::FindAPointInTheFace(f1,pnt1); SC.StateP3DReference(pnt1); TopAbs_State stpnt1 = SC.State(); if (stpnt1 == TopAbs_IN) return 2; if (stpnt1 == TopAbs_OUT) return 1; } return 0; } static Standard_Boolean FUN_changev(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& v) { Standard_Boolean changev = HDS->HasShape(v); if (!changev) return Standard_False; changev = HDS->HasSameDomain(v); if (!changev) return Standard_False; Standard_Boolean rankv = HDS->DS().AncestorRank(v); changev = (rankv == 2); return changev; } static Standard_Boolean FUN_updatev (const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopoDS_Edge& newed, const TopoDS_Vertex& v, const TopAbs_Orientation oriv, const Standard_Real parv, const Standard_Boolean changev) { TopOpeBRepDS_BuildTool BT; BRep_Builder BB; if (changev) { TopoDS_Shape oov; Standard_Boolean ok = FUN_ds_getoov(v,HDS,oov); if(!ok) return Standard_False; oov.Orientation(oriv); BB.Add(newed,oov); BT.Parameter(newed,oov,parv); } else { TopoDS_Shape aLocalShape = v.Oriented(oriv); TopoDS_Vertex ov = TopoDS::Vertex(aLocalShape); // TopoDS_Vertex ov = TopoDS::Vertex(v.Oriented(oriv)); BB.Add(newed,ov); BT.Parameter(newed,ov,parv); } return Standard_True; } static Standard_Boolean FUN_makefaces(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, TopTools_DataMapOfShapeListOfShape& EnewE, const TopoDS_Shape& f, const TopoDS_Shape& , TopTools_ListOfShape& newfaces) //prequesitory : ='s outer wire //purpose : ={edow}, // edow=(vf,vl), if(rank(vj)=2 && vj sdm vj1), replace vj by vj1 // gives { TopOpeBRepDS_BuildTool BT; BRep_Builder BB; TopoDS_Shape aLocalShape = f.Oriented(TopAbs_FORWARD); TopoDS_Face F = TopoDS::Face(aLocalShape); // working on FORWARD face // TopoDS_Face F = TopoDS::Face(f.Oriented(TopAbs_FORWARD)); // working on FORWARD face TopAbs_Orientation of = f.Orientation(); //the new outer wire : // ------------------- TopTools_ListOfShape loe; // ------- TopoDS_Wire outerwf = BRepTools::OuterWire(F); TopExp_Explorer ex(outerwf, TopAbs_EDGE); for (; ex.More(); ex.Next()){ const TopoDS_Edge& ed = TopoDS::Edge(ex.Current()); TopAbs_Orientation oe = ed.Orientation(); Standard_Boolean issplit = BU.IsSplit(ed,TopAbs_ON); Standard_Boolean isbound = EnewE.IsBound(ed); if (!isbound && !issplit) { // new edge TopoDS_Vertex vf,vl; TopExp::Vertices(ed,vf,vl); Standard_Boolean changevf = ::FUN_changev(HDS,vf); Standard_Boolean changevl = ::FUN_changev(HDS,vl); Standard_Boolean changee = changevf || changevl; if (changee) { Standard_Real ff = BRep_Tool::Parameter(vf, ed); Standard_Real l = BRep_Tool::Parameter(vl, ed); TopoDS_Edge newed; BT.CopyEdge(ed.Oriented(TopAbs_FORWARD),newed); Standard_Boolean ok = ::FUN_updatev(HDS,newed,vf,TopAbs_FORWARD,ff,changevf); if (!ok) return Standard_False; ok = ::FUN_updatev(HDS,newed,vl,TopAbs_REVERSED,l,changevl); if (!ok) return Standard_False; newed.Orientation(oe); TopTools_ListOfShape led; led.Append(newed); EnewE.Bind(ed,led); isbound = Standard_True; } } if (issplit) { const TopTools_ListOfShape& speds = BU.Splits(ed,TopAbs_ON); if (speds.Extent() == 0) return Standard_False; const TopoDS_Edge& spe = TopoDS::Edge(speds.First()); Standard_Boolean sameori = FUN_tool_SameOri(ed,spe); TopAbs_Orientation orisp = spe.Orientation(); if (!sameori) orisp = TopAbs::Complement(orisp); TopTools_ListIteratorOfListOfShape it(speds); for (; it.More(); it.Next()) { TopoDS_Edge esp = TopoDS::Edge(it.Value()); Standard_Boolean ok = FUN_tool_pcurveonF(TopoDS::Face(f),esp); if (!ok) return Standard_False; TopoDS_Shape ee = esp.Oriented(orisp); loe.Append(ee); } } else if (isbound) { const TopTools_ListOfShape& neweds = EnewE.ChangeFind(ed); TopTools_ListIteratorOfListOfShape itnes(neweds); for (; itnes.More(); itnes.Next()) loe.Append(itnes.Value().Oriented(oe)); } else loe.Append(ed); } TopoDS_Wire newW; //--------------- BB.MakeWire(newW); for (TopTools_ListIteratorOfListOfShape itee(loe); itee.More(); itee.Next()) BB.Add(newW,itee.Value()); // the new face : // -------------- aLocalShape = F.EmptyCopied(); TopoDS_Face newf = TopoDS::Face(aLocalShape); // TopoDS_Face newf = TopoDS::Face(F.EmptyCopied()); BB.Add(newf,newW); // other wires of : TopExp_Explorer exw(F, TopAbs_WIRE); for (; exw.More(); exw.Next()){ const TopoDS_Wire OOw = TopoDS::Wire(exw.Current()); if (OOw.IsSame(outerwf)) continue; BB.Add(newf,OOw); } if (M_REVERSED(of)) newf.Orientation(TopAbs_REVERSED); // xpu140898 : CTS21251 TopoDS_Face Newf = newf; Standard_Boolean ok = TopOpeBRepTool::CorrectONUVISO(TopoDS::Face(f),Newf); if (ok) newfaces.Append(Newf); else newfaces.Append(newf); return Standard_True; } static Standard_Boolean FUN_rebuildfc(const TopOpeBRepBuild_Builder& BU, const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopAbs_State , const TopoDS_Shape& Fk, TopTools_DataMapOfShapeListOfShape& EnewE, TopTools_IndexedDataMapOfShapeListOfShape& fcnewfc) // Owk = 's outer wire //prequesitory: Owk = {edk}, Splits(edk,Stk) = spedk //purpose: fills up = {(fcFk,newfcFk)} // with {fcFk} = faces of shape k connexed to Owk // fcFk has edges {edk} { #ifdef DEB // const TopOpeBRepDS_DataStructure& BDS = HDS->DS(); // Standard_Integer rFk = BDS.AncestorRank(Fk); #endif TopoDS_Wire Owk = BRepTools::OuterWire(TopoDS::Face(Fk)); TopTools_ListOfShape eds; FUN_tool_shapes(Owk,TopAbs_EDGE,eds); TopTools_ListIteratorOfListOfShape ite(eds); ite.Initialize(eds); for (; ite.More(); ite.Next()){ const TopoDS_Shape& ed = ite.Value(); TopTools_ListOfShape lfcFk; // faces of shapei connexed to ed FDSCNX_FaceEdgeConnexFaces(TopoDS::Face(Fk),ed,HDS,lfcFk); // prequesitory : ed in {edges of Owk} // ed's faces ancestor = {Fk,fofj} if (lfcFk.Extent() != 1) return Standard_False; // purpose : Building up new topologies on connexed faces // attached to outer wire's edges. const TopoDS_Shape& fcFk = lfcFk.First(); TopTools_ListOfShape newfcFk; Standard_Boolean ok = FUN_makefaces(BU,HDS,EnewE,fcFk,Owk,newfcFk); if (!ok) return Standard_False; fcnewfc.Add(fcFk,newfcFk); } return Standard_True; } // FUN_rebuildfc #ifdef DEB Standard_EXPORT void debiskoletge() {} #endif //======================================================================= //function : MergeKPartiskoletge //purpose : //======================================================================= void TopOpeBRepBuild_Builder::MergeKPartiskoletge() { #ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); if (TKPB) KPreturn(myIsKPart); debiskoletge(); #endif const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); // Standard_Integer ibid; if ( myIsKPart != 5 ) {FUN_Raise(); return;} GMapShapes(myShape1,myShape2); // NYI : on doit pouvoir faire l'economie du mapping GMapShapes(...) // NYI en allant chercher l'indice 1,2 retourne par GShapeRank(S) // NYI dans la DS. l'index est defini pour tous les shapes HasSameDomain TopTools_ListOfShape& lmergesha1 = ChangeMerged(myShape1,myState1); ChangeMerged(myShape2,myState2); TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain KPiskoletgesh(myShape1,lShsd1,lfhsd1); KPiskoletgesh(myShape2,lShsd2,lfhsd2); // traitement de tous les solides NYI TopoDS_Shape sol1 = lShsd1.First(); TopoDS_Shape sol2 = lShsd2.First(); ChangeMerged(sol1,myState1); ChangeMerged(sol2,myState2); TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1,lcyhsd1); TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2,lcyhsd2); const TopoDS_Face& fac1 = TopoDS::Face(lplhsd1.First()); const TopoDS_Face& fac2 = TopoDS::Face(lplhsd2.First()); #ifdef DEB Standard_Integer iF1 = #endif myDataStructure->Shape(fac1); //DEB #ifdef DEB Standard_Integer iF2 = #endif myDataStructure->Shape(fac2); //DEB #ifdef DEB if (TKPB) {cout<<""< 1 || aMapOfSolid2.Extent() > 1) { TopTools_IndexedMapOfShape aMapOfResult; if(Opefus()) { if(!disjPerformFuse(aMapOfSolid1, aMapOfSolid2, aMapOfResult)) return; } else if(Opec12()) { if(!disjPerformCut(aMapOfSolid1, aMapOfSolid2, aMapOfResult)) return; } else if(Opec21()) { if(!disjPerformCut(aMapOfSolid2, aMapOfSolid1, aMapOfResult)) return; } else if(Opecom()) { if(!disjPerformCommon(aMapOfSolid1, aMapOfSolid2, aMapOfResult)) return; } for(Standard_Integer ii=1; ii<=aMapOfResult.Extent(); ii++) { lmergesha1.Append(aMapOfResult(ii)); } return; } //end if(aMapOfSolid1.Extent() > 1 || aMapOfSolid2.Extent() > 1) else { //modified by NIZHNY-MKK Fri May 19 16:47:23 2000.END sol1 = TopoDS::Solid(exsol1.Current()); ChangeMerged(sol1,myState1); outsha1 = BRepTools::OuterShell(sol1); sol2 = TopoDS::Solid(exsol2.Current()); ChangeMerged(sol2,myState2); outsha2 = BRepTools::OuterShell(sol2); TopAbs_State stsol1 = KPclasSS(outsha1,sol2); TopAbs_State stsol2 = KPclasSS(outsha2,sol1); Standard_Integer ires,icla1,icla2; KPisdisjanalyse(stsol1,stsol2,ires,icla1,icla2); if (ires == RESUNDEF) { return; } else if (icla1 == SHEUNDEF || icla2 == SHEUNDEF) { return; } else if (ires == RESNULL) { return; } else if (ires == RESSHAPE12) { lmergesha1.Append(myShape1); lmergesha1.Append(myShape2); return; } else if (ires == RESSHAPE1) { lmergesha1.Append(myShape1); return; } else if (ires == RESSHAPE2) { lmergesha1.Append(myShape2); return; } else if (ires == RESNEWSHA1 || ires == RESNEWSHA2) { //modified by NIZHNY-MKK Tue May 23 11:36:33 2000.BEGIN TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, myState1, myState2); //modified by NIZHNY-MKK Tue May 23 11:36:39 2000.END lmergesha1.Append(newsol); return; } else { #ifdef DEB cout<<"TopOpeBRepBuild_MergeKPart soldisj : ires = "< 1 || aMapOfSolid2.Extent() > 1) } // if (soldisj) else { // if (Opec12()) { lmergesha1.Append(myShape1); } else if (Opec21()) { lmergesha1.Append(myShape2); } else if (Opecom()) { lmergesha1.Clear(); } else if (Opefus()) { lmergesha1.Append(myShape1); lmergesha1.Append(myShape2); } else return; } // ( !soldisj ) return; } // MergeKPartisdisj //======================================================================= //function : MergeKPartisfafa //purpose : //======================================================================= void TopOpeBRepBuild_Builder::MergeKPartisfafa() { #ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); if (TKPB) KPreturn(myIsKPart); #endif if ( myIsKPart == 3 ) { // isfafa TopExp_Explorer ex; ex.Init(myShape1,TopAbs_FACE); if (! ex.More() ) return; TopoDS_Shape F1 = ex.Current(); ex.Init(myShape2,TopAbs_FACE); if (! ex.More() ) return; TopoDS_Shape F2 = ex.Current(); TopTools_ListOfShape LF1,LF2; GFindSamDom(F1,LF1,LF2); TopAbs_ShapeEnum tf = TopAbs_FACE; TopOpeBRepBuild_GTopo G; if (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf); else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted(); else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf); else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf); else return; GMapShapes(myShape1,myShape2); GMergeFaces(LF1,LF2,G); if (myShape1.ShapeType() == TopAbs_COMPOUND) { TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1); L1 = ChangeMerged(F1,myState1); } if (myShape2.ShapeType() == TopAbs_COMPOUND) { TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2); L2 = ChangeMerged(F2,myState2); } } } // MergeKPartisfafa //======================================================================= //function : MergeKPartissoso //purpose : //======================================================================= void TopOpeBRepBuild_Builder::MergeKPartissoso() { #ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); if (TKPB) KPreturn(myIsKPart); #endif if ( myIsKPart == 4 ) { // issoso TopExp_Explorer ex; TopoDS_Shape SO1; if (!myShape1.IsNull()) { ex.Init(myShape1,TopAbs_SOLID); if (! ex.More() ) return; SO1 = ex.Current(); } TopoDS_Shape SO2; if (!myShape2.IsNull()) { ex.Init(myShape2,TopAbs_SOLID); if (! ex.More() ) return; SO2 = ex.Current(); } if (SO1.IsNull()) return; TopTools_ListOfShape LSO1,LSO2; GFindSamDom(SO1,LSO1,LSO2); TopAbs_ShapeEnum tf = TopAbs_FACE; // NYI TopAbs_SOLID TopOpeBRepBuild_GTopo G; if (Opec12()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf); else if (Opec21()) G=TopOpeBRepBuild_GTool::GCutSame(tf,tf).CopyPermuted(); else if (Opecom()) G=TopOpeBRepBuild_GTool::GComSame(tf,tf); else if (Opefus()) G=TopOpeBRepBuild_GTool::GFusSame(tf,tf); else return; GMapShapes(myShape1,myShape2); GMergeSolids(LSO1,LSO2,G); if (!myShape1.IsNull()) { if (myShape1.ShapeType() == TopAbs_COMPOUND) { TopTools_ListOfShape& L1 = ChangeMerged(myShape1,myState1); L1 = ChangeMerged(SO1,myState1); } } if (!myShape2.IsNull()) { if (myShape2.ShapeType() == TopAbs_COMPOUND) { TopTools_ListOfShape& L2 = ChangeMerged(myShape2,myState2); L2 = ChangeMerged(SO2,myState2); } } } } // MergeKPartissoso static Standard_Boolean sectionedgesON(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& outerw1, const TopTools_IndexedMapOfShape& mape2) // prequesitory : all edges of are section edges { TopExp_Explorer ex1(outerw1, TopAbs_EDGE); for (; ex1.More(); ex1.Next()){ const TopoDS_Shape& e1 = ex1.Current(); TopTools_ListIteratorOfListOfShape it2 = HDS->SameDomain(e1); if (!it2.More()) return Standard_False; // xpu231098 : cto904C7 : e1 !hsd for (; it2.More(); it2.Next()){ const TopoDS_Shape& e2 = it2.Value(); Standard_Boolean isbound = mape2.Contains(e2); if (!isbound) return Standard_False; } } return Standard_True; } static Standard_Boolean allIonsectionedges(const Handle(TopOpeBRepDS_HDataStructure)& HDS, const TopoDS_Shape& f1, const TopTools_IndexedMapOfShape& mape1, const TopTools_IndexedMapOfShape& mape2) // prequesitory : all interferences attached to are SSI { TopOpeBRepDS_ListIteratorOfListOfInterference it1(HDS->DS().ShapeInterferences(f1)); for (; it1.More(); it1.Next()){ const Handle(TopOpeBRepDS_ShapeShapeInterference)& SSI1 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(it1.Value()); Standard_Integer G1 = SSI1->Geometry(); Standard_Boolean isgbound = SSI1->GBound(); const TopoDS_Shape& e1 = HDS->Shape(G1); Standard_Boolean isbound = isgbound? mape1.Contains(e1): mape2.Contains(e1); if (!isbound) return Standard_False; } return Standard_True; } //======================================================================= //function : KPiskoletge //purpose : detection faces collees tangentes sur wire exterieur //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPiskoletge() { /*#ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); #endif*/ TopTools_ListOfShape lShsd1,lShsd2; // liste de solides HasSameDomain TopTools_ListOfShape lfhsd1,lfhsd2; // liste de faces HasSameDomain Standard_Boolean iskp1 = KPiskoletgesh(myShape1,lShsd1,lfhsd1); if ( !iskp1 ) return 0; TopTools_ListOfShape lplhsd1, lcyhsd1; ::FUN_sortplcy(lfhsd1,lplhsd1, lcyhsd1); Standard_Integer nplhsd1 = lplhsd1.Extent(); Standard_Integer ncyhsd1 = lcyhsd1.Extent(); if ( nplhsd1 != 1 ) return 0; if ( ncyhsd1 > 1 ) return 0; Standard_Boolean iskp2 = KPiskoletgesh(myShape2,lShsd2,lfhsd2); if ( !iskp2 ) return 0; TopTools_ListOfShape lplhsd2, lcyhsd2; ::FUN_sortplcy(lfhsd2,lplhsd2, lcyhsd2); Standard_Integer nplhsd2 = lplhsd2.Extent(); Standard_Integer ncyhsd2 = lcyhsd2.Extent(); if ( nplhsd2 != 1 ) return 0; // Si l'un des objets est constitue de plusieurs solides on passe // dans le cas general. Standard_Integer nshsd1 = lShsd1.Extent(); Standard_Integer nshsd2 = lShsd2.Extent(); if ( nshsd1>1 || nshsd2>1 ) return 0; // NYI : (nplhsd1 > 1) || (nplhsd2 > 1) // ------------------------------------ const TopoDS_Face& f1 = TopoDS::Face(lplhsd1.First()); #ifdef DEB // Standard_Boolean isb1 = myKPMAPf1f2.IsBound(f1); // DEB #endif const TopoDS_Face& f2 = TopoDS::Face(lplhsd2.First()); #ifdef DEB // Standard_Boolean isb2 = myKPMAPf1f2.IsBound(f2); // DEB #endif #ifdef DEB Standard_Integer iF1,iF2; Standard_Boolean tSPS1 = GtraceSPS(f1,iF1); Standard_Boolean tSPS2 = GtraceSPS(f2,iF2); if(tSPS1 || tSPS2) {GdumpSHA( f1, (char *) "KPiskoletge "); cout< interfers with faces of on edges different from outerw's edges // ------------------------------------------------------------------------------ Standard_Boolean allI1onseouterw = ::allIonsectionedges(myDataStructure,f1,mape1,mape2); if (!allI1onseouterw) return 0; Standard_Boolean allI2onseouterw = ::allIonsectionedges(myDataStructure,f2,mape2,mape1); if (!allI2onseouterw) return 0; // NYI : (ncyhsd1 > 1) || (ncyhsd2 > 1) // ------------------------------------ // KPcycy : if (ncyhsd1 > 0) { Standard_Boolean cycy = ( ncyhsd1 == 1 ) && ( ncyhsd2 == 1 ); if (!cycy) return 0; Standard_Boolean isbound1 = FUN_tool_inS(outerw1,f1); if (!isbound1) return 0; Standard_Boolean isbound2 = FUN_tool_inS(outerw2,f2); if (!isbound2) return 0; } return 1; } //======================================================================= //function : KPisdisj //purpose : detection shapes disjoints //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPisdisj() { #ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); #endif // myShape1 et myShape2 : aucune interference const TopOpeBRepDS_DataStructure& DS = myDataStructure->DS(); // Standard_Integer nsh = DS.NbShapes(); // if (nsh != 2) return 0; if (!DS.HasShape(myShape1)) return 0; if (!DS.HasShape(myShape2)) return 0; Standard_Integer isdisj1 = KPisdisjsh(myShape1); Standard_Integer isdisj2 = KPisdisjsh(myShape2); #ifdef DEB if (TKPB) { cout<<"isdisj : "< nb des subsshapes de qui sont HasGeometry() //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const { TopTools_ListOfShape L; Standard_Integer n = KPlhg(S,T,L); return n; } //======================================================================= //function : KPlhg //purpose : --> nb +liste des subsshapes de qui sont HasGeometry() //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPlhg(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const { Standard_Integer n = 0; L.Clear(); TopExp_Explorer ex; for (ex.Init(S,T); ex.More(); ex.Next()) { // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) { const TopoDS_Shape& s = ex.Current(); Standard_Boolean hg = myDataStructure->HasGeometry(s); if (hg) { n++; L.Append(s); } } return n; } //======================================================================= //function : KPlhsd //purpose : // KPlhsd --> nb des subsshapes de qui sont HasSameDomain() //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) const { TopTools_ListOfShape L; Standard_Integer n = KPlhsd(S,T,L); return n; } //======================================================================= //function : KPlhsd //purpose : // KPlhsd --> nb + liste des subsshapes de qui sont HasSameDomain() //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPlhsd(const TopoDS_Shape& S,const TopAbs_ShapeEnum T,TopTools_ListOfShape& L) const { Standard_Integer n = 0; L.Clear(); TopExp_Explorer ex; for (ex.Init(S,T); ex.More(); ex.Next()) { // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) { const TopoDS_Shape& s = ex.Current(); Standard_Boolean hsd = myDataStructure->HasSameDomain(s); if (hsd) { n++; L.Append(s); } } return n; } //======================================================================= //function : KPclasSS //purpose : // classifie le shape S1 par rapport a S2 en evitant de prendre // les shape exLS1 de S1 comme element de classification. // exS1 peut etre IsNull(). // S1,S2 = SOLID | SHELL //======================================================================= TopAbs_State TopOpeBRepBuild_Builder::KPclasSS(const TopoDS_Shape& S1,const TopTools_ListOfShape& exLS1,const TopoDS_Shape& S2) { TopAbs_State state = TopAbs_UNKNOWN; state = myShapeClassifier.StateShapeShape(S1,exLS1,S2); #ifdef DEB if (TopOpeBRepBuild_GettraceKPB()) { const gp_Pnt& P1 = myShapeClassifier.P3D(); cout<<"point P1 "<DS(); Standard_Boolean iskolesh = FUNKP_KPiskolesh((*this),BDS,Sarg,lShsd,lfhsd); if (!iskolesh) return Standard_False; #ifdef DEB Standard_Integer nfhsd = #endif KPlhsd(Sarg,TopAbs_FACE,lfhsd); TopTools_ListIteratorOfListOfShape it(lfhsd); for (; it.More(); it.Next() ) { const TopoDS_Face& fac = TopoDS::Face(it.Value()); Standard_Boolean isplan = FUN_tool_plane(fac); Standard_Boolean iscylinder = FUN_tool_cylinder(fac); if (iscylinder) continue; if (!isplan) return Standard_False; TopoDS_Wire outerw = BRepTools::OuterWire(fac); if (outerw.IsNull()) return Standard_False; TopExp_Explorer exe(outerw, TopAbs_EDGE); // Standard_Integer ne = 0; for (; exe.More(); exe.Next()){ const TopoDS_Edge& ed = TopoDS::Edge(exe.Current()); Standard_Boolean isse = BDS.IsSectionEdge(ed); const TopTools_ListOfShape& sp = (*this).Splits(ed,TopAbs_ON); if (sp.Extent() == 0) return Standard_False; if (!isse) return Standard_False; // ne++; } // if (ne > 1) return Standard_False; #ifdef DEB Standard_Integer isol = myDataStructure->Shape(Sarg); Standard_Integer ifac = myDataStructure->Shape(fac); if(TKPB){cout<<"isol "< 0 || nl2 > 0 ) { TopTools_ListIteratorOfListOfShape it1(L1); for (i=1 ; i<=nl1; i++) { const TopoDS_Shape& S1 = it1.Value(); #ifdef DEB // Standard_Integer iS1 = myDataStructure->Shape(S1); #endif TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1)); for (; itsd.More(); itsd.Next() ) { const TopoDS_Shape& S2 = itsd.Value(); #ifdef DEB // Standard_Integer iS2 = myDataStructure->Shape(S2); #endif Standard_Boolean found = KPContains(S2,L2); if ( ! found ) { L2.Prepend(S2); nl2++; } } it1.Next(); } nl1 = 0; TopTools_ListIteratorOfListOfShape it2(L2); for (i=1 ; i<=nl2; i++) { const TopoDS_Shape& S2 = it2.Value(); #ifdef DEB // Standard_Integer iS2 = myDataStructure->Shape(S2); #endif TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2)); for (; itsd.More(); itsd.Next() ) { const TopoDS_Shape& S1 = itsd.Value(); #ifdef DEB // Standard_Integer iS1 = myDataStructure->Shape(S1); #endif Standard_Boolean found = KPContains(S1,L1); if ( ! found ) { L1.Prepend(S1); nl1++; } } it2.Next(); } nl2 = 0; } } //======================================================================= //function : KPisdisjsh //purpose : S est il un shape traite par le cas particulier "disjoint" //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPisdisjsh(const TopoDS_Shape& Sarg) const { if ( Sarg.IsNull() ) return 0; TopExp_Explorer ex; Standard_Integer nhg; nhg = KPlhg(Sarg,TopAbs_SOLID); if ( nhg != 0 ) return 0; nhg = KPlhg(Sarg,TopAbs_FACE); if ( nhg != 0 ) return 0; nhg = KPlhg(Sarg,TopAbs_EDGE); if ( nhg != 0 ) return 0; // un seul niveau de HasSameDomain Standard_Integer n1,n2; TopTools_ListOfShape lshsd; n1 = KPlhsd(Sarg,TopAbs_SOLID,lshsd); if ( n1 ) { TopTools_ListIteratorOfListOfShape it(lshsd); for(;it.More();it.Next()) { const TopoDS_Shape& s = it.Value(); n2 = KPlhsd(s,TopAbs_FACE); if (n2 != 0 ) return 0; } } n1 = KPlhsd(Sarg,TopAbs_FACE,lshsd); if ( n1 ) { TopTools_ListIteratorOfListOfShape it(lshsd); for(;it.More();it.Next()) { const TopoDS_Shape& s = it.Value(); n2 = KPlhsd(s,TopAbs_EDGE); if (n2 != 0 ) return 0; } } return 1; } //======================================================================= //function : KPissososh //purpose : detection S = {solid} tous HasSameDomain //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPissososh(const TopoDS_Shape& Sarg) const { // que des solides volants (nb total de solides = nb de solides volants) Standard_Integer nsol1 = 0; TopExp_Explorer ex1(Sarg,TopAbs_SOLID); for(; ex1.More(); ex1.Next()) nsol1++; Standard_Integer nsol2 = 0; TopExp_Explorer ex2(Sarg,TopAbs_SOLID,TopAbs_COMPSOLID); for(; ex2.More(); ex2.Next()) nsol2++; if (nsol1 && (nsol1 != nsol2)) return 0; // toutes les solides sont HasSameDomain() Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_SOLID); if (nhsd != nsol1) return 0; Standard_Integer n; TopExp_Explorer ex; // pas de shell volant n = 0; for (ex.Init(Sarg,TopAbs_SHELL,TopAbs_SOLID); ex.More(); ex.Next()) n++; if (n) return 0; // pas de face volant n = 0; for (ex.Init(Sarg,TopAbs_FACE,TopAbs_SHELL); ex.More(); ex.Next()) n++; if (n) return 0; // pas d'edge volant n = 0; for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++; if (n) return 0; // pas de vertex volant n = 0; for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++; if (n) return 0; return 1; } //======================================================================= //function : KPisfafash //purpose : detection S = {face} toutes HasSameDomain //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPisfafash(const TopoDS_Shape& Sarg) const { // il n'y a que des faces volantes (nb total de faces = nb de faces volantes) Standard_Integer nfac1 = 0; TopExp_Explorer ex1(Sarg,TopAbs_FACE); for(; ex1.More(); ex1.Next()) nfac1++; Standard_Integer nfac2 = 0; TopExp_Explorer ex2(Sarg,TopAbs_FACE,TopAbs_SHELL); for(; ex2.More(); ex2.Next()) nfac2++; if (nfac1 && (nfac1 != nfac2)) return 0; // toutes les faces sont HasSameDomain() Standard_Integer nhsd = KPlhsd(Sarg,TopAbs_FACE); if (nhsd != nfac1) return 0; Standard_Integer n; TopExp_Explorer ex; // pas de wire volant n = 0; for (ex.Init(Sarg,TopAbs_WIRE,TopAbs_FACE); ex.More(); ex.Next()) n++; if (n) return 0; // pas d'edge volant n = 0; for (ex.Init(Sarg,TopAbs_EDGE,TopAbs_WIRE); ex.More(); ex.Next()) n++; if (n) return 0; // pas de vertex volant n = 0; for (ex.Init(Sarg,TopAbs_VERTEX,TopAbs_EDGE); ex.More(); ex.Next()) n++; if (n) return 0; return 1; } //======================================================================= //function : KPiskoletgeanalyse //purpose : //======================================================================= void TopOpeBRepBuild_Builder::KPiskoletgeanalyse(const TopOpeBRepDS_Config config2, const TopAbs_State Stsol1, const TopAbs_State Stsol2, Standard_Integer& ires) const { // ----------------------------------------------------------------------------- // prequesitory : (nplhsd1 == 1) || (nplhsd2 == 1) // ------------- has all interferences Ii = (T, G=edge of outerw1 // ||edge of outerw2, S) // ----------------------------------------------------------------------------- ires = RESUNDEF; Standard_Boolean SameOriented = (config2 == TopOpeBRepDS_SAMEORIENTED); Standard_Boolean DiffOriented = (config2 == TopOpeBRepDS_DIFFORIENTED); // Standard_Boolean com = Opecom(); // Standard_Boolean c12 = Opec12(); // Standard_Boolean c21 = Opec21(); // Standard_Boolean fus = Opefus(); if (DiffOriented) { if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN) // if (com) ires = RESNULL; ires = RESNULL; if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) { // if (c12) ires = RESSHAPE1; // rank(sol1) == 1 && rank(sol2) == 2 // if (c21) ires = RESSHAPE2; // rank(sol1) == 2 && rank(sol2) == 1 ires = RESSHAPE1; } if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) { // if (c12) ires = RESSHAPE2; // rank(sol2) == 1 && rank(sol1) == 2 // if (c21) ires = RESSHAPE1; // rank(sol2) == 2 && rank(sol1) == 1 ires = RESSHAPE2; } if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) // if (fus) ires = RESNEWSOL; ires = RESNEWSOL; } // DiffOriented if (SameOriented) { // ============================== // PREQUESITORY :sol1 is IN sol2 // ============================== if (Stsol1 == TopAbs_IN && Stsol2 == TopAbs_IN) // if (com) ires = RESSHAPE1; ires = RESSHAPE1; if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_IN) { // if (c12) ires = RESNULL; // rank(sol1) == 1 && rank(sol2) == 2 // if (c21) ires = RESNEWSOL; // rank(sol1) == 2 && rank(sol2) == 1 ires = RESNULL; } if (Stsol2 == TopAbs_OUT && Stsol1 == TopAbs_IN) { // if (c12) ires = RESNULL; // rank(sol2) == 1 && rank(sol1) == 2 // if (c21) ires = RESNEWSOL; // rank(sol2) == 2 && rank(sol1) == 1 ires = RESNEWSOL; } if (Stsol1 == TopAbs_OUT && Stsol2 == TopAbs_OUT) // if (fus) ires = RESSHAPE2; ires = RESSHAPE2; } // SameOriented #ifdef DEB Standard_Boolean TKPB = TopOpeBRepBuild_GettraceKPB(); if (TKPB) cout<<"ires = "< nb des subsshapes de //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S,const TopAbs_ShapeEnum T) { TopTools_ListOfShape L; Standard_Integer n = KPls(S,T,L); return n; } //======================================================================= //function : KPls (class method) //purpose : // KPls --> nb + liste des subsshapes de //======================================================================= Standard_Integer TopOpeBRepBuild_Builder::KPls(const TopoDS_Shape& S, const TopAbs_ShapeEnum T, TopTools_ListOfShape& L) { Standard_Integer n = 0; L.Clear(); TopExp_Explorer ex; for (ex.Init(S,T); ex.More(); ex.Next()) { // for (TopExp_Explorer ex(S,T); ex.More(); ex.Next()) { const TopoDS_Shape& s = ex.Current(); n++; L.Append(s); } return n; } //======================================================================= //function : KPclassF (class method) //purpose : // KPclassF : classification F1 par rapport a F2 // F1 et F2 ne partagent aucune arete // F1 et F2 sont SameDomain //======================================================================= TopAbs_State TopOpeBRepBuild_Builder::KPclassF(const TopoDS_Shape& F1,const TopoDS_Shape& F2) { if (F1.IsNull()) return TopAbs_UNKNOWN; if (F2.IsNull()) return TopAbs_UNKNOWN; TopoDS_Face F1F = TopoDS::Face(F1); F1F.Orientation(TopAbs_FORWARD); TopoDS_Face F2F = TopoDS::Face(F2); F2F.Orientation(TopAbs_FORWARD); TopTools_ListOfShape le1; Standard_Integer ne1 = KPls(F1F,TopAbs_EDGE,le1); if ( ne1 == 0 ) return TopAbs_UNKNOWN; const TopoDS_Edge& e1 = TopoDS::Edge(le1.First()); Standard_Integer isamdom = 1; TopAbs_State St1 = TopAbs_UNKNOWN; St1 = myShapeClassifier.StateShapeShape(e1,F2F,isamdom); return St1; } //======================================================================= //function : KPclassFF (class method) //purpose : // classifie F1/F2 --> etats des faces l'une par rapport a l'autre //======================================================================= void TopOpeBRepBuild_Builder::KPclassFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2) { St1 = KPclassF(F1,F2); St2 = KPclassF(F2,F1); #ifdef DEB if (TopOpeBRepBuild_GettraceKPB()) { cout<<"Stf1 ";TopAbs::Print(St1,cout); cout<<" "; cout<<"Stf2 ";TopAbs::Print(St2,cout); cout< etats des faces l'une par rapport a l'autre // --> True si la configutration topologique correspond au cas "iskole". //======================================================================= Standard_Boolean TopOpeBRepBuild_Builder::KPiskoleFF(const TopoDS_Shape& F1,const TopoDS_Shape& F2,TopAbs_State& St1,TopAbs_State& St2) { #ifdef DEB Standard_Integer iF1; Standard_Boolean tSPS1 = GtraceSPS(F1,iF1); Standard_Integer iF2; Standard_Boolean tSPS2 = GtraceSPS(F2,iF2); if(tSPS1) { GdumpSHA(F1, (char *) "KPiskoleFF ");cout< aMaxNumberOfIterations) { cout << "disjPerformFuse: programming error" << endl; return Standard_False; } theMapOfResult.Add(acurrentsolid); } //end for(i) return Standard_True; } //====================================================================================================== // static function : disjPerformCommon // purpose: is needed in case of KPart==2 // attention: theMapOfResult is cleared before computations //====================================================================================================== static Standard_Boolean disjPerformCommon(const TopTools_IndexedMapOfShape& theMapOfSolid1, const TopTools_IndexedMapOfShape& theMapOfSolid2, TopTools_IndexedMapOfShape& theMapOfResult) { TopoDS_Solid sol1; TopoDS_Shell outsha1; TopoDS_Solid sol2; TopoDS_Shell outsha2; TopOpeBRepTool_ShapeClassifier aShapeClassifier; TopoDS_Shape Snull; TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2, aMapOfCommonOfCouple; theMapOfResult.Clear(); disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1); disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2); // Now common parts of all couples of solids are different for(Standard_Integer i=1; i <=aMapOfSeparatedSolid1.Extent(); i++) { const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i); if(localshape1.ShapeType()!=TopAbs_SOLID) return Standard_False; sol1 = TopoDS::Solid(localshape1); outsha1 = BRepTools::OuterShell(sol1); for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent(); j++) { const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j); if(localshape2.ShapeType()!=TopAbs_SOLID) return Standard_False; sol2 = TopoDS::Solid(localshape2); outsha2 = BRepTools::OuterShell(sol2); TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2); TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,sol1); Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF; LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Common, ires, icla1, icla2); if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) { cout << "Warning: disjPerformCommon: can not determine solid's states" << endl; continue; } switch (ires) { case RESNULL: { continue; break; } case RESSHAPE12 : { aMapOfCommonOfCouple.Add(sol1); aMapOfCommonOfCouple.Add(sol2); continue; break; } case RESSHAPE1 : { aMapOfCommonOfCouple.Add(sol1); continue; break; } case RESSHAPE2 : { aMapOfCommonOfCouple.Add(sol2); break; } case RESNEWSHA1: case RESNEWSHA2: { TopoDS_Solid newsol = BuildNewSolid(sol1, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_IN, TopAbs_IN); aMapOfCommonOfCouple.Add(newsol); break; } default: continue; }//end switch } //end for(j) } //end for(i) disjPerformFuse(aMapOfCommonOfCouple, aMapOfCommonOfCouple, theMapOfResult); return Standard_True; } //====================================================================================================== // static function : disjPerformCut // purpose: is needed in case of KPart==2 // attention: theMapOfResult is cleared before computations //====================================================================================================== static Standard_Boolean disjPerformCut(const TopTools_IndexedMapOfShape& theMapOfSolid1, const TopTools_IndexedMapOfShape& theMapOfSolid2, TopTools_IndexedMapOfShape& theMapOfResult) { TopoDS_Solid sol1; TopoDS_Shell outsha1; TopoDS_Solid sol2; TopoDS_Shell outsha2; TopOpeBRepTool_ShapeClassifier aShapeClassifier; TopoDS_Shape Snull; TopoDS_Solid acurrentsolid; TopTools_IndexedMapOfShape aMapOfSeparatedSolid1, aMapOfSeparatedSolid2; theMapOfResult.Clear(); disjPerformFuse(theMapOfSolid1, theMapOfSolid1, aMapOfSeparatedSolid1); disjPerformFuse(theMapOfSolid2, theMapOfSolid2, aMapOfSeparatedSolid2); for(Standard_Integer i=1; i<= aMapOfSeparatedSolid1.Extent(); i++) { const TopoDS_Shape& localshape1 = aMapOfSeparatedSolid1(i); if(localshape1.ShapeType()!=TopAbs_SOLID) return Standard_False; sol1 = TopoDS::Solid(localshape1); acurrentsolid = sol1; Standard_Boolean NullResult = Standard_False; for(Standard_Integer j=1; j<=aMapOfSeparatedSolid2.Extent() && !NullResult; j++) { const TopoDS_Shape& localshape2 = aMapOfSeparatedSolid2(j); if(localshape2.ShapeType()!=TopAbs_SOLID) return Standard_False; sol2 = TopoDS::Solid(localshape2); outsha2 = BRepTools::OuterShell(sol2); outsha1 = BRepTools::OuterShell(acurrentsolid); TopAbs_State stsol1 = aShapeClassifier.StateShapeShape(outsha1,Snull,sol2); TopAbs_State stsol2 = aShapeClassifier.StateShapeShape(outsha2,Snull,acurrentsolid); Standard_Integer ires=RESUNDEF, icla1=SHEUNDEF, icla2=SHEUNDEF; LocalKPisdisjanalyse(stsol1, stsol2, TopOpeBRepBuild_KPart_Operation_Cut12, ires, icla1, icla2); if (ires == RESUNDEF || icla1 == SHEUNDEF || icla2 == SHEUNDEF) { cout << "Warning: disjPerformCut: can not determine solid's states" << endl; continue; } switch (ires) { case RESNULL: { NullResult=Standard_True; break; } case RESSHAPE12 : { NullResult=Standard_True; break; } case RESSHAPE1 : { NullResult=Standard_False; break; } case RESSHAPE2 : { NullResult=Standard_True; break; } case RESNEWSHA1: case RESNEWSHA2: { TopoDS_Solid newsol = BuildNewSolid(acurrentsolid, sol2, stsol1, stsol2, ires, icla1, icla2, TopAbs_OUT, TopAbs_IN); acurrentsolid = newsol; break; } default: continue; }//end switch } //end for(j) if(!NullResult) { if(acurrentsolid.IsNull()) return Standard_False; theMapOfResult.Add(acurrentsolid); } } //end for(i) return Standard_True; } //modified by NIZHNY-MKK Tue May 23 09:49:03 2000.END