0022746: Progress indicator in ShapeHealing
[occt.git] / src / ShapeFix / ShapeFix.cxx
CommitLineData
7fd59977 1// File: ShapeFix.cxx
2// Created: Fri Jan 21 12:00:39 2000
3// Author: data exchange team
4// <det@nnov.matra-dtv.fr>
5
6
7#include <ShapeFix.hxx>
8//:k2 abv 16.12.98: eliminating code duplication
9//pdn 18.12.98: checking deviation for SP edges
10//: abv 22.02.99: method FillFace() removed since PRO13123 is fixed
11//szv#4 S4163
12//szv#9:S4244:19Aug99: Added method FixWireGaps
13//szv#10:S4244:23Aug99: Added method FixFaceGaps
14
15#include <BRep_Builder.hxx>
16#include <BRep_Tool.hxx>
17
18#include <Geom2d_Curve.hxx>
19#include <Geom_Curve.hxx>
20
21#include <Precision.hxx>
22
23#include <Standard_ErrorHandler.hxx>
24#include <Standard_Failure.hxx>
25
26#include <TopExp_Explorer.hxx>
27#include <TopLoc_Location.hxx>
28#include <TopoDS.hxx>
29#include <TopoDS_Edge.hxx>
30#include <TopoDS_Face.hxx>
31#include <Geom_Surface.hxx>
32
33//:i2
34#include <gp_Pnt.hxx>
35#include <Geom_Plane.hxx>
36#include <ShapeFix_Edge.hxx>
37#include <Geom2dAdaptor_HCurve.hxx>
38#include <Adaptor3d_CurveOnSurface.hxx>
39#include <Geom_RectangularTrimmedSurface.hxx>
40#include <ShapeAnalysis_Surface.hxx>
41
42#include <ShapeFix_Edge.hxx>
43#include <ShapeFix_Shape.hxx>
44#include <ShapeFix_Wire.hxx>
45#include <ShapeFix_Face.hxx>
46#include <TopoDS_Iterator.hxx>
47#include <GeomAdaptor_HSurface.hxx>
48#include <TopTools_MapOfShape.hxx>
49#include <BRepLib.hxx>
50
51#include <ShapeAnalysis_Edge.hxx>
52#include <ShapeBuild_Edge.hxx>
53#include <TopoDS_Vertex.hxx>
54#include <ShapeBuild_ReShape.hxx>
55#include <TColgp_SequenceOfPnt.hxx>
56#include <TopTools_ListOfShape.hxx>
57#include <TopTools_ListIteratorOfListOfShape.hxx>
58#include <TopTools_SequenceOfShape.hxx>
59#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
60#include <TopExp.hxx>
61
b485ee79 62#include <Message_ProgressSentry.hxx>
7fd59977 63
64//=======================================================================
65//function : SameParameter
66//purpose :
67//=======================================================================
68
69Standard_Boolean ShapeFix::SameParameter(const TopoDS_Shape& shape,
70 const Standard_Boolean enforce,
b485ee79
KD
71 const Standard_Real preci,
72 const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 73{
b485ee79
KD
74 // Calculate number of edges
75 Standard_Integer aNbEdges = 0;
76 for ( TopExp_Explorer anEdgeExp(shape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next() )
77 ++aNbEdges;
78
79 // Calculate number of faces
80 Standard_Integer aNbFaces = 0;
81 for ( TopExp_Explorer anEdgeExp(shape, TopAbs_FACE); anEdgeExp.More(); anEdgeExp.Next() )
82 ++aNbFaces;
83
7fd59977 84 BRep_Builder B;
85 //Standard_Integer nbexcp = 0;
86 Standard_Integer nbfail = 0, numedge = 0;
87 Standard_Boolean status = Standard_True;
88 Standard_Real tol = preci;
89 Standard_Boolean iatol = (tol > 0);
90 Handle(ShapeFix_Edge) sfe = new ShapeFix_Edge;
91 TopExp_Explorer ex(shape,TopAbs_EDGE);
92
b485ee79
KD
93 // Start progress scope (no need to check if progress exists -- it is safe)
94 Message_ProgressSentry aPSentry(theProgress, "Fixing same parameter problem", 0, 2, 1);
95
96 {
97 // Start progress scope (no need to check if progress exists -- it is safe)
98 Message_ProgressSentry aPSentry(theProgress, "Fixing edge", 0, aNbEdges, 1);
99
100 while ( ex.More() )
101 {
102 TopoDS_Edge E;
103 while ( ex.More() && aPSentry.More() )
104 {
105 numedge ++;
106 int ierr = 0;
107 TopLoc_Location loc;
108 E = TopoDS::Edge (ex.Current());
109 ex.Next();
110
111 if (!iatol)
112 tol = BRep_Tool::Tolerance (E);
113 if (enforce)
114 {
115 B.SameRange (E,Standard_False);
116 B.SameParameter (E,Standard_False);
117 }
118
119 sfe->FixSameParameter (E); // K2-SEP97
120
121 if (!BRep_Tool::SameParameter (E)) { ierr = 1; nbfail ++; }
122
123 if (ierr)
124 {
125 status = Standard_False;
126 B.SameRange (E,Standard_False);
127 B.SameParameter (E,Standard_False);
128 }
129
130 // Complete step in current progress scope
131 aPSentry.Next();
132 } // -- end while
133
134 // Halt algorithm in case of user's abort
135 if ( !aPSentry.More() )
136 return Standard_False;
7fd59977 137 }
b485ee79
KD
138
139 }
140 // Switch to "Update tolerances" step
141 aPSentry.Next();
142
143 {
144 // Start progress scope (no need to check if progress exists -- it is safe)
145 Message_ProgressSentry aPSentry(theProgress, "Update tolerances", 0, aNbFaces, 1);
146
147 //:i2 abv 21 Aug 98: ProSTEP TR8 Motor.rle face 710:
148 // Update tolerance of edges on planes (no pcurves are stored)
149 for ( TopExp_Explorer exp ( shape, TopAbs_FACE ); exp.More() && aPSentry.More(); exp.Next(), aPSentry.Next() )
150 {
151 TopoDS_Face face = TopoDS::Face ( exp.Current() );
152 Handle(Geom_Surface) Surf = BRep_Tool::Surface ( face );
153
154 Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast ( Surf );
155 if ( plane.IsNull() ) {
156 Handle(Geom_RectangularTrimmedSurface) GRTS =
157 Handle(Geom_RectangularTrimmedSurface)::DownCast ( Surf );
158 if ( ! GRTS.IsNull() )
159 plane = Handle(Geom_Plane)::DownCast ( GRTS->BasisSurface() );
160 if ( plane.IsNull() )
161 continue;
7fd59977 162 }
b485ee79
KD
163
164 Handle(GeomAdaptor_HSurface) AS = new GeomAdaptor_HSurface ( plane );
165 for ( TopExp_Explorer ed ( face, TopAbs_EDGE ); ed.More(); ed.Next() ) {
166 TopoDS_Edge edge = TopoDS::Edge ( ed.Current() );
167 Standard_Real f, l;
168 Handle(Geom_Curve) crv = BRep_Tool::Curve ( edge, f, l );
169 if ( crv.IsNull() )
170 continue;
171
172 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface ( edge, face, f, l );;
173 if ( c2d.IsNull() ) continue;
174 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve ( c2d, f, l );
175 Adaptor3d_CurveOnSurface ACS(GHPC,AS);
176
177 Standard_Real tol0 = BRep_Tool::Tolerance(edge);
178 tol = tol0;
179 Standard_Real tol2 = tol*tol;
180 const Standard_Integer NCONTROL = 23;
181 for ( Standard_Integer i = 0; i < NCONTROL; i++ )
182 {
183 Standard_Real par = ( f * ( NCONTROL - 1 - i ) + l * i ) / ( NCONTROL - 1 );
184 gp_Pnt pnt = crv->Value ( par );
185 gp_Pnt prj = ACS.Value( par );
186 Standard_Real dist = pnt.SquareDistance(prj);
187 if ( tol2 < dist )
188 tol2 = dist;
189 }
190 tol = 1.00005 * sqrt(tol2); // coeff: see trj3_pm1-ct-203.stp #19681, edge 10
191 if ( tol >= tol0 )
192 {
193 B.UpdateEdge ( edge, tol );
194 for ( TopoDS_Iterator itV(edge); itV.More(); itV.Next() )
195 {
196 TopoDS_Shape S = itV.Value();
197 B.UpdateVertex ( TopoDS::Vertex ( S ), tol );
198 }
199 }
7fd59977 200 }
b485ee79
KD
201
202 // Halt algorithm in case of user's abort
203 if ( !aPSentry.More() )
204 return Standard_False;
7fd59977 205 }
206 }
207
208 if (!status) {
209#ifdef DEB
210 cout<<"** SameParameter not complete. On "<<numedge<<" Edges:";
211 if (nbfail > 0) cout<<" "<<nbfail<<" Failed";
7fd59977 212 cout<<endl;
213#endif
214 }
215 return status;
216}
217
218
219//=======================================================================
220//function : EncodeRegularity
221//purpose :
222//=======================================================================
223
224static void EncodeRegularity (const TopoDS_Shape& shape,
225 const Standard_Real tolang,
226 TopTools_MapOfShape &aMap)
227{
228 TopoDS_Shape S = shape;
229 TopLoc_Location L;
230 S.Location ( L );
231 if ( ! aMap.Add ( S ) ) return;
232
233 if ( S.ShapeType() == TopAbs_COMPOUND ||
234 S.ShapeType() == TopAbs_COMPSOLID ) {
235 for ( TopoDS_Iterator it(S); it.More(); it.Next() ) {
236 EncodeRegularity ( it.Value(), tolang, aMap );
237 }
238 return;
239 }
240
241 try {
242 OCC_CATCH_SIGNALS
243 BRepLib::EncodeRegularity ( S, tolang );
244 }
245 catch(Standard_Failure) {
246#ifdef DEB
247 cout << "Warning: Exception in ShapeFix::EncodeRegularity(): ";
248 Standard_Failure::Caught()->Print ( cout );
249 cout << endl;
250#endif
251 }
252}
253
254void ShapeFix::EncodeRegularity (const TopoDS_Shape& shape,
255 const Standard_Real tolang)
256{
257 TopTools_MapOfShape aMap;
258 ::EncodeRegularity ( shape, tolang, aMap );
259}
260
261
262//=======================================================================
263//function : RemoveSmallEdges
264//purpose :
265//=======================================================================
266
267TopoDS_Shape ShapeFix::RemoveSmallEdges (TopoDS_Shape& Shape,
268 const Standard_Real Tolerance,
269 Handle(ShapeBuild_ReShape)& context)
270{
271 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
272 sfs->Init(Shape);
273 sfs->SetPrecision(Tolerance);
274 Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixMissingSeamMode() = Standard_False;
275 Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixOrientationMode() = Standard_False;
276 Handle(ShapeFix_Face)::DownCast(sfs->FixFaceTool())->FixSmallAreaWireMode() = Standard_False;
277 sfs->FixWireTool()->ModifyTopologyMode() = Standard_True;
278 //sfs.FixWireTool().FixReorderMode() = Standard_False;
279 sfs->FixWireTool()->FixConnectedMode() = Standard_False;
280 sfs->FixWireTool()->FixEdgeCurvesMode() = Standard_False;
281 sfs->FixWireTool()->FixDegeneratedMode() = Standard_False;
282 Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixSelfIntersectionMode() = Standard_False;
283 Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixLackingMode() = Standard_False;
284 Handle(ShapeFix_Wire)::DownCast(sfs->FixWireTool())->FixSmallMode() = Standard_True;
285 sfs->Perform();
286 TopoDS_Shape result = sfs->Shape();
287 context = sfs->Context();
288 return result;
289}
290
291
292//=======================================================================
293//function : ReplaceVertex
294//purpose : auxilary for FixVertexPosition
295//=======================================================================
296static TopoDS_Edge ReplaceVertex(const TopoDS_Edge& theEdge,
297 const gp_Pnt theP,
298 const Standard_Boolean theFwd)
299{
300 TopoDS_Vertex aNewVertex;
301 BRep_Builder aB;
302 aB.MakeVertex(aNewVertex,theP,Precision::Confusion());
303 TopoDS_Vertex aV1,aV2;
304 if(theFwd) {
305 aV1 = aNewVertex;
306 aV1.Orientation( TopAbs_FORWARD);
307 }
308 else {
309 aV2 = aNewVertex;
310 aV2.Orientation( TopAbs_REVERSED);
311 }
312 ShapeBuild_Edge aSbe;
313 TopoDS_Edge e1 = theEdge;
314 TopAbs_Orientation Ori = e1.Orientation();
315 e1.Orientation(TopAbs_FORWARD);
316 TopoDS_Edge aNewEdge = aSbe.CopyReplaceVertices(e1,aV1,aV2);
317 aNewEdge.Orientation(Ori);
318 return aNewEdge;
319}
320
321
322//=======================================================================
323//function : getNearPoint
324//purpose : auxilary for FixVertexPosition
325//=======================================================================
326static Standard_Real getNearPoint(const TColgp_SequenceOfPnt& aSeq1,
327 const TColgp_SequenceOfPnt& aSeq2,
328 gp_XYZ& acent)
329{
330 Standard_Integer i =1;
331 Standard_Integer ind1 =0,ind2 =0;
332 Standard_Real mindist =RealLast();
333 for( ; i <= aSeq1.Length(); i++) {
334 gp_Pnt p1 = aSeq1.Value(i);
335 Standard_Integer j=1;
336 for( ; j <= aSeq2.Length(); j++) {
337 gp_Pnt p2 = aSeq2.Value(j);
338 Standard_Real d = p1.Distance(p2);
339 if(fabs(d -mindist ) <= Precision::Confusion())
340 continue;
341 if(d < mindist) {
342 mindist = d;
343 ind1 =i;
344 ind2 = j;
345 }
346
347 }
348 }
349 if(ind1 && ind2)
350 acent = (aSeq1.Value(ind1).XYZ() + aSeq2.Value(ind2).XYZ())/2.0;
351 return mindist;
352}
353
354
355//=======================================================================
356//function : getNearestEdges
357//purpose : auxilary for FixVertexPosition
358//=======================================================================
359static Standard_Boolean getNearestEdges(TopTools_ListOfShape& theLEdges,
360 const TopoDS_Vertex theVert,
361 TopTools_SequenceOfShape& theSuitEdges,
362 TopTools_SequenceOfShape& theRejectEdges,
363 const Standard_Real theTolerance,
364 gp_XYZ& thecentersuit,
365 gp_XYZ& thecenterreject)
366{
367 if(theLEdges.IsEmpty())
368 return Standard_False;
369 TopTools_MapOfShape aMapEdges;
370
371 TopTools_ListOfShape atempList;
372 atempList= theLEdges;
373 TopTools_ListIteratorOfListOfShape alIter(atempList);
374
375 TopoDS_Edge aEdge1 = TopoDS::Edge(alIter.Value());
376 TopoDS_Vertex aVert11,aVert12;
377 TopExp::Vertices(aEdge1, aVert11,aVert12 );
378 aMapEdges.Add(aEdge1);
379 Standard_Real aFirst1,aLast1;
380 Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(aEdge1,aFirst1,aLast1);
381 gp_Pnt p11;
382 gp_Pnt p12;
383 Standard_Boolean isFirst1 = theVert.IsSame(aVert11);
384 Standard_Boolean isSame1 = aVert11.IsSame(aVert12);
385 if( !aCurve1.IsNull()) {
386 if(isFirst1)
387 p11 = aCurve1->Value(aFirst1);
388 else if(!isSame1)
389 p11 = aCurve1->Value(aLast1);
390 if(isSame1)
391 p12 = aCurve1->Value(aLast1);
392 }
393 else return Standard_False;
394 alIter.Next();
395 TopTools_SequenceOfShape aseqreject;
396 TopTools_SequenceOfShape aseqsuit;
397
398 Standard_Integer anumLoop =0;
399 for( ; alIter.More(); ) {
400 TopoDS_Edge aEdge = TopoDS::Edge(alIter.Value());
401 if( aMapEdges.Contains(aEdge)) {
402 atempList.Remove(alIter);
403 continue;
404 }
405
406 TopoDS_Vertex aVert1,aVert2;
407 TopExp::Vertices(aEdge, aVert1,aVert2 );
408 Standard_Real isFirst = theVert.IsSame(aVert1);
409 Standard_Boolean isSame = aVert1.IsSame(aVert2);
410
411 Standard_Boolean isLoop = ((aVert1.IsSame(aVert11) && aVert2.IsSame(aVert12)) ||
412 (aVert1.IsSame(aVert12) && aVert2.IsSame(aVert11)));
413 if(isLoop /*&& !aseqsuit.Length()*/ && (atempList.Extent() >anumLoop)) {
414 atempList.Append(aEdge);
415 atempList.Remove(alIter);
416 anumLoop++;
417 continue;
418 }
419 aMapEdges.Add(aEdge);
420 Standard_Real aFirst,aLast;
421 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
422 if( !aCurve.IsNull()) {
423 gp_Pnt p1;
424 gp_Pnt p2;
425 if(isFirst)
426 p1 = aCurve->Value(aFirst);
427 else
428 p1 = aCurve->Value(aLast);
429 if(isSame)
430 p2 = aCurve->Value(aLast);
431 Standard_Real aMinDist = RealLast();
432 gp_XYZ acent;
433 if(!isSame && ! isSame1) {
434 aMinDist = p1.Distance(p11);
435 acent = (p1.XYZ() + p11.XYZ())/2.0;
436 }
437 else {
438 TColgp_SequenceOfPnt aSeq1;
439 TColgp_SequenceOfPnt aSeq2;
440 aSeq1.Append(p11);
441 if(isSame1)
442 aSeq1.Append(p12);
443 aSeq2.Append(p1);
444 if(isSame)
445 aSeq2.Append(p2);
446 aMinDist = getNearPoint(aSeq1,aSeq2,acent);
447 }
448
449 if(aMinDist > theTolerance) {
450 if(!aseqreject.Length())
451 thecenterreject = acent;
452 aseqreject.Append(aEdge);
453 }
454 else {
455 if(!aseqsuit.Length()) {
456 thecentersuit = acent;
457 aseqsuit.Append(aEdge);
458 }
459 else if(!isSame1)
460 aseqsuit.Append(aEdge);
461 else if((thecentersuit - acent).Modulus() < theTolerance)
462 aseqsuit.Append(aEdge);
463 else
464 aseqreject.Append(aEdge);
465 }
466
467 }
468 atempList.Remove(alIter);
469 }
470
471 Standard_Boolean isDone = (!aseqsuit.IsEmpty() || !aseqreject.IsEmpty());
472 if(isDone) {
473 if(aseqsuit.IsEmpty()) {
474 theRejectEdges.Append(aEdge1);
475 theLEdges.RemoveFirst();
476
477 getNearestEdges(theLEdges,theVert,theSuitEdges,theRejectEdges,
478 theTolerance,thecentersuit,thecenterreject);
479 }
480 else {
481 theSuitEdges.Append(aEdge1);
482 theSuitEdges.Append(aseqsuit);
483 theRejectEdges.Append(aseqreject);
484 }
485 }
486 else
487 theRejectEdges.Append(aEdge1);
488
489 return isDone;
490}
491
492
493//=======================================================================
494//function : FixVertexPosition
495//purpose :
496//=======================================================================
497
498Standard_Boolean ShapeFix::FixVertexPosition(TopoDS_Shape& theshape,
499 const Standard_Real theTolerance,
500 const Handle(ShapeBuild_ReShape)& thecontext)
501{
502 TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdges;
503 TopExp_Explorer aExp1(theshape,TopAbs_EDGE);
504 for( ; aExp1.More(); aExp1.Next()) {
505 TopoDS_Shape aVert1;
506 Standard_Integer nV =1;
507 TopoDS_Iterator aExp3(aExp1.Current());
508 for( ; aExp3.More(); aExp3.Next(),nV++) {
509 TopoDS_Shape aVert = aExp3.Value();
510 if(nV ==1)
511 aVert1 = aVert;
512 else if(aVert1.IsSame(aVert))
513 continue;
514 if(aMapVertEdges.Contains(aVert))
515 aMapVertEdges.ChangeFromKey(aVert).Append(aExp1.Current());
516 else {
517 TopTools_ListOfShape alEdges;
518 alEdges.Append(aExp1.Current());
519 aMapVertEdges.Add(aVert,alEdges);
520 }
521 }
522 }
523 Standard_Boolean isDone = Standard_False;
524 Standard_Integer i=1;
525 for( ; i <= aMapVertEdges.Extent(); i++) {
526 TopoDS_Vertex aVert = TopoDS::Vertex(aMapVertEdges.FindKey(i));
527 Standard_Real aTolVert = BRep_Tool::Tolerance(aVert);
528 if(aTolVert <= theTolerance)
529 continue;
530
531 BRep_Builder aB1;
532 aB1.UpdateVertex(aVert,theTolerance);
533 gp_Pnt aPvert = BRep_Tool::Pnt(aVert);
534 gp_XYZ acenter(aPvert.XYZ()), acenterreject(aPvert.XYZ());
535
536 TopTools_SequenceOfShape aSuitEdges;
537 TopTools_SequenceOfShape aRejectEdges;
538 TopTools_ListOfShape aledges;
539 aledges= aMapVertEdges.FindFromIndex(i);
540 if(aledges.Extent() ==1)
541 continue;
542 //if tolerance of vertex is more than specified tolerance
543 // check distance between curves and vertex
544
545 if(!getNearestEdges(aledges,aVert,aSuitEdges,aRejectEdges,theTolerance,acenter,acenterreject))
546 continue;
547
548 //update vertex by nearest point
549 Standard_Boolean isAdd = Standard_False;
550 Standard_Integer k =1;
551 for( ; k <= aSuitEdges.Length(); k++) {
552
553 TopoDS_Edge aEdgeOld = TopoDS::Edge(aSuitEdges.Value(k));
554 TopoDS_Vertex aVert1,aVert2;
555 TopExp::Vertices(aEdgeOld, aVert1,aVert2 );
556
557 Standard_Boolean isFirst = (aVert1.IsSame(aVert));
558 Standard_Boolean isLast = (aVert2.IsSame(aVert));
559 if(!isFirst && !isLast)
560 continue;
561 Standard_Real aFirst,aLast;
562 Handle(Geom_Curve) aCurve;
563 TopoDS_Edge aEdge = TopoDS::Edge(thecontext->Apply(aEdgeOld));
564
565 TopoDS_Vertex aVert1n,aVert2n;
566 TopExp::Vertices(aEdge, aVert1n,aVert2n );
567 aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
568 if( !aCurve.IsNull()) {
569 gp_Pnt p1 = aCurve->Value(aFirst);
570 gp_Pnt p2 = aCurve->Value(aLast);
571
572 //if distance between ends of curve more than specified tolerance
573 //but vertices are the same that one of the vertex will be replaced.
574
575 Standard_Boolean isReplace = (aVert1n.IsSame(aVert2n) && p1.Distance(p2) >theTolerance);
576
577 //Standard_Real dd1 = (acenter - p1.XYZ()).Modulus();
578 //Standard_Real dd2 = (acenter - p2.XYZ()).Modulus();
579 if(isFirst) {
580 if( k>2) {
581 acenter += p1.XYZ();
582 acenter /= 2.0;
583 }
584 if(isReplace) {
585 TopoDS_Edge enew;
586 if(p1.Distance(acenter) < p2.Distance(acenter))
587 enew = ReplaceVertex(aEdge,p2,Standard_False);
588 else
589 enew = ReplaceVertex(aEdge,p1,Standard_True);
590 thecontext->Replace(aEdge,enew);
591 isDone = Standard_True;
592 }
593 }
594 else {
595 if( k>2) {
596 acenter += p2.XYZ();
597 acenter /= 2.0;
598 }
599 if(isReplace) {
600 TopoDS_Edge enew;
601 if(p1.Distance(acenter) < p2.Distance(acenter))
602 enew = ReplaceVertex(aEdge,p2,Standard_False);
603 else
604 enew = ReplaceVertex(aEdge,p1,Standard_True);
605 thecontext->Replace(aEdge,enew);
606 isDone = Standard_True;
607 }
608 }
609
610
611
612 isAdd = Standard_True;
613
614 }
615 }
616
617
618 if(isAdd && aPvert.Distance(acenter) > theTolerance)
619 {
620
621 BRep_Builder aB;
622
623 // aB.UpdateVertex(aVert,Precision::Confusion());
624 //else {
625 isDone = Standard_True;
626 TopoDS_Vertex aNewVertex;
627 aB.MakeVertex(aNewVertex,acenter,Precision::Confusion());
628 aNewVertex.Orientation(aVert.Orientation());
629 thecontext->Replace(aVert,aNewVertex);
630
631 }
632
633 for( k =1; k <= aRejectEdges.Length(); k++) {
634 TopoDS_Edge aEdgeOld = TopoDS::Edge( aRejectEdges.Value(k));
635 TopoDS_Vertex aVert1,aVert2;
636 TopExp::Vertices(aEdgeOld, aVert1,aVert2 );
637
638 Standard_Boolean isFirst = (aVert1.IsSame(aVert));
639 Standard_Boolean isLast = (aVert2.IsSame(aVert));
640 if(!isFirst && !isLast)
641 continue;
642 Standard_Boolean isSame = aVert1.IsSame(aVert2);
643 Handle(Geom_Curve) aCurve;
644 TopoDS_Edge aEdge = TopoDS::Edge(thecontext->Apply(aEdgeOld));
645
646 TopoDS_Vertex aVert1n,aVert2n;
647 TopExp::Vertices(aEdge, aVert1n,aVert2n );
648
649 Standard_Real aFirst,aLast;
650 aCurve = BRep_Tool::Curve(aEdge,aFirst,aLast);
651 if( !aCurve.IsNull()) {
652 gp_Pnt p1 = aCurve->Value(aFirst);
653 gp_Pnt p2 = aCurve->Value(aLast);
654 TopoDS_Edge enew;
655 if(isFirst) {
656 enew = ReplaceVertex(aEdge,p1,Standard_True);
657 if(isSame)
658 enew = ReplaceVertex(enew,p2,Standard_False);
659 }
660 else {
661 enew = ReplaceVertex(aEdge,p2,Standard_False);
662 if(isSame)
663 enew = ReplaceVertex(enew ,p1,Standard_True);
664 }
665
666 thecontext->Replace(aEdge,enew);
667 isDone = Standard_True;
668
669
670 }
671
672 }
673 }
674 if(isDone)
675 theshape = thecontext->Apply(theshape);
676 return isDone;
677}
678
679
680//=======================================================================
681//function : LeastEdgeSize
682//purpose :
683//=======================================================================
684
685Standard_Real ShapeFix::LeastEdgeSize(TopoDS_Shape& theShape)
686{
687 Standard_Real aRes = RealLast();
688 for(TopExp_Explorer exp(theShape,TopAbs_EDGE); exp.More(); exp.Next()) {
689 TopoDS_Edge edge = TopoDS::Edge ( exp.Current() );
690 Standard_Real first,last;
691 Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge, first, last);
692 if(!c3d.IsNull()) {
693 Bnd_Box bb;
694 bb.Add(c3d->Value(first));
695 bb.Add(c3d->Value(last));
696 bb.Add(c3d->Value((last+first)/2.));
697 Standard_Real x1,x2,y1,y2,z1,z2,size;
698 bb.Get(x1,y1,z1,x2,y2,z2);
699 size = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1);
700 if(size<aRes) aRes = size;
701 }
702 }
703 aRes = sqrt(aRes);
704 return aRes;
705}