0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_ProcessFaceInterferences.cxx
1 // Created on: 1997-02-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TopoDS.hxx>
18 #include <TopExp.hxx>
19 #include <TopExp_Explorer.hxx>
20 #include <TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger.hxx>
21 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
22 #include <TColStd_ListIteratorOfListOfInteger.hxx>
23 #include <TColStd_ListOfInteger.hxx>
24 #include <BRepAdaptor_Curve.hxx>
25 #include <BRepAdaptor_Surface.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRepClass3d_SolidClassifier.hxx>
28 #include <TopoDS_Shell.hxx>
29 #include <TopoDS_Solid.hxx>
30 #include <gp_Vec.hxx>
31 #include <Precision.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Surface.hxx>
34 #include <GeomAPI_ProjectPointOnSurf.hxx>
35 #include <BRepTools.hxx>
36
37 #include <TopOpeBRepTool_ShapeTool.hxx>
38 #include <TopOpeBRepTool_EXPORT.hxx>
39 #include <TopOpeBRepTool_TOOL.hxx>
40
41 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
42 #include <TopOpeBRepDS_define.hxx>
43 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
44 #include <TopOpeBRepDS_FaceEdgeInterference.hxx>
45 #include <TopOpeBRepDS_FaceInterferenceTool.hxx>
46 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
47 #include <TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State.hxx>
48 #include <TopOpeBRepTool_ShapeClassifier.hxx>
49 #include <TopOpeBRepTool_PShapeClassifier.hxx>
50 #include <TopOpeBRepDS_ShapeShapeInterference.hxx>
51
52 Standard_EXPORT void FUN_UNKFstasta(const TopoDS_Face& FF,const TopoDS_Face& FS,
53                                     const TopoDS_Edge& EE,const Standard_Boolean EEofFF,
54                                     TopAbs_State& stateb,TopAbs_State& statea,
55                                     TopOpeBRepTool_PShapeClassifier pClassif);
56
57 #define MDShfei Handle(TopOpeBRepDS_FaceEdgeInterference)
58 #define MAKEFEI(IJKLM) (Handle(TopOpeBRepDS_FaceEdgeInterference)::DownCast(IJKLM))
59
60 Standard_EXPORT Standard_Boolean FUN_Parameters(const gp_Pnt& Pnt,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
61 Standard_EXPORT Standard_Boolean FUN_Parameters(const Standard_Real& Param,const TopoDS_Shape& E,const TopoDS_Shape& F,Standard_Real& u,Standard_Real& v);
62
63 //=======================================================================
64 // 3D
65 // purpose : The compute of transition face <F> /face <FS>,
66 //           or edge <E>
67 // prequesitory : <E> is IN 2dmatter(F) and IN 2dmatter(FS)
68 //=======================================================================
69
70 Standard_EXPORT Standard_Boolean FUN_mkTonF(const TopoDS_Face& F, const TopoDS_Face& FS, const TopoDS_Edge& E, 
71                                TopOpeBRepDS_Transition& T)
72 {
73   Standard_Boolean isdgE = BRep_Tool::Degenerated(E); 
74   if (isdgE) return Standard_False;
75   T.Set(TopAbs_UNKNOWN,TopAbs_UNKNOWN);
76
77   Standard_Real tola = 1.e-6; // nyitol
78   Standard_Real f,l; FUN_tool_bounds(E,f,l);
79   const Standard_Real PAR_T = 0.456789;
80   Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
81   gp_Vec tgE; 
82   Standard_Boolean ok; 
83   
84   ok = TopOpeBRepTool_TOOL::TggeomE(pmil,E,tgE);
85   //modified by NIZNHY-PKV Fri Aug  4 10:59:44 2000 f
86   if (!ok) {
87     return Standard_False;
88   }
89     //modified by NIZNHY-PKV Fri Aug  4 10:59:48 2000 t
90   
91   gp_Pnt2d uvF; 
92   ok = FUN_tool_parF(E,pmil,F,uvF);
93   if (!ok) 
94     return Standard_False;
95  
96   gp_Pnt2d uvFS; 
97   ok = FUN_tool_parF(E,pmil,FS,uvFS);
98   if (!ok) 
99     return Standard_False;
100   
101   gp_Dir ngF = FUN_tool_nggeomF(uvF,F);
102   Standard_Real xx = Abs(ngF.Dot(tgE));
103   Standard_Boolean tgt = (Abs(1-xx) < tola);
104   if (tgt) return Standard_False;
105
106   gp_Dir ntFS; 
107   ok = TopOpeBRepTool_TOOL::Nt(uvFS,FS, ntFS);
108   if (!ok) 
109     return Standard_False;
110   gp_Dir beafter = ngF^tgE;
111   Standard_Real yy = beafter.Dot(ntFS);
112   Standard_Boolean unk = (Abs(yy) < tola);
113   if (unk) 
114     return Standard_False;
115
116   if (yy < 0.) T.Set(TopAbs_FORWARD);
117   else         T.Set(TopAbs_REVERSED);
118   return Standard_True;
119 }
120
121
122 //------------------------------------------------------
123 // FUN_edgeofface :  True si le edge E est un edge de F
124 Standard_EXPORT Standard_Boolean FUN_edgeofface
125 //------------------------------------------------------
126 (const TopoDS_Shape& E,const TopoDS_Shape& F)
127 {
128   Standard_Boolean isv = Standard_False;
129   TopExp_Explorer ex;
130   for (ex.Init(F,TopAbs_EDGE); ex.More(); ex.Next())
131 //  for (TopExp_Explorer ex(F,TopAbs_EDGE); ex.More(); ex.Next())
132     if (ex.Current().IsSame(E) ) {
133       isv = Standard_True;
134       break;
135     }
136   return isv;
137 }
138
139 //------------------------------------------------------
140 Standard_EXPORT Standard_Boolean FUN_keepFinterference
141 //------------------------------------------------------
142 (const TopOpeBRepDS_DataStructure& DS,const Handle(TopOpeBRepDS_Interference)& I,const TopoDS_Shape& F)
143 {
144   TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; FDS_data(I,GT1,G1,ST1,S1);
145   
146   Standard_Boolean res = Standard_True;
147   if ( I->IsKind(STANDARD_TYPE(TopOpeBRepDS_FaceEdgeInterference)) ) {
148     
149     const TopoDS_Shape& EG = DS.Shape(I->Geometry());
150     // I rejetee si son edge-geometrie est une arete de la face qui accede I.
151     Standard_Boolean k3 = ! ::FUN_edgeofface(EG,F);
152     res = res && k3;
153   }
154   
155   return res;
156 }
157
158 //------------------------------------------------------
159 Standard_EXPORT void FUN_unkeepFdoubleGBoundinterferences
160 //------------------------------------------------------
161 (TopOpeBRepDS_ListOfInterference& LI,const TopOpeBRepDS_DataStructure& /*BDS*/, const Standard_Integer )    
162 {
163 //                 BDS.Shape(SIX);
164   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
165   
166   // process interferences of LI with VERTEX geometry
167   
168   it1.Initialize(LI);
169   while (it1.More() ) {
170     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
171     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1;
172     const TopOpeBRepDS_Transition& T1 = I1->Transition();
173     Standard_Boolean isunk1 = T1.IsUnknown();
174     if (isunk1) { it1.Next(); continue; }
175
176     FDS_data(I1,GT1,G1,ST1,S1);
177     Handle(TopOpeBRepDS_ShapeShapeInterference) SSI1 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I1);
178     if (SSI1.IsNull()) { it1.Next(); continue; }
179
180     Standard_Boolean isB1 = SSI1->GBound();
181     
182     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1);
183     it2.Next();
184     Standard_Boolean cond1 = Standard_False;    
185     Standard_Boolean cond2 = Standard_False;    
186     
187     while ( it2.More() ) {
188       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
189       TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2;
190       const TopOpeBRepDS_Transition& T2 = I2->Transition();
191       Standard_Boolean isunk2 = T2.IsUnknown();
192       if (isunk2) { it2.Next(); continue; }
193
194       FDS_data(I2,GT2,G2,ST2,S2);
195       Handle(TopOpeBRepDS_ShapeShapeInterference) SSI2 = Handle(TopOpeBRepDS_ShapeShapeInterference)::DownCast(I2);
196       if ( SSI2.IsNull() ) { it2.Next(); continue; }
197
198       Standard_Boolean isB2 = SSI2->GBound();       
199       cond2 = (GT2 == GT1 && GT1 == TopOpeBRepDS_EDGE && G2 == G1 &&
200                ST2 == ST1 && ST1 == TopOpeBRepDS_FACE && S2 != S1 &&
201                isB1 && isB2);
202       
203       if (cond2) {
204         cond1 = Standard_True;
205         LI.Remove(it2);
206       }
207       else it2.Next();
208     } // it2.More()
209
210     if (cond1) {
211       LI.Remove(it1);
212     }
213     else it1.Next();
214   } // it1.More()
215
216 } // FUN_unkeepFdoubleGBoundinterferences
217
218 //------------------------------------------------------
219 Standard_EXPORT void FUN_resolveFUNKNOWN
220 //------------------------------------------------------
221 (TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_DataStructure& BDS,
222  const Standard_Integer SIX,
223  const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& MEsp,
224  TopOpeBRepTool_PShapeClassifier pClassif)
225 {
226   const TopoDS_Shape& F = BDS.Shape(SIX);
227   TopOpeBRepDS_ListIteratorOfListOfInterference it1;
228   
229   const TopoDS_Face& FF = TopoDS::Face(F);
230 //  Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
231   
232   // process interferences of LI with UNKNOWN transition
233   
234   for (it1.Initialize(LI); it1.More(); it1.Next() ) {
235     Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
236     const TopOpeBRepDS_Transition& T1 = I1->Transition();
237     Standard_Boolean isunk = T1.IsUnknown();
238     if (!isunk) continue;
239     
240     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1; 
241     FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
242     Standard_Boolean idt = (tsb1==TopAbs_FACE && tsa1==TopAbs_FACE 
243                && GT1==TopOpeBRepDS_EDGE && ST1==TopOpeBRepDS_FACE);
244     Standard_Boolean idi = (isb1==S1 && isa1==S1);
245     Standard_Boolean etgf = idt && idi; // face tangent a une face en 1 edge
246     if (!etgf) continue;
247
248     const TopoDS_Edge& EE = TopoDS::Edge(BDS.Shape(G1));
249     Standard_Real fE,lE; BRep_Tool::Range(EE,fE,lE);
250
251     Handle(TopOpeBRepDS_FaceEdgeInterference) fei = MAKEFEI(I1);
252     if (fei.IsNull()) continue;
253
254     const TopoDS_Face& FS = TopoDS::Face(BDS.Shape(S1));
255
256 //    if (!go) continue;
257
258     // la face FF transitionne par la transition T1.IsUnknown()
259     // en l'arete EE par rapport a la face FS.
260     // range de EE = [fE,lE].
261     // EE est une arete de FF ou non.
262     // EE est une arete de section.
263     // EE est une arete de couture.
264     Standard_Boolean isEEGB = fei->GBound();
265     Standard_Boolean isEEsp = MEsp.IsBound(EE);
266     TopoDS_Edge EEsp = EE;
267     if (isEEsp) {
268       const TopOpeBRepDS_ListOfShapeOn1State& los1 = MEsp.Find(EE);
269       isEEsp = los1.IsSplit();
270       if (isEEsp) {
271         const TopTools_ListOfShape& los = los1.ListOnState();
272         Standard_Integer n = los.Extent();
273         if ( n ) {
274           EEsp = TopoDS::Edge(los.First());
275           if (!EEsp.IsSame(EE)) isEEGB = Standard_False;
276           if (n > 1) {
277             // MSV: treat the case of multiple splits:
278             //      select the split which lies on both faces
279             TopTools_ListIteratorOfListOfShape it(los);
280             for (; it.More(); it.Next()) {
281               const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
282               Standard_Real f,l; FUN_tool_bounds(aE,f,l);
283               const Standard_Real PAR_T = 0.456789;
284               Standard_Real pmil = (1.-PAR_T)*f + PAR_T*l;
285               gp_Pnt2d uvF; 
286               if (FUN_tool_parF(aE,pmil,FF,uvF) && FUN_tool_parF(aE,pmil,FS,uvF)) {
287                 EEsp = aE;
288                 break;
289               }
290             }
291           }
292         }
293       }
294     }
295     Standard_Boolean isSO = Standard_True;
296     if (!EEsp.IsSame(EE))
297       if (!FUN_tool_curvesSO(EEsp,EE,isSO)) continue;
298
299     TopAbs_State stateb,statea;     
300     TopOpeBRepDS_Transition T; Standard_Boolean ok = FUN_mkTonF(FF,FS,EEsp,T); //xpu230498
301     if (ok) {stateb = T.Before(); statea =T.After();} //xpu230498
302     else {
303       TopOpeBRepTool_PShapeClassifier pClass = 0;
304       if (pClassif) {
305         // MSV: find Solids of the same object rank as FS
306         //      to determine transition relatively solid rather then face
307         //      if possible (see pb. in CFE002 C2, when SIX==13)
308         Standard_Integer rankFS = BDS.AncestorRank(S1);
309         TopoDS_Shape aSRef = BDS.Shape(rankFS);
310         TopExp_Explorer ex(aSRef,TopAbs_SOLID);
311         if (ex.More()) {
312           pClass = pClassif;
313           pClass->SetReference(aSRef);
314         }
315       }
316       FUN_UNKFstasta(FF,FS,EEsp,isEEGB,stateb,statea,pClass);
317     }
318     if (stateb==TopAbs_UNKNOWN || statea==TopAbs_UNKNOWN) continue;
319
320     TopOpeBRepDS_Transition& newT1 = I1->ChangeTransition();
321     if (!isSO) {
322       TopAbs_State stmp = stateb; stateb = statea; statea = stmp;
323     }
324     newT1.Set(stateb,statea,tsb1,tsa1);
325   }
326   FUN_unkeepUNKNOWN(LI,BDS,SIX);
327 }