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