0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / TopOpeBRep / TopOpeBRep_EdgesFiller.cxx
CommitLineData
b311480e 1// Created on: 1994-10-12
2// Created by: Jean Yves LEBEY
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 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>
7fd59977 28#include <TopOpeBRepDS_Config.hxx>
7fd59977 29#include <TopOpeBRepDS_EXPORT.hxx>
42cf5bc1 30#include <TopOpeBRepDS_HDataStructure.hxx>
31#include <TopOpeBRepDS_Interference.hxx>
7fd59977 32#include <TopOpeBRepDS_InterferenceTool.hxx>
42cf5bc1 33#include <TopOpeBRepDS_Point.hxx>
34#include <TopOpeBRepDS_TKI.hxx>
35#include <TopOpeBRepDS_Transition.hxx>
7fd59977 36#include <TopOpeBRepTool_EXPORT.hxx>
7fd59977 37
0797d9d3 38#ifdef OCCT_DEBUG
ec357c5c 39#include <TopOpeBRepDS_CurvePointInterference.hxx>
1d0a9d4d 40extern Standard_Boolean TopOpeBRep_GettraceEEFF();
04232180 41Standard_EXPORT void debposesd(void) {/*std::cout<<"+++ debposesd"<<std::endl;*/}
42Standard_EXPORT void debposnesd(void) {std::cout<<"+++ debposnesd"<<std::endl;}
7fd59977 43Standard_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//=======================================================================
55TopOpeBRep_EdgesFiller::TopOpeBRep_EdgesFiller() : myPDS(NULL),myPEI(NULL) {}
56
57void rototo() {}
58
59//=======================================================================
60//function : Insert
61//purpose :
62//=======================================================================
63void 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;
536a3cb8 72
7fd59977 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;
7fd59977 78
7fd59977 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);
7fd59977 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);
96a95605
DB
95 if ( ! myF1.IsNull() ) myPDS->AddShape(myF1,1);
96 if ( ! myF2.IsNull() ) myPDS->AddShape(myF2,2);
7fd59977 97
7fd59977 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
0797d9d3 109#ifdef OCCT_DEBUG
7fd59977 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) {
04232180 117 std::cout<<std::endl;
118 std::cout<<"*** TopOpeBRep_EdgesFiller : isvertex1 && isvertex2 : P3D non confondus"<<std::endl;
119 std::cout<<"point PV1 "<<P3D1.X()<<" "<<P3D1.Y()<<" "<<P3D1.Z()<<std::endl;
120 std::cout<<"point PV2 "<<P3D2.X()<<" "<<P3D2.Y()<<" "<<P3D2.Z()<<std::endl;
121 std::cout<<std::endl;
7fd59977 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);
7fd59977 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) {
0797d9d3 142#ifdef OCCT_DEBUG
63c629aa 143 Standard_Boolean foundvertex = (found) && (K == TopOpeBRepDS_VERTEX);
04232180 144 std::cout<<"- - - faulty EdgesFiller : G "<<G<<" K ";TopOpeBRepDS::Print(K,std::cout);std::cout.flush();
145 std::cout<<" isvertex="<<isvertex;std::cout.flush();
146 std::cout<<" isop="<<foundpoint<<" isov="<<foundvertex;std::cout.flush();
147 std::cout<<" isnp="<<isnewpoint<<" isnv="<<isnewvertex<<std::endl;std::cout.flush();
7fd59977 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
0797d9d3 168#ifdef OCCT_DEBUG
7fd59977 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();
1d47d8d0 174
7fd59977 175 Standard_Integer gevi=0;
1d47d8d0 176
7fd59977 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
0797d9d3 188#ifdef OCCT_DEBUG
04232180 189 TopOpeBRepDS::Print(K,G,std::cout,"TopOpeBRep_EdgesFiller : remplacer "," ");
190 TopOpeBRepDS::Print(TopOpeBRepDS_VERTEX,gevi,std::cout,"par "," dans les courbes NYI\n");
7fd59977 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//=======================================================================
286void 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 }
7fd59977 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//=======================================================================
315Standard_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//=======================================================================
327Standard_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);
6e6cd5d9 333 myPDS->AddShape(P2D.Vertex(2),2);
7fd59977 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//=======================================================================
356void 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);
9775fa61 360 else throw Standard_Failure("Face(i,f) : ISI incorrect");
7fd59977 361}
362
363//=======================================================================
364//function : Face
365//purpose :
366//=======================================================================
367const TopoDS_Shape& TopOpeBRep_EdgesFiller::Face(const Standard_Integer ISI) const
368{
369 if (ISI == 1) return myF1;
370 else if (ISI == 2) return myF2;
9775fa61 371 else throw Standard_Failure("Face(i) : ISI incorrect");
7fd59977 372}
373
374//=======================================================================
375//function : StorePI
376//purpose :
377//=======================================================================
378Handle(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//=======================================================================
396Handle(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//=======================================================================
35e08fe8 415Standard_Boolean TopOpeBRep_EdgesFiller::ToRecompute(const TopOpeBRep_Point2d& P2D,const Handle(TopOpeBRepDS_Interference)& /*I*/,const Standard_Integer /*IEmother*/)
7fd59977 416{
417 Standard_Boolean b = Standard_True;
7fd59977 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//=======================================================================
428void 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//=======================================================================
438void 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
7fd59977 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
7fd59977 450 Handle(TopOpeBRepDS_Interference)& iloi = loi.First();
451 TopOpeBRepDS_Transition& TU = iloi->ChangeTransition();
452 Standard_Integer ifb = TU.IndexBefore();
7fd59977 453 const TopoDS_Face& fb = TopoDS::Face(myPDS->Shape(ifb));
7fd59977 454
7fd59977 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());
302f96fb 458
302f96fb 459 FDS_stateEwithF2d(*myPDS,E,pE,K,G,fb,TN);
7fd59977 460
7fd59977 461 } // tki.More
462} // RecomputeInterferences