0028643: Coding rules - eliminate GCC compiler warnings -Wmisleading-indentation
[occt.git] / src / BRepTools / BRepTools_Quilt.cxx
CommitLineData
b311480e 1// Created on: 1994-12-23
2// Created by: Remi LEQUETTE
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_Builder.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepTools_Quilt.hxx>
21#include <Geom2d_Curve.hxx>
22#include <Standard_NoSuchObject.hxx>
23#include <TopExp_Explorer.hxx>
7fd59977 24#include <TopoDS.hxx>
42cf5bc1 25#include <TopoDS_Compound.hxx>
26#include <TopoDS_Edge.hxx>
7fd59977 27#include <TopoDS_Face.hxx>
42cf5bc1 28#include <TopoDS_Iterator.hxx>
7fd59977 29#include <TopoDS_Shape.hxx>
30#include <TopoDS_Shell.hxx>
42cf5bc1 31#include <TopoDS_Vertex.hxx>
32#include <TopoDS_Wire.hxx>
7fd59977 33#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
34#include <TopTools_DataMapOfShapeShape.hxx>
7fd59977 35#include <TopTools_IndexedDataMapOfShapeShape.hxx>
42cf5bc1 36#include <TopTools_ListOfShape.hxx>
37#include <TopTools_MapIteratorOfMapOfShape.hxx>
38#include <TopTools_MapOfShape.hxx>
7fd59977 39
40//=======================================================================
41//function : BRepTools_Quilt
42//purpose :
43//=======================================================================
7fd59977 44BRepTools_Quilt::BRepTools_Quilt() : hasCopy(Standard_False)
45{
46}
47
48//=======================================================================
49//function : Add
50//purpose :
51//=======================================================================
52static Standard_Boolean NeedCopied(const TopoDS_Shape& theShape,const TopTools_IndexedDataMapOfShapeShape& myBounds)
53{
54 // test if the shape must be copied
55 // i.e. it contains a bound subshape
56 Standard_Boolean IsCopied = Standard_False;
57 TopoDS_Iterator itv(theShape) ;
58 for ( ; itv.More(); itv.Next()) {
59 if (myBounds.Contains(itv.Value())) {
60 IsCopied = Standard_True;
61 break;
62 }
63 }
64 return IsCopied;
65}
66static void CopyShape(const TopoDS_Edge& E,TopTools_IndexedDataMapOfShapeShape& myBounds)
67{
68 TopoDS_Edge NE = E;
69 NE.EmptyCopy();
70 NE.Orientation(TopAbs_FORWARD);
71 BRep_Builder B;
72 // add the edges
73 TopoDS_Iterator itv;
74 itv.Initialize(E,Standard_False) ; //TCollection_DataMap
75 for ( ; itv.More(); itv.Next()) {
76 const TopoDS_Shape& V = itv.Value();
77 if (myBounds.Contains(V)) {
78 B.Add(NE,myBounds.FindFromKey(V).Oriented(V.Orientation()));
79 }
80 else {
81 B.Add(NE,V);
82 }
83 }
84 // set the 3d range
85 Standard_Real f,l;
86 BRep_Tool::Range(E,f,l);
87 B.Range(NE,f,l);
88 myBounds.Add(E,NE.Oriented(TopAbs_FORWARD));
89}
90/*static void CopyShape(const TopoDS_Wire& W,TopTools_DataMapOfShapeShape& myBounds)
91{
92 TopoDS_Wire NW;
93 B.MakeWire(NW);
94 TopoDS_Iterator ite(W,Standard_False);
95 for ( ; ite.More(); ite.Next()){
96 const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
97 TopAbs_Orientation OE = E.Orientation();
98 if (myBounds.IsBound(E)) {
99 TopoDS_Edge& NE = TopoDS::Edge(myBounds(E));
100 B.Add(NW,NE.Oriented(OE));
101 }
102 else
103 B.Add(NW,E);
104 }
105 NW.Orientation(W.Orientation());
106 myBounds.Bind(W,NW);
107}*/
108void BRepTools_Quilt::Add(const TopoDS_Shape& S)
109{
110 //cout <<" Version of sewing with free edges"<<endl;
111 // Binds all the faces of S
112 // - to the face itself if it is not copied
113 // - to the copy if it is copied
c48e2889 114 if(myBounds.Contains(S))
115 {
116 return;
117 }
118
7fd59977 119 BRep_Builder B;
c48e2889 120 for (TopExp_Explorer wex(S,TopAbs_WIRE,TopAbs_FACE); wex.More(); wex.Next())
121 {
122 myBounds.Add(wex.Current(),wex.Current());
123 }
124
7fd59977 125 for (TopExp_Explorer eex(S,TopAbs_EDGE,TopAbs_WIRE); eex.More(); eex.Next())
c48e2889 126 {
7fd59977 127 myBounds.Add(eex.Current(),eex.Current());
c48e2889 128 }
129
7fd59977 130 for (TopExp_Explorer vex(S,TopAbs_VERTEX,TopAbs_EDGE); vex.More(); vex.Next())
c48e2889 131 {
7fd59977 132 myBounds.Add(vex.Current(),vex.Current());
c48e2889 133 }
134
7fd59977 135 // explore the faces
136 for (TopExp_Explorer fex(S,TopAbs_FACE); fex.More(); fex.Next()) {
137
138 // explore the edges of the face and try to copy them
139 // if one edge is bound the face must be copied
140
141 Standard_Boolean copyFace = Standard_False;
142 const TopoDS_Face& F = TopoDS::Face(fex.Current());
143
144 if (hasCopy) { // if their is no binding, do not test for copy
145
146 for (TopExp_Explorer fed(F,TopAbs_EDGE); fed.More(); fed.Next()) {
147
148 if (myBounds.Contains(fed.Current())) {
149 copyFace = Standard_True;
150 }
151 else {
152 // test if the edge must be copied
153 // i.e. it contains a bound vertex
154
155 Standard_Boolean copyEdge = NeedCopied(fed.Current(),myBounds);
156 //Standard_Boolean copyEdge = Standard_False;
157 const TopoDS_Edge& E = TopoDS::Edge(fed.Current());
158
159 // TopoDS_Iterator itv(E) ;
160 // for ( ; itv.More(); itv.Next()) {
161 // if (myBounds.IsBound(itv.Value())) {
162 // copyEdge = Standard_True;
163 // break;
164 // }
165 // }
166
167 if (copyEdge) {
168
169 // copy of an edge
170
171 copyFace = Standard_True;
172 CopyShape(E,myBounds);
173 //TopoDS_Edge NE = E; //gka version for free edges
174 //NE.EmptyCopy();
175
176 //NE.Orientation(TopAbs_FORWARD);
177 // add the edges
178 //itv.Initialize(E,Standard_False) ;
179 //for ( ; itv.More(); itv.Next()) {
180 //const TopoDS_Shape& V = itv.Value();
181 //if (myBounds.IsBound(V)) {
182 // B.Add(NE,myBounds(V).Oriented(V.Orientation()));
183 //}
184 //else {
185 // B.Add(NE,V);
186 //}
187 //}
188 // set the 3d range
189 //Standard_Real f,l;
190 //BRep_Tool::Range(E,f,l);
191 //B.Range(NE,f,l);
192
193 //myBounds.Bind(E,NE.Oriented(TopAbs_FORWARD));
194 }
195 }
196 }
197 }
198
199 // NF will be the copy of F or F itself
200 TopoDS_Face NF = F;
201
202 if (copyFace) {
203
204 // copy of a face
205
206 NF.EmptyCopy();
207 NF.Orientation(TopAbs_FORWARD);
208
209 for (TopoDS_Iterator itw(F,Standard_False); itw.More(); itw.Next()) {
210 const TopoDS_Wire& W = TopoDS::Wire(itw.Value());
211
212 TopoDS_Wire NW;
213 B.MakeWire(NW);
214 TopoDS_Iterator ite(W,Standard_False);
7fd59977 215 Standard_Real UFirst,ULast;
216
217 // Reconstruction des wires.
218
219 for ( ; ite.More(); ite.Next()){
220 const TopoDS_Edge& E = TopoDS::Edge(ite.Value());
221 TopAbs_Orientation OE = E.Orientation();
222 if (myBounds.Contains(E)) {
223 const TopoDS_Edge& NE = TopoDS::Edge(myBounds.FindFromKey(E));
224 // pcurve.
225 if (NE.Orientation() == TopAbs_FORWARD) {
226 B.UpdateEdge(NE,
227 BRep_Tool::CurveOnSurface(E,F,UFirst,ULast),
228 F,BRep_Tool::Tolerance(E));
229 }
230 else {
231 // Si NE est REVERSED
232 // => les curve3d n ont pas la meme orientation.
233 // ( C est une convention cf BRepTools_Quilt.cdl. et la methode
234 // Bind.)
235 // => la PCurve de E sur F doit etre inversee.
236
237 OE = TopAbs::Reverse(OE);
238 Handle(Geom2d_Curve) CE =
239 BRep_Tool::CurveOnSurface(E,F,UFirst,ULast);
240 Handle(Geom2d_Curve) NCE = CE->Reversed();
241 B.UpdateEdge(NE,NCE,F,BRep_Tool::Tolerance(E));
242 Standard_Real tmp = UFirst;
243 UFirst = CE->ReversedParameter(ULast);
244 ULast = CE->ReversedParameter(tmp);
245 }
246 // pcurve range
247 B.Range(NE,F,UFirst,ULast);
248
249 B.Add(NW,NE.Oriented(OE));
250 }
251 else {
252 B.Add(NW,E);
253 }
254 }
255 NW.Orientation(W.Orientation());
256 B.Add(NF,NW);
257 }
258 NF.Orientation(F.Orientation());
259 }
260
261 // binds the face to itself or its copy
262 myBounds.Add(F,NF);
263 }
264
265}
266
267//=======================================================================
268//function : Bind
269//purpose :
270//=======================================================================
271
272void BRepTools_Quilt::Bind(const TopoDS_Vertex& Vold,
273 const TopoDS_Vertex& Vnew)
274{
275 if (!myBounds.Contains(Vold)) {
276 myBounds.Add(Vold,Vnew);
277 }
278}
279
280//=======================================================================
281//function : Bind
282//purpose :
283//=======================================================================
284
285void BRepTools_Quilt::Bind(const TopoDS_Edge& Eold, const TopoDS_Edge& Enew)
286{
287 if (!myBounds.Contains(Eold)) {
288 TopoDS_Edge ENew = Enew;
289 if (IsCopied(Enew)) {
290 ENew = TopoDS::Edge(Copy(Enew));
291 ENew.Orientation(Enew.Orientation());
292 }
293
294 if (Eold.Orientation() != ENew.Orientation()) {
295 myBounds.Add(Eold.Oriented(TopAbs_FORWARD),
296 ENew.Oriented(TopAbs_REVERSED));
297 }
298 else {
299 myBounds.Add(Eold.Oriented(TopAbs_FORWARD),
300 ENew.Oriented(TopAbs_FORWARD));
301 }
302 // if new binding bind also the vertices
303 TopoDS_Iterator itold(Eold);
304 while (itold.More()) {
305 if (!myBounds.Contains(itold.Value())) {
306 // find the vertex of Enew with same orientation
307 TopAbs_Orientation anOrien = itold.Value().Orientation();
308 TopoDS_Iterator itnew(ENew);
309 while (itnew.More()) {
310 if (itnew.Value().Orientation() == anOrien) {
311 TopoDS_Vertex VNew = TopoDS::Vertex(itnew.Value());
312 if (IsCopied(VNew)) {
313 // if VNew has been copied take the copy
314 VNew = TopoDS::Vertex(Copy(VNew));
315 }
316 myBounds.Add(itold.Value(),VNew);
317 break;
318 }
319 itnew.Next();
320 }
321 }
322 itold.Next();
323 }
324 hasCopy = Standard_True;
325 }
326}
327
328//=======================================================================
329//function : IsBound
330//purpose :
331//=======================================================================
332
333Standard_Boolean BRepTools_Quilt::IsCopied(const TopoDS_Shape& S) const
334{
335 if (myBounds.Contains(S)) {
336 return !S.IsSame(myBounds.FindFromKey(S));
337 }
338 else
339 return Standard_False;
340}
341
342//=======================================================================
343//function : Copy
344//purpose :
345//=======================================================================
346
347const TopoDS_Shape& BRepTools_Quilt::Copy(const TopoDS_Shape& S) const
348{
349 Standard_NoSuchObject_Raise_if(!IsCopied(S),"BRepTools_Quilt::Copy");
350 return myBounds.FindFromKey(S);
351}
352
353//=======================================================================
354//function : Shells
355//purpose :
356//=======================================================================
357
358TopoDS_Shape BRepTools_Quilt::Shells() const
359{
360 // Outline of the algorithm
361 //
362 // In the map M we bind the free edges to their shells
363 // We explore all the faces in myBounds
364 // For each one we search the edges in the map and either :
365 //
366 // - Start a new shell if no edge is a free edge.
367 // - Add the face to an existing shell
368 // - Connect other shells if the face touch more than one shell
369
370 // In the Map M the Shell is bound withe the relative orientation of E
371 // in the shell
372 // In the map MF we binb the face to its shell.
373 // In the Map MF the Shell is bound with the relative orientation of F
374 // in the shell
375
376 TopTools_DataMapOfShapeShape M, MF;
377 BRep_Builder B;
378 TopoDS_Compound result;
379
380 B.MakeCompound(result);
381
382 TopTools_MapOfShape MapOtherShape; //gka
383 TopTools_MapOfShape EdgesFaces;
384
385 // loop on the face in myBounds
386 //TopTools_DataMapIteratorOfDataMapOfShapeShape it(myBounds);
387
388 //while (it.More())
389 for(Standard_Integer ii =1; ii <= myBounds.Extent(); ii++) {
390 const TopoDS_Shape& Shape = myBounds.FindFromIndex(ii); //it.Value();
391 if (Shape.ShapeType() == TopAbs_FACE) {
392 for(TopExp_Explorer aExpEdg(Shape,TopAbs_EDGE); aExpEdg.More(); aExpEdg.Next()) //gka
393 EdgesFaces.Add(aExpEdg.Current());
394
395 TopoDS_Shell SH;
396 TopAbs_Orientation NewO;
397
398 TopExp_Explorer itf1( Shape,TopAbs_EDGE);
399 for ( ; itf1.More(); itf1.Next()) {
400 const TopoDS_Shape& E = itf1.Current();
401 if (M.IsBound(E)) {
402 SH = TopoDS::Shell(M(E));
403 if (SH.Orientation() == E.Orientation())
404 NewO = TopAbs::Reverse(Shape.Orientation());
405 else
406 NewO = Shape.Orientation();
407
408 MF.Bind (Shape,SH.Oriented(NewO));
409 break;
410 }
411 }
412
413 if (SH.IsNull()) {
414 // Create a new shell, closed. Add it to the result.
415 B.MakeShell(SH);
416 SH.Closed(Standard_True);
417 B.Add(result,SH);
418 MF.Bind (Shape,SH.Oriented(Shape.Orientation()));
419 }
420
421
422 // Add the face to the shell
423 SH.Free(Standard_True);
424// B.Add(SH.Oriented(TopAbs_FORWARD), F .Oriented(MF(F).Orientation()));
425 TopoDS_Shape arefShape = SH.Oriented(TopAbs_FORWARD) ;
426 B.Add( arefShape , Shape.Oriented(MF(Shape).Orientation()));
427
428 TopExp_Explorer itf(Shape.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
429
430 for ( ;itf.More(); itf.Next()) {
431 const TopoDS_Edge& E = TopoDS::Edge(itf.Current());
432
433 if (M.IsBound(E)) {
434 const TopoDS_Shape oldShell = M(E);
435 if (!oldShell.IsSame(SH)) {
436 // Fuse the old shell with the new one
437 // Compare the orientation of E in SH and in oldshell.
438 TopAbs_Orientation anOrien = E.Orientation();
439 if (MF(Shape).Orientation() == TopAbs_REVERSED)
440 anOrien = TopAbs::Reverse(anOrien);
441
442 Standard_Boolean Rev = (anOrien == oldShell.Orientation());
443 //if rev = True oldShell has to be reversed.
444
445 // Add the faces of oldShell in SH.
446 for (TopoDS_Iterator its(oldShell); its.More(); its.Next()) {
447 const TopoDS_Face Fo = TopoDS::Face(its.Value());
51740958 448 TopAbs_Orientation NewOFo;
7fd59977 449 // update the orientation of Fo in SH.
450 if (Rev)
51740958 451 NewOFo = TopAbs::Reverse(MF(Fo).Orientation());
7fd59977 452 else
51740958 453 NewOFo = MF(Fo).Orientation();
7fd59977 454
51740958 455 MF.Bind(Fo,SH.Oriented(NewOFo));
7fd59977 456// B.Add (SH.Oriented(TopAbs_FORWARD),Fo.Oriented(NewO));
51740958 457 TopoDS_Shape arefShapeFo = SH.Oriented(TopAbs_FORWARD) ;
458 B.Add ( arefShapeFo,Fo.Oriented(NewOFo));
7fd59977 459 }
7fd59977 460 // Rebind the free edges of the old shell to the new shell
461 //gka BUG 6491
462 TopExp_Explorer aexp(SH,TopAbs_EDGE);
463 for( ; aexp.More(); aexp.Next()) {
464 //for (TopTools_DataMapIteratorOfDataMapOfShapeShape itm(M);
465// itm.More(); ) {
466 if(!M.IsBound(aexp.Current()))
467 continue;
468 TopoDS_Shape ae = aexp.Current();
469 TopoDS_Shape as = M.Find(ae);
470 if (as.IsSame(oldShell)) {
471 // update the orientation of free edges in SH.
472 if (Rev)
473 NewO = TopAbs::Reverse(as.Orientation());
474 else
475 NewO = as.Orientation();
476
477 M.Bind(ae,SH.Oriented(NewO));
478 }
479 }
480 // remove the old shell from the result
481 B.Remove(result,oldShell.Oriented(TopAbs_FORWARD));
482 }
483 // Test if SH is always orientable.
484 TopAbs_Orientation anOrien = E.Orientation();
485 if (MF(Shape).Orientation() == TopAbs_REVERSED)
486 anOrien = TopAbs::Reverse(anOrien);
487
488 if (M(E).Orientation() == anOrien)
489 SH.Orientable(Standard_False);
490
491 // remove the edge from M (no more a free edge)
492 M.UnBind(E);
493 }
494 else {
495 NewO = E.Orientation();
496 if (MF(Shape).Orientation() == TopAbs_REVERSED)
497 NewO = TopAbs::Reverse(NewO);
498 if(!E.IsNull())
499 M.Bind(E,SH.Oriented(NewO));
500 else
501 continue;
502 }
503 }
504
505 // freeze the shell
506 SH.Free(Standard_False);
507 }
508 else
509 MapOtherShape.Add(Shape);
510
511 //it.Next();
512 }
513
514 // Unclose all shells having free edges
515 for (TopTools_DataMapIteratorOfDataMapOfShapeShape it(M); it.More(); it.Next()) {
516 TopoDS_Shape S = it.Value();
dde68833 517 S.Closed (Standard_False);
7fd59977 518 }
519
520 TopTools_MapIteratorOfMapOfShape itother(MapOtherShape); //gka version for free edges
521 for( ; itother.More() ; itother.Next()) {
522 if(!EdgesFaces.Contains(itother.Key()) && myBounds.Contains(itother.Key())) {
523 TopoDS_Shape aSh = myBounds.FindFromKey(itother.Key());
524 B.Add(result,aSh);
525 }
526 }
527 return result;
528}
529