dfe4c045b4ca5d6eff3c5b7f2d30713dd4614557
[occt.git] / src / StdPrs / StdPrs_WFDeflectionRestrictedFace.cxx
1 // Created on: 1995-08-07
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <StdPrs_WFDeflectionRestrictedFace.ixx>
18
19 #include <Hatch_Hatcher.hxx>
20 #include <Graphic3d_Group.hxx>
21 #include <gp_Pnt.hxx>
22 #include <gp_Pnt2d.hxx>
23 #include <Prs3d_IsoAspect.hxx>
24 #include <Adaptor2d_Curve2d.hxx>
25 #include <GCPnts_QuasiUniformDeflection.hxx>
26 #include <Adaptor3d_IsoCurve.hxx>
27 #include <StdPrs_DeflectionCurve.hxx>
28 #include <StdPrs_ToolRFace.hxx>
29 #include <Bnd_Box2d.hxx>
30 #include <BndLib_Add2dCurve.hxx>
31 #include <Precision.hxx>
32 #include <GeomAdaptor_Curve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <GeomAbs_SurfaceType.hxx>
35 #include <Geom_Surface.hxx>
36 #include <TColgp_SequenceOfPnt2d.hxx>
37
38
39
40
41 #ifdef DEB_MESH
42 #include <OSD_Chronometer.hxx>
43 extern OSD_Chronometer FFaceTimer1,FFaceTimer2,FFaceTimer3,FFaceTimer4;
44 #endif
45
46
47 //==================================================================
48 // function: FindLimits
49 // purpose:
50 //==================================================================
51 static void FindLimits(const Adaptor3d_Curve& aCurve,
52                        const Standard_Real  aLimit,
53                        Standard_Real&       First,
54                        Standard_Real&       Last)
55 {
56   First = Max(aCurve.FirstParameter(), First);
57   Last  = Min(aCurve.LastParameter(), Last);
58   Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
59   Standard_Boolean lastInf  = Precision::IsPositiveInfinite(Last);
60
61   if (firstInf || lastInf) {
62     gp_Pnt P1,P2;
63     Standard_Real delta = 1;
64     if (firstInf && lastInf) {
65       do {
66         delta *= 2;
67         First = - delta;
68         Last  =   delta;
69         aCurve.D0(First,P1);
70         aCurve.D0(Last,P2);
71       } while (P1.Distance(P2) < aLimit);
72     }
73     else if (firstInf) {
74       aCurve.D0(Last,P2);
75       do {
76         delta *= 2;
77         First = Last - delta;
78         aCurve.D0(First,P1);
79       } while (P1.Distance(P2) < aLimit);
80     }
81     else if (lastInf) {
82       aCurve.D0(First,P1);
83       do {
84         delta *= 2;
85         Last = First + delta;
86         aCurve.D0(Last,P2);
87       } while (P1.Distance(P2) < aLimit);
88     }
89   }    
90
91 }
92
93
94 //=========================================================================
95 // function: Add
96 // purpose
97 //=========================================================================
98 void StdPrs_WFDeflectionRestrictedFace::Add
99   (const Handle (Prs3d_Presentation)& aPresentation,
100    const Handle(BRepAdaptor_HSurface)& aFace,
101    const Standard_Boolean DrawUIso,
102    const Standard_Boolean DrawVIso,
103    const Quantity_Length Deflection,
104    const Standard_Integer NBUiso,
105    const Standard_Integer NBViso,
106    const Handle(Prs3d_Drawer)& aDrawer,
107    Prs3d_NListOfSequenceOfPnt& Curves) {
108
109 #ifdef DEB_MESH
110   FFaceTimer1.Start();
111 #endif
112
113   StdPrs_ToolRFace ToolRst (aFace);
114   Standard_Real UF, UL, VF, VL;
115   UF = aFace->FirstUParameter();
116   UL = aFace->LastUParameter();
117   VF = aFace->FirstVParameter();
118   VL = aFace->LastVParameter();
119
120   Standard_Real aLimit = aDrawer->MaximalParameterValue();
121
122   // compute bounds of the restriction
123   Standard_Real UMin,UMax,VMin,VMax;
124   //Standard_Real u,v,step;
125   Standard_Integer i;//,nbPoints = 10;
126
127   UMin = Max(UF, -aLimit);
128   UMax = Min(UL, aLimit);
129   VMin = Max(VF, -aLimit);
130   VMax = Min(VL, aLimit);
131
132
133   // update min max for the hatcher.
134   gp_Pnt2d P1,P2;
135   Standard_Real U1, U2;
136   gp_Pnt dummypnt;
137   Standard_Real ddefle= Max(UMax-UMin, VMax-VMin) * aDrawer->DeviationCoefficient();
138   TColgp_SequenceOfPnt2d tabP;
139   Standard_Real aHatchingTol = 1.e100;
140
141   UMin = VMin = 1.e100;
142   UMax = VMax = -1.e100;
143   
144   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
145     TopAbs_Orientation Orient = ToolRst.Orientation();
146     if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
147       Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
148       if (TheRCurve->GetType() != GeomAbs_Line) {
149         GCPnts_QuasiUniformDeflection UDP(*TheRCurve, ddefle);
150         if (UDP.IsDone()) {
151           Standard_Integer NumberOfPoints = UDP.NbPoints();
152           if ( NumberOfPoints >= 2 ) {
153             dummypnt = UDP.Value(1);
154             P2.SetCoord(dummypnt.X(), dummypnt.Y());
155             UMin = Min(P2.X(), UMin);
156             UMax = Max(P2.X(), UMax);
157             VMin = Min(P2.Y(), VMin);
158             VMax = Max(P2.Y(), VMax);
159             for (i = 2; i <= NumberOfPoints; i++) {
160               P1 = P2;
161               dummypnt = UDP.Value(i);
162               P2.SetCoord(dummypnt.X(), dummypnt.Y());
163               UMin = Min(P2.X(), UMin);
164               UMax = Max(P2.X(), UMax);
165               VMin = Min(P2.Y(), VMin);
166               VMax = Max(P2.Y(), VMax);
167               aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
168
169               if(Orient == TopAbs_FORWARD ) {
170                 //isobuild.Trim(P1,P2);
171                 tabP.Append(P1);
172                 tabP.Append(P2);
173               }
174               else {
175                 //isobuild.Trim(P2,P1);
176                 tabP.Append(P2);
177                 tabP.Append(P1);
178               }
179             }
180           }
181         }
182         else {
183           cout << "Cannot evaluate curve on surface"<<endl;
184         }
185       }
186       else {
187         U1 = TheRCurve->FirstParameter();
188         U2 = TheRCurve->LastParameter();
189         // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
190         // ensure that distance U2-U1 is not greater than aLimit*2,
191         // if greater then choose an origin and use aLimit to define
192         // U1 and U2 anew
193         Standard_Real aOrigin = 0.;
194         if (!Precision::IsNegativeInfinite(U1) || !Precision::IsPositiveInfinite(U2)) {
195           if (Precision::IsNegativeInfinite(U1))
196             aOrigin = U2 - aLimit;
197           else if (Precision::IsPositiveInfinite(U2))
198             aOrigin = U1 + aLimit;
199           else
200             aOrigin = (U1 + U2) * 0.5;
201         }
202         U1 = Max(aOrigin - aLimit, U1);
203         U2 = Min(aOrigin + aLimit, U2);
204         P1 = TheRCurve->Value(U1);
205         P2 = TheRCurve->Value(U2);
206         UMin = Min(P1.X(), UMin);
207         UMax = Max(P1.X(), UMax);
208         VMin = Min(P1.Y(), VMin);
209         VMax = Max(P1.Y(), VMax);
210         UMin = Min(P2.X(), UMin);
211         UMax = Max(P2.X(), UMax);
212         VMin = Min(P2.Y(), VMin);
213         VMax = Max(P2.Y(), VMax);
214         aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
215
216         if(Orient == TopAbs_FORWARD ) {
217          // isobuild.Trim(P1,P2);
218           tabP.Append(P1);
219           tabP.Append(P2);
220         }
221         else {
222           //isobuild.Trim(P2,P1);
223           tabP.Append(P2);
224           tabP.Append(P1);
225         }
226       }
227     }
228   }
229
230
231 #ifdef DEB_MESH
232   FFaceTimer1.Stop();
233
234   FFaceTimer2.Start();
235 #endif
236
237   // Compute the hatching tolerance.
238   aHatchingTol *= 0.1;
239   aHatchingTol = Max(Precision::Confusion(), aHatchingTol);
240   aHatchingTol = Min(1.e-5, aHatchingTol);
241
242   // load the isos
243   Hatch_Hatcher isobuild(aHatchingTol, ToolRst.IsOriented());
244   Standard_Boolean UClosed = aFace->IsUClosed();
245   Standard_Boolean VClosed = aFace->IsVClosed();
246
247   if ( ! UClosed ) {
248     UMin = UMin + ( UMax - UMin) /1000.;
249     UMax = UMax - ( UMax - UMin) /1000.; 
250   }
251
252   if ( ! VClosed ) {
253     VMin = VMin + ( VMax - VMin) /1000.;
254     VMax = VMax - ( VMax - VMin) /1000.; 
255   }
256
257   if (DrawUIso){
258     if (NBUiso > 0) {
259       UClosed = Standard_False; // En attendant un hatcher de course.
260       Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
261       for (i=1; i<=NBUiso;i++){
262         isobuild.AddXLine(UMin+du*i);
263       }
264     }
265   }
266   if (DrawVIso){
267     if ( NBViso > 0) {
268       VClosed = Standard_False;
269       Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
270       for (i=1; i<=NBViso;i++){
271         isobuild.AddYLine(VMin+dv*i);
272       }
273     }
274   }
275
276 #ifdef DEB_MESH
277   FFaceTimer2.Stop();
278   FFaceTimer3.Start();
279 #endif
280
281   
282   Standard_Integer ll = tabP.Length();
283   for (i = 1; i <= ll; i+=2) {
284     isobuild.Trim(tabP(i),tabP(i+1));
285   }
286
287
288 #ifdef DEB_MESH  
289   FFaceTimer3.Stop();
290   FFaceTimer4.Start();
291 #endif
292
293   // draw the isos
294
295   Adaptor3d_IsoCurve anIso;
296   anIso.Load(aFace);
297   Handle(Geom_Curve) BC;
298   const BRepAdaptor_Surface& BS = *(BRepAdaptor_Surface*)&(aFace->Surface());
299   GeomAbs_SurfaceType thetype = aFace->GetType();
300
301   Standard_Integer NumberOfLines = isobuild.NbLines();
302   Handle(Geom_Surface) GB;
303   if (thetype == GeomAbs_BezierSurface) {
304     GB = BS.Bezier();
305   }
306   else if (thetype == GeomAbs_BSplineSurface){
307     GB = BS.BSpline();
308   }
309
310   Standard_Real anAngle = aDrawer->DeviationAngle();
311
312   for (i = 1; i <= NumberOfLines; i++) {
313     Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
314     Standard_Real Coord = isobuild.Coordinate(i);
315     for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
316       Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
317
318
319       if (!GB.IsNull()) {
320         if (isobuild.IsXLine(i))
321           BC = GB->UIso(Coord);
322         else 
323           BC = GB->VIso(Coord);
324         GeomAdaptor_Curve GC(BC);
325         FindLimits(GC, aLimit,b1, b2);
326         if (b2-b1>Precision::Confusion()) {
327           Handle(TColgp_HSequenceOfPnt) Points = new TColgp_HSequenceOfPnt;
328           StdPrs_DeflectionCurve::Add (aPresentation, GC, b1, b2, Deflection, 
329                                        Points->ChangeSequence(), anAngle, Standard_False);
330           Curves.Append(Points);
331         }
332       }
333       else {
334         if (isobuild.IsXLine(i))
335           anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
336         else
337           anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
338         FindLimits(anIso, aLimit,b1, b2);
339         if (b2-b1>Precision::Confusion()) {
340           Handle(TColgp_HSequenceOfPnt) Points = new TColgp_HSequenceOfPnt;
341           StdPrs_DeflectionCurve::Add (aPresentation, anIso, b1, b2, Deflection, 
342                                        Points->ChangeSequence(), anAngle, Standard_False);
343           Curves.Append(Points);
344         }
345       }
346     }
347   }
348 #ifdef DEB_MESH
349   FFaceTimer4.Stop();
350 #endif
351 }
352
353
354 //=========================================================================
355 // function: Match
356 // purpose
357 //=========================================================================
358 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
359   (const Quantity_Length X,
360    const Quantity_Length Y,
361    const Quantity_Length Z,
362    const Quantity_Length aDistance,
363    const Handle(BRepAdaptor_HSurface)& aFace,
364    const Handle(Prs3d_Drawer)& aDrawer,
365    const Standard_Boolean DrawUIso,
366    const Standard_Boolean DrawVIso,
367    const Quantity_Length Deflection,
368    const Standard_Integer NBUiso,
369    const Standard_Integer NBViso)
370 {
371
372    StdPrs_ToolRFace ToolRst (aFace);
373    const Standard_Real aLimit = aDrawer->MaximalParameterValue();
374
375   // compute bounds of the restriction
376   Standard_Real UMin,UMax,VMin,VMax;
377   Standard_Real u,v,step;
378   Standard_Integer i,nbPoints = 10;
379   UMin = VMin = RealLast();
380   UMax = VMax = RealFirst();
381   
382   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
383     Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
384     u = TheRCurve->FirstParameter();
385     v = TheRCurve->LastParameter();
386     step = ( v - u) / nbPoints;
387     for (i = 0; i <= nbPoints; i++) {
388       gp_Pnt2d P = TheRCurve->Value(u);
389       if (P.X() < UMin) UMin = P.X();
390       if (P.X() > UMax) UMax = P.X();
391       if (P.Y() < VMin) VMin = P.Y();
392       if (P.Y() > VMax) VMax = P.Y();
393       u += step;
394     }
395   }
396   
397   // load the isos
398   Hatch_Hatcher isobuild(1.e-5,ToolRst.IsOriented());
399   Standard_Boolean UClosed = aFace->IsUClosed();
400   Standard_Boolean VClosed = aFace->IsVClosed();
401
402   if ( ! UClosed ) {
403     UMin = UMin + ( UMax - UMin) /1000.;
404     UMax = UMax - ( UMax - UMin) /1000.; 
405   }
406
407   if ( ! VClosed ) {
408     VMin = VMin + ( VMax - VMin) /1000.;
409     VMax = VMax - ( VMax - VMin) /1000.; 
410   }
411
412   if (DrawUIso){
413     if (NBUiso > 0) {
414       UClosed = Standard_False; // En attendant un hatcher de course.
415       Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
416       for (i=1; i<=NBUiso;i++){
417         isobuild.AddXLine(UMin+du*i);
418       }
419     }
420   }
421   if (DrawVIso){
422     if ( NBViso > 0) {
423       VClosed = Standard_False;
424       Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
425       for (i=1; i<=NBViso;i++){
426         isobuild.AddYLine(VMin+dv*i);
427       }
428     }
429   }
430
431   // trim the isos
432   gp_Pnt2d P1,P2;
433   gp_Pnt dummypnt;
434   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
435     TopAbs_Orientation Orient = ToolRst.Orientation();
436     if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
437       Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
438       GCPnts_QuasiUniformDeflection UDP(*TheRCurve, Deflection);
439       if (UDP.IsDone()) {
440         Standard_Integer NumberOfPoints = UDP.NbPoints();
441         if ( NumberOfPoints >= 2 ) {
442           dummypnt = UDP.Value(1);
443           P2.SetCoord(dummypnt.X(), dummypnt.Y());
444           for (i = 2; i <= NumberOfPoints; i++) {
445             P1 = P2;
446             dummypnt = UDP.Value(i);
447             P2.SetCoord(dummypnt.X(), dummypnt.Y());
448             if(Orient == TopAbs_FORWARD )
449               isobuild.Trim(P1,P2);
450             else
451               isobuild.Trim(P2,P1);
452           }
453         }
454       }
455       else {
456         cout << "Cannot evaluate curve on surface"<<endl;
457       }
458     }
459   }
460   
461   // draw the isos
462
463   Adaptor3d_IsoCurve anIso;
464   anIso.Load(aFace);
465   Standard_Integer NumberOfLines = isobuild.NbLines();
466   Standard_Real anAngle = aDrawer->DeviationAngle();
467
468   for (i = 1; i <= NumberOfLines; i++) {
469     Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
470     Standard_Real Coord = isobuild.Coordinate(i);
471     for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
472       Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
473
474       b1 = b1 == RealFirst() ? - aLimit : b1;
475       b2 = b2 == RealLast()  ?   aLimit : b2;
476
477       if (isobuild.IsXLine(i))
478         anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
479       else
480         anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
481     
482       if (StdPrs_DeflectionCurve::Match(X,Y,Z,aDistance,anIso, b1, b2, Deflection, anAngle))
483           return Standard_True;
484     }
485   }
486   return Standard_False;
487 }
488
489
490 //=========================================================================
491 // function: Add
492 // purpose
493 //=========================================================================
494 void StdPrs_WFDeflectionRestrictedFace::Add
495   (const Handle (Prs3d_Presentation)& aPresentation,
496    const Handle(BRepAdaptor_HSurface)& aFace,
497    const Handle (Prs3d_Drawer)& aDrawer)
498 {
499   Prs3d_NListOfSequenceOfPnt Curves;
500   StdPrs_WFDeflectionRestrictedFace::Add (aPresentation,
501                                           aFace,
502                                           Standard_True,
503                                           Standard_True,
504                                           aDrawer->MaximalChordialDeviation(),
505                                           aDrawer->UIsoAspect()->Number(),
506                                           aDrawer->VIsoAspect()->Number(),
507                                           aDrawer,
508                                           Curves);
509 }
510
511
512 //=========================================================================
513 // function: AddUIso
514 // purpose
515 //=========================================================================
516 void StdPrs_WFDeflectionRestrictedFace::AddUIso
517   (const Handle (Prs3d_Presentation)& aPresentation,
518    const Handle(BRepAdaptor_HSurface)& aFace,
519    const Handle (Prs3d_Drawer)& aDrawer)
520 {
521   Prs3d_NListOfSequenceOfPnt Curves;
522   StdPrs_WFDeflectionRestrictedFace::Add ( 
523                       aPresentation,
524                       aFace,
525                       Standard_True,
526                       Standard_False,
527                       aDrawer->MaximalChordialDeviation(),
528                       aDrawer->UIsoAspect()->Number(),
529                       aDrawer->VIsoAspect()->Number(),
530                       aDrawer,
531                       Curves);
532 }
533
534
535 //=========================================================================
536 // function: AddVIso
537 // purpose
538 //=========================================================================
539 void StdPrs_WFDeflectionRestrictedFace::AddVIso
540   (const Handle (Prs3d_Presentation)& aPresentation,
541    const Handle(BRepAdaptor_HSurface)& aFace,
542    const Handle (Prs3d_Drawer)& aDrawer)
543 {
544   Prs3d_NListOfSequenceOfPnt Curves;
545   StdPrs_WFDeflectionRestrictedFace::Add ( 
546                       aPresentation,
547                       aFace,
548                       Standard_False,
549                       Standard_True,
550                       aDrawer->MaximalChordialDeviation(),
551                       aDrawer->UIsoAspect()->Number(),
552                       aDrawer->VIsoAspect()->Number(),
553                       aDrawer,
554                       Curves);
555 }
556
557
558 //=========================================================================
559 // function: Match
560 // purpose
561 //=========================================================================
562 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
563   (const Quantity_Length X,
564    const Quantity_Length Y,
565    const Quantity_Length Z,
566    const Quantity_Length aDistance,
567    const Handle(BRepAdaptor_HSurface)& aFace,
568    const Handle (Prs3d_Drawer)& aDrawer)
569 {
570   return StdPrs_WFDeflectionRestrictedFace::Match (  
571                       X,Y,Z,aDistance,
572                       aFace,
573                       aDrawer,
574                       Standard_True,
575                       Standard_True,
576                       aDrawer->MaximalChordialDeviation(),
577                       aDrawer->UIsoAspect()->Number(),
578                       aDrawer->VIsoAspect()->Number());
579 }
580
581
582 //=========================================================================
583 // function: MatchUIso
584 // purpose
585 //=========================================================================
586 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchUIso
587   (const Quantity_Length X,
588    const Quantity_Length Y,
589    const Quantity_Length Z,
590    const Quantity_Length aDistance,
591    const Handle(BRepAdaptor_HSurface)& aFace,
592    const Handle (Prs3d_Drawer)& aDrawer)
593 {
594   return StdPrs_WFDeflectionRestrictedFace::Match ( 
595                       X,Y,Z,aDistance,
596                       aFace,
597                       aDrawer,
598                       Standard_True,
599                       Standard_False,
600                       aDrawer->MaximalChordialDeviation(),
601                       aDrawer->UIsoAspect()->Number(),
602                       aDrawer->VIsoAspect()->Number());
603 }
604
605
606 //=========================================================================
607 // function: MatchVIso
608 // purpose
609 //=========================================================================
610 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
611   (const Quantity_Length X,
612    const Quantity_Length Y,
613    const Quantity_Length Z,
614    const Quantity_Length aDistance,
615    const Handle(BRepAdaptor_HSurface)& aFace,
616    const Handle (Prs3d_Drawer)& aDrawer)
617 {
618   return StdPrs_WFDeflectionRestrictedFace::Match ( 
619                       X,Y,Z,aDistance,
620                       aFace,
621                       aDrawer,
622                       Standard_False,
623                       Standard_True,
624                       aDrawer->MaximalChordialDeviation(),
625                       aDrawer->UIsoAspect()->Number(),
626                       aDrawer->VIsoAspect()->Number());
627 }