0024200: Wrong result obtained by Exterma Curve/Curve
[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>
b4109929 82#include <Geom2dAdaptor_Curve.hxx>
83#include <IntRes2d_Domain.hxx>
84#include <Geom2dInt_GInter.hxx>
85#include <IntRes2d_IntersectionPoint.hxx>
4e57c75e 86
87static
88 void CheckEdge (const TopoDS_Edge& E,
89 const Standard_Real aMaxTol);
90static
91 void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
92 const TopoDS_Face& S,
93 const Standard_Real aMaxTol);
94static
95 Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
96 const Adaptor3d_Curve& Other,
97 const Standard_Real Tol,
98 const Standard_Boolean SameParameter,
99 Standard_Real& aNewTolerance);
100
101static
102 void CorrectVertexTolerance(const TopoDS_Edge& aE);
103
104static
105 void CorrectWires(const TopoDS_Face& aF);
106
b4109929 107static
108 Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
109 const TopoDS_Face& aF,
110 const TopoDS_Edge& aE1,
111 const TopoDS_Edge& aE2);
112
4e57c75e 113static
114 void UpdateEdges(const TopoDS_Face& aF);
115
116static
117 void UpdateVertices(const TopoDS_Edge& aE);
118
119//=======================================================================
120// Function : CorrectTolerances
121// purpose :
122//=======================================================================
123 void BOPTools_AlgoTools::CorrectTolerances(const TopoDS_Shape& aShape,
124 const Standard_Real aMaxTol)
125{
126 BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol);
127 BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol);
128}
129
130//=======================================================================
131// Function : CorrectPointOnCurve
132// purpose :
133//=======================================================================
134 void BOPTools_AlgoTools::CorrectPointOnCurve(const TopoDS_Shape& S,
135 const Standard_Real aMaxTol)
136{
137 Standard_Integer i, aNb;
138 TopTools_IndexedMapOfShape Edges;
139 TopExp::MapShapes (S, TopAbs_EDGE, Edges);
140 aNb=Edges.Extent();
141 for (i=1; i<=aNb; i++) {
142 const TopoDS_Edge& E= TopoDS::Edge(Edges(i));
143 CheckEdge(E, aMaxTol);
144 }
145}
146
147//=======================================================================
148// Function : CorrectCurveOnSurface
149// purpose :
150//=======================================================================
151 void BOPTools_AlgoTools::CorrectCurveOnSurface(const TopoDS_Shape& S,
152 const Standard_Real aMaxTol)
153{
154 Standard_Integer i, aNbFaces, j, aNbEdges;
155 TopTools_IndexedMapOfShape Faces;
156 TopExp::MapShapes (S, TopAbs_FACE, Faces);
157
158 aNbFaces=Faces.Extent();
159 for (i=1; i<=aNbFaces; i++) {
160 const TopoDS_Face& F= TopoDS::Face(Faces(i));
161 //
162 CorrectWires(F);
163 //
164 TopTools_IndexedMapOfShape Edges;
165 TopExp::MapShapes (F, TopAbs_EDGE, Edges);
166 aNbEdges=Edges.Extent();
167 for (j=1; j<=aNbEdges; j++) {
168 const TopoDS_Edge& E= TopoDS::Edge(Edges(j));
169 CorrectEdgeTolerance (E, F, aMaxTol);
170 }
171 }
172}
173//=======================================================================
174// Function : CorrectWires
175// purpose :
176//=======================================================================
177void CorrectWires(const TopoDS_Face& aFx)
178{
4e57c75e 179 Standard_Integer i, aNbV;
b4109929 180 Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT, aTol2d;
4e57c75e 181 gp_Pnt aP, aPV;
182 gp_Pnt2d aP2D;
183 TopoDS_Face aF;
184 BRep_Builder aBB;
185 TopTools_IndexedDataMapOfShapeListOfShape aMVE;
b4109929 186 TopTools_ListIteratorOfListOfShape aIt, aIt1;
4e57c75e 187 //
188 aF=aFx;
189 aF.Orientation(TopAbs_FORWARD);
b4109929 190 aTol2d = Precision::Confusion();
191 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
4e57c75e 192 //
193 TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
194 aNbV=aMVE.Extent();
195 for (i=1; i<=aNbV; ++i) {
196 const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i));
197 aPV=BRep_Tool::Pnt(aV);
198 aTol=BRep_Tool::Tolerance(aV);
199 aTol2=aTol*aTol;
200 //
201 aD2max=-1.;
202 const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
203 aIt.Initialize(aLE);
204 for (; aIt.More(); aIt.Next()) {
b4109929 205 const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
4e57c75e 206 aT=BRep_Tool::Parameter(aV, aE);
207 const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
208 aC2D->D0(aT, aP2D);
4e57c75e 209 aS->D0(aP2D.X(), aP2D.Y(), aP);
210 aD2=aPV.SquareDistance(aP);
211 if (aD2>aD2max) {
212 aD2max=aD2;
213 }
b4109929 214 //check self interference
215 if (aNbV == 2) {
216 continue;
217 }
218 aIt1 = aIt;
219 aIt1.Next();
220 for (; aIt1.More(); aIt1.Next()) {
221 const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
222 //do not perform check for edges that have two common vertices
223 {
224 TopoDS_Vertex aV11, aV12, aV21, aV22;
225 TopExp::Vertices(aE, aV11, aV12);
226 TopExp::Vertices(aE1, aV21, aV22);
227 if (aV11.IsSame(aV21) && aV12.IsSame(aV22) ||
228 aV12.IsSame(aV21) && aV11.IsSame(aV22)) {
229 continue;
230 }
231 }
232 aD2 = IntersectCurves2d(aPV, aF, aE, aE1);
233 if (aD2>aD2max) {
234 aD2max=aD2;
235 }
236 }
4e57c75e 237 }
238 if (aD2max>aTol2) {
239 aTol=sqrt(aD2max);
240 aBB.UpdateVertex(aV, aTol);
241 }
242 }
243}
244//=======================================================================
b4109929 245// Function : IntersectCurves2d
246// purpose : Intersect 2d curves of edges
247//=======================================================================
248Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
249 const TopoDS_Face& aF,
250 const TopoDS_Edge& aE1,
251 const TopoDS_Edge& aE2)
252{
253 const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF);
254 GeomAdaptor_Surface aGAS (aS);
255 if (aGAS.IsUPeriodic() || aGAS.IsVPeriodic()) {
256 return 0;
257 }
258 //
259 Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d;
260 Standard_Integer j, aNbPnt;
261 Geom2dInt_GInter aInter;
262 gp_Pnt aP;
263 gp_Pnt2d aP2D;
264 //
265 aDist = 0.;
266 aTol2d = Precision::Confusion();
267 //
268 const Handle(Geom2d_Curve)& aC2D1=BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
269 const Handle(Geom2d_Curve)& aC2D2=BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
270 //
271 Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
272 IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, aC2D1->Value(aT12), aT12, aTol2d),
273 aDom2(aC2D2->Value(aT21), aT21, aTol2d, aC2D2->Value(aT22), aT22, aTol2d);
274 //
275 aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
276 if (aInter.IsDone()) {
277 if (aInter.NbSegments()) {
278 return aDist;
279 }
280 aNbPnt = aInter.NbPoints();
281 if (aNbPnt) {
282 aDist = Precision::Infinite();
283 for (j = 1; j <= aNbPnt; ++j) {
284 aP2D = aInter.Point(j).Value();
285 aS->D0(aP2D.X(), aP2D.Y(), aP);
286 aD=aPV.SquareDistance(aP);
287 if (aD < aDist) {
288 aDist = aD;
289 }
290 }
291 }
292 }
293 return aDist;
294}
295
296//=======================================================================
4e57c75e 297// Function : CorrectEdgeTolerance
298// purpose : Correct tolerances for Edge
299//=======================================================================
300void CorrectEdgeTolerance (const TopoDS_Edge& myShape,
301 const TopoDS_Face& S,
302 const Standard_Real aMaxTol)
303{
304 //
305 // 1. Minimum of conditions to Perform
306 Handle (BRep_CurveRepresentation) myCref;
307 Handle (Adaptor3d_HCurve) myHCurve;
308
309 myCref.Nullify();
310
311 Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape());
312 BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves());
313 Standard_Boolean Degenerated, SameParameterx, SameRangex;
314
315 Standard_Integer unique = 0;
316
317 Degenerated = TEx->Degenerated();
318 SameParameterx = TEx->SameParameter();
319 SameRangex = TEx->SameRange();
320
321 if (!SameRangex && SameParameterx) {
322 return;
323 }
324
325 Handle(Geom_Curve) C3d;
326 while (itcrx.More()) {
327 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
328 if (cr->IsCurve3D()) {
329 unique++;
330 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
331 myCref = cr;
332 }
333 }
334 itcrx.Next();
335 }
336
337 if (unique==0) {
338 return;//...No3DCurve
339 }
340 if (unique>1) {
341 return;//...Multiple3DCurve;
342 }
343
344 if (myCref.IsNull() && !Degenerated) {
345 itcrx.Initialize(TEx->Curves());
346 while (itcrx.More()) {
347 const Handle(BRep_CurveRepresentation)& cr = itcrx.Value();
348 if (cr->IsCurveOnSurface()) {
349 myCref = cr;
350 break;
351 }
352 itcrx.Next();
353 }
354 }
355
356 else if (!myCref.IsNull() && Degenerated){
357 return ;//...InvalidDegeneratedFlag;
358 }
359
360 if (!myCref.IsNull()) {
361 const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref);
362 Standard_Real First,Last;
363 GCref->Range(First,Last);
364 if (Last<=First) {
365 myCref.Nullify();
366 return ;//InvalidRange;
367 }
368
369 else {
370 if (myCref->IsCurve3D()) {
371 Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast
372 (myCref->Curve3D()->Transformed (myCref->Location().Transformation()));
373 GeomAdaptor_Curve GAC3d(C3dx, First, Last);
374 myHCurve = new GeomAdaptor_HCurve(GAC3d);
375 }
376 else { // curve on surface
377 Handle(Geom_Surface) Sref = myCref->Surface();
378 Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation()));
379 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
380 Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref);
381 Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last);
382 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
383 myHCurve = new Adaptor3d_HCurveOnSurface(ACSref);
384 }
385 }
386 }
387
388 //===============================================
389 // 2. Tolerances in InContext
390 {
391 if (myCref.IsNull())
392 return;
393 Standard_Boolean ok=Standard_True;;
394
395 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
396 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
397 Standard_Real aNewTol=Tol;
398
399 Standard_Boolean SameParameter = TE->SameParameter();
400 Standard_Boolean SameRange = TE->SameRange();
401 Standard_Real First = myHCurve->FirstParameter();
402 Standard_Real Last = myHCurve->LastParameter();
4e57c75e 403 Standard_Real Delta =1.e-12;
404
405 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
406 const TopLoc_Location& Floc = S.Location();
407 const TopLoc_Location& TFloc = TF->Location();
408 const Handle(Geom_Surface)& Su = TF->Surface();
409 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
4e57c75e 410 Standard_Boolean pcurvefound = Standard_False;
411
412 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
413 while (itcr.More()) {
414 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
415 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
416 pcurvefound = Standard_True;
417 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
418 Standard_Real f,l;
419 GC->Range(f,l);
420 if (SameRange && (f != First || l != Last)) {
d3f26155 421 return ;//BRepCheck_InvalidSameRangeFlag;
4e57c75e 422 }
423
424 Handle(Geom_Surface) Sb = cr->Surface();
425 Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation()));
426 Handle(Geom2d_Curve) PC = cr->PCurve();
427 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb);
428 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
429 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
430 ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol);
431 if (ok) {
432 if (cr->IsCurveOnClosedSurface()) {
433 //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
434 }
435 else {
436 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
437 }
438 if (SameParameter) {
439 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
440 }
441 //
442 if (aNewTol<aMaxTol) {
443 TE->UpdateTolerance(aNewTol+Delta);
444 //
445 CorrectVertexTolerance(myShape);
446 }
447 }
448
449 if (cr->IsCurveOnClosedSurface()) {
450 //checkclosed = Standard_True;
451 GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds
452 ACS.Load(GAHS); // sans doute inutile
453 ACS.Load(GHPC); // meme remarque...
454 ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol);
455 if (ok) {
456 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
457 if (SameParameter) {
458 //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
459 }
460 if (aNewTol<aMaxTol) {
461 TE->UpdateTolerance(aNewTol+Delta);
462 CorrectVertexTolerance(myShape);
463 }
464 }
465 }
466 }
467 itcr.Next();
468 }
469
470 if (!pcurvefound) {
471 Handle(Geom_Plane) P;
472 Handle(Standard_Type) styp = Su->DynamicType();
473 if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
474 P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface)::
475 DownCast(Su)->BasisSurface());
476 }
477 else {
478 P = Handle(Geom_Plane)::DownCast(Su);
479 }
480 if (P.IsNull()) { // not a plane
481 return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
482 }
483
484 else {// on fait la projection a la volee, comme BRep_Tool
485 P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation()));
486 //on projette Cref sur ce plan
487 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P);
488
489 // Dub - Normalement myHCurve est une GeomAdaptor_HCurve
490 GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve();
491 Handle(Geom_Curve) C3dx = Gac.Curve();
492 Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane
493 (new Geom_TrimmedCurve(C3dx,First,Last), P, P->Position().Direction(), Standard_True);
494
495 Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane);
496
497 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
498 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
499 Handle(Geom2dAdaptor_HCurve) GHPC =
500 new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter());
501
502 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
503
504 Standard_Boolean okx = Validate(myHCurve->Curve(),ACS,
505 Tol,Standard_True, aNewTol); // voir dub...
506 if (okx) {
507 //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
508 if (aNewTol<aMaxTol) {
509 TE->UpdateTolerance(aNewTol+Delta);
510 CorrectVertexTolerance(myShape);
511 }
512 }
513 }
514
515 }//end of if (!pcurvefound) {
516 } // end of 2. Tolerances in InContext
517
518}
519
520//=======================================================================
521// Function : CorrectShapeTolerances
522// purpose :
523//=======================================================================
524 void BOPTools_AlgoTools::CorrectShapeTolerances(const TopoDS_Shape& aShape)
525{
526 TopExp_Explorer aExp;
527 Standard_Integer aDim;
528 //
529 aDim=Dimension(aShape);
530 if (aDim == 1) {
531 aExp.Init(aShape, TopAbs_EDGE);
532 for (; aExp.More(); aExp.Next()) {
533 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current();
534 UpdateVertices(aE);
535 }
536 } else {
537 aExp.Init(aShape, TopAbs_FACE);
538 for (; aExp.More(); aExp.Next()) {
539 const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
540 UpdateEdges(aF);
541 }
542 }
543}
544
545//=======================================================================
546//function : CorrectVertexTolerance
547//purpose :
548//=======================================================================
549void CorrectVertexTolerance(const TopoDS_Edge& aE)
550{
551 Standard_Integer k, aNbV;
552 Standard_Real aTolE, aTolV;
553 TopTools_IndexedMapOfShape aVMap;
554
555 aTolE=BRep_Tool::Tolerance(aE);
556
557 TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap);
558 aNbV=aVMap.Extent();
559 for (k=1; k<=aNbV; ++k) {
560 const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k));
561 aTolV=BRep_Tool::Tolerance(aV);
562 if (aTolV<aTolE) {
563 Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aV.TShape());
564 aTV->UpdateTolerance(aTolE);
565 }
566 }
567}
568
569#define NCONTROL 23
570//=======================================================================
571//function : Validate
572//purpose :
573//=======================================================================
574Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
575 const Adaptor3d_Curve& Other,
576 const Standard_Real Tol,
577 const Standard_Boolean SameParameter,
578 Standard_Real& aNewTolerance)
579{
580 Standard_Real First, Last, MaxDistance, aD, Tol2;
581
582 First = CRef.FirstParameter();
583 Last = CRef.LastParameter();
584 MaxDistance = 0.;
585 Tol2 = Tol*Tol;
586
587 Standard_Integer i, aNC1=NCONTROL-1;
588
589 Standard_Boolean aFlag=Standard_False;
590 Standard_Boolean proj = (!SameParameter ||
591 First != Other.FirstParameter() ||
592 Last != Other.LastParameter());
593 //
594 // 1.
595 if (!proj) {
596 for (i = 0; i < NCONTROL; i++) {
597 Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1;
598 gp_Pnt pref = CRef.Value(prm);
599 gp_Pnt pother = Other.Value(prm);
600
601 aD=pref.SquareDistance(pother);
602
603 if (aD > Tol2) {
604 if (aD>MaxDistance) {
605 MaxDistance=aD;
606 }
607 aFlag=Standard_True;
608 }
609 }
610
611 if (aFlag) {
612 aNewTolerance=sqrt(MaxDistance);
613 }
614 return aFlag;
615 }
616
617 //
618 // 2.
619 else {
620 Extrema_LocateExtPC refd,otherd;
621 Standard_Real OFirst, OLast;
622 OFirst = Other.FirstParameter();
623 OLast = Other.LastParameter();
624
625 gp_Pnt pd = CRef.Value(First);
626 gp_Pnt pdo = Other.Value(OFirst);
627
628 aD = pd.SquareDistance(pdo);
629 if (aD > Tol2) {
630 if (aD>MaxDistance) {
631 MaxDistance=aD;
632 }
633 aFlag=Standard_True;
634 }
635
636 pd = CRef.Value(Last);
637 pdo = Other.Value(OLast);
638 aD = pd.SquareDistance(pdo);
639 if (aD > Tol2 && aD > MaxDistance) {
640 MaxDistance=aD;
641 aFlag=Standard_True;
642 }
643
644 refd.Initialize(CRef, First, Last, CRef.Resolution(Tol));
645 otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol));
646
647 for (i = 2; i< aNC1; i++) {
648 Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1;
649 gp_Pnt pref = CRef.Value(rprm);
650
651 Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1;
652 gp_Pnt pother = Other.Value(oprm);
653
654 refd.Perform(pother,rprm);
655 if (!refd.IsDone() || refd.SquareDistance() > Tol2) {
656 if (refd.IsDone()) {
657 aD=refd.SquareDistance();
658 if (aD > Tol2 && aD>MaxDistance) {
659 aFlag=Standard_True;
660 MaxDistance=aD;
661 }
662 }
663 }
664
665 otherd.Perform(pref,oprm);
666 if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) {
667
668 if (otherd.IsDone()) {
669 aD=otherd.SquareDistance();
670 if (aD > Tol2 && aD>MaxDistance) {
671 aFlag=Standard_True;
672 MaxDistance=aD;
673 }
674 }
675 }
676 }
677 }
678
679 aD=sqrt (MaxDistance);
680 aNewTolerance=aD;
681
682 return aFlag;
683
684}
685
686//=======================================================================
687// Function : CheckEdge
688// purpose : Correct tolerances for Vertices on Edge
689//=======================================================================
690void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol)
691{
692 TopoDS_Edge E=Ed;
693 E.Orientation(TopAbs_FORWARD);
694
695 gp_Pnt Controlp;
696
697 TopExp_Explorer aVExp;
698 aVExp.Init(E, TopAbs_VERTEX);
699 for (; aVExp.More(); aVExp.Next()) {
700 TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current());
701
702 Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape());
703 const gp_Pnt& prep = TV->Pnt();
704
705 Standard_Real Tol, aD2, aNewTolerance, dd;
706
707 Tol =BRep_Tool::Tolerance(aVertex);
708 Tol = Max(Tol, BRep_Tool::Tolerance(E));
709 dd=0.1*Tol;
710 Tol*=Tol;
711
712 const TopLoc_Location& Eloc = E.Location();
713 BRep_ListIteratorOfListOfPointRepresentation itpr;
714
715 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
716 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
717 while (itcr.More()) {
718 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
719 const TopLoc_Location& loc = cr->Location();
720 TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location());
721
722 if (cr->IsCurve3D()) {
723 const Handle(Geom_Curve)& C = cr->Curve3D();
724 if (!C.IsNull()) {
725 itpr.Initialize(TV->Points());
726 while (itpr.More()) {
727 const Handle(BRep_PointRepresentation)& pr = itpr.Value();
728 if (pr->IsPointOnCurve(C,L)) {
729 Controlp = C->Value(pr->Parameter());
730 Controlp.Transform(L.Transformation());
731 aD2=prep.SquareDistance(Controlp);
732 if (aD2 > Tol) {
733 aNewTolerance=sqrt(aD2)+dd;
734 if (aNewTolerance<aMaxTol)
735 TV->UpdateTolerance(aNewTolerance);
736 }
737 }
738 itpr.Next();
739 }
740
741 TopAbs_Orientation orv = aVertex.Orientation();
742 if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) {
743 const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr);
744
745 if (orv==TopAbs_FORWARD)
746 Controlp = C->Value(GC->First());
747 else
748 Controlp = C->Value(GC->Last());
749
750 Controlp.Transform(L.Transformation());
751 aD2=prep.SquareDistance(Controlp);
752
753 if (aD2 > Tol) {
754 aNewTolerance=sqrt(aD2)+dd;
755 if (aNewTolerance<aMaxTol)
756 TV->UpdateTolerance(aNewTolerance);
757 }
758 }
759 }
760 }
761 itcr.Next();
762 }
763 }
764}
765
766//=======================================================================
767// Function : UpdateVertices
768// purpose :
769//=======================================================================
770 void UpdateVertices(const TopoDS_Edge& aE)
771{
772 Standard_Real aTolE, aTolV;
773 TopoDS_Iterator aItE;
774 BRep_Builder aBB;
775 //
776 aTolE = BRep_Tool::Tolerance(aE);
777 aItE.Initialize(aE);
778 for (; aItE.More(); aItE.Next()) {
779 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItE.Value();
780 aTolV = BRep_Tool::Tolerance(aV);
781 if (aTolV < aTolE) {
782 aBB.UpdateVertex(aV, aTolE);
783 }
784 }
785}
786//=======================================================================
787// Function : UpdateEdges
788// purpose :
789//=======================================================================
790 void UpdateEdges(const TopoDS_Face& aF)
791{
792 Standard_Real aTolF, aTolE, aTolV;
793 TopoDS_Iterator aItF, aItW, aItE;
794 BRep_Builder aBB;
795 //
1d47d8d0 796 aTolE = aTolF = BRep_Tool::Tolerance(aF);
4e57c75e 797 aItF.Initialize(aF);
798 for (; aItF.More(); aItF.Next()) {
799 const TopoDS_Shape& aS = aItF.Value();
800 if (aS.ShapeType()==TopAbs_WIRE) {
801 aItW.Initialize(aS);
802 for (; aItW.More(); aItW.Next()) {
803 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItW.Value();
804 aTolE = BRep_Tool::Tolerance(aE);
805 if (aTolE < aTolF) {
806 aBB.UpdateEdge(aE, aTolF);
807 aTolE = aTolF;
808 }
809 UpdateVertices(aE);
810 }
811 }
812 else {
813 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItF.Value();
814 aTolV = BRep_Tool::Tolerance(aV);
815 if (aTolV < aTolE) {
816 aBB.UpdateVertex(aV, aTolF);
817 }
818 }
819 }
820}