0023705: Isoline in the AIS viewer is not trimmed
[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   Standard_Real aHatchingTol = 1.e100;
146
147   UMin = VMin = 1.e100;
148   UMax = VMax = -1.e100;
149   
150   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
151     TopAbs_Orientation Orient = ToolRst.Orientation();
152     if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
153       Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
154       if (TheRCurve->GetType() != GeomAbs_Line) {
155         GCPnts_QuasiUniformDeflection UDP(*TheRCurve, ddefle);
156         if (UDP.IsDone()) {
157           Standard_Integer NumberOfPoints = UDP.NbPoints();
158           if ( NumberOfPoints >= 2 ) {
159             dummypnt = UDP.Value(1);
160             P2.SetCoord(dummypnt.X(), dummypnt.Y());
161             UMin = Min(P2.X(), UMin);
162             UMax = Max(P2.X(), UMax);
163             VMin = Min(P2.Y(), VMin);
164             VMax = Max(P2.Y(), VMax);
165             for (i = 2; i <= NumberOfPoints; i++) {
166               P1 = P2;
167               dummypnt = UDP.Value(i);
168               P2.SetCoord(dummypnt.X(), dummypnt.Y());
169               UMin = Min(P2.X(), UMin);
170               UMax = Max(P2.X(), UMax);
171               VMin = Min(P2.Y(), VMin);
172               VMax = Max(P2.Y(), VMax);
173               aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
174
175               if(Orient == TopAbs_FORWARD ) {
176                 //isobuild.Trim(P1,P2);
177                 tabP.Append(P1);
178                 tabP.Append(P2);
179               }
180               else {
181                 //isobuild.Trim(P2,P1);
182                 tabP.Append(P2);
183                 tabP.Append(P1);
184               }
185             }
186           }
187         }
188         else {
189           cout << "Cannot evaluate curve on surface"<<endl;
190         }
191       }
192       else {
193         U1 = TheRCurve->FirstParameter();
194         U2 = TheRCurve->LastParameter();
195         // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
196         // ensure that distance U2-U1 is not greater than aLimit*2,
197         // if greater then choose an origin and use aLimit to define
198         // U1 and U2 anew
199         Standard_Real aOrigin = 0.;
200         if (!Precision::IsNegativeInfinite(U1) || !Precision::IsPositiveInfinite(U2)) {
201           if (Precision::IsNegativeInfinite(U1))
202             aOrigin = U2 - aLimit;
203           else if (Precision::IsPositiveInfinite(U2))
204             aOrigin = U1 + aLimit;
205           else
206             aOrigin = (U1 + U2) * 0.5;
207         }
208         U1 = Max(aOrigin - aLimit, U1);
209         U2 = Min(aOrigin + aLimit, U2);
210         P1 = TheRCurve->Value(U1);
211         P2 = TheRCurve->Value(U2);
212         UMin = Min(P1.X(), UMin);
213         UMax = Max(P1.X(), UMax);
214         VMin = Min(P1.Y(), VMin);
215         VMax = Max(P1.Y(), VMax);
216         UMin = Min(P2.X(), UMin);
217         UMax = Max(P2.X(), UMax);
218         VMin = Min(P2.Y(), VMin);
219         VMax = Max(P2.Y(), VMax);
220         aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
221
222         if(Orient == TopAbs_FORWARD ) {
223          // isobuild.Trim(P1,P2);
224           tabP.Append(P1);
225           tabP.Append(P2);
226         }
227         else {
228           //isobuild.Trim(P2,P1);
229           tabP.Append(P2);
230           tabP.Append(P1);
231         }
232       }
233     }
234   }
235
236
237 #ifdef DEB_MESH
238   FFaceTimer1.Stop();
239
240   FFaceTimer2.Start();
241 #endif
242
243   // Compute the hatching tolerance.
244   aHatchingTol *= 0.1;
245   aHatchingTol = Max(Precision::Confusion(), aHatchingTol);
246   aHatchingTol = Min(1.e-5, aHatchingTol);
247
248   // load the isos
249   Hatch_Hatcher isobuild(aHatchingTol, ToolRst.IsOriented());
250   Standard_Boolean UClosed = aFace->IsUClosed();
251   Standard_Boolean VClosed = aFace->IsVClosed();
252
253   if ( ! UClosed ) {
254     UMin = UMin + ( UMax - UMin) /1000.;
255     UMax = UMax - ( UMax - UMin) /1000.; 
256   }
257
258   if ( ! VClosed ) {
259     VMin = VMin + ( VMax - VMin) /1000.;
260     VMax = VMax - ( VMax - VMin) /1000.; 
261   }
262
263   if (DrawUIso){
264     if (NBUiso > 0) {
265       UClosed = Standard_False; // En attendant un hatcher de course.
266       Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
267       for (i=1; i<=NBUiso;i++){
268         isobuild.AddXLine(UMin+du*i);
269       }
270     }
271   }
272   if (DrawVIso){
273     if ( NBViso > 0) {
274       VClosed = Standard_False;
275       Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
276       for (i=1; i<=NBViso;i++){
277         isobuild.AddYLine(VMin+dv*i);
278       }
279     }
280   }
281
282 #ifdef DEB_MESH
283   FFaceTimer2.Stop();
284   FFaceTimer3.Start();
285 #endif
286
287   
288   Standard_Integer ll = tabP.Length();
289   for (i = 1; i <= ll; i+=2) {
290     isobuild.Trim(tabP(i),tabP(i+1));
291   }
292
293
294 #ifdef DEB_MESH  
295   FFaceTimer3.Stop();
296   FFaceTimer4.Start();
297 #endif
298
299   // draw the isos
300
301   Adaptor3d_IsoCurve anIso;
302   anIso.Load(aFace);
303   Handle(Geom_Curve) BC;
304   const BRepAdaptor_Surface& BS = *(BRepAdaptor_Surface*)&(aFace->Surface());
305   GeomAbs_SurfaceType thetype = aFace->GetType();
306
307   Standard_Integer NumberOfLines = isobuild.NbLines();
308   Handle(Geom_Surface) GB;
309   if (thetype == GeomAbs_BezierSurface) {
310     GB = BS.Bezier();
311   }
312   else if (thetype == GeomAbs_BSplineSurface){
313     GB = BS.BSpline();
314   }
315
316   Standard_Real anAngle = aDrawer->DeviationAngle();
317
318   for (i = 1; i <= NumberOfLines; i++) {
319     Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
320     Standard_Real Coord = isobuild.Coordinate(i);
321     for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
322       Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
323
324
325       if (!GB.IsNull()) {
326         if (isobuild.IsXLine(i))
327           BC = GB->UIso(Coord);
328         else 
329           BC = GB->VIso(Coord);
330         GeomAdaptor_Curve GC(BC);
331         FindLimits(GC, aLimit,b1, b2);
332         if (b2-b1>Precision::Confusion()) {
333           TColgp_SequenceOfPnt Points;
334           StdPrs_DeflectionCurve::Add(aPresentation, GC, b1, b2, Deflection, Points, anAngle, Standard_False);
335           Curves.Append(Points);
336         }
337       }
338       else {
339         if (isobuild.IsXLine(i))
340           anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
341         else
342           anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
343         FindLimits(anIso, aLimit,b1, b2);
344         if (b2-b1>Precision::Confusion()) {
345           TColgp_SequenceOfPnt Points;
346           StdPrs_DeflectionCurve::Add(aPresentation, anIso, b1, b2, Deflection, Points, anAngle, Standard_False);
347           Curves.Append(Points);
348         }
349       }
350     }
351   }
352 #ifdef DEB_MESH
353   FFaceTimer4.Stop();
354 #endif
355 }
356
357
358 //=========================================================================
359 // function: Match
360 // purpose
361 //=========================================================================
362 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
363   (const Quantity_Length X,
364    const Quantity_Length Y,
365    const Quantity_Length Z,
366    const Quantity_Length aDistance,
367    const Handle(BRepAdaptor_HSurface)& aFace,
368    const Handle(Prs3d_Drawer)& aDrawer,
369    const Standard_Boolean DrawUIso,
370    const Standard_Boolean DrawVIso,
371    const Quantity_Length Deflection,
372    const Standard_Integer NBUiso,
373    const Standard_Integer NBViso)
374 {
375
376    StdPrs_ToolRFace ToolRst (aFace);
377    const Standard_Real aLimit = aDrawer->MaximalParameterValue();
378
379   // compute bounds of the restriction
380   Standard_Real UMin,UMax,VMin,VMax;
381   Standard_Real u,v,step;
382   Standard_Integer i,nbPoints = 10;
383   UMin = VMin = RealLast();
384   UMax = VMax = RealFirst();
385   
386   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
387     Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
388     u = TheRCurve->FirstParameter();
389     v = TheRCurve->LastParameter();
390     step = ( v - u) / nbPoints;
391     for (i = 0; i <= nbPoints; i++) {
392       gp_Pnt2d P = TheRCurve->Value(u);
393       if (P.X() < UMin) UMin = P.X();
394       if (P.X() > UMax) UMax = P.X();
395       if (P.Y() < VMin) VMin = P.Y();
396       if (P.Y() > VMax) VMax = P.Y();
397       u += step;
398     }
399   }
400   
401   // load the isos
402   Hatch_Hatcher isobuild(1.e-5,ToolRst.IsOriented());
403   Standard_Boolean UClosed = aFace->IsUClosed();
404   Standard_Boolean VClosed = aFace->IsVClosed();
405
406   if ( ! UClosed ) {
407     UMin = UMin + ( UMax - UMin) /1000.;
408     UMax = UMax - ( UMax - UMin) /1000.; 
409   }
410
411   if ( ! VClosed ) {
412     VMin = VMin + ( VMax - VMin) /1000.;
413     VMax = VMax - ( VMax - VMin) /1000.; 
414   }
415
416   if (DrawUIso){
417     if (NBUiso > 0) {
418       UClosed = Standard_False; // En attendant un hatcher de course.
419       Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
420       for (i=1; i<=NBUiso;i++){
421         isobuild.AddXLine(UMin+du*i);
422       }
423     }
424   }
425   if (DrawVIso){
426     if ( NBViso > 0) {
427       VClosed = Standard_False;
428       Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
429       for (i=1; i<=NBViso;i++){
430         isobuild.AddYLine(VMin+dv*i);
431       }
432     }
433   }
434
435   // trim the isos
436   gp_Pnt2d P1,P2;
437   gp_Pnt dummypnt;
438   for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
439     TopAbs_Orientation Orient = ToolRst.Orientation();
440     if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
441       Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
442       GCPnts_QuasiUniformDeflection UDP(*TheRCurve, Deflection);
443       if (UDP.IsDone()) {
444         Standard_Integer NumberOfPoints = UDP.NbPoints();
445         if ( NumberOfPoints >= 2 ) {
446           dummypnt = UDP.Value(1);
447           P2.SetCoord(dummypnt.X(), dummypnt.Y());
448           for (i = 2; i <= NumberOfPoints; i++) {
449             P1 = P2;
450             dummypnt = UDP.Value(i);
451             P2.SetCoord(dummypnt.X(), dummypnt.Y());
452             if(Orient == TopAbs_FORWARD )
453               isobuild.Trim(P1,P2);
454             else
455               isobuild.Trim(P2,P1);
456           }
457         }
458       }
459       else {
460         cout << "Cannot evaluate curve on surface"<<endl;
461       }
462     }
463   }
464   
465   // draw the isos
466
467   Adaptor3d_IsoCurve anIso;
468   anIso.Load(aFace);
469   Standard_Integer NumberOfLines = isobuild.NbLines();
470   Standard_Real anAngle = aDrawer->DeviationAngle();
471
472   for (i = 1; i <= NumberOfLines; i++) {
473     Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
474     Standard_Real Coord = isobuild.Coordinate(i);
475     for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
476       Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
477
478       b1 = b1 == RealFirst() ? - aLimit : b1;
479       b2 = b2 == RealLast()  ?   aLimit : b2;
480
481       if (isobuild.IsXLine(i))
482         anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
483       else
484         anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
485     
486       if (StdPrs_DeflectionCurve::Match(X,Y,Z,aDistance,anIso, b1, b2, Deflection, anAngle))
487           return Standard_True;
488     }
489   }
490   return Standard_False;
491 }
492
493
494 //=========================================================================
495 // function: Add
496 // purpose
497 //=========================================================================
498 void StdPrs_WFDeflectionRestrictedFace::Add
499   (const Handle (Prs3d_Presentation)& aPresentation,
500    const Handle(BRepAdaptor_HSurface)& aFace,
501    const Handle (Prs3d_Drawer)& aDrawer)
502 {
503   Prs3d_NListOfSequenceOfPnt Curves;
504   StdPrs_WFDeflectionRestrictedFace::Add (aPresentation,
505                                           aFace,
506                                           Standard_True,
507                                           Standard_True,
508                                           aDrawer->MaximalChordialDeviation(),
509                                           aDrawer->UIsoAspect()->Number(),
510                                           aDrawer->VIsoAspect()->Number(),
511                                           aDrawer,
512                                           Curves);
513 }
514
515
516 //=========================================================================
517 // function: AddUIso
518 // purpose
519 //=========================================================================
520 void StdPrs_WFDeflectionRestrictedFace::AddUIso
521   (const Handle (Prs3d_Presentation)& aPresentation,
522    const Handle(BRepAdaptor_HSurface)& aFace,
523    const Handle (Prs3d_Drawer)& aDrawer)
524 {
525   Prs3d_NListOfSequenceOfPnt Curves;
526   StdPrs_WFDeflectionRestrictedFace::Add ( 
527                       aPresentation,
528                       aFace,
529                       Standard_True,
530                       Standard_False,
531                       aDrawer->MaximalChordialDeviation(),
532                       aDrawer->UIsoAspect()->Number(),
533                       aDrawer->VIsoAspect()->Number(),
534                       aDrawer,
535                       Curves);
536 }
537
538
539 //=========================================================================
540 // function: AddVIso
541 // purpose
542 //=========================================================================
543 void StdPrs_WFDeflectionRestrictedFace::AddVIso
544   (const Handle (Prs3d_Presentation)& aPresentation,
545    const Handle(BRepAdaptor_HSurface)& aFace,
546    const Handle (Prs3d_Drawer)& aDrawer)
547 {
548   Prs3d_NListOfSequenceOfPnt Curves;
549   StdPrs_WFDeflectionRestrictedFace::Add ( 
550                       aPresentation,
551                       aFace,
552                       Standard_False,
553                       Standard_True,
554                       aDrawer->MaximalChordialDeviation(),
555                       aDrawer->UIsoAspect()->Number(),
556                       aDrawer->VIsoAspect()->Number(),
557                       aDrawer,
558                       Curves);
559 }
560
561
562 //=========================================================================
563 // function: Match
564 // purpose
565 //=========================================================================
566 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
567   (const Quantity_Length X,
568    const Quantity_Length Y,
569    const Quantity_Length Z,
570    const Quantity_Length aDistance,
571    const Handle(BRepAdaptor_HSurface)& aFace,
572    const Handle (Prs3d_Drawer)& aDrawer)
573 {
574   return StdPrs_WFDeflectionRestrictedFace::Match (  
575                       X,Y,Z,aDistance,
576                       aFace,
577                       aDrawer,
578                       Standard_True,
579                       Standard_True,
580                       aDrawer->MaximalChordialDeviation(),
581                       aDrawer->UIsoAspect()->Number(),
582                       aDrawer->VIsoAspect()->Number());
583 }
584
585
586 //=========================================================================
587 // function: MatchUIso
588 // purpose
589 //=========================================================================
590 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchUIso
591   (const Quantity_Length X,
592    const Quantity_Length Y,
593    const Quantity_Length Z,
594    const Quantity_Length aDistance,
595    const Handle(BRepAdaptor_HSurface)& aFace,
596    const Handle (Prs3d_Drawer)& aDrawer)
597 {
598   return StdPrs_WFDeflectionRestrictedFace::Match ( 
599                       X,Y,Z,aDistance,
600                       aFace,
601                       aDrawer,
602                       Standard_True,
603                       Standard_False,
604                       aDrawer->MaximalChordialDeviation(),
605                       aDrawer->UIsoAspect()->Number(),
606                       aDrawer->VIsoAspect()->Number());
607 }
608
609
610 //=========================================================================
611 // function: MatchVIso
612 // purpose
613 //=========================================================================
614 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
615   (const Quantity_Length X,
616    const Quantity_Length Y,
617    const Quantity_Length Z,
618    const Quantity_Length aDistance,
619    const Handle(BRepAdaptor_HSurface)& aFace,
620    const Handle (Prs3d_Drawer)& aDrawer)
621 {
622   return StdPrs_WFDeflectionRestrictedFace::Match ( 
623                       X,Y,Z,aDistance,
624                       aFace,
625                       aDrawer,
626                       Standard_False,
627                       Standard_True,
628                       aDrawer->MaximalChordialDeviation(),
629                       aDrawer->UIsoAspect()->Number(),
630                       aDrawer->VIsoAspect()->Number());
631 }