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