0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / ShapeFix / ShapeFix_FaceConnect.cxx
CommitLineData
b311480e 1// Created on: 1999-06-18
2// Created by: Sergei ZERTCHANINOV
3// Copyright (c) 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 <BRepBuilderAPI_Sewing.hxx>
21#include <Geom2d_Curve.hxx>
22#include <gp_Pnt.hxx>
23#include <ShapeAnalysis_Edge.hxx>
24#include <ShapeAnalysis_WireOrder.hxx>
25#include <ShapeBuild_ReShape.hxx>
26#include <ShapeFix_Face.hxx>
27#include <ShapeFix_FaceConnect.hxx>
28#include <ShapeFix_Wire.hxx>
7fd59977 29#include <Standard_ErrorHandler.hxx>
30#include <Standard_Failure.hxx>
42cf5bc1 31#include <TopExp.hxx>
32#include <TopExp_Explorer.hxx>
7fd59977 33#include <TopoDS.hxx>
7fd59977 34#include <TopoDS_Edge.hxx>
42cf5bc1 35#include <TopoDS_Face.hxx>
7fd59977 36#include <TopoDS_Iterator.hxx>
42cf5bc1 37#include <TopoDS_Shell.hxx>
38#include <TopoDS_Vertex.hxx>
39#include <TopoDS_Wire.hxx>
7fd59977 40#include <TopTools_Array1OfShape.hxx>
7fd59977 41#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
42cf5bc1 42#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
43#include <TopTools_ListIteratorOfListOfShape.hxx>
44#include <TopTools_ListOfShape.hxx>
7fd59977 45
0797d9d3 46#ifdef OCCT_DEBUG
7fd59977 47#include <TopTools_MapOfShape.hxx>
48#endif
49
50//=======================================================================
51//function : ShapeFix_FaceConnect
52//=======================================================================
53
54ShapeFix_FaceConnect::ShapeFix_FaceConnect() {}
55
56//=======================================================================
57//function : Connect
58//purpose :
59//=======================================================================
60
61 Standard_Boolean ShapeFix_FaceConnect::Add(const TopoDS_Face& aFirst,
62 const TopoDS_Face& aSecond)
63{
64 if (!aFirst.IsNull() && !aSecond.IsNull()) {
65 // Process first face
66 if (myConnected.IsBound(aFirst)) {
67 // Find list for the first face
68 TopTools_ListOfShape& theFirstList = myConnected(aFirst);
69 // Append second face to the first list
70 TopTools_ListIteratorOfListOfShape theIter;
71 for ( theIter.Initialize(theFirstList); theIter.More(); theIter.Next() )
72 if (theIter.Value().IsSame(aSecond)) return Standard_True;
73 theFirstList.Append(aSecond);
74 }
75 else {
76 // Append second face to the first list
77 TopTools_ListOfShape theNewFirstList;
78 theNewFirstList.Append(aSecond);
79 myConnected.Bind(aFirst,theNewFirstList);
80 }
81
82 // Process second face if not same
83 if (!aFirst.IsSame(aSecond)) {
84 if (myConnected.IsBound(aSecond)) {
85 // No need to iterate on faces - append first
86 myConnected(aSecond).Append(aFirst);
87 }
88 else {
89 // Append first face to the second list
90 TopTools_ListOfShape theNewSecondList;
91 theNewSecondList.Append(aFirst);
92 myConnected.Bind(aSecond,theNewSecondList);
93 }
94 }
95
96 return Standard_True;
97 }
98
99 return Standard_False;
100}
101
102//=======================================================================
103//function : Build
104//purpose :
105//=======================================================================
106
107 TopoDS_Shell ShapeFix_FaceConnect::Build (const TopoDS_Shell& shell,
108 const Standard_Real sewtoler,
109 const Standard_Real fixtoler)
110{
111 TopoDS_Shell result = shell;
112
113 /***************************************************************
114 / INITIAL PREPARATIONS
115 / Fill map of original free edges,
116 / fill maps of resulting free and shared edges
117 ***************************************************************/
118
119 // Clear maps of free and shared edges
120 myOriFreeEdges.Clear();
121 myResFreeEdges.Clear();
122 myResSharEdges.Clear();
123
124 TopTools_DataMapOfShapeShape theFreeEdges;
125 TopoDS_Shape theEdge, theFace;
126
127 // Fill map of free edges / faces
128 for ( TopoDS_Iterator itf(result); itf.More(); itf.Next() ) {
129 theFace = itf.Value();
130 for ( TopExp_Explorer expe(theFace,TopAbs_EDGE); expe.More(); expe.Next() ) {
131 theEdge = expe.Current();
132 if (theFreeEdges.IsBound(theEdge)) theFreeEdges.UnBind(theEdge);
133 else theFreeEdges.Bind(theEdge,theFace);
134 }
135 }
136
137 // Fill maps of original and resulting edges
138 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theFEIter( theFreeEdges );
139 theFEIter.More(); theFEIter.Next() ) {
140 // Get pair (face / free edge)
141 theEdge = theFEIter.Key(), theFace = theFEIter.Value();
142 // Process faces with bad connectivities only
143 if (myConnected.IsBound(theFace) &&
144 !BRep_Tool::Degenerated(TopoDS::Edge(theEdge))) {
145 // Add to the map of original free edges
146 if (myOriFreeEdges.IsBound(theFace)) {
147 // Append free edge to the existing list
148 myOriFreeEdges(theFace).Append(theEdge);
149 }
150 else {
151 // Append free edge to the new list
152 TopTools_ListOfShape theNewList;
153 theNewList.Append(theEdge);
154 myOriFreeEdges.Bind(theFace,theNewList);
155 }
156 // Add to the maps of intermediate free and resulting edges
157 if (!myResFreeEdges.IsBound(theEdge)) {
158 TopTools_ListOfShape theFree, theShared;
159 theFree.Append(theEdge);
160 myResFreeEdges.Bind(theEdge,theFree);
161 myResSharEdges.Bind(theEdge,theShared);
162 }
163 }
164 }
165
166 // Clear the temporary map of free edges
167 theFreeEdges.Clear();
168
0797d9d3 169#ifdef OCCT_DEBUG
7fd59977 170 //-------------------------------
171 //szv debug - preparation results
172 //-------------------------------
173 if (!myOriFreeEdges.IsEmpty()) {
174 cout<<endl<<"FACE CONNECT PREPARATION RESULTS:"<<endl;
175 cout<<"---------------------------------"<<endl;
176 Standard_Integer freenum = 0, facenum = 0;
177 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOFIter( myOriFreeEdges );
178 theOFIter.More(); theOFIter.Next() ) {
179 freenum += theOFIter.Value().Extent();
180 facenum++;
181 }
182 cout<<"TOTAL: "<<facenum<<" faces containing "<<freenum<<" free edges"<<endl;
183 }
184 //-------------------------------
185#endif
186
187 /***************************************************************
188 / APPLY SEWING ON CONNECTED FACES
189 / Change maps of original free edges and resulting shared edges
190 ***************************************************************/
191
192 if (!myOriFreeEdges.IsEmpty()) {
193
194 // Allocate array of faces to be sewed
195 TopoDS_Shape theFirstFace, theSecondFace;
196 TopTools_Array1OfShape theFacesToSew(1,2);
197 Standard_Integer theNumOfFacesToSew = 0;
198 Standard_Boolean skip_pair = Standard_False;
199
200 TopTools_ListIteratorOfListOfShape theOriginalIter, theResultsIter;
201 TopoDS_Shape theAuxE, theOrigE, theAuxF;
202
203 BRep_Builder theBuilder;
204
205 TopTools_DataMapOfShapeListOfShape theProcessed;
206
207 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theConnectedIter( myConnected );
208 theConnectedIter.More(); theConnectedIter.Next() ) {
209 // Process first face only if it is in the map of faces / free edges
210 theFirstFace = theConnectedIter.Key();
211 if (myOriFreeEdges.IsBound(theFirstFace)) {
212
213 // Place first face into the array
214 theFacesToSew.SetValue(1,theFirstFace);
215 theNumOfFacesToSew = 1;
216 // Create the list of processed faces
217 TopTools_ListOfShape theProcessedList;
218
219 // Explore the list of connected faces
220 const TopTools_ListOfShape& theConnectedList = theConnectedIter.Value();
221 TopTools_ListIteratorOfListOfShape theConnectedListIter;
222 for ( theConnectedListIter.Initialize(theConnectedList);
223 theConnectedListIter.More(); theConnectedListIter.Next() ) {
224 // Process second face only if it is in the map of faces / free edges
225 theSecondFace = theConnectedListIter.Value();
226 if (myOriFreeEdges.IsBound(theSecondFace)) {
227
228 // Place second face into the array
229 theFacesToSew.SetValue(2,theSecondFace);
230 // Add second face to the list of processed faces
231 theProcessedList.Append(theSecondFace);
232
233 // Skip the pair if already processed
234 skip_pair = Standard_False;
235 if (theProcessed.IsBound(theSecondFace)) {
236 TopTools_ListOfShape& theProcCnxList = theProcessed(theSecondFace);
237 TopTools_ListIteratorOfListOfShape theProcCnxListIter;
238 for ( theProcCnxListIter.Initialize(theProcCnxList);
239 theProcCnxListIter.More() && !skip_pair; theProcCnxListIter.Next() )
240 if (theFirstFace.IsSame(theProcCnxListIter.Value()))
241 skip_pair = Standard_True;
242 }
243 if (!skip_pair) {
244
245 // Process second face for the pair of different faces only
246 if (theFirstFace.IsSame(theSecondFace)) {
0797d9d3 247#ifdef OCCT_DEBUG
7fd59977 248 cout<<"Warning: ShapeFix_FaceConnect::Build: Self-connected face"<<endl;
249#endif
250 }
251 else theNumOfFacesToSew = 2;
252
253 TopTools_DataMapOfShapeShape theSewerWires;
254 BRepBuilderAPI_Sewing theSewer(sewtoler);
255
256 // Prepare set of faces containing free edges
257 Standard_Integer i = 1;
258 for (i=1; i<=theNumOfFacesToSew; i++) {
259 // Prepare empty face to fill with free edges
260 TopoDS_Shape theFaceToSew = theFacesToSew(i);
261 theAuxF = theFaceToSew.EmptyCopied();
262 // Fill empty face with free edges
263 for ( theOriginalIter.Initialize(myOriFreeEdges(theFaceToSew));
264 theOriginalIter.More(); theOriginalIter.Next() ) {
265 for ( theResultsIter.Initialize(myResFreeEdges(theOriginalIter.Value()));
266 theResultsIter.More(); theResultsIter.Next() ) {
267 // Bind free edge to wire to find results later
268 theAuxE = theResultsIter.Value();
269 TopoDS_Wire theAuxW;
270 theBuilder.MakeWire(theAuxW);
271 theBuilder.Add(theAuxW,theAuxE);
272 theBuilder.Add(theAuxF,theAuxW);
273 theSewerWires.Bind(theAuxE,theAuxW);
274 theSewer.Add(theAuxW);
275 }
276 }
277 // Add constructed face to sewer
278 theSewer.Add(theAuxF);
279 }
280
281 // Perform sewing on the list of free edges
282 Standard_Boolean sewing_ok = Standard_True;
283 {
284 try { OCC_CATCH_SIGNALS theSewer.Perform(); }
a738b534 285 catch(Standard_Failure const&) { sewing_ok = Standard_False; }
7fd59977 286 }
287 if ( sewing_ok )
288 if (theSewer.SewedShape().IsNull()) sewing_ok = Standard_False;
289
290 if ( sewing_ok ) {
291 TopTools_DataMapOfShapeShape theResultEdges;
292
293 // Find modified edges for the faces
294 for (i=1; i<=theNumOfFacesToSew; i++) {
295 for ( theOriginalIter.Initialize(myOriFreeEdges(theFacesToSew(i)));
296 theOriginalIter.More(); theOriginalIter.Next() ) {
297 // Get original free edge
298 theOrigE = theOriginalIter.Value();
299 TopTools_ListOfShape& theOldFreeList = myResFreeEdges(theOrigE);
300 theResultsIter.Initialize(theOldFreeList);
301 while ( theResultsIter.More() ) {
302 theAuxE = theSewerWires(theResultsIter.Value());
303 // Process modified edges
304 if (theSewer.IsModified(theAuxE)) {
305 // Fill map of result edges
306 for ( TopExp_Explorer expe(theSewer.Modified(theAuxE),TopAbs_EDGE);
307 expe.More(); expe.Next() ) {
308 theAuxE = expe.Current();
309 // Check edge for being shared
310 if (theResultEdges.IsBound(theAuxE)) {
311 // Edge was shared - move in results list
312 myResSharEdges(theResultEdges(theAuxE)).Append(theAuxE);
313 myResSharEdges(theOrigE).Append(theAuxE);
314 theResultEdges.UnBind(theAuxE);
315 }
316 else theResultEdges.Bind(theAuxE,theOrigE);
317 }
318 // Remove modified free edge from the list
319 theOldFreeList.Remove(theResultsIter);
320 }
321 else theResultsIter.Next();
322 }
323 }
324 }
325
326 // Put free edges back to the lists of results
327 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theResIter( theResultEdges );
328 theResIter.More(); theResIter.Next() ) {
329 theAuxE = theResIter.Key();
330 myResFreeEdges(theResIter.Value()).Append(theAuxE);
331 }
332 }
333 }
334 }
335 }
336
337 // Bind the list of processed faces to the processed face
338 theProcessed.Bind(theFirstFace,theProcessedList);
339 }
340 }
341
342 // Clear the temporary map of processed faces
343 theProcessed.Clear();
344
0797d9d3 345#ifdef OCCT_DEBUG
7fd59977 346 //-------------------------------
347 //szv debug - sewing results
348 //-------------------------------
349 cout<<endl<<"FACE CONNECT SEWING RESULTS:"<<endl;
350 cout<<"----------------------------"<<endl;
351 cout<<"Sewing tolerance was set to "<<sewtoler<<endl;
352 Standard_Integer totfree = 0, totshared = 0;
353 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOF2Iter( myOriFreeEdges );
354 theOF2Iter.More(); theOF2Iter.Next() ) {
355 TopTools_ListIteratorOfListOfShape theOFL2Iter;
356 for ( theOFL2Iter.Initialize(theOF2Iter.Value());
357 theOFL2Iter.More(); theOFL2Iter.Next() ) {
358 totfree += myResFreeEdges(theOFL2Iter.Value()).Extent();
359 totshared += myResSharEdges(theOFL2Iter.Value()).Extent();
360 }
361 }
362 cout<<"TOTAL: "<<totfree<<" free, "<<totshared<<" shared edges"<<endl;
363 //-------------------------------
364#endif
365
366 /***************************************************************
367 / PERFORM EDGES REPLACEMENT
368 ***************************************************************/
369
370 TopTools_DataMapOfShapeShape theRepEdges;
371 TopTools_DataMapOfShapeListOfShape theRepVertices;
372 TopTools_DataMapOfShapeShape theOldVertices;
373 TopTools_DataMapOfShapeListOfShape theNewVertices;
374
375 // Replace old edges by resulting ones
376 TopoDS_Wire theNewW;
377 TopoDS_Vertex theOldV1, theOldV2, theNewV1, theNewV2, theNewV;
378 gp_Pnt theOldP1, theOldP2;
379 Standard_Real dist1, dist2, curdist1, curdist2;
380 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOEIter( myOriFreeEdges );
381 theOEIter.More(); theOEIter.Next() ) {
382 // Iterate on original free edges
383 for ( theOriginalIter.Initialize(theOEIter.Value());
384 theOriginalIter.More(); theOriginalIter.Next() ) {
385 TopoDS_Edge theOldE = TopoDS::Edge(theOriginalIter.Value());
386
387 // Prepare empty wire to add new edges for reshape
388 theBuilder.MakeWire(theNewW);
389
390 // Explore new edges and vertices
391 Standard_Boolean emptywire = Standard_True;
392 for (Standard_Integer i = 1; i<=2; i++) {
393 // Select list of free or shared edges
394 if (i==1) theResultsIter.Initialize(myResFreeEdges(theOldE));
395 else theResultsIter.Initialize(myResSharEdges(theOldE));
396 // Iterate on new edges
397 for ( ; theResultsIter.More(); theResultsIter.Next() ) {
398 theAuxE = theResultsIter.Value();
399 if (!theAuxE.IsSame(theOldE)) {
400 // Add new edge to the wire
401 theBuilder.Add(theNewW,theAuxE);
402 emptywire = Standard_False;
403 }
404 }
405 }
406
407 if (!emptywire) {
408
409 // Get vertices on old and new edges
410 TopExp::Vertices(theOldE,theOldV1,theOldV2);
411 theOldP1 = BRep_Tool::Pnt(theOldV1);
412 theOldP2 = BRep_Tool::Pnt(theOldV2);
413
414 // Process vertices for replacing
415 dist1 = -1.; dist2 = -1.;
416 for ( TopExp_Explorer expv(theNewW,TopAbs_VERTEX);
417 expv.More(); expv.Next() ) {
418 TopoDS_Vertex theNewVtx = TopoDS::Vertex(expv.Current());
419 gp_Pnt theNewPt = BRep_Tool::Pnt(theNewVtx);
420 curdist1 = theOldP1.Distance(theNewPt);
421 curdist2 = theOldP2.Distance(theNewPt);
422 if (dist1<0 || curdist1<dist1) { dist1 = curdist1; theNewV1 = theNewVtx; }
423 if (dist2<0 || curdist2<dist2) { dist2 = curdist2; theNewV2 = theNewVtx; }
424 }
425
426 // Place results in map for replacing
427 if (!theOldV1.IsSame(theNewV1)) {
428 if (theRepVertices.IsBound(theOldV1)) {
429 TopTools_ListOfShape& theList1 = theRepVertices(theOldV1);
430 TopTools_ListIteratorOfListOfShape theIter1;
431 Standard_Boolean found = Standard_False;
432 for ( theIter1.Initialize(theList1); theIter1.More(); theIter1.Next() )
433 if (theIter1.Value().IsSame(theNewV1)) { found = Standard_True; break; }
434 if (!found) theList1.Append(theNewV1);
435 }
436 else {
437 TopTools_ListOfShape theNewList1;
438 theNewList1.Append(theNewV1);
439 theRepVertices.Bind(theOldV1,theNewList1);
440 }
441 }
442 if (!theOldV2.IsSame(theNewV2)) {
443 if (theRepVertices.IsBound(theOldV2)) {
444 TopTools_ListOfShape& theList2 = theRepVertices(theOldV2);
445 TopTools_ListIteratorOfListOfShape theIter2;
446 Standard_Boolean found = Standard_False;
447 for ( theIter2.Initialize(theList2); theIter2.More(); theIter2.Next() )
448 if (theIter2.Value().IsSame(theNewV2)) { found = Standard_True; break; }
449 if (!found) theList2.Append(theNewV2);
450 }
451 else {
452 TopTools_ListOfShape theNewList2;
453 theNewList2.Append(theNewV2);
454 theRepVertices.Bind(theOldV2,theNewList2);
455 }
456 }
457
458 // Bind edge to replace
459 theRepEdges.Bind(theOldE,theNewW);
460 }
461 }
462 }
463
464 if (!theRepEdges.IsEmpty()) {
465
466 Handle(ShapeBuild_ReShape) theReShape = new ShapeBuild_ReShape;
467
468 // Replace edges
469 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theREIter( theRepEdges );
470 theREIter.More(); theREIter.Next() ) {
471 theReShape->Replace(theREIter.Key()/*.Oriented(TopAbs_FORWARD)*/,
472 theREIter.Value()/*.Oriented(TopAbs_FORWARD)*/);
473 }
474//smh#8
475 TopoDS_Shape tmpReShape = theReShape->Apply(result);
476 result = TopoDS::Shell(tmpReShape);
477 if (theReShape->Status(ShapeExtend_OK)) {
0797d9d3 478#ifdef OCCT_DEBUG
7fd59977 479 cout<<"Warning: ShapeFix_FaceConnect::Build: Edges not replaced by ReShape"<<endl;
480#endif
481 }
482 else if (theReShape->Status(ShapeExtend_FAIL1)) {
0797d9d3 483#ifdef OCCT_DEBUG
7fd59977 484 cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on edges"<<endl;
485#endif
486 }
487 else {
488
489 Handle(ShapeFix_Wire) SFW = new ShapeFix_Wire;
490 Handle(ShapeFix_Face) SFF = new ShapeFix_Face;
491 ShapeAnalysis_Edge SAE;
492 Standard_Real f,l;
493 Handle(Geom2d_Curve) c2d;
494 Handle(ShapeExtend_WireData) sewd;
495
496 // Perform necessary fixes on subshapes
497//smh#8
498 TopoDS_Shape emptyCopiedShell = result.EmptyCopied();
499 TopoDS_Shell theShell = TopoDS::Shell(emptyCopiedShell);
500 for ( TopoDS_Iterator itf1(result); itf1.More(); itf1.Next() ) {
501 TopoDS_Face newface = TopoDS::Face(itf1.Value());
502//smh#8
503 TopoDS_Shape emptyCopiedFace = newface.EmptyCopied();
504 TopoDS_Face EmpFace = TopoDS::Face(emptyCopiedFace);
505 for ( TopoDS_Iterator itw(newface); itw.More(); itw.Next() ) {
506 if(itw.Value().ShapeType() != TopAbs_WIRE)
507 continue;
508 TopoDS_Wire theWire = TopoDS::Wire(itw.Value());
509
510 sewd = new ShapeExtend_WireData( theWire );
511 ShapeAnalysis_WireOrder SAWO(Standard_False, 0);
512 for (Standard_Integer i = 1; i <= sewd->NbEdges(); i++) {
513
514//smh#8
515 TopoDS_Shape tmpFace = EmpFace.Oriented(TopAbs_FORWARD);
516 if (!SAE.PCurve(sewd->Edge(i),
517 TopoDS::Face(tmpFace),
518 c2d,f,l)) continue;
519 SAWO.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
520 }
521 SAWO.Perform();
522
523 SFW->Load(sewd);
524 SFW->FixReorder(SAWO);
525 SFW->FixReorder();
526
527 SFW->SetFace(EmpFace);
528 SFW->SetPrecision(fixtoler);
529 SFW->SetMaxTolerance(sewtoler);
530
531 SFW->FixEdgeCurves();
532 SFW->FixSelfIntersection();
533 theWire = SFW->Wire();
534 theBuilder.Add(EmpFace,theWire);
535 }
536// #ifdef AIX CKY : applies to all platforms
537 SFF->Init(EmpFace);
538// SFF->Init(TopoDS::Face(EmpFace));
539
540 TopTools_DataMapOfShapeListOfShape MapWires;
541 MapWires.Clear();
542 if (SFF->FixOrientation(MapWires)) EmpFace = SFF->Face();
543 theBuilder.Add(theShell,EmpFace);
544 }
ab860031 545 theShell.Closed (BRep_Tool::IsClosed (theShell));
7fd59977 546 result = theShell;
547
548 if (!theRepVertices.IsEmpty()) {
549
550 // Prepare vertices to replace
551 TopoDS_Shape theOld, theNew, theRep, theAux;
552 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV1Iter( theRepVertices );
553 theRV1Iter.More(); theRV1Iter.Next() ) {
554 // Get the old vertex, create empty list of replaced vertices
555 theOld = theRV1Iter.Key();
556 TopTools_ListOfShape theNewList;
557 // Explore the list of new vertices
558 TopTools_ListIteratorOfListOfShape theN1Iter;
559 for ( theN1Iter.Initialize(theRV1Iter.Value()); theN1Iter.More(); theN1Iter.Next() ) {
560 theNew = theN1Iter.Value();
561 if (theOldVertices.IsBound(theNew)) {
562 // Vertex has a replacing vertex in the map
563 theRep = theOldVertices(theNew);
564 if (!theRep.IsSame(theOld)) {
565 // Vertex is not in current list
566 theOldVertices.Bind(theRep,theOld);
567 theNewList.Append(theRep);
568 TopTools_ListIteratorOfListOfShape theN3Iter;
569 for ( theN3Iter.Initialize(theNewVertices(theRep));
570 theN3Iter.More(); theN3Iter.Next() ) {
571 theAux = theN3Iter.Value();
572 theOldVertices(theAux) = theOld;
573 theNewList.Append(theAux);
574 }
575 theNewVertices.UnBind(theRep);
576 }
577 }
578 else {
579 theOldVertices.Bind(theNew,theOld);
580 theNewList.Append(theNew);
581 }
582 }
583 theNewVertices.Bind(theOld,theNewList);
584 }
585
586 // Update vertices positions and tolerances
587 TopoDS_Vertex theNewVert, theOldVert;
588 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theRV2Iter( theNewVertices );
589 theRV2Iter.More(); theRV2Iter.Next() ) {
590 theNewVert = TopoDS::Vertex(theRV2Iter.Key());
591 // Calculate the vertex position
592 gp_Pnt theLBound, theRBound, thePosition;
593 theLBound = theRBound = BRep_Tool::Pnt(theNewVert);
594 TopTools_ListIteratorOfListOfShape theN2Iter;
595 for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) {
596 thePosition = BRep_Tool::Pnt(TopoDS::Vertex(theN2Iter.Value()));
597 Standard_Real val = thePosition.X();
598 if ( val < theLBound.X() ) theLBound.SetX( val );
599 else if ( val > theRBound.X() ) theRBound.SetX( val );
600 val = thePosition.Y();
601 if ( val < theLBound.Y() ) theLBound.SetY( val );
602 else if ( val > theRBound.Y() ) theRBound.SetY( val );
603 val = thePosition.Z();
604 if ( val < theLBound.Z() ) theLBound.SetZ( val );
605 else if ( val > theRBound.Z() ) theRBound.SetZ( val );
606 }
607 thePosition = gp_Pnt((theLBound.XYZ() + theRBound.XYZ())/2.);
608 Standard_Real theTolerance = 0., curtoler;
609 // Calculate the vertex tolerance
610 for ( theN2Iter.Initialize(theRV2Iter.Value()); theN2Iter.More(); theN2Iter.Next() ) {
611 theOldVert = TopoDS::Vertex(theN2Iter.Value());
612 curtoler = thePosition.Distance(BRep_Tool::Pnt(theOldVert)) +
613 BRep_Tool::Tolerance(theOldVert);
614 if (curtoler > theTolerance) theTolerance = curtoler;
615 }
616 curtoler = thePosition.Distance(BRep_Tool::Pnt(theNewVert)) +
617 BRep_Tool::Tolerance(theNewVert);
618 if (curtoler > theTolerance) theTolerance = curtoler;
619 theBuilder.UpdateVertex( theNewVert, thePosition, theTolerance );
620 }
621
622 // Replace vertices
623 theReShape->Clear();
624 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theNVIter( theOldVertices );
625 theNVIter.More(); theNVIter.Next() )
626 theReShape->Replace(theNVIter.Key().Oriented(TopAbs_FORWARD),
627 theNVIter.Value().Oriented(TopAbs_FORWARD));
628//smh#8
629 TopoDS_Shape tmpshape = theReShape->Apply(result);
630 result = TopoDS::Shell(tmpshape);
631
632 if (theReShape->Status(ShapeExtend_FAIL1)) {
0797d9d3 633#ifdef OCCT_DEBUG
7fd59977 634 cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on vertices"<<endl;
635#endif
636 }
637 }
638
0797d9d3 639#ifdef OCCT_DEBUG
7fd59977 640 //-------------------------------
641 //szv debug - reshape results
642 //-------------------------------
643 cout<<endl<<"FACE CONNECT REPLACEMENT RESULTS:"<<endl;
644 cout<<"---------------------------------"<<endl;
645 TopTools_MapOfShape theTmpMap;
646 Standard_Integer toteold = 0, totenew = 0;
647 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR1Iter( theRepEdges );
648 theR1Iter.More(); theR1Iter.Next() ) {
649 toteold++;
650 if (!theTmpMap.Contains(theR1Iter.Value())) {
651 theTmpMap.Add(theR1Iter.Value());
652 for ( TopoDS_Iterator itw(TopoDS::Wire(theR1Iter.Value()));
653 itw.More(); itw.Next() ) totenew++;
654 }
655 }
656 Standard_Integer totvold = 0, totvnew = 0;
657 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR2Iter( theOldVertices );
658 theR2Iter.More(); theR2Iter.Next() ) {
659 totvold++;
660 if (!theTmpMap.Contains(theR2Iter.Value())) {
661 theTmpMap.Add(theR2Iter.Value());
662 totvnew++;
663 }
664 }
665 cout<<"TOTAL: "<<toteold<<" edges, "<<totvold<<" vertices replaced by "
666 <<totenew<<" edges, "<<totvnew<<" vertices"<<endl<<endl;
667 //-------------------------------
668#endif
669
670 }
671 }
672 }
673
674 return result;
675}
676
677//=======================================================================
678//function : Clear
679//purpose :
680//=======================================================================
681
682 void ShapeFix_FaceConnect::Clear()
683{
684 myConnected.Clear();
685 myOriFreeEdges.Clear();
686 myResFreeEdges.Clear();
687 myResSharEdges.Clear();
688}