0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / TopOpeBRepDS / TopOpeBRepDS_repvg.cxx
1 // Created on: 1998-02-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1998-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 <TopOpeBRepDS_repvg.hxx>
18 #include <TopoDS.hxx>
19 #include <BRep_Tool.hxx>
20 #include <TopExp.hxx>
21
22 #include <TopOpeBRepTool_EXPORT.hxx>
23 #include <TopOpeBRepTool_SC.hxx>
24 #include <TopOpeBRepTool_makeTransition.hxx>
25
26 #include <TopOpeBRepDS_EdgeInterferenceTool.hxx>
27 #include <TopOpeBRepDS_EdgeVertexInterference.hxx>
28 #include <TopOpeBRepDS_Interference.hxx>
29 #include <TopOpeBRepDS_TKI.hxx>
30 #include <TopOpeBRepDS_ProcessInterferencesTool.hxx>
31 #include <TopOpeBRepDS_EXPORT.hxx>
32 #include <TopOpeBRepDS_define.hxx>
33 #include <Precision.hxx>
34
35 #include <TopOpeBRepDS_DataMapOfIntegerListOfInterference.hxx>
36 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfIntegerListOfInterference.hxx>
37 #define MDSdmoiloi TopOpeBRepDS_DataMapOfIntegerListOfInterference
38 #define MDSdmiodmoiloi TopOpeBRepDS_DataMapIteratorOfDataMapOfIntegerListOfInterference
39
40 #ifdef DEB
41 #include <TopOpeBRepDS_reDEB.hxx>
42 extern Standard_Boolean TopOpeBRepDS_GetcontextMKTONREG();
43 #endif
44   
45 //------------------------------------------------------
46 Standard_EXPORT void FDS_repvg2
47 (const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer EIX,const TopOpeBRepDS_Kind GT,TopOpeBRepDS_ListOfInterference& LI,TopOpeBRepDS_ListOfInterference& RLI)
48 //------------------------------------------------------
49 {
50 #ifdef DEB
51   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
52   TRC = Standard_False; //xpu170898
53 #endif
54   const TopoDS_Edge& E = TopoDS::Edge(BDS.Shape(EIX));
55   Standard_Boolean isEd = BRep_Tool::Degenerated(E);
56   if (isEd) return;
57   
58 #ifdef DEB
59   if (TRC) cout<<endl<<"repvg1 E"<<EIX<<" <- "<<LI.Extent()<<endl;
60   if (TRC) debredpvg(EIX);
61 #endif
62
63   Standard_Boolean ispoint  = (GT == TopOpeBRepDS_POINT);
64   Standard_Boolean isvertex = (GT == TopOpeBRepDS_VERTEX);
65
66   Standard_Boolean nLI = LI.Extent();
67
68   TopOpeBRepDS_ListIteratorOfListOfInterference it1(LI);
69   while (it1.More()) {
70     const Handle(TopOpeBRepDS_Interference)& I1 = it1.Value();
71     TopOpeBRepDS_Kind GT1,ST1; Standard_Integer G1,S1; TopAbs_ShapeEnum tsb1,tsa1; Standard_Integer isb1,isa1; 
72     FDS_Idata(I1,tsb1,isb1,tsa1,isa1,GT1,G1,ST1,S1);
73     if (tsb1 != TopAbs_FACE) {it1.Next(); continue;}
74     if (tsa1 != TopAbs_FACE) {it1.Next(); continue;}
75     if (GT1 != GT) {it1.Next(); continue;}
76
77     // xpu121198 : raise in PRO16303, if G1 is a vertex same domain, make sure 
78     // rk(G1)= rk(E1)
79     Standard_Integer rkG1 = BDS.AncestorRank(G1);
80     Standard_Integer rkS1 = BDS.AncestorRank(S1);
81     if (isvertex && (rkG1 != rkS1)) {
82       TopoDS_Shape oovG; Standard_Boolean issd = FUN_ds_getoov(BDS.Shape(G1),BDS,oovG);
83       if (!issd) {it1.Next(); continue;} //!!NYIRAISE
84       G1 = BDS.Shape(oovG);
85     }
86
87     const TopoDS_Edge& E1 = TopoDS::Edge(BDS.Shape(S1));
88     const TopoDS_Face& F1 = TopoDS::Face(BDS.Shape(isb1));
89     TopOpeBRepDS_Point PDS; TopoDS_Shape VDS;
90     if      (ispoint)  PDS = BDS.Point(G1);
91     else if (isvertex) VDS = BDS.Shape(G1);
92     else Standard_Failure::Raise("TopOpeBRepDS FDS_repvg2 1");
93
94     Standard_Boolean isEd1 = BRep_Tool::Degenerated(E1); if (isEd1) {it1.Next(); continue;}
95     TopOpeBRepDS_ListIteratorOfListOfInterference it2(it1); if (it2.More()) it2.Next(); else {it1.Next(); continue; }
96
97     TopOpeBRepDS_EdgeInterferenceTool EITool;
98     Standard_Boolean memeS = Standard_False; TopOpeBRepDS_Transition TrmemeS; Standard_Boolean isComplex = Standard_False;
99
100     while ( it2.More() ) {
101       const Handle(TopOpeBRepDS_Interference)& I2 = it2.Value();
102       TopOpeBRepDS_Kind GT2,ST2; Standard_Integer G2,S2; TopAbs_ShapeEnum tsb2,tsa2; Standard_Integer isb2,isa2; 
103       FDS_Idata(I2,tsb2,isb2,tsa2,isa2,GT2,G2,ST2,S2);
104       if (tsb2 != TopAbs_FACE) {it2.Next(); continue;}
105       if (tsa2 != TopAbs_FACE) {it2.Next(); continue;}
106
107       Standard_Boolean cond = (G1 == G2); if (!cond) { it2.Next(); continue; }
108   
109 #ifdef DEB
110       if (TRC && isvertex && DSREDUEDGETRCE(BDS.Shape(VDS))) debreducerEV(EIX,BDS.Shape(VDS));
111 #endif
112       
113       const TopoDS_Edge& E2 = TopoDS::Edge(BDS.Shape(S2));
114       Standard_Boolean isEd2 = BRep_Tool::Degenerated(E2);
115       if (isEd2) {it2.Next(); continue;}
116
117       memeS = (S1 == S2);
118       memeS = memeS && (nLI == 2);
119
120       if (!isComplex && memeS) {
121         Standard_Boolean mktone = Standard_False;
122 #ifdef DEB
123         // NYI XPU : corriger la sequence suivante (avec mkTonE) qui produit une
124         // NYI transition (ON,ON) dans le cas cto 009 B4 pour l'arete 6* / face *21
125         // NYI aux PDS 1 et 5, au lieu de (IN,IN).
126         mktone = TopOpeBRepDS_GetcontextMKTONREG();
127         if (mktone) {
128           const TopOpeBRepDS_ListOfInterference& LOI = BDS.ShapeInterferences(E);
129           Standard_Real pbef,paft; Standard_Boolean isonper; 
130           Standard_Real pE = FDS_Parameter(I1);
131           Standard_Boolean ok = FDS_LOIinfsup(BDS,E,pE,GT1,G1,LOI,pbef,paft,isonper); 
132           if (!ok) {it2.Next();continue;}
133           Standard_Real pE1;     ok = FUN_tool_parE(E,pE,E1,pE1);   if (!ok) {it2.Next();continue;}
134           gp_Pnt2d uv; ok = FUN_tool_paronEF(E,pE,F1,uv); if (!ok) {it2.Next();continue;}
135           Standard_Real factor = 0.789;
136           TopOpeBRepTool_makeTransition MKT; 
137           TopAbs_State stb = TopAbs_UNKNOWN,sta = TopAbs_UNKNOWN; 
138           ok = MKT.Initialize(E,pbef,paft,pE, F1,uv, factor);
139           if (ok) ok = MKT.SetRest(E1,pE1);
140           if (ok) ok = MKT.MkTonE(stb,sta);
141           if (!ok) {it2.Next();continue;}  
142           TrmemeS.Before(stb); TrmemeS.After(sta);
143         }
144 #endif
145         if (!mktone) {
146           Standard_Real pE = FDS_Parameter(I1);
147           Standard_Boolean ok = FDS_stateEwithF2d(BDS,E,pE,GT1,G1,F1,TrmemeS); if (!ok) {it2.Next();continue;}
148         }
149
150 #ifdef DEB
151         if(TRC){cout<<"memeS result ";TrmemeS.Dump(cout);cout<<endl;}
152 #endif
153         LI.Remove(it2);
154       } // !isComplex && memeS
155
156       if (!isComplex && !memeS) {
157         isComplex = Standard_True;
158         EITool.Init(E,I1);
159         if      (ispoint)  EITool.Add(E,PDS,I1);
160         else if (isvertex) EITool.Add(E1,VDS,I1);
161 #ifdef DEB
162         if (TRC){cout<<endl<<"complex T2d E"<<EIX<<endl;I1->Dump(cout);cout<<endl;}
163         if (TRC){cout<<"init ";Handle(TopOpeBRepDS_Interference) IBID = new TopOpeBRepDS_Interference();
164                  EITool.Transition(IBID);IBID->Transition().Dump(cout);cout<<endl;}
165 #endif
166       } // !isComplex && !memeS
167       
168       if (isComplex && !memeS) {
169 #ifdef DEB
170         if(TRC) I2->Dump(cout,"add ","\n");
171 #endif      
172         if      (ispoint)  EITool.Add(E,PDS,I2);      
173         else if (isvertex) EITool.Add(E2,VDS,I2); 
174         LI.Remove(it2);
175 #ifdef DEB
176         if(TRC){cout<<"result ";Handle(TopOpeBRepDS_Interference) IBID = new TopOpeBRepDS_Interference();
177                 EITool.Transition(IBID);IBID->Transition().Dump(cout);cout<<endl;}
178 #endif
179       } // (isComplex && !memeS)
180
181       if (isComplex && memeS) {
182         it2.Next();
183 #ifdef DEB
184 #endif      
185       } // (isComplex && memeS)
186
187     } // it2
188     
189     if      (!isComplex && memeS) {
190       const TopOpeBRepDS_Transition& T1 = I1->Transition();
191       TrmemeS.Index(T1.Index()); I1->ChangeTransition() = TrmemeS;
192       RLI.Append(I1); LI.Remove(it1);
193     }
194     else if (isComplex && !memeS)  {
195       EITool.Transition(I1);
196       RLI.Append(I1); LI.Remove(it1);
197     }
198     else {
199       it1.Next();
200     }
201
202   } // it1
203   
204 #ifdef DEB
205   if (TRC) cout<<"repvg2 E"<<EIX<<" -> reste "<<LI.Extent()<<" + reduit "<<RLI.Extent()<<endl<<endl;
206 #endif
207 }  // FDS_repvg2
208
209 //------------------------------------------------------
210 Standard_EXPORT void FDS_repvg
211 (const TopOpeBRepDS_DataStructure& BDS,const Standard_Integer EIX,const TopOpeBRepDS_Kind GT,TopOpeBRepDS_ListOfInterference& LOI,TopOpeBRepDS_ListOfInterference& RLOI)
212 //------------------------------------------------------
213 {
214   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LOI);
215 #ifdef DEB
216   Standard_Boolean TRC=DSREDUEDGETRCE(EIX);
217   TRC = Standard_False; //xpu170898
218   if (TRC) cout<<endl<<"repvg E"<<EIX<<" <- "<<LOI.Extent()<<endl;
219   if (TRC) tki.DumpTKIIterator("","\n");
220   if (TRC) debredpvg(EIX);
221 #endif
222
223   // xpu211098 : cto904F6 (e10,FTRA1=f14,FTRA2=f17)
224   MDSdmoiloi mapITRASHA;
225   TopOpeBRepDS_ListIteratorOfListOfInterference it(LOI);
226   while (it.More()) {
227     const Handle(TopOpeBRepDS_Interference)& I = it.Value();
228     Standard_Integer isa = I->Transition().Index();
229     Standard_Boolean bound = mapITRASHA.IsBound(isa);
230     if (!bound) {
231       TopOpeBRepDS_ListOfInterference loi; loi.Append(I);
232       mapITRASHA.Bind(isa,loi);
233     }
234     else mapITRASHA.ChangeFind(isa).Append(I);
235     it.Next();
236   }
237   
238   LOI.Clear();
239   MDSdmiodmoiloi itm(mapITRASHA);
240   for (; itm.More(); itm.Next()){
241     Standard_Integer isa = itm.Key();
242     TopOpeBRepDS_ListOfInterference& loi = mapITRASHA.ChangeFind(isa);
243     Standard_Integer nloi = loi.Extent();
244     if (nloi < 2) continue;
245     TopOpeBRepDS_ListOfInterference rloi; FDS_repvg2(BDS,EIX,GT,loi,rloi);
246     LOI.Append(loi); RLOI.Append(rloi);
247   }  
248
249   /*LOI.Clear();
250   for (tki.Init(); tki.More(); tki.Next()) {
251     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
252 #ifdef DEB
253     if (TRC) {tki.DumpTKI(K,G,"","\n");debredpvg(EIX);}
254 #endif
255     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
256     Standard_Integer nloi = loi.Extent();
257     if      (nloi == 0) continue;
258     else if (nloi == 1) LOI.Append(loi);
259     else {
260       FDS_repvg2(BDS,EIX,GT,loi,Rloi);  
261       LOI.Append(loi); RLOI.Append(Rloi);
262     }
263   }*/
264
265 #ifdef DEB
266   if (TRC) cout<<"repvg E"<<EIX<<" -> reste "<<LOI.Extent()<<" + reduit "<<RLOI.Extent()<<endl<<endl;
267 #endif
268 }
269