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