1 // Created on: 1999-06-18
2 // Created by: Sergei ZERTCHANINOV
3 // Copyright (c) 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 <BRepBuilderAPI_Sewing.hxx>
21 #include <Geom2d_Curve.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>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Face.hxx>
36 #include <TopoDS_Iterator.hxx>
37 #include <TopoDS_Shell.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopTools_Array1OfShape.hxx>
41 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
42 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_ListOfShape.hxx>
47 #include <TopTools_MapOfShape.hxx>
50 //=======================================================================
51 //function : ShapeFix_FaceConnect
52 //=======================================================================
54 ShapeFix_FaceConnect::ShapeFix_FaceConnect() {}
56 //=======================================================================
59 //=======================================================================
61 Standard_Boolean ShapeFix_FaceConnect::Add(const TopoDS_Face& aFirst,
62 const TopoDS_Face& aSecond)
64 if (!aFirst.IsNull() && !aSecond.IsNull()) {
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);
76 // Append second face to the first list
77 TopTools_ListOfShape theNewFirstList;
78 theNewFirstList.Append(aSecond);
79 myConnected.Bind(aFirst,theNewFirstList);
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);
89 // Append first face to the second list
90 TopTools_ListOfShape theNewSecondList;
91 theNewSecondList.Append(aFirst);
92 myConnected.Bind(aSecond,theNewSecondList);
99 return Standard_False;
102 //=======================================================================
105 //=======================================================================
107 TopoDS_Shell ShapeFix_FaceConnect::Build (const TopoDS_Shell& shell,
108 const Standard_Real sewtoler,
109 const Standard_Real fixtoler)
111 TopoDS_Shell result = shell;
113 /***************************************************************
114 / INITIAL PREPARATIONS
115 / Fill map of original free edges,
116 / fill maps of resulting free and shared edges
117 ***************************************************************/
119 // Clear maps of free and shared edges
120 myOriFreeEdges.Clear();
121 myResFreeEdges.Clear();
122 myResSharEdges.Clear();
124 TopTools_DataMapOfShapeShape theFreeEdges;
125 TopoDS_Shape theEdge, theFace;
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);
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);
151 // Append free edge to the new list
152 TopTools_ListOfShape theNewList;
153 theNewList.Append(theEdge);
154 myOriFreeEdges.Bind(theFace,theNewList);
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);
166 // Clear the temporary map of free edges
167 theFreeEdges.Clear();
170 //-------------------------------
171 //szv debug - preparation results
172 //-------------------------------
173 if (!myOriFreeEdges.IsEmpty()) {
174 std::cout<<std::endl<<"FACE CONNECT PREPARATION RESULTS:"<<std::endl;
175 std::cout<<"---------------------------------"<<std::endl;
176 Standard_Integer freenum = 0, facenum = 0;
177 for ( TopTools_DataMapIteratorOfDataMapOfShapeListOfShape theOFIter( myOriFreeEdges );
178 theOFIter.More(); theOFIter.Next() ) {
179 freenum += theOFIter.Value().Extent();
182 std::cout<<"TOTAL: "<<facenum<<" faces containing "<<freenum<<" free edges"<<std::endl;
184 //-------------------------------
187 /***************************************************************
188 / APPLY SEWING ON CONNECTED FACES
189 / Change maps of original free edges and resulting shared edges
190 ***************************************************************/
192 if (!myOriFreeEdges.IsEmpty()) {
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;
200 TopTools_ListIteratorOfListOfShape theOriginalIter, theResultsIter;
201 TopoDS_Shape theAuxE, theOrigE, theAuxF;
203 BRep_Builder theBuilder;
205 TopTools_DataMapOfShapeListOfShape theProcessed;
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)) {
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;
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)) {
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);
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;
245 // Process second face for the pair of different faces only
246 if (theFirstFace.IsSame(theSecondFace)) {
248 std::cout<<"Warning: ShapeFix_FaceConnect::Build: Self-connected face"<<std::endl;
251 else theNumOfFacesToSew = 2;
253 TopTools_DataMapOfShapeShape theSewerWires;
254 BRepBuilderAPI_Sewing theSewer(sewtoler);
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();
270 theBuilder.MakeWire(theAuxW);
271 theBuilder.Add(theAuxW,theAuxE);
272 theBuilder.Add(theAuxF,theAuxW);
273 theSewerWires.Bind(theAuxE,theAuxW);
274 theSewer.Add(theAuxW);
277 // Add constructed face to sewer
278 theSewer.Add(theAuxF);
281 // Perform sewing on the list of free edges
282 Standard_Boolean sewing_ok = Standard_True;
284 try { OCC_CATCH_SIGNALS theSewer.Perform(); }
285 catch(Standard_Failure const&) { sewing_ok = Standard_False; }
288 if (theSewer.SewedShape().IsNull()) sewing_ok = Standard_False;
291 TopTools_DataMapOfShapeShape theResultEdges;
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);
316 else theResultEdges.Bind(theAuxE,theOrigE);
318 // Remove modified free edge from the list
319 theOldFreeList.Remove(theResultsIter);
321 else theResultsIter.Next();
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);
337 // Bind the list of processed faces to the processed face
338 theProcessed.Bind(theFirstFace,theProcessedList);
342 // Clear the temporary map of processed faces
343 theProcessed.Clear();
346 //-------------------------------
347 //szv debug - sewing results
348 //-------------------------------
349 std::cout<<std::endl<<"FACE CONNECT SEWING RESULTS:"<<std::endl;
350 std::cout<<"----------------------------"<<std::endl;
351 std::cout<<"Sewing tolerance was set to "<<sewtoler<<std::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();
362 std::cout<<"TOTAL: "<<totfree<<" free, "<<totshared<<" shared edges"<<std::endl;
363 //-------------------------------
366 /***************************************************************
367 / PERFORM EDGES REPLACEMENT
368 ***************************************************************/
370 TopTools_DataMapOfShapeShape theRepEdges;
371 TopTools_DataMapOfShapeListOfShape theRepVertices;
372 TopTools_DataMapOfShapeShape theOldVertices;
373 TopTools_DataMapOfShapeListOfShape theNewVertices;
375 // Replace old edges by resulting ones
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());
387 // Prepare empty wire to add new edges for reshape
388 theBuilder.MakeWire(theNewW);
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;
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);
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; }
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);
437 TopTools_ListOfShape theNewList1;
438 theNewList1.Append(theNewV1);
439 theRepVertices.Bind(theOldV1,theNewList1);
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);
452 TopTools_ListOfShape theNewList2;
453 theNewList2.Append(theNewV2);
454 theRepVertices.Bind(theOldV2,theNewList2);
458 // Bind edge to replace
459 theRepEdges.Bind(theOldE,theNewW);
464 if (!theRepEdges.IsEmpty()) {
466 Handle(ShapeBuild_ReShape) theReShape = new ShapeBuild_ReShape;
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)*/);
475 TopoDS_Shape tmpReShape = theReShape->Apply(result);
476 result = TopoDS::Shell(tmpReShape);
477 if (theReShape->Status(ShapeExtend_OK)) {
479 std::cout<<"Warning: ShapeFix_FaceConnect::Build: Edges not replaced by ReShape"<<std::endl;
482 else if (theReShape->Status(ShapeExtend_FAIL1)) {
484 std::cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on edges"<<std::endl;
489 Handle(ShapeFix_Wire) SFW = new ShapeFix_Wire;
490 Handle(ShapeFix_Face) SFF = new ShapeFix_Face;
491 ShapeAnalysis_Edge SAE;
493 Handle(Geom2d_Curve) c2d;
494 Handle(ShapeExtend_WireData) sewd;
496 // Perform necessary fixes on subshapes
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());
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)
508 TopoDS_Wire theWire = TopoDS::Wire(itw.Value());
510 sewd = new ShapeExtend_WireData( theWire );
511 ShapeAnalysis_WireOrder SAWO(Standard_False, 0);
512 for (Standard_Integer i = 1; i <= sewd->NbEdges(); i++) {
515 TopoDS_Shape tmpFace = EmpFace.Oriented(TopAbs_FORWARD);
516 if (!SAE.PCurve(sewd->Edge(i),
517 TopoDS::Face(tmpFace),
519 SAWO.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
524 SFW->FixReorder(SAWO);
527 SFW->SetFace(EmpFace);
528 SFW->SetPrecision(fixtoler);
529 SFW->SetMaxTolerance(sewtoler);
531 SFW->FixEdgeCurves();
532 SFW->FixSelfIntersection();
533 theWire = SFW->Wire();
534 theBuilder.Add(EmpFace,theWire);
536 // #ifdef AIX CKY : applies to all platforms
538 // SFF->Init(TopoDS::Face(EmpFace));
540 TopTools_DataMapOfShapeListOfShape MapWires;
542 if (SFF->FixOrientation(MapWires)) EmpFace = SFF->Face();
543 theBuilder.Add(theShell,EmpFace);
545 theShell.Closed (BRep_Tool::IsClosed (theShell));
548 if (!theRepVertices.IsEmpty()) {
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);
575 theNewVertices.UnBind(theRep);
579 theOldVertices.Bind(theNew,theOld);
580 theNewList.Append(theNew);
583 theNewVertices.Bind(theOld,theNewList);
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 );
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;
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 );
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));
629 TopoDS_Shape tmpshape = theReShape->Apply(result);
630 result = TopoDS::Shell(tmpshape);
632 if (theReShape->Status(ShapeExtend_FAIL1)) {
634 std::cout<<"Error: ShapeFix_FaceConnect::Build: ReShape failed on vertices"<<std::endl;
640 //-------------------------------
641 //szv debug - reshape results
642 //-------------------------------
643 std::cout<<std::endl<<"FACE CONNECT REPLACEMENT RESULTS:"<<std::endl;
644 std::cout<<"---------------------------------"<<std::endl;
645 TopTools_MapOfShape theTmpMap;
646 Standard_Integer toteold = 0, totenew = 0;
647 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR1Iter( theRepEdges );
648 theR1Iter.More(); theR1Iter.Next() ) {
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++;
656 Standard_Integer totvold = 0, totvnew = 0;
657 for ( TopTools_DataMapIteratorOfDataMapOfShapeShape theR2Iter( theOldVertices );
658 theR2Iter.More(); theR2Iter.Next() ) {
660 if (!theTmpMap.Contains(theR2Iter.Value())) {
661 theTmpMap.Add(theR2Iter.Value());
665 std::cout<<"TOTAL: "<<toteold<<" edges, "<<totvold<<" vertices replaced by "
666 <<totenew<<" edges, "<<totvnew<<" vertices"<<std::endl<<std::endl;
667 //-------------------------------
677 //=======================================================================
680 //=======================================================================
682 void ShapeFix_FaceConnect::Clear()
685 myOriFreeEdges.Clear();
686 myResFreeEdges.Clear();
687 myResSharEdges.Clear();