// File: TopOpeBRepDS_ProcessFaceInterferences.cxx // Created: Fri Feb 14 10:26:01 1997 // 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 Standard_EXPORT void FUN_UNKFstasta(const TopoDS_Face& FF,const TopoDS_Face& FS, const TopoDS_Edge& EE,const Standard_Boolean EEofFF, TopAbs_State& stateb,TopAbs_State& statea, TopOpeBRepTool_PShapeClassifier pClassif); #define MDShfei Handle(TopOpeBRepDS_FaceEdgeInterference) #define MAKEFEI(IJKLM) (Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(IJKLM)) #ifdef DEB Standard_EXPORT Standard_Boolean TopOpeBRepDS_GetcontextNOPFI(); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettracePFI(); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettracePI(); Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer); static Standard_Boolean TRCF(const Standard_Integer F) { Standard_Boolean b1 = TopOpeBRepDS_GettracePFI(); Standard_Boolean b2 = TopOpeBRepDS_GettracePI(); Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F); return (b1 || b2 || b3); } Standard_EXPORT void debrededg(const Standard_Integer I); Standard_EXPORT void debredunkf(const Standard_Integer /*i*/){}; #endif Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v); Standard_EXPORT Standard_Boolean FUN_Parameters(const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v); //======================================================================= // 3D // purpose : The compute of transition face /face , // or edge // prequesitory : is IN 2dmatter(F) and IN 2dmatter(FS) //======================================================================= Standard_EXPORT Standard_Boolean FUN_mkTonF(const TopoDS_Face& F, const TopoDS_Face& FS, const TopoDS_Edge& E, TopOpeBRepDS_Transition& T) { Standard_Boolean isdgE = BRep_Tool::Degenerated(E); if (isdgE) return Standard_False; T.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN); Standard_Real tola = 1.e-6; // nyitol Standard_Real f,l; FUN_tool_bounds(E,f,l); const Standard_Real PAR_T = 0.456789; Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l; gp_Vec tgE; Standard_Boolean ok; ok = TopOpeBRepTool_TOOL::TggeomE(pmil,E,tgE); //modified by NIZNHY-PKV Fri Aug 4 10:59:44 2000 f if (!ok) { return Standard_False; } //modified by NIZNHY-PKV Fri Aug 4 10:59:48 2000 t gp_Pnt2d uvF; ok = FUN_tool_parF(E,pmil,F,uvF); if (!ok) return Standard_False; gp_Pnt2d uvFS; ok = FUN_tool_parF(E,pmil,FS,uvFS); if (!ok) return Standard_False; gp_Dir ngF = FUN_tool_nggeomF(uvF,F); Standard_Real xx = Abs(ngF.Dot(tgE)); Standard_Boolean tgt = (Abs(1-xx) < tola); if (tgt) return Standard_False; gp_Dir ntFS; ok = TopOpeBRepTool_TOOL::Nt(uvFS,FS, ntFS); if (!ok) return Standard_False; gp_Dir beafter = ngF^tgE; Standard_Real yy = beafter.Dot(ntFS); Standard_Boolean unk = (Abs(yy) < tola); if (unk) return Standard_False; if (yy < 0.) T.Set(TopAbs_FORWARD); else T.Set(TopAbs_REVERSED); return Standard_True; } //------------------------------------------------------ // FUN_edgeofface : True si le edge E est un edge de F Standard_EXPORT Standard_Boolean FUN_edgeofface //------------------------------------------------------ (const TopoDS_Shape& E,const TopoDS_Shape& F) { Standard_Boolean isv = Standard_False; TopExp_Explorer ex; for (ex.Init(F,TopAbs_EDGE); ex.More(); ex.Next()) // for (TopExp_Explorer ex(F,TopAbs_EDGE); ex.More(); ex.Next()) if (ex.Current().IsSame(E) ) { isv = Standard_True; break; } return isv; } //------------------------------------------------------ Standard_EXPORT Standard_Boolean FUN_keepFinterference //------------------------------------------------------ (const TopOpeBRepDS_DataStructure& DS,const Handle(TopOpeBRepDS_Interference)& I,const TopoDS_Shape& F) { TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I,GT1,G1,ST1,S1); Standard_Boolean res = Standard_True; if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_FaceEdgeInterference)) ) { const TopoDS_Shape& EG = DS.Shape(I->Geometry()); // I rejetee si son edge-geometrie est une arete de la face qui accede I. Standard_Boolean k3 = ! ::FUN_edgeofface(EG,F); res = res && k3; } return res; } //------------------------------------------------------ Standard_EXPORT void FUN_unkeepFdoubleGBoundinterferences //------------------------------------------------------ (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& /*BDS*/, #ifdef DEB const Standard_Integer SIX) #else const Standard_Integer ) #endif { #ifdef DEB Standard_Boolean TRC=TRCF(SIX); #endif // BDS.Shape(SIX); TopOpeBRepDS_ListIteratorOfListOfInterference it1; // process interferences of LI with VERTEX geometry it1.Initialize(LI); while (it1.More() ) { Handle(TopOpeBRepDS_Interference)& I1 = it1.Value(); TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; const TopOpeBRepDS_Transition& T1 = I1->Transition(); Standard_Boolean isunk1 = T1.IsUnknown(); if (isunk1) { it1.Next(); continue; } FDS_data(I1,GT1,G1,ST1,S1); Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I1); if (SSI1.IsNull()) { it1.Next(); continue; } Standard_Boolean isB1 = SSI1->GBound(); TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); it2.Next(); Standard_Boolean cond1 = Standard_False; Standard_Boolean cond2 = Standard_False; while ( it2.More() ) { const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value(); TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; const TopOpeBRepDS_Transition& T2 = I2->Transition(); Standard_Boolean isunk2 = T2.IsUnknown(); if (isunk2) { it2.Next(); continue; } FDS_data(I2,GT2,G2,ST2,S2); Handle(TopOpeBRepDS_ShapeShapeInterference) SSI2 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I2); if ( SSI2.IsNull() ) { it2.Next(); continue; } Standard_Boolean isB2 = SSI2->GBound(); cond2 = (GT2 == GT1 && GT1 == TopOpeBRepDS_EDGE && G2 == G1 && ST2 == ST1 && ST1 == TopOpeBRepDS_FACE && S2 != S1 && isB1 && isB2); if (cond2) { #ifdef DEB if(TRC){cout<<"face "<Dump(cout);cout<Dump(cout);cout<Transition(); Standard_Boolean isunk = T1.IsUnknown(); if (!isunk) continue; #ifdef DEB modif = Standard_True; if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T UNKNOWN ";I1->Dump(cout,s,"\n");} #endif TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1; FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1); Standard_Boolean idt = (tsb1==TopAbs_FACE && tsa1==TopAbs_FACE && GT1==TopOpeBRepDS_EDGE && ST1==TopOpeBRepDS_FACE); Standard_Boolean idi = (isb1==S1 && isa1==S1); Standard_Boolean etgf = idt && idi; // face tangent a une face en 1 edge if (!etgf) continue; const TopoDS_Edge& EE = TopoDS::Edge(BDS.Shape(G1)); Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE); #ifdef DEB if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" etgf ";I1->Dump(cout,s,"\n");} #endif Handle(TopOpeBRepDS_FaceEdgeInterference) fei = MAKEFEI(I1); if (fei.IsNull()) continue; const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(S1)); // if (!go) continue; // la face FF transitionne par la transition T1.IsUnknown() // en l'arete EE par rapport a la face FS. // range de EE = [fE,lE]. // EE est une arete de FF ou non. // EE est une arete de section. // EE est une arete de couture. Standard_Boolean isEEGB = fei->GBound(); Standard_Boolean isEEsp = MEsp.IsBound(EE); TopoDS_Edge EEsp = EE; if (isEEsp) { const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EE); isEEsp = los1.IsSplit(); if (isEEsp) { const TopTools_ListOfShape& los = los1.ListOnState(); Standard_Integer n = los.Extent(); if ( n ) { EEsp = TopoDS::Edge(los.First()); if (!EEsp.IsSame(EE)) isEEGB = Standard_False; if (n > 1) { // MSV: treat the case of multiple splits: // select the split which lies on both faces TopTools_ListIteratorOfListOfShape it(los); for (; it.More(); it.Next()) { const TopoDS_Edge& aE = TopoDS::Edge(it.Value()); Standard_Real f,l; FUN_tool_bounds(aE,f,l); const Standard_Real PAR_T = 0.456789; Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l; gp_Pnt2d uvF; if (FUN_tool_parF(aE,pmil,FF,uvF) && FUN_tool_parF(aE,pmil,FS,uvF)) { EEsp = aE; break; } } } } } } Standard_Boolean isSO = Standard_True; if (!EEsp.IsSame(EE)) if (!FUN_tool_curvesSO(EEsp,EE,isSO)) continue; TopAbs_State stateb,statea; TopOpeBRepDS_Transition T; Standard_Boolean ok = FUN_mkTonF(FF,FS,EEsp,T); //xpu230498 if (ok) {stateb = T.Before(); statea =T.After();} //xpu230498 else { TopOpeBRepTool_PShapeClassifier pClass = 0; if (pClassif) { // MSV: find Solids of the same object rank as FS // to determine transition relatively solid rather then face // if possible (see pb. in CFE002 C2, when SIX==13) Standard_Integer rankFS = BDS.AncestorRank(S1); TopoDS_Shape aSRef = BDS.Shape(rankFS); TopExp_Explorer ex(aSRef,TopAbs_SOLID); if (ex.More()) { pClass = pClassif; pClass->SetReference(aSRef); } } FUN_UNKFstasta(FF,FS,EEsp,isEEGB,stateb,statea,pClass); } if (stateb==TopAbs_UNKNOWN || statea==TopAbs_UNKNOWN) continue; TopOpeBRepDS_Transition& newT1 = I1->ChangeTransition(); if (!isSO) { TopAbs_State stmp = stateb; stateb = statea; statea = stmp; } newT1.Set(stateb,statea,tsb1,tsa1); #ifdef DEB if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T corrected ";I1->Dump(cout,s,"\n");} #endif } #ifdef DEB if(TRC && modif){ FDS_dumpLI(LI,"apres correction UNKNOWN : "); } #endif FUN_unkeepUNKNOWN(LI,BDS,SIX); #ifdef DEB if(TRC && modif){ FDS_dumpLI(LI,"sans suppression UNKNOWN residuels : "); } #endif } //========================== DEB start #ifdef DEB //Standard_IMPORT void FUN_ComputeGeomData(const TopoDS_Shape& F,const Standard_Real& u,const Standard_Real& v,gp_Dir& Norm); //------------------------------------------------------ // Automatic testing for complex faces interference on line with cylinders and planes xpu NYI: general case //------------------------------------------------------ Standard_Boolean TestTransition(const TopOpeBRepDS_Transition& T,const TopoDS_Face& F,const TopoDS_Edge& E,const TopoDS_Solid& So) // DEB only { TopAbs_State b, a; b = T.Before(); a = T.After(); BRepAdaptor_Curve ac(E); GeomAbs_CurveType ctyp = ac.GetType(); // TCollection_AsciiString nt; TestTopOpeDraw_TTOT::CurveToString(ctyp,nt); if (ctyp != GeomAbs_Line) { // cout << " Case "<