0021762: Integration of new Boolean Operation algorithm to OCCT.
[occt.git] / src / BOPTools / BOPTools_AlgoTools_1.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
19
20#include <BOPTools_AlgoTools.ixx>
21
22#include <TopTools_IndexedMapOfShape.hxx>
23#include <TopExp.hxx>
24#include <TopExp_Explorer.hxx>
25
26#include <TopoDS.hxx>
27#include <TopoDS_Edge.hxx>
28#include <TopoDS_Vertex.hxx>
29#include <TopoDS_Face.hxx>
30
31#include <TopLoc_Location.hxx>
32
33#include <BRep_TVertex.hxx>
34#include <BRep_TEdge.hxx>
35#include <BRep_TFace.hxx>
36#include <BRep_Tool.hxx>
37#include <BRep_GCurve.hxx>
38#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
39#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
40#include <BRep_CurveRepresentation.hxx>
41#include <BRep_PointRepresentation.hxx>
42
43#include <Geom_Curve.hxx>
44#include <Geom_Surface.hxx>
45#include <Geom_Plane.hxx>
46#include <Geom_TrimmedCurve.hxx>
47
48#include <GeomAdaptor_Curve.hxx>
49#include <GeomAdaptor_HCurve.hxx>
50#include <GeomAdaptor_HSurface.hxx>
51
52#include <Geom2d_Curve.hxx>
53
54#include <Geom2dAdaptor_HCurve.hxx>
55#include <Geom_RectangularTrimmedSurface.hxx>
56#include <Geom2dAdaptor.hxx>
57#include <GeomProjLib.hxx>
58
59#include <ProjLib_ProjectedCurve.hxx>
60#include <Extrema_LocateExtPC.hxx>
61
62#include <gp_Pnt.hxx>
63
64#include <Adaptor3d_HCurve.hxx>
65#include <Adaptor3d_CurveOnSurface.hxx>
66#include <Adaptor3d_HCurveOnSurface.hxx>
67//
68#include <BRepAdaptor_Surface.hxx>
69#include <TopoDS_Iterator.hxx>
70#include <TopoDS_Wire.hxx>
71#include <TopoDS.hxx>
72#include <BRepTools_WireExplorer.hxx>
73#include <gp_Pnt2d.hxx>
74#include <BRep_Tool.hxx>
75#include <BRep_Tool.hxx>
76#include <BRep_Builder.hxx>
77#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
78#include <TopTools_ListOfShape.hxx>
79#include <TopTools_ListIteratorOfListOfShape.hxx>
80#include <Geom2d_Curve.hxx>
81#include <GeomAdaptor_Surface.hxx>
82
83static
84 void CheckEdge (const TopoDS_Edge& E,
85 const Standard_Real aMaxTol);
86static
87 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
88 const TopoDS_Face& S,
89 const Standard_Real aMaxTol);
90static
91 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
92 const Adaptor3d_Curve& Other,
93 const Standard_Real Tol,
94 const Standard_Boolean SameParameter,
95 Standard_Real& aNewTolerance);
96
97static
98 void CorrectVertexTolerance(const TopoDS_Edge& aE);
99
100static
101 void CorrectWires(const TopoDS_Face& aF);
102
103static
104 void UpdateEdges(const TopoDS_Face& aF);
105
106static
107 void UpdateVertices(const TopoDS_Edge& aE);
108
109//=======================================================================
110// Function : CorrectTolerances
111// purpose :
112//=======================================================================
113 void BOPTools_AlgoTools::CorrectTolerances(const TopoDS_Shape& aShape,
114 const Standard_Real aMaxTol)
115{
116 BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol);
117 BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol);
118}
119
120//=======================================================================
121// Function : CorrectPointOnCurve
122// purpose :
123//=======================================================================
124 void BOPTools_AlgoTools::CorrectPointOnCurve(const TopoDS_Shape& S,
125 const Standard_Real aMaxTol)
126{
127 Standard_Integer i, aNb;
128 TopTools_IndexedMapOfShape Edges;
129 TopExp::MapShapes (S, TopAbs_EDGE, Edges);
130 aNb=Edges.Extent();
131 for (i=1; i<=aNb; i++) {
132 const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
133 CheckEdge(E, aMaxTol);
134 }
135}
136
137//=======================================================================
138// Function : CorrectCurveOnSurface
139// purpose :
140//=======================================================================
141 void BOPTools_AlgoTools::CorrectCurveOnSurface(const TopoDS_Shape& S,
142 const Standard_Real aMaxTol)
143{
144 Standard_Integer i, aNbFaces, j, aNbEdges;
145 TopTools_IndexedMapOfShape Faces;
146 TopExp::MapShapes (S, TopAbs_FACE, Faces);
147
148 aNbFaces=Faces.Extent();
149 for (i=1; i<=aNbFaces; i++) {
150 const TopoDS_Face& F= TopoDS::Face(Faces(i));
151 //
152 CorrectWires(F);
153 //
154 TopTools_IndexedMapOfShape Edges;
155 TopExp::MapShapes (F, TopAbs_EDGE, Edges);
156 aNbEdges=Edges.Extent();
157 for (j=1; j<=aNbEdges; j++) {
158 const TopoDS_Edge& E= TopoDS::Edge(Edges(j));
159 CorrectEdgeTolerance (E, F, aMaxTol);
160 }
161 }
162}
163//=======================================================================
164// Function : CorrectWires
165// purpose :
166//=======================================================================
167void CorrectWires(const TopoDS_Face& aFx)
168{
169 GeomAbs_SurfaceType aType;
170 //
171 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
172 //BRepAdaptor_Surface aBAS (aFx, Standard_False);
173 GeomAdaptor_Surface aGAS (aS);
174 aType=aGAS.GetType();
175 if (aType!=GeomAbs_Cylinder) {
176 return;
177 }
178 //
179 Standard_Integer i, aNbV;
180 Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
181 TopoDS_Edge aE1, aE2, aEi, aEj;
182 gp_Pnt aP, aPV;
183 gp_Pnt2d aP2D;
184 TopoDS_Face aF;
185 BRep_Builder aBB;
186 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
187 TopTools_ListIteratorOfListOfShape aIt;
188 //
189 aF=aFx;
190 aF.Orientation(TopAbs_FORWARD);
191 //
192 TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
193 aNbV=aMVE.Extent();
194 for (i=1; i<=aNbV; ++i) {
195 const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i));
196 aPV=BRep_Tool::Pnt(aV);
197 aTol=BRep_Tool::Tolerance(aV);
198 aTol2=aTol*aTol;
199 //
200 aD2max=-1.;
201 const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
202 aIt.Initialize(aLE);
203 for (; aIt.More(); aIt.Next()) {
204 const TopoDS_Edge& aE=TopoDS::Edge(aIt.Value());
205 aT=BRep_Tool::Parameter(aV, aE);
206 const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
207 aC2D->D0(aT, aP2D);
208 //aP=aBAS.Value(aP2D.X(), aP2D.Y());
209 aS->D0(aP2D.X(), aP2D.Y(), aP);
210 aD2=aPV.SquareDistance(aP);
211 if (aD2>aD2max) {
212 aD2max=aD2;
213 }
214 }
215 if (aD2max>aTol2) {
216 aTol=sqrt(aD2max);
217 aBB.UpdateVertex(aV, aTol);
218 }
219 }
220}
221//=======================================================================
222// Function : CorrectEdgeTolerance
223// purpose : Correct tolerances for Edge
224//=======================================================================
225void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
226 const TopoDS_Face& S,
227 const Standard_Real aMaxTol)
228{
229 //
230 // 1. Minimum of conditions to Perform
231 Handle (BRep_CurveRepresentation) myCref;
232 Handle (Adaptor3d_HCurve) myHCurve;
233
234 myCref.Nullify();
235
236 Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
237 BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
238 Standard_Boolean Degenerated, SameParameterx, SameRangex;
239
240 Standard_Integer unique = 0;
241
242 Degenerated = TEx->Degenerated();
243 SameParameterx = TEx->SameParameter();
244 SameRangex = TEx->SameRange();
245
246 if (!SameRangex && SameParameterx) {
247 return;
248 }
249
250 Handle(Geom_Curve) C3d;
251 while (itcrx.More()) {
252 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
253 if (cr->IsCurve3D()) {
254 unique++;
255 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
256 myCref = cr;
257 }
258 }
259 itcrx.Next();
260 }
261
262 if (unique==0) {
263 return;//...No3DCurve
264 }
265 if (unique>1) {
266 return;//...Multiple3DCurve;
267 }
268
269 if (myCref.IsNull() && !Degenerated) {
270 itcrx.Initialize(TEx->Curves());
271 while (itcrx.More()) {
272 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
273 if (cr->IsCurveOnSurface()) {
274 myCref = cr;
275 break;
276 }
277 itcrx.Next();
278 }
279 }
280
281 else if (!myCref.IsNull() && Degenerated){
282 return ;//...InvalidDegeneratedFlag;
283 }
284
285 if (!myCref.IsNull()) {
286 const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref);
287 Standard_Real First,Last;
288 GCref->Range(First,Last);
289 if (Last<=First) {
290 myCref.Nullify();
291 return ;//InvalidRange;
292 }
293
294 else {
295 if (myCref->IsCurve3D()) {
296 Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
297 (myCref->Curve3D()->Transformed (myCref->Location().Transformation()));
298 GeomAdaptor_Curve GAC3d(C3dx, First, Last);
299 myHCurve = new GeomAdaptor_HCurve(GAC3d);
300 }
301 else { // curve on surface
302 Handle(Geom_Surface) Sref = myCref->Surface();
303 Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation()));
304 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
305 Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref);
306 Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last);
307 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
308 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
309 }
310 }
311 }
312
313 //===============================================
314 // 2. Tolerances in InContext
315 {
316 if (myCref.IsNull())
317 return;
318 Standard_Boolean ok=Standard_True;;
319
320 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
321 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
322 Standard_Real aNewTol=Tol;
323
324 Standard_Boolean SameParameter = TE->SameParameter();
325 Standard_Boolean SameRange = TE->SameRange();
326 Standard_Real First = myHCurve->FirstParameter();
327 Standard_Real Last = myHCurve->LastParameter();
328 //Standard_Real Delta =1.e-14;
329 Standard_Real Delta =1.e-12;
330
331 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
332 const TopLoc_Location& Floc = S.Location();
333 const TopLoc_Location& TFloc = TF->Location();
334 const Handle(Geom_Surface)& Su = TF->Surface();
335 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
336 // Standard_Boolean checkclosed = Standard_False;
337 Standard_Boolean pcurvefound = Standard_False;
338
339 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
340 while (itcr.More()) {
341 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
342 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
343 pcurvefound = Standard_True;
344 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
345 Standard_Real f,l;
346 GC->Range(f,l);
347 if (SameRange && (f != First || l != Last)) {
348 return ;//BRepCheck_InvalidSameRangeFlag);
349 if (SameParameter) {
350 return; //BRepCheck_InvalidSameParameterFlag);
351 }
352 }
353
354 Handle(Geom_Surface) Sb = cr->Surface();
355 Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation()));
356 Handle(Geom2d_Curve) PC = cr->PCurve();
357 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb);
358 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
359 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
360 ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol);
361 if (ok) {
362 if (cr->IsCurveOnClosedSurface()) {
363 //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
364 }
365 else {
366 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
367 }
368 if (SameParameter) {
369 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
370 }
371 //
372 if (aNewTol<aMaxTol) {
373 TE->UpdateTolerance(aNewTol+Delta);
374 //
375 CorrectVertexTolerance(myShape);
376 }
377 }
378
379 if (cr->IsCurveOnClosedSurface()) {
380 //checkclosed = Standard_True;
381 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
382 ACS.Load(GAHS); // sans doute inutile
383 ACS.Load(GHPC); // meme remarque...
384 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
385 if (ok) {
386 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
387 if (SameParameter) {
388 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
389 }
390 if (aNewTol<aMaxTol) {
391 TE->UpdateTolerance(aNewTol+Delta);
392 CorrectVertexTolerance(myShape);
393 }
394 }
395 }
396 }
397 itcr.Next();
398 }
399
400 if (!pcurvefound) {
401 Handle(Geom_Plane) P;
402 Handle(Standard_Type) styp = Su->DynamicType();
403 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
404 P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
405 DownCast(Su)->BasisSurface());
406 }
407 else {
408 P = Handle(Geom_Plane)::DownCast(Su);
409 }
410 if (P.IsNull()) { // not a plane
411 return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
412 }
413
414 else {// on fait la projection a la volee, comme BRep_Tool
415 P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
416 //on projette Cref sur ce plan
417 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
418
419 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
420 GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
421 Handle(Geom_Curve) C3dx = Gac.Curve();
422 Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
423 (new Geom_TrimmedCurve(C3dx,First,Last), P, P->Position().Direction(), Standard_True);
424
425 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
426
427 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
428 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
429 Handle(Geom2dAdaptor_HCurve) GHPC =
430 new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
431
432 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
433
434 Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
435 Tol,Standard_True, aNewTol); // voir dub...
436 if (okx) {
437 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
438 if (aNewTol<aMaxTol) {
439 TE->UpdateTolerance(aNewTol+Delta);
440 CorrectVertexTolerance(myShape);
441 }
442 }
443 }
444
445 }//end of if (!pcurvefound) {
446 } // end of 2. Tolerances in InContext
447
448}
449
450//=======================================================================
451// Function : CorrectShapeTolerances
452// purpose :
453//=======================================================================
454 void BOPTools_AlgoTools::CorrectShapeTolerances(const TopoDS_Shape& aShape)
455{
456 TopExp_Explorer aExp;
457 Standard_Integer aDim;
458 //
459 aDim=Dimension(aShape);
460 if (aDim == 1) {
461 aExp.Init(aShape, TopAbs_EDGE);
462 for (; aExp.More(); aExp.Next()) {
463 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
464 UpdateVertices(aE);
465 }
466 } else {
467 aExp.Init(aShape, TopAbs_FACE);
468 for (; aExp.More(); aExp.Next()) {
469 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
470 UpdateEdges(aF);
471 }
472 }
473}
474
475//=======================================================================
476//function : CorrectVertexTolerance
477//purpose :
478//=======================================================================
479void CorrectVertexTolerance(const TopoDS_Edge& aE)
480{
481 Standard_Integer k, aNbV;
482 Standard_Real aTolE, aTolV;
483 TopTools_IndexedMapOfShape aVMap;
484
485 aTolE=BRep_Tool::Tolerance(aE);
486
487 TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
488 aNbV=aVMap.Extent();
489 for (k=1; k<=aNbV; ++k) {
490 const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
491 aTolV=BRep_Tool::Tolerance(aV);
492 if (aTolV<aTolE) {
493 Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aV.TShape());
494 aTV->UpdateTolerance(aTolE);
495 }
496 }
497}
498
499#define NCONTROL 23
500//=======================================================================
501//function : Validate
502//purpose :
503//=======================================================================
504Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
505 const Adaptor3d_Curve& Other,
506 const Standard_Real Tol,
507 const Standard_Boolean SameParameter,
508 Standard_Real& aNewTolerance)
509{
510 Standard_Real First, Last, MaxDistance, aD, Tol2;
511
512 First = CRef.FirstParameter();
513 Last = CRef.LastParameter();
514 MaxDistance = 0.;
515 Tol2 = Tol*Tol;
516
517 Standard_Integer i, aNC1=NCONTROL-1;
518
519 Standard_Boolean aFlag=Standard_False;
520 Standard_Boolean proj = (!SameParameter ||
521 First != Other.FirstParameter() ||
522 Last != Other.LastParameter());
523 //
524 // 1.
525 if (!proj) {
526 for (i = 0; i < NCONTROL; i++) {
527 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
528 gp_Pnt pref = CRef.Value(prm);
529 gp_Pnt pother = Other.Value(prm);
530
531 aD=pref.SquareDistance(pother);
532
533 if (aD > Tol2) {
534 if (aD>MaxDistance) {
535 MaxDistance=aD;
536 }
537 aFlag=Standard_True;
538 }
539 }
540
541 if (aFlag) {
542 aNewTolerance=sqrt(MaxDistance);
543 }
544 return aFlag;
545 }
546
547 //
548 // 2.
549 else {
550 Extrema_LocateExtPC refd,otherd;
551 Standard_Real OFirst, OLast;
552 OFirst = Other.FirstParameter();
553 OLast = Other.LastParameter();
554
555 gp_Pnt pd = CRef.Value(First);
556 gp_Pnt pdo = Other.Value(OFirst);
557
558 aD = pd.SquareDistance(pdo);
559 if (aD > Tol2) {
560 if (aD>MaxDistance) {
561 MaxDistance=aD;
562 }
563 aFlag=Standard_True;
564 }
565
566 pd = CRef.Value(Last);
567 pdo = Other.Value(OLast);
568 aD = pd.SquareDistance(pdo);
569 if (aD > Tol2 && aD > MaxDistance) {
570 MaxDistance=aD;
571 aFlag=Standard_True;
572 }
573
574 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
575 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
576
577 for (i = 2; i< aNC1; i++) {
578 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
579 gp_Pnt pref = CRef.Value(rprm);
580
581 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
582 gp_Pnt pother = Other.Value(oprm);
583
584 refd.Perform(pother,rprm);
585 if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
586 if (refd.IsDone()) {
587 aD=refd.SquareDistance();
588 if (aD > Tol2 && aD>MaxDistance) {
589 aFlag=Standard_True;
590 MaxDistance=aD;
591 }
592 }
593 }
594
595 otherd.Perform(pref,oprm);
596 if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
597
598 if (otherd.IsDone()) {
599 aD=otherd.SquareDistance();
600 if (aD > Tol2 && aD>MaxDistance) {
601 aFlag=Standard_True;
602 MaxDistance=aD;
603 }
604 }
605 }
606 }
607 }
608
609 aD=sqrt (MaxDistance);
610 aNewTolerance=aD;
611
612 return aFlag;
613
614}
615
616//=======================================================================
617// Function : CheckEdge
618// purpose : Correct tolerances for Vertices on Edge
619//=======================================================================
620void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
621{
622 TopoDS_Edge E=Ed;
623 E.Orientation(TopAbs_FORWARD);
624
625 gp_Pnt Controlp;
626
627 TopExp_Explorer aVExp;
628 aVExp.Init(E, TopAbs_VERTEX);
629 for (; aVExp.More(); aVExp.Next()) {
630 TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
631
632 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
633 const gp_Pnt& prep = TV->Pnt();
634
635 Standard_Real Tol, aD2, aNewTolerance, dd;
636
637 Tol =BRep_Tool::Tolerance(aVertex);
638 Tol = Max(Tol, BRep_Tool::Tolerance(E));
639 dd=0.1*Tol;
640 Tol*=Tol;
641
642 const TopLoc_Location& Eloc = E.Location();
643 BRep_ListIteratorOfListOfPointRepresentation itpr;
644
645 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
646 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
647 while (itcr.More()) {
648 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
649 const TopLoc_Location& loc = cr->Location();
650 TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
651
652 if (cr->IsCurve3D()) {
653 const Handle(Geom_Curve)& C = cr->Curve3D();
654 if (!C.IsNull()) {
655 itpr.Initialize(TV->Points());
656 while (itpr.More()) {
657 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
658 if (pr->IsPointOnCurve(C,L)) {
659 Controlp = C->Value(pr->Parameter());
660 Controlp.Transform(L.Transformation());
661 aD2=prep.SquareDistance(Controlp);
662 if (aD2 > Tol) {
663 aNewTolerance=sqrt(aD2)+dd;
664 if (aNewTolerance<aMaxTol)
665 TV->UpdateTolerance(aNewTolerance);
666 }
667 }
668 itpr.Next();
669 }
670
671 TopAbs_Orientation orv = aVertex.Orientation();
672 if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
673 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
674
675 if (orv==TopAbs_FORWARD)
676 Controlp = C->Value(GC->First());
677 else
678 Controlp = C->Value(GC->Last());
679
680 Controlp.Transform(L.Transformation());
681 aD2=prep.SquareDistance(Controlp);
682
683 if (aD2 > Tol) {
684 aNewTolerance=sqrt(aD2)+dd;
685 if (aNewTolerance<aMaxTol)
686 TV->UpdateTolerance(aNewTolerance);
687 }
688 }
689 }
690 }
691 itcr.Next();
692 }
693 }
694}
695
696//=======================================================================
697// Function : UpdateVertices
698// purpose :
699//=======================================================================
700 void UpdateVertices(const TopoDS_Edge& aE)
701{
702 Standard_Real aTolE, aTolV;
703 TopoDS_Iterator aItE;
704 BRep_Builder aBB;
705 //
706 aTolE = BRep_Tool::Tolerance(aE);
707 aItE.Initialize(aE);
708 for (; aItE.More(); aItE.Next()) {
709 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItE.Value();
710 aTolV = BRep_Tool::Tolerance(aV);
711 if (aTolV < aTolE) {
712 aBB.UpdateVertex(aV, aTolE);
713 }
714 }
715}
716//=======================================================================
717// Function : UpdateEdges
718// purpose :
719//=======================================================================
720 void UpdateEdges(const TopoDS_Face& aF)
721{
722 Standard_Real aTolF, aTolE, aTolV;
723 TopoDS_Iterator aItF, aItW, aItE;
724 BRep_Builder aBB;
725 //
726 aTolF = BRep_Tool::Tolerance(aF);
727 aItF.Initialize(aF);
728 for (; aItF.More(); aItF.Next()) {
729 const TopoDS_Shape& aS = aItF.Value();
730 if (aS.ShapeType()==TopAbs_WIRE) {
731 aItW.Initialize(aS);
732 for (; aItW.More(); aItW.Next()) {
733 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItW.Value();
734 aTolE = BRep_Tool::Tolerance(aE);
735 if (aTolE < aTolF) {
736 aBB.UpdateEdge(aE, aTolF);
737 aTolE = aTolF;
738 }
739 UpdateVertices(aE);
740 }
741 }
742 else {
743 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItF.Value();
744 aTolV = BRep_Tool::Tolerance(aV);
745 if (aTolV < aTolE) {
746 aBB.UpdateVertex(aV, aTolF);
747 }
748 }
749 }
750}