0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / BRepOffset / BRepOffset_MakeLoops.cxx
CommitLineData
b311480e 1// Created on: 1996-09-05
2// Created by: Yves FRICAUD
3// Copyright (c) 1996-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
17#include <stdio.h>
18
19#include <BRepOffset_MakeLoops.ixx>
20#include <BRepAlgo_Loop.hxx>
21
22
23#include <BRep_Builder.hxx>
24#include <BRep_Tool.hxx>
25#include <TopExp.hxx>
26#include <TopExp_Explorer.hxx>
27#include <TopTools_ListIteratorOfListOfShape.hxx>
28#include <TopoDS.hxx>
29#include <TopoDS_Face.hxx>
30#include <TopoDS_Edge.hxx>
31#include <TopoDS_Vertex.hxx>
32#include <TopTools_MapOfShape.hxx>
33#include <TopoDS_Iterator.hxx>
34#include <BRep_TVertex.hxx>
35
36#ifdef DRAW
37#include <DBRep.hxx>
7fd59977 38Standard_Integer NbF = 1;
39static Standard_Boolean Affich = Standard_False;
7fd59977 40#endif
41
7fd59977 42BRepOffset_MakeLoops::BRepOffset_MakeLoops()
43{
44}
45
46//=======================================================================
47//function : Build
48//purpose :
49//=======================================================================
50
51void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape& LF,
52 const Handle(BRepAlgo_AsDes)& AsDes,
53 BRepAlgo_Image& Image)
54{
55 TopTools_ListIteratorOfListOfShape it(LF);
56 TopTools_ListIteratorOfListOfShape itl,itLCE;
57 BRepAlgo_Loop Loops;
58 Loops.VerticesForSubstitute( myVerVerMap );
59
60 for (; it.More(); it.Next()) {
61 const TopoDS_Face& F = TopoDS::Face(it.Value());
62 //---------------------------
0d969553 63 // Initialization of Loops.
7fd59977 64 //---------------------------
65 Loops.Init(F);
66 //-----------------------------
0d969553 67 // return edges of F.
7fd59977 68 //-----------------------------
69 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
70 TopTools_ListOfShape AddedEdges;
71
72 for (itl.Initialize(LE); itl.More(); itl.Next()) {
73 TopoDS_Edge E = TopoDS::Edge(itl.Value());
74 if (Image.HasImage(E)) {
75 //-------------------------------------------
0d969553
Y
76 // E was already cut in another face.
77 // Return the cut edges reorientate them as E.
78 // See pb for the edges that have disappeared?
7fd59977 79 //-------------------------------------------
80 const TopTools_ListOfShape& LCE = Image.Image(E);
81 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
82 TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation());
83 Loops.AddConstEdge(TopoDS::Edge(CE));
84 }
85 }
86 else {
87 Loops .AddEdge(E, AsDes->Descendant(E));
88 AddedEdges.Append (E);
89 }
90 }
91 //------------------------
0d969553 92 // Unwind.
7fd59977 93 //------------------------
94 Loops.Perform();
95 Loops.WiresToFaces();
96 //------------------------
97 // MAJ SD.
98 //------------------------
99 const TopTools_ListOfShape& NF = Loops.NewFaces();
100 //-----------------------
0d969553 101 // F => New faces;
7fd59977 102 //-----------------------
103 Image.Bind(F,NF);
104
105 TopTools_ListIteratorOfListOfShape itAdded;
106 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
107 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
108 //-----------------------
0d969553 109 // E => New edges;
7fd59977 110 //-----------------------
111 const TopTools_ListOfShape& LoopNE = Loops.NewEdges(E);
112 if (Image.HasImage(E)) {
113 Image.Add(E,LoopNE);
114 }
115 else {
116 Image.Bind(E,LoopNE);
117 }
118 }
119 }
120 Loops.GetVerticesForSubstitute( myVerVerMap );
121 if (myVerVerMap.IsEmpty())
122 return;
123 BRep_Builder BB;
124 for (it.Initialize( LF ); it.More(); it.Next())
125 {
126 TopoDS_Shape F = it.Value();
127 TopTools_ListOfShape LIF;
128 Image.LastImage( F, LIF );
129 for (itl.Initialize(LIF); itl.More(); itl.Next())
130 {
131 const TopoDS_Shape& IF = itl.Value();
132 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
133 for (; EdExp.More(); EdExp.Next())
134 {
135 TopoDS_Shape E = EdExp.Current();
136 TopTools_ListOfShape VList;
137 TopoDS_Iterator VerExp( E );
138 for (; VerExp.More(); VerExp.Next())
139 VList.Append( VerExp.Value() );
140 TopTools_ListIteratorOfListOfShape itlv( VList );
141 for (; itlv.More(); itlv.Next())
142 {
143 const TopoDS_Shape& V = itlv.Value();
144 if (myVerVerMap.IsBound( V ))
145 {
146 TopoDS_Shape NewV = myVerVerMap( V );
147 E.Free( Standard_True );
148 NewV.Orientation( V.Orientation() );
149 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
150 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
151 if (TV->Tolerance() > NewTV->Tolerance())
152 NewTV->Tolerance( TV->Tolerance() );
153 NewTV->ChangePoints().Append( TV->ChangePoints() );
154 AsDes->Replace( V, NewV );
155 BB.Remove( E, V );
156 BB.Add( E, NewV );
157 }
158 }
159 }
160 }
161 }
162}
163
164//=======================================================================
165//function : IsBetweenCorks
166//purpose :
167//=======================================================================
168
169static Standard_Boolean IsBetweenCorks(const TopoDS_Shape& E,
170 const Handle(BRepAlgo_AsDes)& AsDes,
171 const TopTools_ListOfShape& LContext)
172{
173 if (!AsDes->HasAscendant(E)) return 1;
174 const TopTools_ListOfShape& LF = AsDes->Ascendant(E);
175 TopTools_ListIteratorOfListOfShape it;
176 for (it.Initialize(LF); it.More(); it.Next()) {
177 const TopoDS_Shape& S = it.Value();
178 Standard_Boolean found = 0;
179 TopTools_ListIteratorOfListOfShape it2;
180 for (it2.Initialize(LContext); it2.More(); it2.Next()) {
181 if(S.IsSame(it2.Value())) {
182 found = 1;
183 break;
184 }
185 }
186 if (!found) return 0;
187 }
188 return 1;
189}
190//=======================================================================
191//function : BuildOnContext
192//purpose :
193//=======================================================================
194
195void BRepOffset_MakeLoops::BuildOnContext(const TopTools_ListOfShape& LContext,
196 const BRepOffset_Analyse& Analyse,
197 const Handle(BRepAlgo_AsDes)& AsDes,
198 BRepAlgo_Image& Image,
199 const Standard_Boolean InSide)
200{
201 //-----------------------------------------
0d969553 202 // unwinding of caps.
7fd59977 203 //-----------------------------------------
204 TopTools_ListIteratorOfListOfShape it(LContext);
205 TopTools_ListIteratorOfListOfShape itl,itLCE;
206 BRepAlgo_Loop Loops;
207 Loops.VerticesForSubstitute( myVerVerMap );
208 TopExp_Explorer exp;
209 TopTools_MapOfShape MapExtent;
210
211 for (; it.More(); it.Next()) {
212 const TopoDS_Face& F = TopoDS::Face(it.Value());
213 TopTools_MapOfShape MBound;
214 //-----------------------------------------------
0d969553
Y
215 // Initialisation of Loops.
216 // F is reversed it will be added in myOffC.
217 // and myOffC will be reversed in the final result.
7fd59977 218 //-----------------------------------------------
219 TopoDS_Shape aLocalShape = F.Reversed();
220 if (InSide) Loops.Init(TopoDS::Face(aLocalShape));
221// if (InSide) Loops.Init(TopoDS::Face(F.Reversed()));
222 else Loops.Init(F);
223 //--------------------------------------------------------
0d969553 224 // return edges of F not modified by definition.
7fd59977 225 //--------------------------------------------------------
226 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
227 exp.More();
228 exp.Next()) {
229 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
230 MBound.Add(CE);
231 if (Analyse.HasAncestor(CE)) {
0d969553 232 // the stop of cups except for the connectivity stops between caps.
7fd59977 233 // if (!AsDes->HasAscendant(CE)) {
234 aLocalShape = CE.Reversed();
235 if (InSide) Loops.AddConstEdge(CE);
236 else Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
237// else Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
238 }
239 }
240 //------------------------------------------------------
0d969553 241 // Trace of offsets + connectivity edge between caps.
7fd59977 242 //------------------------------------------------------
243 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
244 TopTools_ListOfShape AddedEdges;
245
246 for (itl.Initialize(LE); itl.More(); itl.Next()) {
247 TopoDS_Edge E = TopoDS::Edge(itl.Value());
248 if (Image.HasImage(E)) {
249 //-------------------------------------------
0d969553
Y
250 // E was already cut in another face.
251 // Return cut edges and orientate them as E.
252 // See pb for the edges that have disappeared?
7fd59977 253 //-------------------------------------------
254 const TopTools_ListOfShape& LCE = Image.Image(E);
255 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
256 TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation());
257 if (MapExtent.Contains(E)) {
258 Loops.AddConstEdge(TopoDS::Edge(CE));
259 continue;
260 }
261 if (!MBound.Contains(E)) CE.Reverse();
262 if (InSide) Loops.AddConstEdge(TopoDS::Edge(CE));
263 else
264 {
265 TopoDS_Shape aLocalShape = CE.Reversed();
266 Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
267 }
268// else Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
269 }
270 }
271 else {
272 if (IsBetweenCorks(E,AsDes,LContext) && AsDes->HasDescendant(E)) {
0d969553 273 //connection between 2 caps
7fd59977 274 MapExtent.Add(E);
275 TopTools_ListOfShape LV;
276 if (InSide) {
277 for (itLCE.Initialize(AsDes->Descendant(E)); itLCE.More(); itLCE.Next()) {
278 LV.Append(itLCE.Value().Reversed());
279 }
280 Loops.AddEdge(E,LV);
281 }
282 else {
283 Loops.AddEdge(E,AsDes->Descendant(E));
284 }
285 AddedEdges.Append (E);
286 }
287 else if (IsBetweenCorks(E,AsDes,LContext)) {
288 TopoDS_Shape aLocalShape = E.Reversed();
289 if (InSide) Loops.AddConstEdge(E);
290 else Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
291// if (InSide) Loops.AddConstEdge(TopoDS::Edge(E));
292// else Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
293 }
294 else {
295 TopoDS_Shape aLocalShape = E.Reversed();
296 if (InSide) Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
297 else Loops.AddConstEdge(E);
298// if (InSide) Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
299// else Loops.AddConstEdge(TopoDS::Edge(E));
300 }
301 }
302 }
303 //------------------------
0d969553 304 // Unwind.
7fd59977 305 //------------------------
306 Loops.Perform();
307 Loops.WiresToFaces();
308 //------------------------
309 // MAJ SD.
310 //------------------------
311 const TopTools_ListOfShape& NF = Loops.NewFaces();
312 //-----------------------
0d969553 313 // F => New faces;
7fd59977 314 //-----------------------
315 Image.Bind(F,NF);
316
317 TopTools_ListIteratorOfListOfShape itAdded;
318 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
319 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
320 //-----------------------
0d969553 321 // E => New edges;
7fd59977 322 //-----------------------
323 if (Image.HasImage(E)) {
324 Image.Add(E,Loops.NewEdges(E));
325 }
326 else {
327 Image.Bind(E,Loops.NewEdges(E));
328 }
329 }
330 }
331 Loops.GetVerticesForSubstitute( myVerVerMap );
332 if (myVerVerMap.IsEmpty())
333 return;
334 BRep_Builder BB;
335 for (it.Initialize( LContext ); it.More(); it.Next())
336 {
337 TopoDS_Shape F = it.Value();
338 TopTools_ListOfShape LIF;
339 Image.LastImage( F, LIF );
340 for (itl.Initialize(LIF); itl.More(); itl.Next())
341 {
342 const TopoDS_Shape& IF = itl.Value();
343 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
344 for (; EdExp.More(); EdExp.Next())
345 {
346 TopoDS_Shape E = EdExp.Current();
347 TopTools_ListOfShape VList;
348 TopoDS_Iterator VerExp( E );
349 for (; VerExp.More(); VerExp.Next())
350 VList.Append( VerExp.Value() );
351 TopTools_ListIteratorOfListOfShape itlv( VList );
352 for (; itlv.More(); itlv.Next())
353 {
354 const TopoDS_Shape& V = itlv.Value();
355 if (myVerVerMap.IsBound( V ))
356 {
357 TopoDS_Shape NewV = myVerVerMap( V );
358 E.Free( Standard_True );
359 NewV.Orientation( V.Orientation() );
360 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
361 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
362 if (TV->Tolerance() > NewTV->Tolerance())
363 NewTV->Tolerance( TV->Tolerance() );
364 NewTV->ChangePoints().Append( TV->ChangePoints() );
365 AsDes->Replace( V, NewV );
366 BB.Remove( E, V );
367 BB.Add( E, NewV );
368 }
369 }
370 }
371 }
372 }
373}
374
375
376//=======================================================================
377//function : BuildFaces
378//purpose :
379//=======================================================================
380
381void BRepOffset_MakeLoops::BuildFaces(const TopTools_ListOfShape& LF,
382 const Handle(BRepAlgo_AsDes)& AsDes,
383 BRepAlgo_Image& Image)
384{
385 TopTools_ListIteratorOfListOfShape itr,itl,itLCE;
386 Standard_Boolean ToRebuild;
387 BRepAlgo_Loop Loops;
388 Loops.VerticesForSubstitute( myVerVerMap );
389 BRep_Builder B;
390
391 //----------------------------------
0d969553 392 // Loop on all faces //.
7fd59977 393 //----------------------------------
394 for (itr.Initialize(LF); itr.More(); itr.Next()) {
395 TopoDS_Face F = TopoDS::Face(itr.Value());
396 Loops.Init(F);
397 ToRebuild = Standard_False;
398 TopTools_ListOfShape AddedEdges;
399
400 if (!Image.HasImage(F)) {
401 //----------------------------------
0d969553 402 // Face F not yet reconstructed.
7fd59977 403 //----------------------------------
404 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
405 //----------------------------------------------------------------
0d969553
Y
406 // first loop to find if the edges of the face were reconstructed.
407 // - maj on map MONV. Some vertices on reconstructed edges
408 // coincide geometrically with old but are not IsSame.
7fd59977 409 //----------------------------------------------------------------
410 TopTools_DataMapOfShapeShape MONV;
411 TopoDS_Vertex OV1,OV2,NV1,NV2;
412
413 for (itl.Initialize(LE); itl.More(); itl.Next()) {
414 TopoDS_Edge E = TopoDS::Edge(itl.Value());
415 if (Image.HasImage(E)) {
416 const TopTools_ListOfShape& LCE = Image.Image(E);
417 if (LCE.Extent() == 1 && LCE.First().IsSame(E)) {
418 TopoDS_Shape aLocalShape = LCE.First().Oriented(E.Orientation());
419 TopoDS_Edge CE = TopoDS::Edge(aLocalShape);
420// TopoDS_Edge CE = TopoDS::Edge(LCE.First().Oriented(E.Orientation()));
421 Loops.AddConstEdge(CE);
422 continue;
423 }
424 //----------------------------------
0d969553 425 // F should be reconstructed.
7fd59977 426 //----------------------------------
427 ToRebuild = Standard_True;
428 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
429 TopoDS_Shape aLocalShape = itLCE.Value().Oriented(E.Orientation());
430 TopoDS_Edge CE = TopoDS::Edge(aLocalShape);
431// TopoDS_Edge CE = TopoDS::Edge(itLCE.Value().Oriented(E.Orientation()));
432 TopExp::Vertices (E ,OV1,OV2);
433 TopExp::Vertices (CE,NV1,NV2);
434 if (!OV1.IsSame(NV1)) MONV.Bind(OV1,NV1);
435 if (!OV2.IsSame(NV2)) MONV.Bind(OV2,NV2);
436 Loops.AddConstEdge(CE);
437 }
438 }
439 }
440 if (ToRebuild) {
441#ifdef DRAW
7fd59977 442 if ( Affich) {
1896126e 443 char name[256];
7fd59977 444 sprintf(name,"CF_%d",NbF++);
445 DBRep::Set(name,F);
446 }
447#endif
448
449 //-----------------------------------------------------------
0d969553
Y
450 // Non-reconstructed edges on other faces are added.
451 // If their vertices were reconstructed they are reconstructed.
7fd59977 452 //-----------------------------------------------------------
453 for (itl.Initialize(LE); itl.More(); itl.Next()) {
454 Standard_Real f,l;
455 TopoDS_Edge E = TopoDS::Edge(itl.Value());
456 BRep_Tool::Range(E,f,l);
457 if (!Image.HasImage(E)) {
458 TopExp::Vertices (E,OV1,OV2);
459 TopTools_ListOfShape LV;
460 if (MONV.IsBound(OV1)) {
461 TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV1));
462 VV.Orientation(TopAbs_FORWARD);
463 LV.Append(VV);
464 TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
465 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
466 f,E,BRep_Tool::Tolerance(VV));
467 }
468 if (MONV.IsBound(OV2)) {
469 TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV2));
470 VV.Orientation(TopAbs_REVERSED);
471 LV.Append(VV);
472 TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
473 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
474 l,E,BRep_Tool::Tolerance(VV));
475// B.UpdateVertex(TopoDS::Vertex(VV.Oriented(TopAbs_INTERNAL)),
476// l,E,BRep_Tool::Tolerance(VV));
477 }
478 if (LV.IsEmpty()) Loops.AddConstEdge(E);
479 else {
480 Loops.AddEdge (E,LV);
481 AddedEdges.Append(E);
482 }
483 }
484 }
485 }
486 }
487 if (ToRebuild) {
488 //------------------------
489 // Reconstruction.
490 //------------------------
491 Loops.Perform();
492 Loops.WiresToFaces();
493 //------------------------
494 // MAJ SD.
495 //------------------------
496 const TopTools_ListOfShape& NF = Loops.NewFaces();
497 //-----------------------
0d969553 498 // F => New faces;
7fd59977 499 //-----------------------
500 Image.Bind(F,NF);
501
502 TopTools_ListIteratorOfListOfShape itAdded;
503 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
504 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
505 //-----------------------
0d969553 506 // E => New edges;
7fd59977 507 //-----------------------
508 if (Image.HasImage(E)) {
509 Image.Add(E,Loops.NewEdges(E));
510 }
511 else {
512 Image.Bind(E,Loops.NewEdges(E));
513 }
514 }
515 }
516 }
517 Loops.GetVerticesForSubstitute( myVerVerMap );
518 if (myVerVerMap.IsEmpty())
519 return;
520 BRep_Builder BB;
521 for (itr.Initialize( LF ); itr.More(); itr.Next())
522 {
523 TopoDS_Shape F = itr.Value();
524 TopTools_ListOfShape LIF;
525 Image.LastImage( F, LIF );
526 for (itl.Initialize(LIF); itl.More(); itl.Next())
527 {
528 const TopoDS_Shape& IF = itl.Value();
529 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
530 for (; EdExp.More(); EdExp.Next())
531 {
532 TopoDS_Shape E = EdExp.Current();
533 TopTools_ListOfShape VList;
534 TopoDS_Iterator VerExp( E );
535 for (; VerExp.More(); VerExp.Next())
536 VList.Append( VerExp.Value() );
537 TopTools_ListIteratorOfListOfShape itlv( VList );
538 for (; itlv.More(); itlv.Next())
539 {
540 const TopoDS_Shape& V = itlv.Value();
541 if (myVerVerMap.IsBound( V ))
542 {
543 TopoDS_Shape NewV = myVerVerMap( V );
544 E.Free( Standard_True );
545 NewV.Orientation( V.Orientation() );
546 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
547 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
548 if (TV->Tolerance() > NewTV->Tolerance())
549 NewTV->Tolerance( TV->Tolerance() );
550 NewTV->ChangePoints().Append( TV->ChangePoints() );
551 AsDes->Replace( V, NewV );
552 BB.Remove( E, V );
553 BB.Add( E, NewV );
554 }
555 }
556 }
557 }
558 }
559}