0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / DrawTrSurf / DrawTrSurf_Surface.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <DrawTrSurf_Surface.ixx>
16 #include <GeomTools_SurfaceSet.hxx>
17 #include <GeomAdaptor_HSurface.hxx>
18 #include <Adaptor3d_IsoCurve.hxx>
19 #include <Precision.hxx>
20
21 Standard_Real DrawTrSurf_SurfaceLimit = 400;
22
23
24 //=======================================================================
25 //function : DrawTrSurf_Surface
26 //purpose  : 
27 //=======================================================================
28
29 DrawTrSurf_Surface::DrawTrSurf_Surface (const Handle(Geom_Surface)& S) 
30 : DrawTrSurf_Drawable (16, 0.01, 1) 
31 {
32   surf = S;
33   boundsLook = Draw_jaune;
34   isosLook = Draw_bleu;
35   nbUIsos = 1;
36   nbVIsos = 1;
37 }
38
39
40
41
42 //=======================================================================
43 //function : DrawTrSurf_Surface
44 //purpose  : 
45 //=======================================================================
46
47 DrawTrSurf_Surface::DrawTrSurf_Surface 
48   (const Handle(Geom_Surface)& S, const Standard_Integer Nu, 
49    const Standard_Integer Nv,
50    const Draw_Color& BoundsColor, const Draw_Color& IsosColor,
51    const Standard_Integer Discret, const Standard_Real Deflection,
52    const Standard_Integer DrawMode) 
53 :  DrawTrSurf_Drawable (Discret, Deflection, DrawMode) 
54 {
55   surf = S;
56   boundsLook = BoundsColor;
57   isosLook = IsosColor;
58   nbUIsos = Abs(Nu);
59   nbVIsos = Abs(Nv);
60 }
61
62
63
64 //=======================================================================
65 //function : DrawOn
66 //purpose  : 
67 //=======================================================================
68
69 void DrawTrSurf_Surface::DrawOn (Draw_Display& dis) const 
70 {
71   DrawOn(dis,Standard_True);
72 }
73
74 //=======================================================================
75 //function : DrawOn
76 //purpose  : 
77 //=======================================================================
78
79 void DrawTrSurf_Surface::DrawOn (Draw_Display& dis,
80                                  const Standard_Boolean Iso) const 
81 {
82   Standard_Real UFirst, ULast, VFirst, VLast;
83   surf->Bounds (UFirst, ULast, VFirst, VLast);
84   
85   Standard_Boolean UfirstInf = Precision::IsNegativeInfinite(UFirst);
86   Standard_Boolean UlastInf  = Precision::IsPositiveInfinite(ULast);
87   Standard_Boolean VfirstInf = Precision::IsNegativeInfinite(VFirst);
88   Standard_Boolean VlastInf  = Precision::IsPositiveInfinite(VLast);
89   
90   if (UfirstInf || UlastInf) {
91     gp_Pnt P1,P2;
92     Standard_Real v;
93     if (VfirstInf && VlastInf) 
94       v = 0;
95     else if (VfirstInf)
96       v = VLast;
97     else if (VlastInf)
98       v = VFirst;
99     else
100       v = (VFirst + VLast) / 2;
101     
102     Standard_Real delta = 1.;
103
104     if (UfirstInf && UlastInf) {
105       do {
106         delta *= 2;
107         UFirst = - delta;
108         ULast  =   delta;
109         surf->D0(UFirst,v,P1);
110         surf->D0(ULast,v,P2);
111       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
112     }
113     else if (UfirstInf) {
114       surf->D0(ULast,v,P2);
115       do {
116         delta *= 2;
117         UFirst = ULast - delta;
118         surf->D0(UFirst,v,P1);
119       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
120     }
121     else if (UlastInf) {
122       surf->D0(UFirst,v,P1);
123       do {
124         delta *= 2;
125         ULast = UFirst + delta;
126         surf->D0(ULast,v,P2);
127       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
128     }
129   }
130
131   if (VfirstInf || VlastInf) {
132     gp_Pnt P1,P2;
133     Standard_Real u = (UFirst + ULast) /2 ;
134
135     Standard_Real delta = 1.;
136
137     if (VfirstInf && VlastInf) {
138       do {
139         delta *= 2;
140         VFirst = - delta;
141         VLast  =   delta;
142         surf->D0(u,VFirst,P1);
143         surf->D0(u,VLast,P2);
144       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
145     }
146     else if (VfirstInf) {
147       surf->D0(u,VLast,P2);
148       do {
149         delta *= 2;
150         VFirst = VLast - delta;
151         surf->D0(u,VFirst,P1);
152       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
153     }
154     else if (VlastInf) {
155       surf->D0(u,VFirst,P1);
156       do {
157         delta *= 2;
158         VLast = VFirst + delta;
159         surf->D0(u,VLast,P2);
160       } while (P1.Distance(P2) < DrawTrSurf_SurfaceLimit);
161     }
162   }
163
164
165   Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface();
166   HS->ChangeSurface().Load(surf,UFirst,ULast,VFirst,VLast);
167
168   Adaptor3d_IsoCurve C(HS);
169   
170   if (Iso) {
171     dis.SetColor(isosLook);
172     Standard_Integer i, j;
173     
174     Standard_Real Du = (ULast - UFirst) / (nbUIsos + 1);
175     Standard_Real U = UFirst;
176     for (i = 1; i <= nbUIsos; i++) {
177       U += Du;
178       DrawIsoCurveOn(C,GeomAbs_IsoU,U,VFirst,VLast,dis);
179     }
180     
181     Standard_Real Dv = (VLast - VFirst) / (nbVIsos + 1);
182     Standard_Real V = VFirst;
183     for (j = 1; j <= nbVIsos; j++) {
184       V += Dv;
185       DrawIsoCurveOn(C,GeomAbs_IsoV,V,UFirst,ULast,dis);
186     }
187   }
188
189   // draw bounds
190   dis.SetColor(boundsLook);
191   if (!UfirstInf) DrawIsoCurveOn(C,GeomAbs_IsoU,UFirst,VFirst,VLast,dis);
192   if (!UlastInf)  DrawIsoCurveOn(C,GeomAbs_IsoU,ULast ,VFirst,VLast,dis);
193   if (!VfirstInf) DrawIsoCurveOn(C,GeomAbs_IsoV,VFirst,UFirst,ULast,dis);
194   if (!VlastInf)  DrawIsoCurveOn(C,GeomAbs_IsoV,VLast ,UFirst,ULast,dis);
195
196   // draw marker
197   DrawIsoCurveOn(C,GeomAbs_IsoU,
198                  UFirst+(ULast-UFirst)/10.,
199                  VFirst, VFirst + (VLast-VFirst)/10.,
200                  dis);
201 }
202
203
204
205 //=======================================================================
206 //function : ShowIsos
207 //purpose  : 
208 //=======================================================================
209
210 void DrawTrSurf_Surface::ShowIsos ( const Standard_Integer Nu, 
211                                     const Standard_Integer Nv) 
212 {
213   nbUIsos = Abs(Nu);
214   nbVIsos = Abs(Nv);
215 }
216
217
218 //=======================================================================
219 //function : ClearIsos
220 //purpose  : 
221 //=======================================================================
222
223 void DrawTrSurf_Surface::ClearIsos () 
224 {
225   nbUIsos = 0;
226   nbVIsos = 0;
227 }
228
229
230 //=======================================================================
231 //function : Copy
232 //purpose  : 
233 //=======================================================================
234
235 Handle(Draw_Drawable3D)  DrawTrSurf_Surface::Copy() const 
236 {
237   Handle(DrawTrSurf_Surface) DS = new DrawTrSurf_Surface
238     (Handle(Geom_Surface)::DownCast(surf->Copy()),
239      nbUIsos,nbVIsos,boundsLook,isosLook,
240      GetDiscretisation(),GetDeflection(),GetDrawMode());
241      
242   return DS;
243 }
244
245
246 //=======================================================================
247 //function : Dump
248 //purpose  : 
249 //=======================================================================
250
251 void  DrawTrSurf_Surface::Dump(Standard_OStream& S)const 
252 {
253   GeomTools_SurfaceSet::PrintSurface(surf,S);
254 }
255
256
257 //=======================================================================
258 //function : Whatis
259 //purpose  : 
260 //=======================================================================
261
262 void  DrawTrSurf_Surface::Whatis(Draw_Interpretor& S)const 
263 {
264   S << "a surface";
265 }