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