// file: TopOpeBRepBuild_GridSS.cxx // Created: Thu Mar 7 10:49:33 1996 // 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DRAW #include #include #endif #ifdef DEB #define DEBSHASET(sarg,meth,shaset,str) TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceSTRANGE(); Standard_EXPORT void debsplitf(const Standard_Integer i){cout<<"++ debsplitf "<Geometry(); iEinterf = SSI->Support(); const TopOpeBRepDS_Point& DSP = HDS->Point(GI); const gp_Pnt& P3d = DSP.Point(); Standard_Real tolp = DSP.Tolerance(); Standard_Boolean sameP = P3d.IsEqual(P,tolp); if (sameP) return GI; } return 0; } //---------------------------------------------------------------------- // FUN_EPIforEvisoONperiodicF : // Let be a periodic face, // an edge with as pcurve on a Viso line. // // if the pcurve of par u not bound in [0,2PI] : computes interference on // to split the edge at the point p2pi of u = 2PI; returns true. // else : returns false. // // To split the edge, scans among the list of edge point interferences // in order to get a geometry point falling into geometry P2pi on // of UV parameters = p2pi. // Gets the new vertex of array attached to the geometry P2pi. //---------------------------------------------------------------------- #define SPLITEDGE ( 0) #define INCREASEPERIOD ( 1) #define DECREASEPERIOD (-1) static Standard_Boolean FUN_EPIforEvisoONperiodicF (const TopoDS_Edge& E,const TopoDS_Face& F,const TopOpeBRepDS_ListOfInterference& EPIlist,const Handle(TopOpeBRepDS_HDataStructure) HDS,TopOpeBRepDS_ListOfInterference& loCPI) { Standard_Real parone=-1.e7; TopOpeBRepTool_CORRISO CORRISO(F); CORRISO.Init(F); Standard_Real uper; Standard_Boolean onU = CORRISO.Refclosed(1,uper); Standard_Real tolF = BRep_Tool::Tolerance(F); Standard_Real tolu = CORRISO.Tol(1,tolF); Standard_Integer recadre = CORRISO.EdgeOUTofBoundsUV(E,onU,tolu,parone); //Standard_Integer recadre = FUN_tool_outofUVbounds(F,E,parone); if (recadre != SPLITEDGE) return Standard_False; gp_Pnt p3d; Standard_Boolean ok = FUN_tool_value(parone,E,p3d); if (!ok) return Standard_False; // nyi FUN_Raise Standard_Integer iEinterf=0; Standard_Integer iG = FUN_getG(p3d,EPIlist,HDS,iEinterf); if (iG == 0) { #ifdef DEB Standard_Boolean strange = TopOpeBRepDS_GettraceSTRANGE(); if (strange) cout<<"strange : FUN_EPIforEvisoONperiodicF"<Shape(iEinterf).ShapeType() != TopAbs_EDGE) iEinterf = 0; // else V2pi = TopoDS::Vertex(newV->Array1().Value(iG)); // : Standard_Integer iS = HDS->Shape(E); TopOpeBRepDS_Transition T(TopAbs_IN, TopAbs_IN, TopAbs_EDGE, TopAbs_EDGE); T.Index(iS); Handle(TopOpeBRepDS_CurvePointInterference) CPI = new TopOpeBRepDS_CurvePointInterference (T,TopOpeBRepDS_EDGE,iEinterf,TopOpeBRepDS_POINT,iG,parone); loCPI.Append(CPI); return Standard_True; } //FUN_EPIforEvisoONperiodicF //---------------------------------------------------------------------- // FUN_GetSplitsON : // is a periodic face, has for pcurve on a visoline // of par u not bound in [0,2PI]. // Splits the edge at (UV point for has its u=2PI) // Recompute the pcurve for the split with (parameter on edge >= ) //---------------------------------------------------------------------- /*static void FUN_GetSplitsON (const TopoDS_Edge& E, TopoDS_Vertex& V2pi, const Standard_Real& paronE,const TopoDS_Face& F, TopTools_ListOfShape& losplits) { Standard_Real pf,pl,tolpc; TopoDS_Vertex Vf, Vl; TopExp::Vertices(E,Vf,Vl); Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(E,F,pf,pl,tolpc); const Handle(Geom_Surface)& S = BRep_Tool::Surface(F); Standard_Real tole = BRep_Tool::Tolerance(E); TopOpeBRepDS_BuildTool BT; BRep_Builder BB; TopAbs_Orientation oriVinf, oriVsup, oriE = E.Orientation(); oriVinf = (oriE == TopAbs_FORWARD)? TopAbs_FORWARD: TopAbs_REVERSED; oriVsup = (oriE == TopAbs_FORWARD)? TopAbs_REVERSED: TopAbs_FORWARD; // Einf2pi : TopoDS_Edge Einf2pi; BT.CopyEdge(E,Einf2pi); Vf.Orientation(oriVinf); BB.Add(Einf2pi,Vf); BT.Parameter(Einf2pi,Vf,pf); V2pi.Orientation(oriVsup); BB.Add(Einf2pi,V2pi); BT.Parameter(Einf2pi,V2pi,paronE); // Esup2pi : TopoDS_Edge Esup2pi; BT.CopyEdge(E,Esup2pi); V2pi.Orientation(oriVinf); BB.Add(Esup2pi,V2pi); BT.Parameter(Esup2pi,V2pi,paronE); Vl.Orientation(oriVsup); BB.Add(Esup2pi,Vl); BT.Parameter(Esup2pi,Vl,pl); gp_Pnt2d tmp = PC->Value(pf); Standard_Real v = tmp.Y(); Handle(Geom2d_Line) L2d = new Geom2d_Line(gp_Pnt2d(-paronE,v),gp_Dir2d(1.,0.)); Handle(Geom2d_TrimmedCurve) PCsup2pi = new Geom2d_TrimmedCurve(L2d,paronE,pl); TopOpeBRepDS_SetThePCurve(BB,Esup2pi,F,oriE,PCsup2pi); #ifdef DEB Standard_Boolean trc = Standard_False; #ifdef DRAW if (trc) {TCollection_AsciiString aa("PCinf");FUN_tool_draw(aa,Einf2pi,F,0);} if (trc) {TCollection_AsciiString aa("PCsup");FUN_tool_draw(aa,Esup2pi,F,0);} #endif #endif losplits.Append(Einf2pi); losplits.Append(Esup2pi); }*/ //--------------------------------------------- static void FUN_getEPI(const TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& EPI) //--------------------------------------------- { TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); Handle(TopOpeBRepDS_CurvePointInterference) CPI; for (; ILI.More(); ILI.Next() ) { const Handle(TopOpeBRepDS_Interference)& I = ILI.Value(); CPI = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I); if (CPI.IsNull()) continue; TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(CPI,GT,GI,ST,SI); if (GT != TopOpeBRepDS_POINT || ST != TopOpeBRepDS_FACE) continue; EPI.Append(I); } } //--------------------------------------------- static void FUN_getEPIonEds(const TopoDS_Shape& FOR,const Handle(TopOpeBRepDS_HDataStructure)& HDS,TopOpeBRepDS_ListOfInterference& EPI) //--------------------------------------------- { TopExp_Explorer ex(FOR, TopAbs_EDGE); for (; ex.More(); ex.Next()) { const TopoDS_Shape& E = ex.Current(); if (HDS->HasShape(E)) { const TopOpeBRepDS_ListOfInterference& LII = HDS->DS().ShapeInterferences(E); FUN_getEPI(LII,EPI); } } } //======================================================================= //function : GMergeSolids //purpose : //======================================================================= void TopOpeBRepBuild_Builder::GMergeSolids(const TopTools_ListOfShape& LSO1,const TopTools_ListOfShape& LSO2,const TopOpeBRepBuild_GTopo& G1) { if ( LSO1.IsEmpty() ) return; TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); const TopoDS_Shape& SO1 = LSO1.First(); #ifdef DEB Standard_Integer iSO; Standard_Boolean tSPS = GtraceSPS(SO1,iSO); if(tSPS){ cout<HasShape(SH); if ( ! hasshape ) { // shell SH is not in DS : classify it with LSO2 solids Standard_Boolean keep = GKeepShape(SH,LSO2,TB1); if (keep) { TopAbs_Orientation oriSH = SH.Orientation(); TopAbs_Orientation neworiSH = Orient(oriSH,RevOri1); SH.Orientation(neworiSH); #ifdef DEB if(tSPS){ DEBSHASET(ss,"--- GFillSolidSFS ",SFS," AddShape SFS+ shell "); GdumpSHA(SH,(Standard_Address)ss.ToCString()); cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 shell "; TopAbs::Print(neworiSH,cout); cout<Shape(mySolidReference); Standard_Integer ifil = myDataStructure->Shape(mySolidToFill); if(tSPS){ cout<<"ifil : "< } // GFillSurfaceTopologySFS //======================================================================= //function : GFillShellSFS //purpose : //======================================================================= void TopOpeBRepBuild_Builder::GFillShellSFS(const TopoDS_Shape& SH, const TopTools_ListOfShape& LSO2, const TopOpeBRepBuild_GTopo& G1, TopOpeBRepBuild_ShellFaceSet& SFS) { TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); #ifdef DEB Standard_Integer ish; Standard_Boolean tSPS = GtraceSPS(SH,ish); if(tSPS){ cout<Shape(FOR); Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR); if ( hsd ) { GFillFaceSFS(FOR,LSO2,G1,SFS); } // hsd nlsfs = SFS.ChangeStartShapes().Extent(); } // exFace.More() #ifdef DEB if (tSPS) { SFS.DumpSS(); } #endif // 2/ : toutes les faces non HasSameDomain for (exFace.Init(SH,TopAbs_FACE); exFace.More(); exFace.Next()) { nlsfs = SFS.ChangeStartShapes().Extent(); const TopoDS_Shape& FOR = exFace.Current(); ifor = myDataStructure->Shape(FOR); Standard_Boolean hsd = myDataStructure->HasSameDomain(FOR); if ( !hsd ) { GFillFaceSFS(FOR,LSO2,G1,SFS); } // hsd nlsfs = SFS.ChangeStartShapes().Extent(); } } // GFillShellSFS // ---------------------------------------------------------------------- static void FUNBUILD_MAPSUBSHAPES(const TopoDS_Shape& S, const TopAbs_ShapeEnum T, TopTools_IndexedMapOfShape& _IM) { TopExp::MapShapes(S,T,_IM); } // ---------------------------------------------------------------------- static void FUNBUILD_MAPSUBSHAPES(const TopTools_ListOfShape& LOFS, const TopAbs_ShapeEnum T,TopTools_IndexedMapOfShape& _IM) { for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) FUNBUILD_MAPSUBSHAPES(it.Value(),T,_IM); } // ---------------------------------------------------------------------- static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, const TopoDS_Shape& S, const TopAbs_State STATE, TopTools_IndexedDataMapOfShapeListOfShape& _IDM) { Standard_Boolean issp = B.IsSplit(S,STATE); if (issp) { const TopTools_ListOfShape& l = B.Splits(S,STATE); for (TopTools_ListIteratorOfListOfShape it(l);it.More();it.Next()) { const TopoDS_Shape& sps = it.Value(); // sps = split result of S on state STATE TopTools_ListOfShape thelist; if ( ! _IDM.Contains(sps) ) _IDM.Add(sps, thelist); _IDM.ChangeFromKey(sps).Append(S); } } } // ---------------------------------------------------------------------- static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, const TopoDS_Shape& S, TopTools_IndexedDataMapOfShapeListOfShape& _IDM) { FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_IN, _IDM); FUNBUILD_MAPANCSPLSHAPES(B,S,TopAbs_OUT,_IDM); } // ---------------------------------------------------------------------- static void FUNBUILD_MAPANCSPLSHAPES(TopOpeBRepBuild_Builder& B, const TopTools_IndexedMapOfShape& M, TopTools_IndexedDataMapOfShapeListOfShape& _IDM) { Standard_Integer n = M.Extent(); for(Standard_Integer i = 1;i <= n;i++) FUNBUILD_MAPANCSPLSHAPES(B,M(i),_IDM); } static TopTools_IndexedMapOfShape stabuild_IMELF1; static TopTools_IndexedMapOfShape stabuild_IMELF2; static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF1; static TopTools_IndexedDataMapOfShapeListOfShape stabuild_IDMEALF2; static TopOpeBRepDS_Config static_CONF1; static TopOpeBRepDS_Config static_CONF2; // ---------------------------------------------------------------------- Standard_EXPORT void FUNBUILD_ANCESTORRANKPREPARE(TopOpeBRepBuild_Builder& B, const TopTools_ListOfShape& LF1, const TopTools_ListOfShape& LF2, const TopOpeBRepDS_Config CONF1, const TopOpeBRepDS_Config CONF2) { static_CONF1 = CONF1; static_CONF2 = CONF2; FUNBUILD_MAPSUBSHAPES(LF1,TopAbs_EDGE,stabuild_IMELF1); FUNBUILD_MAPSUBSHAPES(LF2,TopAbs_EDGE,stabuild_IMELF2); FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF1,stabuild_IDMEALF1); FUNBUILD_MAPANCSPLSHAPES(B,stabuild_IMELF2,stabuild_IDMEALF2); } static TopTools_IndexedMapOfShape stabuild_IMEF; // ---------------------------------------------------------------------- Standard_EXPORT void FUNBUILD_ANCESTORRANKGET(TopOpeBRepBuild_Builder& /*B*/, const TopoDS_Shape& f, Standard_Boolean& of1, Standard_Boolean& of2) { FUNBUILD_MAPSUBSHAPES(f,TopAbs_EDGE,stabuild_IMEF); Standard_Integer ief = 1,nef = stabuild_IMEF.Extent(); of1 = Standard_False; for (ief = 1; ief <= nef; ief++ ) { const TopoDS_Shape& e = stabuild_IMEF(ief); of1 = stabuild_IDMEALF1.Contains(e); if (of1) break; } of2 = Standard_False; for (ief = 1; ief <= nef; ief++ ) { const TopoDS_Shape& e = stabuild_IMEF(ief); of2 = stabuild_IDMEALF2.Contains(e); if (of2) break; } } // ---------------------------------------------------------------------- Standard_EXPORT void FUNBUILD_ORIENTLOFS(TopOpeBRepBuild_Builder& B, const TopAbs_State TB1, const TopAbs_State TB2, TopTools_ListOfShape& LOFS) { for (TopTools_ListIteratorOfListOfShape it(LOFS);it.More();it.Next()) { TopoDS_Shape& f = it.Value(); Standard_Boolean of1,of2; FUNBUILD_ANCESTORRANKGET(B,f,of1,of2); TopAbs_Orientation orif = f.Orientation(); Standard_Boolean r12 = B.Reverse(TB1,TB2); Standard_Boolean r21 = B.Reverse(TB2,TB1); Standard_Boolean rf = Standard_False; if (of1 && !of2) rf = r12; else if (of2 && !of1) rf = r21; TopAbs_Orientation neworif = B.Orient(orif,rf); f.Orientation(neworif); } } Standard_EXPORT Standard_Boolean GLOBAL_revownsplfacori = Standard_False; // GLOBAL_REVerseOWNSPLittedFACeORIentation = True : dans GSplitFaceSFS on // applique le retournement d'orientation de la face splittee FS de F // a l'orientation de FS elle-meme (au lieu de l'appliquer a l'orientation // de la face F comme en standard) //Standard_IMPORT extern TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 Standard_EXPORTEXTERN TopTools_DataMapOfShapeInteger* GLOBAL_SplitAnc; //xpu260598 //static TopAbs_Orientation FUN_intTOori(const Standard_Integer Iori) //{ // if (Iori == 1) return TopAbs_FORWARD; // if (Iori == 2) return TopAbs_REVERSED; // if (Iori == 11) return TopAbs_INTERNAL; // if (Iori == 22) return TopAbs_EXTERNAL; // return TopAbs_EXTERNAL; //} //Standard_IMPORT extern TopTools_ListOfShape* GLOBAL_lfr1; Standard_EXPORTEXTERN TopTools_ListOfShape* GLOBAL_lfr1; //Standard_IMPORT extern Standard_Boolean GLOBAL_lfrtoprocess; Standard_EXPORTEXTERN Standard_Boolean GLOBAL_lfrtoprocess; //======================================================================= //function : GSplitFaceSFS //purpose : //======================================================================= void TopOpeBRepBuild_Builder::GSplitFaceSFS (const TopoDS_Shape& FOR,const TopTools_ListOfShape& LSclass,const TopOpeBRepBuild_GTopo& G1, TopOpeBRepBuild_ShellFaceSet& SFS) { TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); Standard_Boolean RevOri1 = G1.IsToReverse1(); TopAbs_Orientation oriF = FOR.Orientation(); TopAbs_Orientation neworiF = Orient(oriF,RevOri1); const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); #ifdef DEB Standard_Integer iFOR = #endif BDS.Shape(FOR); #ifdef DEB Standard_Integer iiFOR; Standard_Boolean tSPS = GtraceSPS(FOR,iiFOR); if(tSPS){ cout<IsBound(newF); //xpu260598 Standard_Boolean opeFus = Opefus(); Standard_Boolean opec12 = Opec12(); Standard_Boolean opec21 = Opec21(); Standard_Boolean opeCut = opec12 || opec21; Standard_Boolean opeCom = Opecom(); if (hasoridef) { Standard_Integer iAnc = GLOBAL_SplitAnc->Find(newF); Standard_Integer rkAnc = BDS.AncestorRank(iAnc); TopAbs_Orientation oAnc = BDS.Shape(iAnc).Orientation(); #ifdef DEB Standard_Integer iFanc; Standard_Boolean tSPSa = GtraceSPS(BDS.Shape(iAnc),iFanc); if (tSPSa) debspanc(iAnc); #endif if (opeCom) { // xpu260598 : orifspIN = orifanc // bcl1;bcl2 tspIN(f23) is splitIN(f23), f9 SDDO f23 neworiF = oAnc; } else if (opeCut) { // xpu280598 : cto100G1 spIN(f21) TopAbs_State TBAnc = TopAbs_UNKNOWN; if (opec12) TBAnc = (rkAnc == 1)? TopAbs_OUT : TopAbs_IN; if (opec21) TBAnc = (rkAnc == 2)? TopAbs_OUT : TopAbs_IN; // if TBAnc == OUT : we keep orientation // else we reverse it if (TBAnc == TopAbs_OUT) neworiF = oAnc; else neworiF = TopAbs::Complement(oAnc); } else if (opeFus) { neworiF = oAnc; //xpu290598 } Standard_Boolean reverse = Standard_False; Standard_Integer irefAnc = BDS.SameDomainRef(iAnc); if (irefAnc != iAnc) { // newFace is built on geometry of refAnc Standard_Boolean samegeom=Standard_False; TopOpeBRepDS_Config cAnc = BDS.SameDomainOri(iAnc); if (cAnc == TopOpeBRepDS_SAMEORIENTED) samegeom = Standard_True; else if (cAnc == TopOpeBRepDS_DIFFORIENTED) samegeom = Standard_False; TopAbs_Orientation orefAnc = BDS.Shape(irefAnc).Orientation(); if (oAnc != orefAnc) samegeom = !samegeom; reverse = !samegeom; } if (reverse) neworiF = TopAbs::Complement(neworiF); } // hasoridef } newF.Orientation(neworiF); if (GLOBAL_lfrtoprocess) { GLOBAL_lfr1->Append(newF); } else { #ifdef DEB if(tSPS){ DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddStartElement SFS+ face "); GdumpSHA(newF,(Standard_Address)ss.ToCString()); cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; TopAbs::Print(neworiF,cout); cout<HasShape(FOR); Standard_Boolean hg = myDataStructure->HasGeometry(FOR); Standard_Boolean testkeep = Standard_True; testkeep = (hs && (!hg)); // +12/05 macktruck if (testkeep) { Standard_Boolean keep = GKeepShape(FOR,LSclass,TB1); add = keep; } if (add) { TopoDS_Shape F = FOR; F.Orientation(neworiF); #ifdef DEB if(tSPS){ DEBSHASET(ss,"--- GSplitFaceSFS ",SFS," AddElement SFS+ face "); GdumpSHA(F,(Standard_Address)ss.ToCString()); cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; TopAbs::Print(neworiF,cout); cout<SameDomainReference(FOR); const TopoDS_Shape& Fref = myDataStructure->Shape(iFref); Standard_Boolean Fisref = FOR.IsSame(Fref); addmerge = Fisref; if ( addmerge ) { const TopTools_ListOfShape& ME = Merged(FOR,TopAbs_IN); for(TopTools_ListIteratorOfListOfShape it(ME);it.More();it.Next()) { TopoDS_Shape newF = it.Value(); newF.Orientation(neworiF); #ifdef DEB if(tSPS){ DEBSHASET(ss,"--- GMergeFaceSFS ",SFS," AddStartElement SFS+ face "); GdumpSHA(newF,(Standard_Address)ss.ToCString()); cout<<" ";TopAbs::Print(TB1,cout)<<" : 1 face "; TopAbs::Print(neworiF,cout); cout<DS().ShapeInterferences(FF); if (LLI.Extent() == 0) return Standard_True; TopOpeBRepDS_ListOfInterference LI; TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LLI); for (; ILI.More(); ILI.Next() ) LI.Append(ILI.Value()); // LI3 = {I3 = (T(FACE),EG=EDGE,FS=FACE)} TopOpeBRepDS_ListOfInterference LI1; Standard_Integer nIGtEDGE = FUN_selectGKinterference(LI,TopOpeBRepDS_EDGE,LI1); if (nIGtEDGE < 1) return Standard_True; TopOpeBRepDS_ListOfInterference LI2; Standard_Integer nIStFACE = FUN_selectSKinterference(LI1,TopOpeBRepDS_FACE,LI2); if (nIStFACE < 1) return Standard_True; TopOpeBRepDS_ListOfInterference LI3; Standard_Integer nITRASHAFACE = FUN_selectTRASHAinterference(LI2,TopAbs_FACE,LI3); if (nITRASHAFACE < 1) return Standard_True; Handle(TopOpeBRepDS_ShapeShapeInterference) SSI; ILI.Initialize(LI3); for (; ILI.More(); ILI.Next() ) { SSI = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(ILI.Value()); TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI); const TopoDS_Face& FS = TopoDS::Face( HDS->Shape(SI)); #ifdef DEB Standard_Integer iFS = #endif HDS->Shape(FS); // Standard_Boolean FSper = FUN_periodicS(FS); Standard_Boolean FSper = FUN_tool_closedS(FS); if (!FSper) continue; const TopoDS_Edge& EG = TopoDS::Edge(HDS->Shape(GI)); #ifdef DEB Standard_Integer iEG = #endif HDS->Shape(EG); Standard_Boolean isrest = HDS->DS().IsSectionEdge(EG); if (!isrest) continue; // -------------------------------------------------- // has no representation on face yet, // set the pcurve on . // -------------------------------------------------- Standard_Real pf,pl,tol; Handle(Geom2d_Curve) PC = FC2D_CurveOnSurface(EG,FS,pf,pl,tol); if (PC.IsNull()) { TopoDS_Edge EEG = EG; Standard_Boolean ok = FUN_tool_pcurveonF(FS,EEG); if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl"); Standard_Real f,l; PC = FC2D_CurveOnSurface(EEG,FS,f,l,tol); } Standard_Boolean uiso,viso;gp_Dir2d d2d;gp_Pnt2d o2d; TopOpeBRepTool_TOOL::UVISO(PC,uiso,viso,d2d,o2d); if (!viso) continue; // a. cylinders same domain on cylindrical face, with closing edges non same domain : // the 2d rep. of an edge VisoLineOnCyl on the cylindrical face of the other shape // is not bounded in [0,2PI]. // b. cylinder + sphere interfering on the circular edge E (section edge) of the cylinder // with the E's 2d rep on the spherical surface not bounded in [0,2PI] (cto 016 D*). // We have to split the edge at point (2PI,v), and we translate // the split of u >= 2PI to have it in [0,2PI]. TopOpeBRepDS_DataStructure& BDS = HDS->ChangeDS(); TopOpeBRepDS_ListOfInterference EPIlist; FUN_getEPIonEds(FS,HDS,EPIlist); TopOpeBRepDS_ListOfInterference loCPI; #ifdef DEB Standard_Boolean recadre = #endif FUN_EPIforEvisoONperiodicF(EG,FS,EPIlist, HDS,loCPI); TopOpeBRepDS_ListOfInterference& lIEG = BDS.ChangeShapeInterferences(EG); lIEG.Append(loCPI); #ifdef DEB Standard_Boolean trc = TopOpeBRepDS_GettraceSTRANGE(); if (trc) {cout<<"!! recadre is "; if (!recadre) cout<<"not "; cout<<"done on face FS "< a Visoline not // U-bounded in [0,2PI]. // modifies : myDataStructure // Scans among the interferences attached to faces for FEI with // support = cylinder, geometry ; adds pcurve on // for edge if necessay. //======================================================================= void TopOpeBRepBuild_Builder::SplitEvisoONperiodicF() { // myEsplitsONcycy.Clear(); Standard_Integer nsha = myDataStructure->NbShapes(); for (Standard_Integer i = 1; i <= nsha; i++) { const TopoDS_Shape& FOR = myDataStructure->Shape(i); Standard_Boolean isface = (FOR.ShapeType() == TopAbs_FACE); if (!isface) continue; TopLoc_Location loc; const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(FOR),loc); Standard_Boolean periodic = S->IsUPeriodic() || S->IsVPeriodic(); if (!periodic) continue; TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); Standard_Boolean ok = FUN_SplitEvisoONperiodicF(myDataStructure,FF); if (!ok) Standard_ProgramError::Raise("_Builder::SplitONVisolineonCyl"); } // i } //======================================================================= //function : GSplitFace //purpose : //======================================================================= void TopOpeBRepBuild_Builder::GSplitFace (const TopoDS_Shape& FOR,const TopOpeBRepBuild_GTopo& GG1,const TopTools_ListOfShape& LSclass) { TopOpeBRepBuild_GTopo G1 = GG1; Standard_Boolean RevOri = Standard_False; G1.SetReverse(RevOri); TopAbs_State TB1,TB2; G1.StatesON(TB1,TB2); TopAbs_ShapeEnum t1,t2; G1.Type(t1,t2); // work on a FORWARD face TopoDS_Shape FF = FOR; FF.Orientation(TopAbs_FORWARD); #ifdef DEB Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(FOR,iF); if(tSPS){ cout< GSplitFace , after GFillONPartsWES nstartelWES = "< GSplitFace , after GFillFaceWES nstartelWES = "< GSplitFace , after GFillCurveTopologyWES nstartelWES = "<DS().AncestorRank(aFAnc1) == 1) { const TopoDS_Face& aFace1 = TopoDS::Face(myONFacesMap.FindKey(i)); // map edges of the first face TopTools_IndexedMapOfShape aMapE1; TopExp::MapShapes(aFace1, TopAbs_EDGE, aMapE1); // find a non-degenerated edge TopoDS_Edge aChkEdge; Standard_Integer k; for (k=1; k <= aMapE1.Extent() && aChkEdge.IsNull(); k++) { const TopoDS_Edge& aE = TopoDS::Edge(aMapE1(k)); if (!BRep_Tool::Degenerated(aE)) aChkEdge = aE; } if (aChkEdge.IsNull()) continue; // find a point and a normal BRepAdaptor_Curve2d aBAC1(aChkEdge, aFace1); gp_Pnt2d aP2d; const Standard_Real PAR_T = 0.456321; Standard_Real par = aBAC1.FirstParameter()*(1.-PAR_T) + aBAC1.LastParameter() * PAR_T; aBAC1.D0(par, aP2d); BRepAdaptor_Surface aBAS1(aFace1); gp_Pnt aPbid; gp_Vec aN1,aDU,aDV; aBAS1.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV); aN1 = aDU ^ aDV; Standard_Real norm = aN1.Magnitude(); if (norm < Precision::Confusion()) continue; aN1 /= norm; if (aFace1.Orientation() == TopAbs_REVERSED) aN1.Reverse(); // iterate on faces from the second shape Standard_Boolean ok = Standard_True; for (j=i+1; j <= myONFacesMap.Extent() && ok; j++) { const TopoDS_Shape& aFAnc2 = myONFacesMap(j); if (myDataStructure->DS().AncestorRank(aFAnc2) == 2) { const TopoDS_Face& aFace2 = TopoDS::Face(myONFacesMap.FindKey(j)); // check that the second face has the same boundaries TopTools_IndexedMapOfShape aMapE2; TopExp::MapShapes(aFace2, TopAbs_EDGE, aMapE2); if (aMapE1.Extent() != aMapE2.Extent()) continue; Standard_Boolean sameBnd = Standard_True; for (k=1; k <= aMapE2.Extent() && sameBnd; k++) if (!aMapE1.Contains(aMapE2(k))) sameBnd = Standard_False; if (!sameBnd) continue; // check if it is needed to have a patch here; // for that the normals should be oriented in the same sense. BRepAdaptor_Curve2d aBAC2(aChkEdge, aFace2); aBAC2.D0(par,aP2d); BRepAdaptor_Surface aBAS2(aFace2); gp_Vec aN2; aBAS2.D1(aP2d.X(),aP2d.Y(),aPbid,aDU,aDV); aN2 = aDU ^ aDV; norm = aN2.Magnitude(); if (norm < Precision::Confusion()) { ok = Standard_False; continue; } aN2 /= norm; if (aFace2.Orientation() == TopAbs_REVERSED) aN2.Reverse(); Standard_Real scal = aN1 * aN2; if (scal < scalMin) { ok = Standard_False; continue; } // select one of the two faces Standard_Boolean takeFirst = Standard_True; TopoDS_Face aPatch; TopAbs_Orientation neworiF; if (takeFirst) { aPatch = aFace1; neworiF = Orient(aFAnc1.Orientation(), G1.IsToReverse1()); } else { aPatch = aFace2; neworiF = Orient(aFAnc2.Orientation(), G1.IsToReverse2()); } aPatch.Orientation(neworiF); // add patch to SFS SFS.AddStartElement(aPatch); // save ON splits MarkSplit(aFAnc1,TopAbs_ON); TopTools_ListOfShape& aLOFS1 = ChangeSplit(aFAnc1,TopAbs_ON); aLOFS1.Append(aFace1); MarkSplit(aFAnc2,TopAbs_ON); TopTools_ListOfShape& aLOFS2 = ChangeSplit(aFAnc2,TopAbs_ON); aLOFS2.Append(aFace2); } } } } } //======================================================================= //function : AreFacesCoincideInArea //purpose : //======================================================================= static Standard_Boolean AreFacesCoincideInArea (const TopoDS_Shape& theBaseFace, const TopoDS_Shape& theFace, const TopoDS_Shape& theEdge, const TopTools_ListOfShape& allEdges, Standard_Boolean& isSameOri) { // there are given: // theBaseFace, theFace - possibly coinciding faces; // allEdges - the edges lying on theBaseFace forming the new boundary loops, // they determine the areas of coincidence; // theEdge - an edge from allEdges pointing to the area to check in. // we should check that the faces are coincide in this area and have // the same orientation considering the orientations of the faces. TopAbs_Orientation anEdgeOri = theEdge.Orientation(); if (anEdgeOri != TopAbs_FORWARD && anEdgeOri != TopAbs_REVERSED) return Standard_False; Standard_Boolean reverse = (anEdgeOri == TopAbs_REVERSED); TopoDS_Face aBaseFace = TopoDS::Face(theBaseFace); TopoDS_Face aFace = TopoDS::Face(theFace); TopoDS_Edge anEdge = TopoDS::Edge(theEdge); BRep_Builder BB; // create a ray from the inside of anEdge to the matter side Standard_Real pf,pl,tol; Standard_Boolean trim3d = Standard_True; Handle(Geom2d_Curve) PCref = BRep_Tool::CurveOnSurface(anEdge,aBaseFace,pf,pl); if (PCref.IsNull()) { PCref = FC2D_CurveOnSurface(anEdge,aBaseFace,pf,pl,tol,trim3d); if (PCref.IsNull()) return Standard_False; tol = BRep_Tool::Tolerance(anEdge); BB.UpdateEdge(anEdge,PCref,aBaseFace,tol); } const Standard_Real T = 0.456789; Standard_Real pm = (1.-T)*pf + T*pl; gp_Pnt2d pt; gp_Vec2d d1; PCref->D1(pm, pt, d1); if (d1.Magnitude() < gp::Resolution()) return Standard_False; if (reverse) d1.Reverse(); gp_Vec2d vecInside(-d1.Y(),d1.X()); gp_Lin2d aLin(pt,vecInside); // find the nearest intersection of aLin with other edges Standard_Boolean hasInt = Standard_False; Standard_Real pLinMin = RealLast(); Standard_Real tol2d = Precision::PConfusion(); BRepClass_Intersector anInter; BRepClass_Edge aBCE; aBCE.Face() = aBaseFace; Standard_Real maxDist = Max (BRep_Tool::Tolerance(aBaseFace), BRep_Tool::Tolerance(aFace)); Standard_Boolean isError = Standard_False; TopTools_ListIteratorOfListOfShape it(allEdges); for (; it.More() && !isError; it.Next()) { const TopoDS_Edge& aE = TopoDS::Edge(it.Value()); Standard_Real tolE = BRep_Tool::Tolerance(aE); if (tolE > maxDist) maxDist = tolE; if (aE.IsEqual(anEdge) || aE.Orientation() != TopAbs_FORWARD && aE.Orientation() != TopAbs_REVERSED && aE.IsSame(anEdge)) continue; // the same pcurve Handle(Geom2d_Curve) PC = BRep_Tool::CurveOnSurface(aE,aBaseFace,pf,pl); if (PC.IsNull()) { PC = FC2D_CurveOnSurface(aE,aBaseFace,pf,pl,tol,trim3d); if (PC.IsNull()) {isError = Standard_True; break;} BB.UpdateEdge(aE,PC,aBaseFace,tolE); } aBCE.Edge() = aE; anInter.Perform(aLin,pLinMin,tol2d,aBCE); if (anInter.IsDone()) { Standard_Integer i; for (i=1; i <= anInter.NbPoints(); i++) { const IntRes2d_IntersectionPoint& aIP = anInter.Point(i); Standard_Real pLin = aIP.ParamOnFirst(); if (pLin > tol2d && pLin < pLinMin) { pLinMin = pLin; hasInt = Standard_True; } } for (i=1; i <= anInter.NbSegments() && !isError; i++) { const IntRes2d_IntersectionSegment& aIS = anInter.Segment(i); Standard_Real pLinF = aIS.HasFirstPoint() ? aIS.FirstPoint().ParamOnFirst() : -Precision::Infinite(); Standard_Real pLinL = aIS.HasLastPoint() ? aIS.LastPoint().ParamOnFirst() : Precision::Infinite(); if (pLinF < tol2d && pLinL > -tol2d) isError = Standard_True; else if (pLinF > tol2d && pLinF < pLinMin) { pLinMin = pLinF; hasInt = Standard_True; } } } } if (isError || !hasInt) return Standard_False; // create a point in the area and get the normal to aBaseFace at it gp_Pnt2d aP2d = ElCLib::Value(pLinMin*T,aLin); BRepAdaptor_Surface aBAS(aBaseFace); gp_Pnt aPnt; gp_Vec d1u,d1v; aBAS.D1(aP2d.X(),aP2d.Y(),aPnt,d1u,d1v); gp_Vec aNormBase = d1u ^ d1v; Standard_Real mag = aNormBase.Magnitude(); if (mag < gp::Resolution()) return Standard_False; if (aBaseFace.Orientation() == TopAbs_REVERSED) mag = -mag; aNormBase /= mag; // project the point aPnt to the second face aFace Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); Standard_Real umin,umax,vmin,vmax; BRepTools::UVBounds(aFace,umin,umax,vmin,vmax); GeomAPI_ProjectPointOnSurf aProj(aPnt,aSurf,umin,umax,vmin,vmax); if (!aProj.NbPoints() || aProj.LowerDistance() > maxDist) return Standard_False; Standard_Real u,v; aProj.LowerDistanceParameters(u,v); aSurf->D1(u,v,aPnt,d1u,d1v); gp_Vec aNorm = d1u ^ d1v; mag = aNorm.Magnitude(); if (mag < gp::Resolution()) return Standard_False; if (aFace.Orientation() == TopAbs_REVERSED) mag = -mag; aNorm /= mag; // check normales Standard_Real dot = aNormBase * aNorm; const Standard_Real minDot = 0.9999; if (Abs(dot) < minDot) return Standard_False; isSameOri = (dot > 0.); return Standard_True; } //======================================================================= //function : FillOnPatches //purpose : //======================================================================= void TopOpeBRepBuild_Builder::FillOnPatches (const TopTools_ListOfShape& anEdgesON, const TopoDS_Shape& aBaseFace, const TopTools_IndexedMapOfOrientedShape& avoidMap) { TopoDS_Shape FF = aBaseFace; FF.Orientation(TopAbs_FORWARD); Standard_Integer rankBF = ShapeRank(aBaseFace); Standard_Integer rankOpp; if (rankBF == 1) rankOpp = 2; else if (rankBF == 2) rankOpp = 1; else return; TopOpeBRepBuild_WireEdgeSet WES(FF,this); TopTools_MapOfShape aMapON,aMapON1; TopTools_DataMapOfShapeInteger aMapFState; TopTools_ListOfShape allEdges; TopTools_ListIteratorOfListOfShape it; TopoDS_Iterator itW; for (it.Initialize(anEdgesON); it.More(); it.Next()) { const TopoDS_Shape& aE = it.Value(); // is it a part of the boundary of aBaseFace ? if (!myONElemMap.Contains(aE) && !myONElemMap.Contains(aE.Reversed()) && !avoidMap.Contains(aE)) { allEdges.Append(aE); aMapON.Add(aE); } } Standard_Integer i; Standard_Boolean hasWires = Standard_False; for (i=1; i <= myONElemMap.Extent(); i++) { const TopoDS_Shape& aE = myONElemMap(i); if (aE.ShapeType() == TopAbs_WIRE) { for (itW.Initialize(aE); itW.More(); itW.Next()) if (!avoidMap.Contains(itW.Value())) { allEdges.Append(itW.Value()); hasWires = Standard_True; } } else if (!avoidMap.Contains(aE)) { allEdges.Append(aE); aMapON1.Add(aE); } } // +++ // add elements from anEdgesON (they come from BuilderON) TopTools_DataMapOfShapeShape anAncMap; if (!aMapON.IsEmpty()) FillSecEdgeAncestorMap(rankOpp,aMapON,anAncMap); if (!anAncMap.IsEmpty()) { for (it.Initialize(anEdgesON); it.More(); it.Next()) { const TopoDS_Shape& aE = it.Value(); // an ON part if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) { const TopoDS_Shape& anAncE = anAncMap(aE); // its ancestor edge from opposite shape const TopTools_ListOfShape& aFaces = // connex faces of anAncE FDSCNX_EdgeConnexityShapeIndex (anAncE,myDataStructure,rankOpp); // determine if aBaseFace has coinciding part on the left side of aE // with one of connex faces, and this pair of faces are same oriented Standard_Boolean isOnFace = Standard_False; TopTools_ListOfShape aFacesToCheck; TopTools_ListIteratorOfListOfShape itF; for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) { const TopoDS_Shape& aF = itF.Value(); if (aMapFState.IsBound(aF)) { Standard_Integer state = aMapFState(aF); if (state) isOnFace = Standard_True; } else aFacesToCheck.Append(aF); } for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) { const TopoDS_Shape& aF = itF.Value(); Standard_Boolean isSameOri = Standard_False; Standard_Boolean ok; if (aE.Orientation() != TopAbs_FORWARD && aE.Orientation() != TopAbs_REVERSED) { ok = AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_FORWARD), allEdges,isSameOri); ok = ok || AreFacesCoincideInArea(aBaseFace,aF,aE.Oriented(TopAbs_REVERSED), allEdges,isSameOri); } else ok = AreFacesCoincideInArea(aBaseFace,aF,aE, allEdges,isSameOri); if (ok && isSameOri) { aMapFState.Bind(aF,1); isOnFace = Standard_True; } else aMapFState.Bind(aF,0); } if (isOnFace) WES.AddStartElement(aE); } } } // +++ // add elements from myONElemMap (consisting of parts of the boundary of aBaseFace) anAncMap.Clear(); if (!aMapON1.IsEmpty()) FillSecEdgeAncestorMap(rankBF,aMapON1,anAncMap); if (hasWires || !anAncMap.IsEmpty()) { for (i=1; i <= myONElemMap.Extent(); i++) { const TopoDS_Shape& aE = myONElemMap(i); TopoDS_Shape anEdge, anAncE; if (aE.ShapeType() == TopAbs_WIRE) { // for a wire get one non-degenerated edge for test for (itW.Initialize(aE); itW.More() && anEdge.IsNull(); itW.Next()) { const TopoDS_Edge& e = TopoDS::Edge(itW.Value()); if (avoidMap.Contains(e)) break; if (!BRep_Tool::Degenerated(e)) anEdge = anAncE = e; } } else if (anAncMap.IsBound(aE) && !avoidMap.Contains(aE)) { anEdge = aE; anAncE = anAncMap(aE); } if (!anEdge.IsNull()) { // find faces of the opposite shape touching anAncE TopTools_ListOfShape aFaces; FDSCNX_FaceEdgeConnexFaces (aBaseFace,anAncE,myDataStructure,aFaces); if (aFaces.IsEmpty()) continue; TopoDS_Shape aCnxF = aFaces.First(); aFaces.Clear(); FindFacesTouchingEdge (aCnxF,anAncE,rankOpp,aFaces); // determine if aBaseFace has coinciding part on the left side of anEdge // with one of found faces, and this pair of faces are same oriented Standard_Boolean isOnFace = Standard_False; TopTools_ListOfShape aFacesToCheck; TopTools_ListIteratorOfListOfShape itF; for (itF.Initialize(aFaces); itF.More() && !isOnFace; itF.Next()) { const TopoDS_Shape& aF = itF.Value(); if (aMapFState.IsBound(aF)) { Standard_Integer state = aMapFState(aF); if (state) isOnFace = Standard_True; } else aFacesToCheck.Append(aF); } for (itF.Initialize(aFacesToCheck); itF.More() && !isOnFace; itF.Next()) { const TopoDS_Shape& aF = itF.Value(); Standard_Boolean isSameOri = Standard_False; Standard_Boolean ok = AreFacesCoincideInArea (aBaseFace,aF,anEdge,allEdges,isSameOri); if (ok && isSameOri) { aMapFState.Bind(aF,1); isOnFace = Standard_True; } else aMapFState.Bind(aF,0); } if (isOnFace) { if (aE.ShapeType() == TopAbs_WIRE) WES.AddShape(aE); else WES.AddStartElement(aE); } } } } WES.InitShapes(); WES.InitStartElements(); if (WES.MoreShapes() || WES.MoreStartElements()) { TopTools_ListOfShape LOF; GWESMakeFaces(FF,WES,LOF); // save ON faces for (it.Initialize(LOF); it.More(); it.Next()) { const TopoDS_Face& aF = TopoDS::Face(it.Value()); myONFacesMap.Add(aF,aBaseFace); } } } //======================================================================= //function : FindFacesTouchingEdge //purpose : //======================================================================= void TopOpeBRepBuild_Builder::FindFacesTouchingEdge(const TopoDS_Shape& aFace, const TopoDS_Shape& anEdge, const Standard_Integer aShRank, TopTools_ListOfShape& aFaces) const { const TopOpeBRepDS_DataStructure& BDS=myDataStructure->DS(); Standard_Integer anEdgeInd = BDS.Shape(anEdge); if (!anEdgeInd) return; const TopOpeBRepDS_ListOfInterference& LI=BDS.ShapeInterferences(aFace); TopOpeBRepDS_ListIteratorOfListOfInterference ILI(LI); for (;ILI.More();ILI.Next() ) { const Handle(TopOpeBRepDS_Interference)& I=ILI.Value(); Handle(TopOpeBRepDS_ShapeShapeInterference) SSI= Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I); if (SSI.IsNull()) continue; TopOpeBRepDS_Kind GT,ST;Standard_Integer GI,SI;FDS_data(SSI,GT,GI,ST,SI); if (GT != TopOpeBRepDS_EDGE || ST != TopOpeBRepDS_FACE) continue; if (GI != anEdgeInd) continue; const TopOpeBRepDS_Transition& TFE=SSI->Transition(); if (TFE.ShapeBefore() != TopAbs_FACE || TFE.ShapeAfter() != TopAbs_FACE) continue; const TopoDS_Shape& FS=BDS.Shape(SI); if (ShapeRank(FS) != aShRank) continue; aFaces.Append(FS); } }