0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / TopOpeBRep / TopOpeBRep_EdgesFiller.cxx
1 // Created on: 1994-10-12
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-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
18 #include <BRep_Tool.hxx>
19 #include <TopoDS.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopOpeBRep_define.hxx>
23 #include <TopOpeBRep_EdgesFiller.hxx>
24 #include <TopOpeBRep_EdgesIntersector.hxx>
25 #include <TopOpeBRep_Point2d.hxx>
26 #include <TopOpeBRep_PointGeomTool.hxx>
27 #include <TopOpeBRepDS.hxx>
28 #include <TopOpeBRepDS_Config.hxx>
29 #include <TopOpeBRepDS_EXPORT.hxx>
30 #include <TopOpeBRepDS_HDataStructure.hxx>
31 #include <TopOpeBRepDS_Interference.hxx>
32 #include <TopOpeBRepDS_InterferenceTool.hxx>
33 #include <TopOpeBRepDS_Point.hxx>
34 #include <TopOpeBRepDS_TKI.hxx>
35 #include <TopOpeBRepDS_Transition.hxx>
36 #include <TopOpeBRepTool_EXPORT.hxx>
37
38 #ifdef OCCT_DEBUG
39 #include <TopOpeBRepDS_CurvePointInterference.hxx>
40 extern Standard_Boolean TopOpeBRep_GettraceEEFF();
41 Standard_EXPORT void debposesd(void) {/*cout<<"+++ debposesd"<<endl;*/}
42 Standard_EXPORT void debposnesd(void) {cout<<"+++ debposnesd"<<endl;}
43 Standard_EXPORT void debeeff() {}
44 #endif
45
46 #define M_REVERSED(O) (O == TopAbs_REVERSED)
47 #define M_FORWARD( O) (O == TopAbs_FORWARD)
48 #define M_INTERNAL(O) (O == TopAbs_INTERNAL)
49 #define M_EXTERNAL(O) (O == TopAbs_EXTERNAL)
50
51 //=======================================================================
52 //function : TopOpeBRep_EdgesFiller
53 //purpose  : 
54 //=======================================================================
55 TopOpeBRep_EdgesFiller::TopOpeBRep_EdgesFiller() : myPDS(NULL),myPEI(NULL) {}
56
57 void rototo() {}
58
59 //=======================================================================
60 //function : Insert
61 //purpose  : 
62 //=======================================================================
63 void TopOpeBRep_EdgesFiller::Insert(const TopoDS_Shape& E1,const TopoDS_Shape& E2,TopOpeBRep_EdgesIntersector& EDGINT,const Handle(TopOpeBRepDS_HDataStructure)& HDS)
64 {
65   myPEI = &EDGINT;
66   myPDS = &(HDS->ChangeDS());
67   myE1 = TopoDS::Edge(E1);
68   myE2 = TopoDS::Edge(E2);
69   myLI1.Clear();
70   myLI2.Clear();
71   myHDS = HDS;
72
73   Standard_Boolean esd = myPEI->SameDomain();
74   if (esd) myPDS->FillShapesSameDomain(E1,E2);
75   
76   // exit if no point.
77   myPEI->InitPoint(); if ( !myPEI->MorePoint() ) return;
78
79   // --- Add <E1,E2> in BDS
80   Standard_Integer E1index = myPDS->AddShape(E1,1);
81   Standard_Integer E2index = myPDS->AddShape(E2,2);
82   
83   // --- get list of interferences connected to edges <E1>,<E2>
84   TopOpeBRepDS_ListOfInterference& EIL1 = myPDS->ChangeShapeInterferences(E1);
85   
86   Handle(TopOpeBRepDS_Interference) EPI;  //edge/point interference
87   Handle(TopOpeBRepDS_Interference) EVI;  //edge/vertex interference
88   
89 //  TopOpeBRepDS_Transition TposF,TposL;
90
91   for (; myPEI->MorePoint(); myPEI->NextPoint() ) {
92     const TopOpeBRep_Point2d P2D = myPEI->Point();
93     Standard_Real par1 = P2D.Parameter(1);
94     Standard_Real par2 = P2D.Parameter(2);
95     if ( ! myF1.IsNull() ) myPDS->AddShape(myF1,1);
96     if ( ! myF2.IsNull() ) myPDS->AddShape(myF2,2);
97
98     TopOpeBRepDS_Transition T1 = P2D.Transition(1);
99     TopOpeBRepDS_Transition T2 = P2D.Transition(2);
100     
101     SetShapeTransition(P2D,T1,T2);
102     
103     Standard_Boolean isvertex1 = P2D.IsVertex(1);
104     TopoDS_Vertex V1; if (isvertex1) V1 = P2D.Vertex(1);
105     Standard_Boolean isvertex2 = P2D.IsVertex(2);
106     TopoDS_Vertex V2; if (isvertex2) V2 = P2D.Vertex(2);
107     Standard_Boolean isvertex = isvertex1 || isvertex2;
108
109 #ifdef OCCT_DEBUG
110     if (isvertex1 && isvertex2) {
111       gp_Pnt P3D1 = BRep_Tool::Pnt(V1);
112       gp_Pnt P3D2 = BRep_Tool::Pnt(V2);
113       Standard_Real tol1 = BRep_Tool::Tolerance(V1);
114       Standard_Real tol2 = BRep_Tool::Tolerance(V2);
115       Standard_Real dpp = P3D1.Distance(P3D2);
116       if (dpp> tol1+tol2) {
117         cout<<endl;
118         cout<<"*** TopOpeBRep_EdgesFiller : isvertex1 && isvertex2 : P3D non confondus"<<endl;
119         cout<<"point PV1 "<<P3D1.X()<<" "<<P3D1.Y()<<" "<<P3D1.Z()<<endl;
120         cout<<"point PV2 "<<P3D2.X()<<" "<<P3D2.Y()<<" "<<P3D2.Z()<<endl;
121         cout<<endl;
122       }
123     }
124 #endif
125     
126     // xpu : 080498 : CTS20072 (e12,e3,p8) 
127     //       edgesintersector called for tolerances = 0.
128     //       facesintersector called for greater tolerances
129     //       we assume facesintersector's ouput data to be valid
130     //       and we use it for correcting edgesintersector's ouput data
131     TopOpeBRepDS_ListIteratorOfListOfInterference itloI1( myPDS->ShapeInterferences(E1) );
132     Standard_Integer G; TopOpeBRepDS_Kind K; 
133     Standard_Boolean found = GetGeometry(itloI1,P2D,G,K);
134     if (!found) MakeGeometry(P2D,G,K);
135
136     Standard_Boolean foundpoint  = (found)  && (K == TopOpeBRepDS_POINT);
137     Standard_Boolean isnewpoint  = (!found) && (K == TopOpeBRepDS_POINT);
138     Standard_Boolean isnewvertex = (!found) && (K == TopOpeBRepDS_VERTEX);
139
140     Standard_Boolean faulty =  (isvertex && isnewpoint) || (!isvertex && isnewvertex);
141     if (faulty) {
142 #ifdef OCCT_DEBUG
143       Standard_Boolean foundvertex = (found)  && (K == TopOpeBRepDS_VERTEX);
144       cout<<"- - - faulty EdgesFiller : G "<<G<<" K ";TopOpeBRepDS::Print(K,cout);cout.flush();
145       cout<<" isvertex="<<isvertex;cout.flush();
146       cout<<" isop="<<foundpoint<<" isov="<<foundvertex;cout.flush();
147       cout<<" isnp="<<isnewpoint<<" isnv="<<isnewvertex<<endl;cout.flush();
148 #endif
149     }
150
151     if (isvertex && foundpoint) {
152       Standard_Integer is = 1, ns = myPDS->NbShapes();
153       for (;is<=ns;is++) {
154         const TopoDS_Shape& s = myPDS->Shape(is);
155         if (s.ShapeType() != TopAbs_EDGE) continue;
156         const TopoDS_Edge& e = TopoDS::Edge(s);
157
158         TopOpeBRepDS_ListOfInterference linew;
159         TopOpeBRepDS_ListOfInterference& li = myPDS->ChangeShapeInterferences(e); TopOpeBRepDS_ListIteratorOfListOfInterference it(li);
160         while (it.More()) {
161
162           Handle(TopOpeBRepDS_Interference) I=it.Value(); TopOpeBRepDS_Kind ki=I->GeometryType(); Standard_Integer gi=I->Geometry();
163           Handle(Standard_Type) DTI = I->DynamicType();
164           Standard_Boolean iscpi = (DTI == STANDARD_TYPE(TopOpeBRepDS_CurvePointInterference)) ;
165           Standard_Boolean condcpi = ((ki==TopOpeBRepDS_POINT) && (gi==G) && iscpi);
166           if (condcpi) { // remplacer G,K de I par le vertex courant
167
168 #ifdef OCCT_DEBUG
169             rototo();
170 #endif
171             Handle(TopOpeBRepDS_CurvePointInterference) epi = Handle(TopOpeBRepDS_CurvePointInterference)::DownCast(I);
172             const TopOpeBRepDS_Transition& tevi = epi->Transition();
173             Standard_Integer sevi = epi->Support();
174
175             Standard_Integer gevi=0;
176
177             if      (isvertex1) gevi = myPDS->AddShape(V1,1);
178             else if (isvertex2) gevi = myPDS->AddShape(V2,2);
179             Standard_Boolean bevi = Standard_False;
180             TopOpeBRepDS_Config cevi = TopOpeBRepDS_UNSHGEOMETRY;
181             Standard_Real pevi = epi->Parameter();
182
183             Handle(TopOpeBRepDS_Interference) evi;
184             evi = TopOpeBRepDS_InterferenceTool::MakeEdgeVertexInterference(tevi,sevi,gevi,bevi,cevi,pevi);
185             const TopOpeBRepDS_Kind& kevi = epi->SupportType();
186             evi->SupportType(kevi);
187
188 #ifdef OCCT_DEBUG
189             TopOpeBRepDS::Print(K,G,cout,"TopOpeBRep_EdgesFiller : remplacer "," ");
190             TopOpeBRepDS::Print(TopOpeBRepDS_VERTEX,gevi,cout,"par "," dans les courbes NYI\n");
191 #endif
192             linew.Append(evi);
193             li.Remove(it);
194           } // cond
195           else {
196             it.Next();
197           }
198         } // it.More()
199         if (!linew.IsEmpty()) {
200           myHDS->StoreInterferences(linew,is,"EdgesFiller modif : ");
201         }
202       } // (is<=ns)
203     } // (isvertex && foundpoint)
204     
205     if (isvertex1) {
206       const TopoDS_Vertex& VV1 = V1;
207 //      const TopoDS_Vertex& VV1 = TopoDS::Vertex(V1);
208       const TopoDS_Edge& EE1 = TopoDS::Edge(E1);
209       par1 = BRep_Tool::Parameter(VV1,EE1);
210     }
211     
212     if (isvertex2) {
213       const TopoDS_Vertex& VV2 = V2;
214 //      const TopoDS_Vertex& VV2 = TopoDS::Vertex(V2);
215       const TopoDS_Edge& EE2 = TopoDS::Edge(E2);
216       par2 = BRep_Tool::Parameter(VV2,EE2);
217     }
218     
219     if ( isvertex1 && isvertex2 ) {
220       myPDS->FillShapesSameDomain(V1,V2);
221     }
222     
223     Standard_Integer DSPindex;
224     Standard_Boolean EPIfound;
225     
226     if ( ! isvertex ) {
227       
228       TopOpeBRepDS_Kind KKK;
229       TopOpeBRepDS_ListIteratorOfListOfInterference itEIL1(EIL1);
230       EPIfound = GetGeometry(itEIL1,P2D,DSPindex,KKK);
231       if ( ! EPIfound ) MakeGeometry(P2D,DSPindex,KKK);
232
233       SetShapeTransition(P2D,T1,T2);
234
235       if      (KKK == TopOpeBRepDS_POINT) {
236         EPI = StorePI(P2D,T1,E2index,DSPindex,par1,1);
237         EPI = StorePI(P2D,T2,E1index,DSPindex,par2,2);
238       }
239       else if ( KKK == TopOpeBRepDS_VERTEX) {
240         Standard_Integer Vindex = DSPindex;
241         Standard_Boolean bevi = Standard_False;
242         TopOpeBRepDS_Config cevi = TopOpeBRepDS_UNSHGEOMETRY;
243         EVI = StoreVI(P2D,T1,E2index,Vindex,bevi,cevi,par1,1);
244         EVI = StoreVI(P2D,T2,E1index,Vindex,bevi,cevi,par2,2);
245       }
246  
247     } // ( ! isvertex )
248     
249     else {
250       
251       SetShapeTransition(P2D,T1,T2);
252       
253       if (isvertex1) {
254         const TopoDS_Shape V = V1;
255         Standard_Integer Vindex = myPDS->AddShape(V,1);
256         TopOpeBRepDS_Config SSC = P2D.EdgesConfig();
257         EVI = StoreVI(P2D,T1,E2index,Vindex,Standard_True,SSC,par1,1);
258         EVI = StoreVI(P2D,T2,E1index,Vindex,Standard_False,SSC,par2,2);
259       }
260       
261       if (isvertex2) {
262         const TopoDS_Shape V = V2;
263         Standard_Integer Vindex = myPDS->AddShape(V,2);
264         TopOpeBRepDS_Config SSC = P2D.EdgesConfig();
265         EVI = StoreVI(P2D,T1,E2index,Vindex,Standard_False,SSC,par1,1);
266         EVI = StoreVI(P2D,T2,E1index,Vindex,Standard_True,SSC,par2,2);
267       }
268       
269     } // ( isvertex )
270     
271   } //  MorePoint()
272   
273   RecomputeInterferences(myE1,myLI1);
274   RecomputeInterferences(myE2,myLI2);
275   
276 } // Insert
277
278 // ===============
279 // private methods
280 // ===============
281
282 //=======================================================================
283 //function : SetShapeTransition
284 //purpose  : 
285 //=======================================================================
286 void TopOpeBRep_EdgesFiller::SetShapeTransition(const TopOpeBRep_Point2d& P2D,
287                                TopOpeBRepDS_Transition& T1,TopOpeBRepDS_Transition& T2) const
288 {
289   Standard_Boolean pointofsegment = P2D.IsPointOfSegment();
290   Standard_Boolean esd = myPEI->SameDomain();
291   Standard_Integer ie1=0,ie2=0,if1=0,if2=0;
292   
293   if      (pointofsegment && esd) {
294     T1.ShapeBefore(TopAbs_EDGE);T1.ShapeAfter(TopAbs_EDGE);
295     T2.ShapeBefore(TopAbs_EDGE);T2.ShapeAfter(TopAbs_EDGE);
296     if ( ! myE1.IsNull() ) ie1 = myPDS->AddShape(myE1,1);
297     if ( ! myE2.IsNull() ) ie2 = myPDS->AddShape(myE2,2);
298     if ( ! myE2.IsNull() ) T1.Index(ie2);
299     if ( ! myE1.IsNull() ) T2.Index(ie1);
300   }
301   else {
302     T1.ShapeBefore(TopAbs_FACE);T1.ShapeAfter(TopAbs_FACE);
303     T2.ShapeBefore(TopAbs_FACE);T2.ShapeAfter(TopAbs_FACE);
304     if ( ! myF1.IsNull() ) if1 = myPDS->AddShape(myF1,1);
305     if ( ! myF2.IsNull() ) if2 = myPDS->AddShape(myF2,2);
306     if ( ! myF1.IsNull() ) T2.Index(if1);
307     if ( ! myF2.IsNull() ) T1.Index(if2);
308   }
309 }
310
311 //=======================================================================
312 //function : GetGeometry
313 //purpose  : private
314 //=======================================================================
315 Standard_Boolean TopOpeBRep_EdgesFiller::GetGeometry(TopOpeBRepDS_ListIteratorOfListOfInterference& IT,const TopOpeBRep_Point2d& P2D,Standard_Integer& G,TopOpeBRepDS_Kind& K) const 
316                        
317 {
318   TopOpeBRepDS_Point DSP = TopOpeBRep_PointGeomTool::MakePoint(P2D);
319   Standard_Boolean b = myHDS->GetGeometry(IT,DSP,G,K);
320   return b;
321 }
322
323 //=======================================================================
324 //function : MakeGeometry
325 //purpose  : 
326 //=======================================================================
327 Standard_Boolean TopOpeBRep_EdgesFiller::MakeGeometry(const TopOpeBRep_Point2d& P2D,Standard_Integer& G,TopOpeBRepDS_Kind& K) const 
328 {
329   Standard_Boolean isvertex1 = P2D.IsVertex(1);
330   Standard_Boolean isvertex2 = P2D.IsVertex(2);
331   if (isvertex1 && isvertex2) {
332     Standard_Integer G1 = myPDS->AddShape(P2D.Vertex(1),1);
333     myPDS->AddShape(P2D.Vertex(2),2);
334     G = G1;
335     K = TopOpeBRepDS_VERTEX;
336   }
337   else if (isvertex1) {
338     G = myPDS->AddShape(P2D.Vertex(1),1);
339     K = TopOpeBRepDS_VERTEX;
340   }
341   else if (isvertex2) {
342     G = myPDS->AddShape(P2D.Vertex(2),2);
343     K = TopOpeBRepDS_VERTEX;
344   }
345   else {
346     G = myPDS->AddPoint(TopOpeBRep_PointGeomTool::MakePoint(P2D));
347     K = TopOpeBRepDS_POINT;
348   }
349   return Standard_True;
350 }
351
352 //=======================================================================
353 //function : Face
354 //purpose  : 
355 //=======================================================================
356 void TopOpeBRep_EdgesFiller::Face(const Standard_Integer ISI,const TopoDS_Shape& F)
357 {
358   if      (ISI == 1) myF1 = TopoDS::Face(F);
359   else if (ISI == 2) myF2 = TopoDS::Face(F);
360   else throw Standard_Failure("Face(i,f) : ISI incorrect");
361 }
362
363 //=======================================================================
364 //function : Face
365 //purpose  : 
366 //=======================================================================
367 const TopoDS_Shape& TopOpeBRep_EdgesFiller::Face(const Standard_Integer ISI) const
368 {
369   if      (ISI == 1) return myF1;
370   else if (ISI == 2) return myF2;
371   else throw Standard_Failure("Face(i) : ISI incorrect");
372 }
373
374 //=======================================================================
375 //function : StorePI
376 //purpose  : 
377 //=======================================================================
378 Handle(TopOpeBRepDS_Interference) TopOpeBRep_EdgesFiller::StorePI(const TopOpeBRep_Point2d& P2D,
379                      const TopOpeBRepDS_Transition& T,const Standard_Integer SI,const Standard_Integer GI,
380                      const Standard_Real param,const Standard_Integer IEmother)
381 {
382   Handle(TopOpeBRepDS_Interference) I = TopOpeBRepDS_InterferenceTool::MakeEdgeInterference(T,TopOpeBRepDS_EDGE,SI,TopOpeBRepDS_POINT,GI,param);
383   TopoDS_Shape Emother;
384   if      (IEmother == 1) Emother = myE1;
385   else if (IEmother == 2) Emother = myE2;
386   myHDS->StoreInterference(I,Emother);
387   Standard_Boolean b = ToRecompute(P2D,I,IEmother);
388   if (b) StoreRecompute(I,IEmother);
389   return I;
390 }
391
392 //=======================================================================
393 //function : StoreVI
394 //purpose  : 
395 //=======================================================================
396 Handle(TopOpeBRepDS_Interference) TopOpeBRep_EdgesFiller::StoreVI(const TopOpeBRep_Point2d& P2D,
397                      const TopOpeBRepDS_Transition& T,const Standard_Integer EI,const Standard_Integer VI,
398                      const Standard_Boolean VisB,const TopOpeBRepDS_Config C,
399                      const Standard_Real param,const Standard_Integer IEmother)
400 {
401   Handle(TopOpeBRepDS_Interference) I = TopOpeBRepDS_InterferenceTool::MakeEdgeVertexInterference(T,EI,VI,VisB,C,param);
402   TopoDS_Shape Emother;
403   if      (IEmother == 1) Emother = myE1;
404   else if (IEmother == 2) Emother = myE2;
405   myHDS->StoreInterference(I,Emother);
406   Standard_Boolean b = ToRecompute(P2D,I,IEmother);
407   if (b) StoreRecompute(I,IEmother);
408   return I;
409 }
410
411 //=======================================================================
412 //function : ToRecompute
413 //purpose  : 
414 //=======================================================================
415 Standard_Boolean TopOpeBRep_EdgesFiller::ToRecompute(const TopOpeBRep_Point2d& P2D,const Handle(TopOpeBRepDS_Interference)& /*I*/,const Standard_Integer /*IEmother*/)
416 {
417   Standard_Boolean b = Standard_True;
418   Standard_Boolean pointofsegment = P2D.IsPointOfSegment();
419   Standard_Boolean esd = myPEI->SameDomain();
420   b = b && (pointofsegment && !esd);
421   return b;
422 }
423
424 //=======================================================================
425 //function : StoreRecompute
426 //purpose  : 
427 //=======================================================================
428 void TopOpeBRep_EdgesFiller::StoreRecompute(const Handle(TopOpeBRepDS_Interference)& I,const Standard_Integer IEmother)
429 {
430   if      (IEmother == 1) myLI1.Append(I);
431   else if (IEmother == 2) myLI2.Append(I);
432 }
433
434 //=======================================================================
435 //function : RecomputeInterferences
436 //purpose  : 
437 //=======================================================================
438 void TopOpeBRep_EdgesFiller::RecomputeInterferences(const TopoDS_Edge& E,TopOpeBRepDS_ListOfInterference& LI)
439 {
440   if (LI.IsEmpty()) return;
441
442   TopOpeBRepDS_TKI tki; tki.FillOnGeometry(LI);
443
444   for (tki.Init(); tki.More(); tki.Next()) {
445     TopOpeBRepDS_Kind K; Standard_Integer G; tki.Value(K,G);
446     TopOpeBRepDS_ListOfInterference& loi = tki.ChangeValue(K,G); TopOpeBRepDS_ListOfInterference Rloi;
447     Standard_Integer nloi = loi.Extent();
448     if (nloi == 0) continue;
449
450     Handle(TopOpeBRepDS_Interference)& iloi = loi.First(); 
451     TopOpeBRepDS_Transition& TU = iloi->ChangeTransition();
452     Standard_Integer ifb = TU.IndexBefore();
453     const TopoDS_Face& fb = TopoDS::Face(myPDS->Shape(ifb));
454
455     Standard_Real pE = FDS_Parameter(iloi); TopOpeBRepDS_Transition TN;
456     TN.ShapeBefore(TU.ShapeBefore());TN.IndexBefore(TU.IndexBefore());
457     TN.ShapeAfter(TU.ShapeAfter());TN.IndexAfter(TU.IndexAfter());
458
459     FDS_stateEwithF2d(*myPDS,E,pE,K,G,fb,TN);
460
461   } // tki.More
462 } // RecomputeInterferences