0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[occt.git] / src / VrmlConverter / VrmlConverter_Curve.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <Adaptor3d_Curve.hxx>
16 #include <gp_Circ.hxx>
17 #include <gp_Dir.hxx>
18 #include <gp_Pnt.hxx>
19 #include <gp_Vec.hxx>
20 #include <Precision.hxx>
21 #include <TColgp_HArray1OfVec.hxx>
22 #include <TColStd_HArray1OfInteger.hxx>
23 #include <Vrml_Coordinate3.hxx>
24 #include <Vrml_IndexedLineSet.hxx>
25 #include <Vrml_Material.hxx>
26 #include <Vrml_Separator.hxx>
27 #include <VrmlConverter_Curve.hxx>
28 #include <VrmlConverter_Drawer.hxx>
29 #include <VrmlConverter_LineAspect.hxx>
30
31 //==================================================================
32 // function: FindLimits
33 // purpose:
34 //==================================================================
35 static void FindLimits(const Adaptor3d_Curve& aCurve,
36                        const Standard_Real  aLimit,
37                        Standard_Real&       First,
38                        Standard_Real&       Last)
39 {
40   First = aCurve.FirstParameter();
41   Last  = aCurve.LastParameter();
42   Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
43   Standard_Boolean lastInf  = Precision::IsPositiveInfinite(Last);
44
45   if (firstInf || lastInf) {
46     gp_Pnt P1,P2;
47     Standard_Real delta = 1;
48     if (firstInf && lastInf) {
49       do {
50         delta *= 2;
51         First = - delta;
52         Last  =   delta;
53         aCurve.D0(First,P1);
54         aCurve.D0(Last,P2);
55       } while (P1.Distance(P2) < aLimit);
56     }
57     else if (firstInf) {
58       aCurve.D0(Last,P2);
59       do {
60         delta *= 2;
61         First = Last - delta;
62         aCurve.D0(First,P1);
63       } while (P1.Distance(P2) < aLimit);
64     }
65     else if (lastInf) {
66       aCurve.D0(First,P1);
67       do {
68         delta *= 2;
69         Last = First + delta;
70         aCurve.D0(Last,P2);
71       } while (P1.Distance(P2) < aLimit);
72     }
73   }    
74 }
75
76
77 //==================================================================
78 // function: DrawCurve
79 // purpose:
80 //==================================================================
81 static void DrawCurve (const Adaptor3d_Curve&          aCurve,
82                        const Standard_Integer        NbP,
83                        const Standard_Real           U1,
84                        const Standard_Real           U2,
85                        const Handle(VrmlConverter_Drawer)& aDrawer, // for passsing of LineAspect
86                        Standard_OStream&             anOStream) 
87 {
88   Standard_Integer nbintervals = 1, i;
89   Handle(TColgp_HArray1OfVec) HAV1;
90   Handle(TColStd_HArray1OfInteger) HAI1;
91   
92   if (aCurve.GetType() == GeomAbs_BSplineCurve) {
93     nbintervals = aCurve.NbKnots() - 1;
94 //     std::cout << "NbKnots "<<aCurve.NbKnots() << std::endl;
95     nbintervals = Max(1, nbintervals/3);
96   }
97
98
99   switch (aCurve.GetType()) {
100   case GeomAbs_Line:
101     {
102      gp_Vec V;
103      HAV1 = new TColgp_HArray1OfVec(1, 2);
104 // array of coordinates of line 
105      gp_Pnt p = aCurve.Value(U1);
106      V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
107      HAV1->SetValue(1,V);
108
109      p = aCurve.Value(U2);
110      V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
111      HAV1->SetValue(2,V);
112
113      HAI1 = new TColStd_HArray1OfInteger(1,3);
114 // array of indexes of line
115      HAI1->SetValue(1,0);       
116      HAI1->SetValue(2,1);
117      HAI1->SetValue(3,-1);
118
119     }
120     break;
121   default:
122     {
123
124       Standard_Real U;
125       Standard_Integer N = Max(2, NbP*nbintervals);
126
127 //     std::cout << "nbintervals " << nbintervals << std::endl;
128 //     std::cout <<  "N " << N << std::endl;
129
130       gp_Vec V;
131       HAV1 = new TColgp_HArray1OfVec(1, N);
132 //      HAI1 = new TColStd_HArray1OfInteger(1,(N/2*3+N%2));
133       HAI1 = new TColStd_HArray1OfInteger(1,N+1);
134       Standard_Real DU = (U2-U1) / (N-1);
135       gp_Pnt p;
136
137       for (i = 1; i <= N;i++) { 
138         U = U1 + (i-1)*DU;
139         p = aCurve.Value(U);
140
141         V.SetX(p.X()); V.SetY(p.Y()); V.SetZ(p.Z());
142         HAV1->SetValue(i,V);
143       }      
144
145 //      Standard_Integer j=1,k;
146
147 //     for (i=HAI1->Lower(); i <= HAI1->Upper(); i++)
148 //      {
149 //        k = i % 3;
150 //        if(k == 0)
151 //          {
152 //            HAI1->SetValue(i,-1);     
153 //            j++;
154 //          }
155 //        else
156 //          {
157 //            HAI1->SetValue(i,i-j);    
158 //          }
159 //      }
160
161      for (i=HAI1->Lower(); i < HAI1->Upper(); i++)
162         {
163           HAI1->SetValue(i,i-1);        
164         }
165         HAI1->SetValue(HAI1->Upper(),-1);
166     }
167   }
168   
169 //  std::cout  << " Array HAI1 - coordIndex " << std::endl;  
170 //  for ( i=HAI1->Lower(); i <= HAI1->Upper(); i++ )
171 //    {
172 //      std::cout << HAI1->Value(i) << std::endl;
173 //       } 
174
175 // creation of Vrml objects
176   Handle(VrmlConverter_LineAspect) LA = new VrmlConverter_LineAspect;
177   LA = aDrawer->LineAspect();
178
179 //     std::cout << "LA->HasMaterial() = " << LA->HasMaterial()  << std::endl;
180
181 // Separator 1 {
182   Vrml_Separator SE1;
183   SE1.Print(anOStream);
184 // Material
185
186   if (LA->HasMaterial()){
187
188     Handle(Vrml_Material) M;
189     M = LA->Material();
190     
191     M->Print(anOStream);
192   }
193 // Coordinate3
194   Handle(Vrml_Coordinate3)  C3 = new Vrml_Coordinate3(HAV1);
195   C3->Print(anOStream);
196 // IndexedLineSet
197   Vrml_IndexedLineSet  ILS;
198   ILS.SetCoordIndex(HAI1);
199   ILS.Print(anOStream);
200 // Separator 1 }
201   SE1.Print(anOStream);
202 }
203
204 //==================================================================
205 // function: Add 1
206 // purpose:
207 //==================================================================
208 void VrmlConverter_Curve::Add(const Adaptor3d_Curve&                aCurve, 
209                               const Handle(VrmlConverter_Drawer)& aDrawer,
210                               Standard_OStream&                   anOStream) 
211 {
212
213
214   Standard_Integer NbPoints = aDrawer->Discretisation();
215   Standard_Real V1, V2;
216   Standard_Real aLimit = aDrawer->MaximalParameterValue();
217   FindLimits(aCurve, aLimit, V1, V2);
218
219 //     std::cout << "V1 = "<< V1 << std::endl;
220 //     std::cout << "V2 = "<< V2 << std::endl;
221 //     std::cout << "NbPoints = "<< NbPoints << std::endl;
222 //     std::cout << "aLimit = "<< aLimit << std::endl;
223
224   DrawCurve(aCurve,
225             NbPoints,
226             V1 , V2, aDrawer, anOStream);
227
228 }
229
230 //==================================================================
231 // function: Add 2
232 // purpose:
233 //==================================================================
234 void VrmlConverter_Curve::Add(const Adaptor3d_Curve&                aCurve, 
235                               const Standard_Real                 U1, 
236                               const Standard_Real                 U2, 
237                               const Handle(VrmlConverter_Drawer)& aDrawer,
238                               Standard_OStream&                   anOStream) 
239 {
240
241   Standard_Integer NbPoints = aDrawer->Discretisation();
242   Standard_Real V1 = U1;
243   Standard_Real V2 = U2;  
244
245   if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
246   if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
247
248 //     std::cout << "V1 = "<< V1 << std::endl;
249 //     std::cout << "V2 = "<< V2 << std::endl;
250 //     std::cout << "NbPoints = "<< NbPoints << std::endl;
251  
252   DrawCurve(aCurve,
253              NbPoints,
254              V1 , V2, aDrawer, anOStream);
255   
256 }
257
258 //==================================================================
259 // function: Add 3
260 // purpose:
261 //==================================================================
262 void VrmlConverter_Curve::Add(const Adaptor3d_Curve&   aCurve, 
263                               const Standard_Real    U1, 
264                               const Standard_Real    U2, 
265                               Standard_OStream&      anOStream, 
266                               const Standard_Integer aNbPoints)
267 {
268   Handle(VrmlConverter_Drawer) aDrawer = new VrmlConverter_Drawer;
269   Handle(VrmlConverter_LineAspect) la = new VrmlConverter_LineAspect;
270   aDrawer->SetLineAspect(la);
271
272
273   Standard_Real V1 = U1;
274   Standard_Real V2 = U2;  
275
276   if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
277   if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
278
279 //     std::cout << "V1 = "<< V1 << std::endl;
280 //     std::cout << "V2 = "<< V2 << std::endl;
281 //     std::cout << "NbPoints = "<< aNbPoints << std::endl;
282
283   DrawCurve(aCurve,
284             aNbPoints,
285             V1 , V2, aDrawer, anOStream);
286
287 }
288