1 // File: TopOpeBRepDS_ProcessFaceInterferences.cxx
2 // Created: Fri Feb 14 10:26:01 1997
3 // Author: Jean Yves LEBEY
4 // <jyl@bistrox.paris1.matra-dtv.fr>
9 #include <TopExp_Explorer.hxx>
10 #include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
11 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
12 #include <TColStd_ListIteratorOfListOfInteger.hxx>
13 #include <TColStd_ListOfInteger.hxx>
14 #include <BRepAdaptor_Curve.hxx>
15 #include <BRepAdaptor_Surface.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepClass3d_SolidClassifier.hxx>
18 #include <TopoDS_Shell.hxx>
19 #include <TopoDS_Solid.hxx>
21 #include <Precision.hxx>
22 #include <Geom_Curve.hxx>
23 #include <Geom_Surface.hxx>
24 #include <GeomAPI_ProjectPointOnSurf.hxx>
25 #include <BRepTools.hxx>
27 #include <TopOpeBRepTool_ShapeTool.hxx>
28 #include <TopOpeBRepTool_EXPORT.hxx>
29 #include <TopOpeBRepTool_TOOL.hxx>
31 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
32 #include <TopOpeBRepDS_define.hxx>
33 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
34 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
35 #include <TopOpeBRepDS_FaceInterferenceTool.hxx>
36 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
37 #include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
38 #include <TopOpeBRepTool_ShapeClassifier.hxx>
39 #include <TopOpeBRepTool_PShapeClassifier.hxx>
41 Standard_EXPORT void FUN_UNKFstasta(const TopoDS_Face& FF,const TopoDS_Face& FS,
42 const TopoDS_Edge& EE,const Standard_Boolean EEofFF,
43 TopAbs_State& stateb,TopAbs_State& statea,
44 TopOpeBRepTool_PShapeClassifier pClassif);
46 #define MDShfei Handle(TopOpeBRepDS_FaceEdgeInterference)
47 #define MAKEFEI(IJKLM) (Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(IJKLM))
50 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GetcontextNOPFI();
51 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettracePFI();
52 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettracePI();
53 Standard_EXPORT Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
54 static Standard_Boolean TRCF(const Standard_Integer F) {
55 Standard_Boolean b1 = TopOpeBRepDS_GettracePFI();
56 Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
57 Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F);
58 return (b1 || b2 || b3);
60 Standard_EXPORT void debrededg(const Standard_Integer I);
61 Standard_EXPORT void debredunkf(const Standard_Integer /*i*/){};
64 Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
65 Standard_EXPORT Standard_Boolean FUN_Parameters(const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
67 //=======================================================================
69 // purpose : The compute of transition face <F> /face <FS>,
71 // prequesitory : <E> is IN 2dmatter(F) and IN 2dmatter(FS)
72 //=======================================================================
74 Standard_EXPORT Standard_Boolean FUN_mkTonF(const TopoDS_Face& F, const TopoDS_Face& FS, const TopoDS_Edge& E,
75 TopOpeBRepDS_Transition& T)
77 Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
78 if (isdgE) return Standard_False;
79 T.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
81 Standard_Real tola = 1.e-6; // nyitol
82 Standard_Real f,l; FUN_tool_bounds(E,f,l);
83 const Standard_Real PAR_T = 0.456789;
84 Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
88 ok = TopOpeBRepTool_TOOL::TggeomE(pmil,E,tgE);
89 //modified by NIZNHY-PKV Fri Aug 4 10:59:44 2000 f
91 return Standard_False;
93 //modified by NIZNHY-PKV Fri Aug 4 10:59:48 2000 t
96 ok = FUN_tool_parF(E,pmil,F,uvF);
98 return Standard_False;
101 ok = FUN_tool_parF(E,pmil,FS,uvFS);
103 return Standard_False;
105 gp_Dir ngF = FUN_tool_nggeomF(uvF,F);
106 Standard_Real xx = Abs(ngF.Dot(tgE));
107 Standard_Boolean tgt = (Abs(1-xx) < tola);
108 if (tgt) return Standard_False;
111 ok = TopOpeBRepTool_TOOL::Nt(uvFS,FS, ntFS);
113 return Standard_False;
114 gp_Dir beafter = ngF^tgE;
115 Standard_Real yy = beafter.Dot(ntFS);
116 Standard_Boolean unk = (Abs(yy) < tola);
118 return Standard_False;
120 if (yy < 0.) T.Set(TopAbs_FORWARD);
121 else T.Set(TopAbs_REVERSED);
122 return Standard_True;
126 //------------------------------------------------------
127 // FUN_edgeofface : True si le edge E est un edge de F
128 Standard_EXPORT Standard_Boolean FUN_edgeofface
129 //------------------------------------------------------
130 (const TopoDS_Shape& E,const TopoDS_Shape& F)
132 Standard_Boolean isv = Standard_False;
134 for (ex.Init(F,TopAbs_EDGE); ex.More(); ex.Next())
135 // for (TopExp_Explorer ex(F,TopAbs_EDGE); ex.More(); ex.Next())
136 if (ex.Current().IsSame(E) ) {
143 //------------------------------------------------------
144 Standard_EXPORT Standard_Boolean FUN_keepFinterference
145 //------------------------------------------------------
146 (const TopOpeBRepDS_DataStructure& DS,const Handle(TopOpeBRepDS_Interference)& I,const TopoDS_Shape& F)
148 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I,GT1,G1,ST1,S1);
150 Standard_Boolean res = Standard_True;
151 if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_FaceEdgeInterference)) ) {
153 const TopoDS_Shape& EG = DS.Shape(I->Geometry());
154 // I rejetee si son edge-geometrie est une arete de la face qui accede I.
155 Standard_Boolean k3 = ! ::FUN_edgeofface(EG,F);
162 //------------------------------------------------------
163 Standard_EXPORT void FUN_unkeepFdoubleGBoundinterferences
164 //------------------------------------------------------
165 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& /*BDS*/,
167 const Standard_Integer SIX)
169 const Standard_Integer )
173 Standard_Boolean TRC=TRCF(SIX);
176 TopOpeBRepDS_ListIteratorOfListOfInterference it1;
178 // process interferences of LI with VERTEX geometry
181 while (it1.More() ) {
182 Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
183 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1;
184 const TopOpeBRepDS_Transition& T1 = I1->Transition();
185 Standard_Boolean isunk1 = T1.IsUnknown();
186 if (isunk1) { it1.Next(); continue; }
188 FDS_data(I1,GT1,G1,ST1,S1);
189 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I1);
190 if (SSI1.IsNull()) { it1.Next(); continue; }
192 Standard_Boolean isB1 = SSI1->GBound();
194 TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
196 Standard_Boolean cond1 = Standard_False;
197 Standard_Boolean cond2 = Standard_False;
199 while ( it2.More() ) {
200 const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
201 TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2;
202 const TopOpeBRepDS_Transition& T2 = I2->Transition();
203 Standard_Boolean isunk2 = T2.IsUnknown();
204 if (isunk2) { it2.Next(); continue; }
206 FDS_data(I2,GT2,G2,ST2,S2);
207 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI2 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I2);
208 if ( SSI2.IsNull() ) { it2.Next(); continue; }
210 Standard_Boolean isB2 = SSI2->GBound();
211 cond2 = (GT2 == GT1 && GT1 == TopOpeBRepDS_EDGE && G2 == G1 &&
212 ST2 == ST1 && ST1 == TopOpeBRepDS_FACE && S2 != S1 &&
217 if(TRC){cout<<"face "<<SIX<<" : G2 "<< G2 <<" GBound ";I2->Dump(cout);cout<<endl;}
219 cond1 = Standard_True;
227 if(TRC){cout<<"face "<<SIX<<" : G1 "<< G1 <<" GBound ";I1->Dump(cout);cout<<endl;}
234 } // FUN_unkeepFdoubleGBoundinterferences
236 //------------------------------------------------------
237 Standard_EXPORT void FUN_resolveFUNKNOWN
238 //------------------------------------------------------
239 (TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_DataStructure& BDS,
240 const Standard_Integer SIX,
241 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp,
242 TopOpeBRepTool_PShapeClassifier pClassif)
245 Standard_Boolean TRC=TRCF(SIX); if (TRC) debredunkf(SIX);
246 Standard_Boolean modif = Standard_False;
249 const TopoDS_Shape& F = BDS.Shape(SIX);
250 TopOpeBRepDS_ListIteratorOfListOfInterference it1;
252 const TopoDS_Face& FF = TopoDS::Face(F);
253 // Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
255 // process interferences of LI with UNKNOWN transition
257 for (it1.Initialize(LI); it1.More(); it1.Next() ) {
258 Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
259 const TopOpeBRepDS_Transition& T1 = I1->Transition();
260 Standard_Boolean isunk = T1.IsUnknown();
261 if (!isunk) continue;
264 modif = Standard_True;
265 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T UNKNOWN ";I1->Dump(cout,s,"\n");}
268 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1;
269 FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
270 Standard_Boolean idt = (tsb1==TopAbs_FACE && tsa1==TopAbs_FACE
271 && GT1==TopOpeBRepDS_EDGE && ST1==TopOpeBRepDS_FACE);
272 Standard_Boolean idi = (isb1==S1 && isa1==S1);
273 Standard_Boolean etgf = idt && idi; // face tangent a une face en 1 edge
276 const TopoDS_Edge& EE = TopoDS::Edge(BDS.Shape(G1));
277 Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
280 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" etgf ";I1->Dump(cout,s,"\n");}
283 Handle(TopOpeBRepDS_FaceEdgeInterference) fei = MAKEFEI(I1);
284 if (fei.IsNull()) continue;
286 const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(S1));
288 Standard_Boolean isclosedFF = BRep_Tool::IsClosed(EE,FF);
289 Standard_Boolean isclosedFS = BRep_Tool::IsClosed(EE,FS);
290 Standard_Boolean go = Standard_True;
291 go = (isclosedFF || isclosedFS);
292 // if (!go) continue;
294 // la face FF transitionne par la transition T1.IsUnknown()
295 // en l'arete EE par rapport a la face FS.
296 // range de EE = [fE,lE].
297 // EE est une arete de FF ou non.
298 // EE est une arete de section.
299 // EE est une arete de couture.
300 Standard_Boolean isEEGB = fei->GBound();
301 Standard_Boolean isEEsp = MEsp.IsBound(EE);
302 TopoDS_Edge EEsp = EE;
304 const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EE);
305 isEEsp = los1.IsSplit();
307 const TopTools_ListOfShape& los = los1.ListOnState();
308 Standard_Integer n = los.Extent();
310 EEsp = TopoDS::Edge(los.First());
311 if (!EEsp.IsSame(EE)) isEEGB = Standard_False;
313 // MSV: treat the case of multiple splits:
314 // select the split which lies on both faces
315 TopTools_ListIteratorOfListOfShape it(los);
316 for (; it.More(); it.Next()) {
317 const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
318 Standard_Real f,l; FUN_tool_bounds(aE,f,l);
319 const Standard_Real PAR_T = 0.456789;
320 Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
322 if (FUN_tool_parF(aE,pmil,FF,uvF) && FUN_tool_parF(aE,pmil,FS,uvF)) {
331 Standard_Boolean isSO = Standard_True;
332 if (!EEsp.IsSame(EE))
333 if (!FUN_tool_curvesSO(EEsp,EE,isSO)) continue;
335 TopAbs_State stateb,statea;
336 TopOpeBRepDS_Transition T; Standard_Boolean ok = FUN_mkTonF(FF,FS,EEsp,T); //xpu230498
337 if (ok) {stateb = T.Before(); statea =T.After();} //xpu230498
339 TopOpeBRepTool_PShapeClassifier pClass = 0;
341 // MSV: find Solids of the same object rank as FS
342 // to determine transition relatively solid rather then face
343 // if possible (see pb. in CFE002 C2, when SIX==13)
344 Standard_Integer rankFS = BDS.AncestorRank(S1);
345 TopoDS_Shape aSRef = BDS.Shape(rankFS);
346 TopExp_Explorer ex(aSRef,TopAbs_SOLID);
349 pClass->SetReference(aSRef);
352 FUN_UNKFstasta(FF,FS,EEsp,isEEGB,stateb,statea,pClass);
354 if (stateb==TopAbs_UNKNOWN || statea==TopAbs_UNKNOWN) continue;
356 TopOpeBRepDS_Transition& newT1 = I1->ChangeTransition();
358 TopAbs_State stmp = stateb; stateb = statea; statea = stmp;
360 newT1.Set(stateb,statea,tsb1,tsa1);
363 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T corrected ";I1->Dump(cout,s,"\n");}
369 if(TRC && modif){ FDS_dumpLI(LI,"apres correction UNKNOWN : "); }
372 FUN_unkeepUNKNOWN(LI,BDS,SIX);
375 if(TRC && modif){ FDS_dumpLI(LI,"sans suppression UNKNOWN residuels : "); }
379 //========================== DEB start
381 //Standard_IMPORT void FUN_ComputeGeomData(const TopoDS_Shape& F,const Standard_Real& u,const Standard_Real& v,gp_Dir& Norm);
382 //------------------------------------------------------
383 // Automatic testing for complex faces interference on line with cylinders and planes xpu NYI: general case
384 //------------------------------------------------------
385 Standard_Boolean TestTransition(const TopOpeBRepDS_Transition& T,const TopoDS_Face& F,const TopoDS_Edge& E,const TopoDS_Solid& So) // DEB only
388 b = T.Before(); a = T.After();
390 BRepAdaptor_Curve ac(E);
391 GeomAbs_CurveType ctyp = ac.GetType();
392 // TCollection_AsciiString nt; TestTopOpeDraw_TTOT::CurveToString(ctyp,nt);
393 if (ctyp != GeomAbs_Line) {
394 // cout << " Case "<<nt;
395 cout <<" not treated"<<endl;
396 return Standard_True;
398 BRepAdaptor_Surface as(F);
399 GeomAbs_SurfaceType styp = as.GetType();
400 // TestTopOpeDraw_TTOT::CurveToString(styp,nt);
401 if (!((styp == GeomAbs_Plane)||(styp == GeomAbs_Cylinder))) {
402 // cout << " Case "<<nt;
403 cout<<" not treated"<<endl;
404 return Standard_True;
406 Standard_Real du = TopOpeBRepTool_ShapeTool::Tolerance(E); du *= 5.; // edge tolerance
407 Standard_Real u, v, up, vp, p = (ac.FirstParameter() + ac.LastParameter())*.5;
408 gp_Pnt pnt, pntnorm; // middle point on edge
409 gp_Vec tgt, beafter; // curve tangent vector at pnt
410 gp_Dir normS; // normal and direction (Before, After) on reference surface.
413 Standard_Boolean prodone = FUN_Parameters(pnt, F, u, v); // DEB u, v pntnorm coordinates on F
415 cout<<" not treated : prendre un point sur le common des aretes de section SDM"<<endl;
416 return Standard_True;
419 // FUN_ComputeGeomData (F, u, v, normS);
421 normS = FUN_tool_nggeomF(gp_Pnt2d(u,v), F);
422 beafter = normS^gp_Vec(tgt); beafter.Scale(du); // beafter of length du
423 pntnorm = gp_Pnt(pnt.XYZ()).Translated(beafter); // (pnt, pntnorm) = du*beafter
424 FUN_Parameters(pntnorm, F, up, vp); // DEB up, vp pntnorm coordinates on F
426 gp_Pnt pAfter, pBefore;
427 as.D0(up, vp, pAfter);
428 as.D0(up-2*(up-u), vp -2*(vp-v), pBefore);
430 Standard_Boolean transok;
431 TopAbs_State stb, sta;
432 BRepClass3d_SolidClassifier classif(So);
434 classif.Perform(pBefore, Precision::Confusion()); stb = classif.State();
435 classif.Perform(pAfter, Precision::Confusion()); sta = classif.State();
436 transok = (stb == b)&&(sta == a);
439 cout<<"States found by classifier :"<<endl;
440 cout<<"Before :"<<TopAbs::Print(stb, cout)<<"After :"<<TopAbs::Print(sta, cout)<<endl;
447 //========================== DEB end