1 // Created on: 1996-09-05
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRep_TVertex.hxx>
21 #include <BRepAlgo_AsDes.hxx>
22 #include <BRepAlgo_Image.hxx>
23 #include <BRepAlgo_Loop.hxx>
24 #include <BRepOffset_Analyse.hxx>
25 #include <BRepOffset_MakeLoops.hxx>
27 #include <TopExp_Explorer.hxx>
29 #include <TopoDS_Edge.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopTools_ListIteratorOfListOfShape.hxx>
34 #include <TopTools_MapOfShape.hxx>
39 Standard_Integer NbF = 1;
40 static Standard_Boolean Affich = Standard_False;
43 BRepOffset_MakeLoops::BRepOffset_MakeLoops()
47 //=======================================================================
50 //=======================================================================
52 void BRepOffset_MakeLoops::Build(const TopTools_ListOfShape& LF,
53 const Handle(BRepAlgo_AsDes)& AsDes,
54 BRepAlgo_Image& Image)
56 TopTools_ListIteratorOfListOfShape it(LF);
57 TopTools_ListIteratorOfListOfShape itl,itLCE;
59 Loops.VerticesForSubstitute( myVerVerMap );
61 for (; it.More(); it.Next()) {
62 const TopoDS_Face& F = TopoDS::Face(it.Value());
63 //---------------------------
64 // Initialization of Loops.
65 //---------------------------
67 //-----------------------------
69 //-----------------------------
70 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
71 TopTools_ListOfShape AddedEdges;
73 for (itl.Initialize(LE); itl.More(); itl.Next()) {
74 TopoDS_Edge E = TopoDS::Edge(itl.Value());
75 if (Image.HasImage(E)) {
76 //-------------------------------------------
77 // E was already cut in another face.
78 // Return the cut edges reorientate them as E.
79 // See pb for the edges that have disappeared?
80 //-------------------------------------------
81 const TopTools_ListOfShape& LCE = Image.Image(E);
82 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
83 TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation());
84 Loops.AddConstEdge(TopoDS::Edge(CE));
88 Loops .AddEdge(E, AsDes->Descendant(E));
89 AddedEdges.Append (E);
92 //------------------------
94 //------------------------
97 //------------------------
99 //------------------------
100 const TopTools_ListOfShape& NF = Loops.NewFaces();
101 //-----------------------
103 //-----------------------
106 TopTools_ListIteratorOfListOfShape itAdded;
107 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
108 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
109 //-----------------------
111 //-----------------------
112 const TopTools_ListOfShape& LoopNE = Loops.NewEdges(E);
113 if (Image.HasImage(E)) {
117 Image.Bind(E,LoopNE);
121 Loops.GetVerticesForSubstitute( myVerVerMap );
122 if (myVerVerMap.IsEmpty())
125 for (it.Initialize( LF ); it.More(); it.Next())
127 TopoDS_Shape F = it.Value();
128 TopTools_ListOfShape LIF;
129 Image.LastImage( F, LIF );
130 for (itl.Initialize(LIF); itl.More(); itl.Next())
132 const TopoDS_Shape& IF = itl.Value();
133 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
134 for (; EdExp.More(); EdExp.Next())
136 TopoDS_Shape E = EdExp.Current();
137 TopTools_ListOfShape VList;
138 TopoDS_Iterator VerExp( E );
139 for (; VerExp.More(); VerExp.Next())
140 VList.Append( VerExp.Value() );
141 TopTools_ListIteratorOfListOfShape itlv( VList );
142 for (; itlv.More(); itlv.Next())
144 const TopoDS_Shape& V = itlv.Value();
145 if (myVerVerMap.IsBound( V ))
147 TopoDS_Shape NewV = myVerVerMap( V );
148 E.Free( Standard_True );
149 NewV.Orientation( V.Orientation() );
150 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
151 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
152 if (TV->Tolerance() > NewTV->Tolerance())
153 NewTV->Tolerance( TV->Tolerance() );
154 NewTV->ChangePoints().Append( TV->ChangePoints() );
155 AsDes->Replace( V, NewV );
165 //=======================================================================
166 //function : IsBetweenCorks
168 //=======================================================================
170 static Standard_Boolean IsBetweenCorks(const TopoDS_Shape& E,
171 const Handle(BRepAlgo_AsDes)& AsDes,
172 const TopTools_ListOfShape& LContext)
174 if (!AsDes->HasAscendant(E)) return 1;
175 const TopTools_ListOfShape& LF = AsDes->Ascendant(E);
176 TopTools_ListIteratorOfListOfShape it;
177 for (it.Initialize(LF); it.More(); it.Next()) {
178 const TopoDS_Shape& S = it.Value();
179 Standard_Boolean found = 0;
180 TopTools_ListIteratorOfListOfShape it2;
181 for (it2.Initialize(LContext); it2.More(); it2.Next()) {
182 if(S.IsSame(it2.Value())) {
187 if (!found) return 0;
191 //=======================================================================
192 //function : BuildOnContext
194 //=======================================================================
196 void BRepOffset_MakeLoops::BuildOnContext(const TopTools_ListOfShape& LContext,
197 const BRepOffset_Analyse& Analyse,
198 const Handle(BRepAlgo_AsDes)& AsDes,
199 BRepAlgo_Image& Image,
200 const Standard_Boolean InSide)
202 //-----------------------------------------
203 // unwinding of caps.
204 //-----------------------------------------
205 TopTools_ListIteratorOfListOfShape it(LContext);
206 TopTools_ListIteratorOfListOfShape itl,itLCE;
208 Loops.VerticesForSubstitute( myVerVerMap );
210 TopTools_MapOfShape MapExtent;
212 for (; it.More(); it.Next()) {
213 const TopoDS_Face& F = TopoDS::Face(it.Value());
214 TopTools_MapOfShape MBound;
215 //-----------------------------------------------
216 // Initialisation of Loops.
217 // F is reversed it will be added in myOffC.
218 // and myOffC will be reversed in the final result.
219 //-----------------------------------------------
220 TopoDS_Shape aReversedF = F.Reversed();
221 if (InSide) Loops.Init(TopoDS::Face(aReversedF));
222 // if (InSide) Loops.Init(TopoDS::Face(F.Reversed()));
224 //--------------------------------------------------------
225 // return edges of F not modified by definition.
226 //--------------------------------------------------------
227 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
230 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
232 if (Analyse.HasAncestor(CE)) {
233 // the stop of cups except for the connectivity stops between caps.
234 // if (!AsDes->HasAscendant(CE)) {
235 TopoDS_Shape aReversedE = CE.Reversed();
236 if (InSide) Loops.AddConstEdge(CE);
237 else Loops.AddConstEdge(TopoDS::Edge(aReversedE));
238 // else Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
241 //------------------------------------------------------
242 // Trace of offsets + connectivity edge between caps.
243 //------------------------------------------------------
244 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
245 TopTools_ListOfShape AddedEdges;
247 for (itl.Initialize(LE); itl.More(); itl.Next()) {
248 TopoDS_Edge E = TopoDS::Edge(itl.Value());
249 if (Image.HasImage(E)) {
250 //-------------------------------------------
251 // E was already cut in another face.
252 // Return cut edges and orientate them as E.
253 // See pb for the edges that have disappeared?
254 //-------------------------------------------
255 const TopTools_ListOfShape& LCE = Image.Image(E);
256 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
257 TopoDS_Shape CE = itLCE.Value().Oriented(E.Orientation());
258 if (MapExtent.Contains(E)) {
259 Loops.AddConstEdge(TopoDS::Edge(CE));
262 if (!MBound.Contains(E)) CE.Reverse();
263 if (InSide) Loops.AddConstEdge(TopoDS::Edge(CE));
266 TopoDS_Shape aReversedE = CE.Reversed();
267 Loops.AddConstEdge(TopoDS::Edge(aReversedE));
269 // else Loops.AddConstEdge(TopoDS::Edge(CE.Reversed()));
273 if (IsBetweenCorks(E,AsDes,LContext) && AsDes->HasDescendant(E)) {
274 //connection between 2 caps
276 TopTools_ListOfShape LV;
278 for (itLCE.Initialize(AsDes->Descendant(E)); itLCE.More(); itLCE.Next()) {
279 LV.Append(itLCE.Value().Reversed());
284 Loops.AddEdge(E,AsDes->Descendant(E));
286 AddedEdges.Append (E);
288 else if (IsBetweenCorks(E,AsDes,LContext)) {
289 TopoDS_Shape aLocalShape = E.Reversed();
290 if (InSide) Loops.AddConstEdge(E);
291 else Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
292 // if (InSide) Loops.AddConstEdge(TopoDS::Edge(E));
293 // else Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
296 TopoDS_Shape aLocalShape = E.Reversed();
297 if (InSide) Loops.AddConstEdge(TopoDS::Edge(aLocalShape));
298 else Loops.AddConstEdge(E);
299 // if (InSide) Loops.AddConstEdge(TopoDS::Edge(E.Reversed()));
300 // else Loops.AddConstEdge(TopoDS::Edge(E));
304 //------------------------
306 //------------------------
308 Loops.WiresToFaces();
309 //------------------------
311 //------------------------
312 const TopTools_ListOfShape& NF = Loops.NewFaces();
313 //-----------------------
315 //-----------------------
318 TopTools_ListIteratorOfListOfShape itAdded;
319 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
320 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
321 //-----------------------
323 //-----------------------
324 if (Image.HasImage(E)) {
325 Image.Add(E,Loops.NewEdges(E));
328 Image.Bind(E,Loops.NewEdges(E));
332 Loops.GetVerticesForSubstitute( myVerVerMap );
333 if (myVerVerMap.IsEmpty())
336 for (it.Initialize( LContext ); it.More(); it.Next())
338 TopoDS_Shape F = it.Value();
339 TopTools_ListOfShape LIF;
340 Image.LastImage( F, LIF );
341 for (itl.Initialize(LIF); itl.More(); itl.Next())
343 const TopoDS_Shape& IF = itl.Value();
344 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
345 for (; EdExp.More(); EdExp.Next())
347 TopoDS_Shape E = EdExp.Current();
348 TopTools_ListOfShape VList;
349 TopoDS_Iterator VerExp( E );
350 for (; VerExp.More(); VerExp.Next())
351 VList.Append( VerExp.Value() );
352 TopTools_ListIteratorOfListOfShape itlv( VList );
353 for (; itlv.More(); itlv.Next())
355 const TopoDS_Shape& V = itlv.Value();
356 if (myVerVerMap.IsBound( V ))
358 TopoDS_Shape NewV = myVerVerMap( V );
359 E.Free( Standard_True );
360 NewV.Orientation( V.Orientation() );
361 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
362 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
363 if (TV->Tolerance() > NewTV->Tolerance())
364 NewTV->Tolerance( TV->Tolerance() );
365 NewTV->ChangePoints().Append( TV->ChangePoints() );
366 AsDes->Replace( V, NewV );
377 //=======================================================================
378 //function : BuildFaces
380 //=======================================================================
382 void BRepOffset_MakeLoops::BuildFaces(const TopTools_ListOfShape& LF,
383 const Handle(BRepAlgo_AsDes)& AsDes,
384 BRepAlgo_Image& Image)
386 TopTools_ListIteratorOfListOfShape itr,itl,itLCE;
387 Standard_Boolean ToRebuild;
389 Loops.VerticesForSubstitute( myVerVerMap );
392 //----------------------------------
393 // Loop on all faces //.
394 //----------------------------------
395 for (itr.Initialize(LF); itr.More(); itr.Next()) {
396 TopoDS_Face F = TopoDS::Face(itr.Value());
398 ToRebuild = Standard_False;
399 TopTools_ListOfShape AddedEdges;
401 if (!Image.HasImage(F)) {
402 //----------------------------------
403 // Face F not yet reconstructed.
404 //----------------------------------
405 const TopTools_ListOfShape& LE = AsDes->Descendant(F);
406 //----------------------------------------------------------------
407 // first loop to find if the edges of the face were reconstructed.
408 // - maj on map MONV. Some vertices on reconstructed edges
409 // coincide geometrically with old but are not IsSame.
410 //----------------------------------------------------------------
411 TopTools_DataMapOfShapeShape MONV;
412 TopoDS_Vertex OV1,OV2,NV1,NV2;
414 for (itl.Initialize(LE); itl.More(); itl.Next()) {
415 TopoDS_Edge E = TopoDS::Edge(itl.Value());
416 if (Image.HasImage(E)) {
417 const TopTools_ListOfShape& LCE = Image.Image(E);
418 if (LCE.Extent() == 1 && LCE.First().IsSame(E)) {
419 TopoDS_Shape aLocalShape = LCE.First().Oriented(E.Orientation());
420 TopoDS_Edge CE = TopoDS::Edge(aLocalShape);
421 // TopoDS_Edge CE = TopoDS::Edge(LCE.First().Oriented(E.Orientation()));
422 Loops.AddConstEdge(CE);
425 //----------------------------------
426 // F should be reconstructed.
427 //----------------------------------
428 ToRebuild = Standard_True;
429 for (itLCE.Initialize(LCE); itLCE.More(); itLCE.Next()) {
430 TopoDS_Shape aLocalShape = itLCE.Value().Oriented(E.Orientation());
431 TopoDS_Edge CE = TopoDS::Edge(aLocalShape);
432 // TopoDS_Edge CE = TopoDS::Edge(itLCE.Value().Oriented(E.Orientation()));
433 TopExp::Vertices (E ,OV1,OV2);
434 TopExp::Vertices (CE,NV1,NV2);
435 if (!OV1.IsSame(NV1)) MONV.Bind(OV1,NV1);
436 if (!OV2.IsSame(NV2)) MONV.Bind(OV2,NV2);
437 Loops.AddConstEdge(CE);
445 sprintf(name,"CF_%d",NbF++);
450 //-----------------------------------------------------------
451 // Non-reconstructed edges on other faces are added.
452 // If their vertices were reconstructed they are reconstructed.
453 //-----------------------------------------------------------
454 for (itl.Initialize(LE); itl.More(); itl.Next()) {
456 TopoDS_Edge E = TopoDS::Edge(itl.Value());
457 BRep_Tool::Range(E,f,l);
458 if (!Image.HasImage(E)) {
459 TopExp::Vertices (E,OV1,OV2);
460 TopTools_ListOfShape LV;
461 if (MONV.IsBound(OV1)) {
462 TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV1));
463 VV.Orientation(TopAbs_FORWARD);
465 TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
466 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
467 f,E,BRep_Tool::Tolerance(VV));
469 if (MONV.IsBound(OV2)) {
470 TopoDS_Vertex VV = TopoDS::Vertex(MONV(OV2));
471 VV.Orientation(TopAbs_REVERSED);
473 TopoDS_Shape aLocalShape = VV.Oriented(TopAbs_INTERNAL);
474 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
475 l,E,BRep_Tool::Tolerance(VV));
476 // B.UpdateVertex(TopoDS::Vertex(VV.Oriented(TopAbs_INTERNAL)),
477 // l,E,BRep_Tool::Tolerance(VV));
479 if (LV.IsEmpty()) Loops.AddConstEdge(E);
481 Loops.AddEdge (E,LV);
482 AddedEdges.Append(E);
489 //------------------------
491 //------------------------
493 Loops.WiresToFaces();
494 //------------------------
496 //------------------------
497 const TopTools_ListOfShape& NF = Loops.NewFaces();
498 //-----------------------
500 //-----------------------
503 TopTools_ListIteratorOfListOfShape itAdded;
504 for (itAdded.Initialize(AddedEdges); itAdded.More(); itAdded.Next()) {
505 const TopoDS_Edge& E = TopoDS::Edge(itAdded.Value());
506 //-----------------------
508 //-----------------------
509 if (Image.HasImage(E)) {
510 Image.Add(E,Loops.NewEdges(E));
513 Image.Bind(E,Loops.NewEdges(E));
518 Loops.GetVerticesForSubstitute( myVerVerMap );
519 if (myVerVerMap.IsEmpty())
522 for (itr.Initialize( LF ); itr.More(); itr.Next())
524 TopoDS_Shape F = itr.Value();
525 TopTools_ListOfShape LIF;
526 Image.LastImage( F, LIF );
527 for (itl.Initialize(LIF); itl.More(); itl.Next())
529 const TopoDS_Shape& IF = itl.Value();
530 TopExp_Explorer EdExp( IF, TopAbs_EDGE );
531 for (; EdExp.More(); EdExp.Next())
533 TopoDS_Shape E = EdExp.Current();
534 TopTools_ListOfShape VList;
535 TopoDS_Iterator VerExp( E );
536 for (; VerExp.More(); VerExp.Next())
537 VList.Append( VerExp.Value() );
538 TopTools_ListIteratorOfListOfShape itlv( VList );
539 for (; itlv.More(); itlv.Next())
541 const TopoDS_Shape& V = itlv.Value();
542 if (myVerVerMap.IsBound( V ))
544 TopoDS_Shape NewV = myVerVerMap( V );
545 E.Free( Standard_True );
546 NewV.Orientation( V.Orientation() );
547 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &V.TShape());
548 Handle(BRep_TVertex)& NewTV = *((Handle(BRep_TVertex)*) &NewV.TShape());
549 if (TV->Tolerance() > NewTV->Tolerance())
550 NewTV->Tolerance( TV->Tolerance() );
551 NewTV->ChangePoints().Append( TV->ChangePoints() );
552 AsDes->Replace( V, NewV );