1 // Created on: 1997-02-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
25 #include <TopExp_Explorer.hxx>
26 #include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
27 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
28 #include <TColStd_ListIteratorOfListOfInteger.hxx>
29 #include <TColStd_ListOfInteger.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepClass3d_SolidClassifier.hxx>
34 #include <TopoDS_Shell.hxx>
35 #include <TopoDS_Solid.hxx>
37 #include <Precision.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_Surface.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <BRepTools.hxx>
43 #include <TopOpeBRepTool_ShapeTool.hxx>
44 #include <TopOpeBRepTool_EXPORT.hxx>
45 #include <TopOpeBRepTool_TOOL.hxx>
47 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
48 #include <TopOpeBRepDS_define.hxx>
49 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
50 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
51 #include <TopOpeBRepDS_FaceInterferenceTool.hxx>
52 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
53 #include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
54 #include <TopOpeBRepTool_ShapeClassifier.hxx>
55 #include <TopOpeBRepTool_PShapeClassifier.hxx>
57 Standard_EXPORT void FUN_UNKFstasta(const TopoDS_Face& FF,const TopoDS_Face& FS,
58 const TopoDS_Edge& EE,const Standard_Boolean EEofFF,
59 TopAbs_State& stateb,TopAbs_State& statea,
60 TopOpeBRepTool_PShapeClassifier pClassif);
62 #define MDShfei Handle(TopOpeBRepDS_FaceEdgeInterference)
63 #define MAKEFEI(IJKLM) (Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(IJKLM))
66 extern Standard_Boolean TopOpeBRepDS_GetcontextNOPFI();
67 extern Standard_Boolean TopOpeBRepDS_GettracePFI();
68 extern Standard_Boolean TopOpeBRepDS_GettracePI();
69 extern Standard_Boolean TopOpeBRepDS_GettraceSPSX(const Standard_Integer);
70 static Standard_Boolean TRCF(const Standard_Integer F) {
71 Standard_Boolean b1 = TopOpeBRepDS_GettracePFI();
72 Standard_Boolean b2 = TopOpeBRepDS_GettracePI();
73 Standard_Boolean b3 = TopOpeBRepDS_GettraceSPSX(F);
74 return (b1 || b2 || b3);
76 static void debredunkf(const Standard_Integer /*i*/){};
79 Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
80 Standard_EXPORT Standard_Boolean FUN_Parameters(const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
82 //=======================================================================
84 // purpose : The compute of transition face <F> /face <FS>,
86 // prequesitory : <E> is IN 2dmatter(F) and IN 2dmatter(FS)
87 //=======================================================================
89 Standard_EXPORT Standard_Boolean FUN_mkTonF(const TopoDS_Face& F, const TopoDS_Face& FS, const TopoDS_Edge& E,
90 TopOpeBRepDS_Transition& T)
92 Standard_Boolean isdgE = BRep_Tool::Degenerated(E);
93 if (isdgE) return Standard_False;
94 T.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
96 Standard_Real tola = 1.e-6; // nyitol
97 Standard_Real f,l; FUN_tool_bounds(E,f,l);
98 const Standard_Real PAR_T = 0.456789;
99 Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
103 ok = TopOpeBRepTool_TOOL::TggeomE(pmil,E,tgE);
104 //modified by NIZNHY-PKV Fri Aug 4 10:59:44 2000 f
106 return Standard_False;
108 //modified by NIZNHY-PKV Fri Aug 4 10:59:48 2000 t
111 ok = FUN_tool_parF(E,pmil,F,uvF);
113 return Standard_False;
116 ok = FUN_tool_parF(E,pmil,FS,uvFS);
118 return Standard_False;
120 gp_Dir ngF = FUN_tool_nggeomF(uvF,F);
121 Standard_Real xx = Abs(ngF.Dot(tgE));
122 Standard_Boolean tgt = (Abs(1-xx) < tola);
123 if (tgt) return Standard_False;
126 ok = TopOpeBRepTool_TOOL::Nt(uvFS,FS, ntFS);
128 return Standard_False;
129 gp_Dir beafter = ngF^tgE;
130 Standard_Real yy = beafter.Dot(ntFS);
131 Standard_Boolean unk = (Abs(yy) < tola);
133 return Standard_False;
135 if (yy < 0.) T.Set(TopAbs_FORWARD);
136 else T.Set(TopAbs_REVERSED);
137 return Standard_True;
141 //------------------------------------------------------
142 // FUN_edgeofface : True si le edge E est un edge de F
143 Standard_EXPORT Standard_Boolean FUN_edgeofface
144 //------------------------------------------------------
145 (const TopoDS_Shape& E,const TopoDS_Shape& F)
147 Standard_Boolean isv = Standard_False;
149 for (ex.Init(F,TopAbs_EDGE); ex.More(); ex.Next())
150 // for (TopExp_Explorer ex(F,TopAbs_EDGE); ex.More(); ex.Next())
151 if (ex.Current().IsSame(E) ) {
158 //------------------------------------------------------
159 Standard_EXPORT Standard_Boolean FUN_keepFinterference
160 //------------------------------------------------------
161 (const TopOpeBRepDS_DataStructure& DS,const Handle(TopOpeBRepDS_Interference)& I,const TopoDS_Shape& F)
163 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I,GT1,G1,ST1,S1);
165 Standard_Boolean res = Standard_True;
166 if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_FaceEdgeInterference)) ) {
168 const TopoDS_Shape& EG = DS.Shape(I->Geometry());
169 // I rejetee si son edge-geometrie est une arete de la face qui accede I.
170 Standard_Boolean k3 = ! ::FUN_edgeofface(EG,F);
177 //------------------------------------------------------
178 Standard_EXPORT void FUN_unkeepFdoubleGBoundinterferences
179 //------------------------------------------------------
180 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& /*BDS*/,
182 const Standard_Integer SIX)
184 const Standard_Integer )
188 Standard_Boolean TRC=TRCF(SIX);
191 TopOpeBRepDS_ListIteratorOfListOfInterference it1;
193 // process interferences of LI with VERTEX geometry
196 while (it1.More() ) {
197 Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
198 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1;
199 const TopOpeBRepDS_Transition& T1 = I1->Transition();
200 Standard_Boolean isunk1 = T1.IsUnknown();
201 if (isunk1) { it1.Next(); continue; }
203 FDS_data(I1,GT1,G1,ST1,S1);
204 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I1);
205 if (SSI1.IsNull()) { it1.Next(); continue; }
207 Standard_Boolean isB1 = SSI1->GBound();
209 TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
211 Standard_Boolean cond1 = Standard_False;
212 Standard_Boolean cond2 = Standard_False;
214 while ( it2.More() ) {
215 const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
216 TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2;
217 const TopOpeBRepDS_Transition& T2 = I2->Transition();
218 Standard_Boolean isunk2 = T2.IsUnknown();
219 if (isunk2) { it2.Next(); continue; }
221 FDS_data(I2,GT2,G2,ST2,S2);
222 Handle(TopOpeBRepDS_ShapeShapeInterference) SSI2 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I2);
223 if ( SSI2.IsNull() ) { it2.Next(); continue; }
225 Standard_Boolean isB2 = SSI2->GBound();
226 cond2 = (GT2 == GT1 && GT1 == TopOpeBRepDS_EDGE && G2 == G1 &&
227 ST2 == ST1 && ST1 == TopOpeBRepDS_FACE && S2 != S1 &&
232 if(TRC){cout<<"face "<<SIX<<" : G2 "<< G2 <<" GBound ";I2->Dump(cout);cout<<endl;}
234 cond1 = Standard_True;
242 if(TRC){cout<<"face "<<SIX<<" : G1 "<< G1 <<" GBound ";I1->Dump(cout);cout<<endl;}
249 } // FUN_unkeepFdoubleGBoundinterferences
251 //------------------------------------------------------
252 Standard_EXPORT void FUN_resolveFUNKNOWN
253 //------------------------------------------------------
254 (TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_DataStructure& BDS,
255 const Standard_Integer SIX,
256 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp,
257 TopOpeBRepTool_PShapeClassifier pClassif)
260 Standard_Boolean TRC=TRCF(SIX); if (TRC) debredunkf(SIX);
261 Standard_Boolean modif = Standard_False;
264 const TopoDS_Shape& F = BDS.Shape(SIX);
265 TopOpeBRepDS_ListIteratorOfListOfInterference it1;
267 const TopoDS_Face& FF = TopoDS::Face(F);
268 // Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
270 // process interferences of LI with UNKNOWN transition
272 for (it1.Initialize(LI); it1.More(); it1.Next() ) {
273 Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
274 const TopOpeBRepDS_Transition& T1 = I1->Transition();
275 Standard_Boolean isunk = T1.IsUnknown();
276 if (!isunk) continue;
279 modif = Standard_True;
280 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T UNKNOWN ";I1->Dump(cout,s,"\n");}
283 TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1;
284 FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
285 Standard_Boolean idt = (tsb1==TopAbs_FACE && tsa1==TopAbs_FACE
286 && GT1==TopOpeBRepDS_EDGE && ST1==TopOpeBRepDS_FACE);
287 Standard_Boolean idi = (isb1==S1 && isa1==S1);
288 Standard_Boolean etgf = idt && idi; // face tangent a une face en 1 edge
291 const TopoDS_Edge& EE = TopoDS::Edge(BDS.Shape(G1));
292 Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
295 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" etgf ";I1->Dump(cout,s,"\n");}
298 Handle(TopOpeBRepDS_FaceEdgeInterference) fei = MAKEFEI(I1);
299 if (fei.IsNull()) continue;
301 const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(S1));
303 Standard_Boolean isclosedFF = BRep_Tool::IsClosed(EE,FF);
304 Standard_Boolean isclosedFS = BRep_Tool::IsClosed(EE,FS);
305 Standard_Boolean go = Standard_True;
306 go = (isclosedFF || isclosedFS);
307 // if (!go) continue;
309 // la face FF transitionne par la transition T1.IsUnknown()
310 // en l'arete EE par rapport a la face FS.
311 // range de EE = [fE,lE].
312 // EE est une arete de FF ou non.
313 // EE est une arete de section.
314 // EE est une arete de couture.
315 Standard_Boolean isEEGB = fei->GBound();
316 Standard_Boolean isEEsp = MEsp.IsBound(EE);
317 TopoDS_Edge EEsp = EE;
319 const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EE);
320 isEEsp = los1.IsSplit();
322 const TopTools_ListOfShape& los = los1.ListOnState();
323 Standard_Integer n = los.Extent();
325 EEsp = TopoDS::Edge(los.First());
326 if (!EEsp.IsSame(EE)) isEEGB = Standard_False;
328 // MSV: treat the case of multiple splits:
329 // select the split which lies on both faces
330 TopTools_ListIteratorOfListOfShape it(los);
331 for (; it.More(); it.Next()) {
332 const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
333 Standard_Real f,l; FUN_tool_bounds(aE,f,l);
334 const Standard_Real PAR_T = 0.456789;
335 Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
337 if (FUN_tool_parF(aE,pmil,FF,uvF) && FUN_tool_parF(aE,pmil,FS,uvF)) {
346 Standard_Boolean isSO = Standard_True;
347 if (!EEsp.IsSame(EE))
348 if (!FUN_tool_curvesSO(EEsp,EE,isSO)) continue;
350 TopAbs_State stateb,statea;
351 TopOpeBRepDS_Transition T; Standard_Boolean ok = FUN_mkTonF(FF,FS,EEsp,T); //xpu230498
352 if (ok) {stateb = T.Before(); statea =T.After();} //xpu230498
354 TopOpeBRepTool_PShapeClassifier pClass = 0;
356 // MSV: find Solids of the same object rank as FS
357 // to determine transition relatively solid rather then face
358 // if possible (see pb. in CFE002 C2, when SIX==13)
359 Standard_Integer rankFS = BDS.AncestorRank(S1);
360 TopoDS_Shape aSRef = BDS.Shape(rankFS);
361 TopExp_Explorer ex(aSRef,TopAbs_SOLID);
364 pClass->SetReference(aSRef);
367 FUN_UNKFstasta(FF,FS,EEsp,isEEGB,stateb,statea,pClass);
369 if (stateb==TopAbs_UNKNOWN || statea==TopAbs_UNKNOWN) continue;
371 TopOpeBRepDS_Transition& newT1 = I1->ChangeTransition();
373 TopAbs_State stmp = stateb; stateb = statea; statea = stmp;
375 newT1.Set(stateb,statea,tsb1,tsa1);
378 if(TRC){debredunkf(SIX);TCollection_AsciiString s="F";s=s+SIX+" T corrected ";I1->Dump(cout,s,"\n");}
384 if(TRC && modif){ FDS_dumpLI(LI,"apres correction UNKNOWN : "); }
387 FUN_unkeepUNKNOWN(LI,BDS,SIX);
390 if(TRC && modif){ FDS_dumpLI(LI,"sans suppression UNKNOWN residuels : "); }
394 //========================== DEB start
396 //Standard_IMPORT void FUN_ComputeGeomData(const TopoDS_Shape& F,const Standard_Real& u,const Standard_Real& v,gp_Dir& Norm);
397 //------------------------------------------------------
398 // Automatic testing for complex faces interference on line with cylinders and planes xpu NYI: general case
399 //------------------------------------------------------
400 Standard_Boolean TestTransition(const TopOpeBRepDS_Transition& T,const TopoDS_Face& F,const TopoDS_Edge& E,const TopoDS_Solid& So) // DEB only
403 b = T.Before(); a = T.After();
405 BRepAdaptor_Curve ac(E);
406 GeomAbs_CurveType ctyp = ac.GetType();
407 // TCollection_AsciiString nt; TestTopOpeDraw_TTOT::CurveToString(ctyp,nt);
408 if (ctyp != GeomAbs_Line) {
409 // cout << " Case "<<nt;
410 cout <<" not treated"<<endl;
411 return Standard_True;
413 BRepAdaptor_Surface as(F);
414 GeomAbs_SurfaceType styp = as.GetType();
415 // TestTopOpeDraw_TTOT::CurveToString(styp,nt);
416 if (!((styp == GeomAbs_Plane)||(styp == GeomAbs_Cylinder))) {
417 // cout << " Case "<<nt;
418 cout<<" not treated"<<endl;
419 return Standard_True;
421 Standard_Real du = TopOpeBRepTool_ShapeTool::Tolerance(E); du *= 5.; // edge tolerance
422 Standard_Real u, v, up, vp, p = (ac.FirstParameter() + ac.LastParameter())*.5;
423 gp_Pnt pnt, pntnorm; // middle point on edge
424 gp_Vec tgt, beafter; // curve tangent vector at pnt
425 gp_Dir normS; // normal and direction (Before, After) on reference surface.
428 Standard_Boolean prodone = FUN_Parameters(pnt, F, u, v); // DEB u, v pntnorm coordinates on F
430 cout<<" not treated : prendre un point sur le common des aretes de section SDM"<<endl;
431 return Standard_True;
434 // FUN_ComputeGeomData (F, u, v, normS);
436 normS = FUN_tool_nggeomF(gp_Pnt2d(u,v), F);
437 beafter = normS^gp_Vec(tgt); beafter.Scale(du); // beafter of length du
438 pntnorm = gp_Pnt(pnt.XYZ()).Translated(beafter); // (pnt, pntnorm) = du*beafter
439 FUN_Parameters(pntnorm, F, up, vp); // DEB up, vp pntnorm coordinates on F
441 gp_Pnt pAfter, pBefore;
442 as.D0(up, vp, pAfter);
443 as.D0(up-2*(up-u), vp -2*(vp-v), pBefore);
445 Standard_Boolean transok;
446 TopAbs_State stb, sta;
447 BRepClass3d_SolidClassifier classif(So);
449 classif.Perform(pBefore, Precision::Confusion()); stb = classif.State();
450 classif.Perform(pAfter, Precision::Confusion()); sta = classif.State();
451 transok = (stb == b)&&(sta == a);
454 cout<<"States found by classifier :"<<endl;
456 TopAbs::Print(stb, cout);
458 TopAbs::Print(sta, cout);
466 //========================== DEB end