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