0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / GeometryTest / GeometryTest_SurfaceCommands.cxx
1 // Created on: 1993-08-12
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1993-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 // 09/06/97 : JPI : suppression des commandes redondantes suite a la creation de GeomliteTest
18 // Modified:    Mon Jan 18 11:06:46 1999
19 //              option -NS dans la commande tuyau pour distinguer les tuyaux
20 //              a section evolutive des tuyaux a N sections avec N = 2
21
22 #include <GeometryTest.hxx>
23 #include <DrawTrSurf.hxx>
24 #include <Draw.hxx>
25 #include <Draw_Interpretor.hxx>
26 #include <Draw_Appli.hxx>
27 #include <Draw_Display.hxx>
28
29 #include <GeomAbs_SurfaceType.hxx>
30 #include <GeomAbs_IsoType.hxx>
31 #include <GeomAbs_Shape.hxx>
32
33 #include <Geom_BSplineSurface.hxx>
34 #include <Geom_BSplineCurve.hxx>
35 #include <GeomConvert.hxx>
36
37
38 #include <GeomAdaptor_Surface.hxx>
39 #include <GeomAdaptor_Curve.hxx>
40 #include <Geom2dAdaptor_Curve.hxx>
41
42 #include <TColgp_Array1OfPnt.hxx>
43 #include <TColgp_Array2OfPnt.hxx>
44 #include <TColStd_Array1OfReal.hxx>
45 #include <TColStd_Array2OfReal.hxx>
46 #include <TColStd_Array1OfInteger.hxx>
47 #include <TColStd_HArray1OfReal.hxx>
48 #include <TColStd_HArray2OfReal.hxx>
49 #include <TColGeom_SequenceOfCurve.hxx>
50
51 #include <Precision.hxx>
52
53 #include <GeomFill.hxx>
54 #include <GeomFill_BSplineCurves.hxx>
55 #include <GeomFill_Pipe.hxx>
56 #include <GeomFill_SectionGenerator.hxx>
57 #include <GeomFill_Line.hxx>
58 #include <GeomFill_AppSurf.hxx>
59
60
61 #include <DrawTrSurf_BezierSurface.hxx>
62 #include <DrawTrSurf_BSplineSurface.hxx>
63
64 #ifdef _MSC_VER
65 #include <stdio.h>
66 //#define strcasecmp strcmp Already defined
67 #endif
68
69 #ifdef _WIN32
70 Standard_IMPORT Draw_Viewer dout;
71 #endif
72
73
74
75
76 //=======================================================================
77 //function : sweep
78 //purpose  : 
79 //=======================================================================
80
81 static Standard_Integer sweep (Draw_Interpretor& di,
82                                Standard_Integer n, const char** a)
83 {
84   GeomFill_Trihedron Option = GeomFill_IsCorrectedFrenet;
85   Standard_Integer ipath =2, isection =4 , NbSeg=30, MaxDegree = 10;
86   Standard_Real Tol = 1.e-4;
87
88   if (n < 4 ) return 1;
89   
90   if (! strcmp(a[2],"-FX")) {
91     ipath = 3;
92     Option = GeomFill_IsFixed;
93   }
94   if (! strcmp(a[2],"-FR")) {
95     ipath = 3;
96     Option = GeomFill_IsFrenet;
97   }
98   if (! strcmp(a[2],"-CF")) {
99     ipath = 3;
100     Option = GeomFill_IsCorrectedFrenet;
101   }
102   if (! strcmp(a[2],"-CN")) {
103     ipath = 3;
104     isection = 7;
105     Option = GeomFill_IsConstantNormal;
106   }
107   if (! strcmp(a[2],"-DX")) {
108     ipath = 3;
109     isection = 5;
110     Option = GeomFill_IsDarboux;
111   }
112
113   GeomFill_Pipe Pipe;
114   Pipe.GenerateParticularCase(Standard_True);
115   
116   if (Option == GeomFill_IsDarboux) {
117     Handle(Geom2d_Curve) path = DrawTrSurf::GetCurve2d(a[ipath]);
118     if ( path.IsNull()) return 1;
119     
120     Handle(Geom_Surface) Support = DrawTrSurf::GetSurface(a[ipath+1]);
121     if ( Support.IsNull()) return 1;
122
123     Handle(Geom_Curve) firstS = DrawTrSurf::GetCurve(a[ipath+2]);
124     if ( firstS.IsNull()) return 1;
125     
126     Pipe.Init(path, Support, firstS);
127   }
128   else if (Option == GeomFill_IsConstantNormal) {
129     gp_Dir D ( Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]) );
130     Handle(Geom_Curve) path = DrawTrSurf::GetCurve(a[6]);
131     Handle(Geom_Curve) firstS = DrawTrSurf::GetCurve(a[7]);
132     Pipe.Init(path, firstS, D);
133   }
134   else  {
135     Handle(Geom_Curve) path = DrawTrSurf::GetCurve(a[ipath]);
136     if ( path.IsNull()) return 1;
137     
138     Handle(Geom_Curve) firstS = DrawTrSurf::GetCurve(a[ipath+1]);
139     if ( firstS.IsNull()) return 1;
140
141     Pipe.Init(path, firstS, Option);
142   }     
143
144   if (n >=isection+2) { 
145     MaxDegree = Draw::Atoi(a[isection+1]);
146     if (n >isection+2) NbSeg = Draw::Atoi(a[isection+2]);
147   }
148     
149   Pipe.Perform(Tol, Standard_False,  GeomAbs_C2, MaxDegree, NbSeg);
150
151   if (!Pipe.IsDone()) {
152     di << "GeomFill_Pipe cannot make a surface\n";
153     return 1;
154   }
155
156   Standard_Real Accuracy = Pipe.ErrorOnSurf();
157   di << "Accuracy of approximation = " << Accuracy << "\n";
158
159   DrawTrSurf::Set(a[1], Pipe.Surface());
160   return 0;
161   
162 }   
163 //=======================================================================
164 //function : tuyau
165 //purpose  : 
166 //=======================================================================
167
168 static Standard_Integer tuyau (Draw_Interpretor& di,
169                                Standard_Integer n, const char** a)
170 {
171   if ( n < 4) return 1;
172
173   GeomAbs_Shape Cont = GeomAbs_C2;
174   GeomFill_Pipe Pipe;
175   Pipe.GenerateParticularCase(Standard_True);
176
177   Standard_Boolean Option_NS = Standard_False;
178   Standard_Integer indice_path = 2, narg = n;
179   if (! strcmp(a[1],"-NS")) {
180     Option_NS = Standard_True;
181     indice_path++;
182     narg--;
183   }
184   Handle(Geom_Curve) path = DrawTrSurf::GetCurve(a[indice_path]);
185   if ( path.IsNull()) return 1;
186
187   Standard_Integer isect = indice_path+1;
188   Handle(Geom_Curve) firstS = DrawTrSurf::GetCurve(a[isect]);
189   if ( firstS.IsNull()) {
190     if ( narg == 4) { 
191       // tuyau a rayon constant.
192       Pipe.Init(path, Draw::Atof(a[isect]));
193     }
194     else 
195       return 1;
196   }
197   else {
198     if ( narg == 4) {
199       // tuyau a section constante.
200       Pipe.Init(path,firstS, GeomFill_IsCorrectedFrenet);
201     }
202     else {
203       if ( narg == 5 && !Option_NS) {
204         // tuyau a section evolutive
205         Handle(Geom_Curve) lastS = DrawTrSurf::GetCurve(a[isect+1]);
206         Cont = GeomAbs_C2;
207         Pipe.Init(path, firstS, lastS); 
208       }
209       else { 
210         // tuyau a N sections, N>=2
211         TColGeom_SequenceOfCurve Seq;
212         Seq.Clear();
213         Seq.Append(firstS);
214         for (Standard_Integer i=isect+1;i<n;i++) {
215           Handle(Geom_Curve) nextS = DrawTrSurf::GetCurve(a[i]);
216           Seq.Append(nextS);
217         }
218         Cont = GeomAbs_C2;
219         Pipe.Init(path, Seq); 
220       }
221     }
222   }
223
224   Pipe.Perform(1.e-4, Standard_False,  Cont);
225   if (!Pipe.IsDone()) {
226     di << "GeomFill_Pipe cannot make a surface\n";
227     return 1;
228   }
229
230   Standard_Real Accuracy = Pipe.ErrorOnSurf();
231   di << "Accuracy of approximation = " << Accuracy << "\n";
232   
233   DrawTrSurf::Set(a[indice_path-1], Pipe.Surface());
234
235   return 0;
236 }
237
238 //=======================================================================
239 //function : ruled
240 //purpose  : 
241 //=======================================================================
242
243 static Standard_Integer ruled(Draw_Interpretor& di,
244                               Standard_Integer n, const char** a)
245 {
246   if ( n < 4) return 1;
247
248   Handle(Geom_Curve) C1 = DrawTrSurf::GetCurve(a[2]);
249   if ( C1.IsNull()) {
250     di << " C1 is not a Curve ==> Command failed\n";
251     return 1;
252   }
253   Handle(Geom_Curve) C2 = DrawTrSurf::GetCurve(a[3]);
254   if ( C2.IsNull()) {
255     di << " C2 is not a Curve ==> Command failed\n";
256     return 1;
257   }
258   
259   Handle(Geom_Surface) S = GeomFill::Surface(C1,C2);
260   if ( S.IsNull()) return 1;
261
262   DrawTrSurf::Set(a[1],S);
263   return 0;
264 }
265
266 //=======================================================================
267 //function : appsurf
268 //purpose  : 
269 //=======================================================================
270
271 static Standard_Integer appsurf(Draw_Interpretor& di,
272                                 Standard_Integer n, const char** a)
273 {
274   if ( n < 4) return 1;
275   
276   GeomFill_SectionGenerator Section;
277   Standard_Integer i;
278   Handle(Geom_Curve) C;
279   for ( i = 2; i < n; i++) {
280     C = DrawTrSurf::GetCurve(a[i]);
281     if (C.IsNull()) 
282       return 1;
283     Section.AddCurve(C);
284   }
285   
286   Section.Perform(Precision::PConfusion());
287
288   Handle(GeomFill_Line) Line = new GeomFill_Line(n-2);
289   Standard_Integer NbIt = 0;
290   GeomFill_AppSurf App( 3, 8, Precision::Confusion(), Precision::PConfusion(),
291                         NbIt);
292
293   App.Perform( Line, Section);
294
295   if ( !App.IsDone()) {
296     di << "    Approximation aux fraises \n";
297   }
298
299   Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots;
300   App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
301
302   Handle(Geom_BSplineSurface) GBS = new 
303     Geom_BSplineSurface(App.SurfPoles(),
304                         App.SurfWeights(),
305                         App.SurfUKnots(),
306                         App.SurfVKnots(),
307                         App.SurfUMults(),
308                         App.SurfVMults(),
309                         App.UDegree(),
310                         App.VDegree());
311
312   DrawTrSurf::Set(a[1],GBS);
313   return 0;
314 }
315
316 static Standard_Integer fillcurves(Draw_Interpretor& /*di*/,
317                                    Standard_Integer n, const char** a)
318 {
319   if ( n < 6) return 1;
320   
321   Standard_Integer i;
322   Handle(Geom_Curve) aC;
323   Handle(Geom_BSplineCurve) C[4];
324   for ( i = 2; i < 6; i++) {
325     aC = DrawTrSurf::GetCurve(a[i]);
326     if (aC.IsNull()) 
327       return 1;
328     C[i-2] = GeomConvert::CurveToBSplineCurve(aC, Convert_RationalC1);
329   }
330
331   Standard_Integer ist = 2;
332   GeomFill_FillingStyle Style = GeomFill_CoonsStyle;
333   if(n > 6) ist = Draw::Atoi(a[6]);
334
335   if(ist == 1) Style =  GeomFill_StretchStyle;
336   if(ist == 2) Style =  GeomFill_CoonsStyle;
337   if(ist == 3) Style =  GeomFill_CurvedStyle;
338
339   GeomFill_BSplineCurves aFilling(C[0], C[1], C[2], C[3], Style);
340    
341   const Handle(Geom_BSplineSurface)& GBS = aFilling.Surface();
342   DrawTrSurf::Set(a[1],GBS);
343   return 0;
344 }
345
346
347 //=======================================================================
348 //function : GetSurfaceContinuity
349 //purpose  : Returns the continuity of the given surface
350 //=======================================================================
351 static Standard_Integer GetSurfaceContinuity( Draw_Interpretor& theDI,
352                                               Standard_Integer theNArg,
353                                               const char** theArgv)
354 {
355   if(theNArg != 2)
356   {
357     theDI << "Use: getsurfcontinuity surface\n";
358     return 1;
359   }
360
361   Handle(Geom_Surface) GS1 = DrawTrSurf::GetSurface(theArgv[1]);
362   if(GS1.IsNull())
363   {
364     theDI << "Argument is not a surface!\n";
365     return 1;
366   }
367
368   char aContName[7][3] = {"C0",   //0
369                           "G1",   //1
370                           "C1",   //2
371                           "G2",   //3
372                           "C2",   //4
373                           "C3",   //5
374                           "CN"};  //6
375
376   theDI << theArgv[1] << " has " << aContName[GS1->Continuity()] << " continuity.\n";
377
378   return 0;
379 }
380
381
382 //=======================================================================
383 //function : SurfaceCommands
384 //purpose  : 
385 //=======================================================================
386
387
388 void  GeometryTest::SurfaceCommands(Draw_Interpretor& theCommands)
389 {
390   static Standard_Boolean loaded = Standard_False;
391   if (loaded) return;
392   loaded = Standard_True;
393
394   DrawTrSurf::BasicCommands(theCommands);
395
396   const char* g;
397
398   g = "GEOMETRY surfaces creation";
399
400
401   theCommands.Add("tuyau",
402                   "tuyau [-NS] result Path Curve/Radius [Curve2] [Curve3] ... \n the option -NS is used only with 2 sections.\n With it, <result> is going from the first section to the last section \n Without, <result> is a pipe by evolutive section ",
403                   __FILE__,
404                   tuyau,g);
405
406   theCommands.Add("partuyau",
407                   "tuyau result Path Curve/Radius [Curve2]\n the parametrization of the surface in the V direction will be as the Path",
408                   __FILE__,
409                   tuyau,g);
410
411   theCommands.Add("sweep", "sweep result [options] path [Surf] curve [Tol [nbsegment]]\n sweep the the curve along the path, options are \n -FX : Tangent and Normal are fixed\n -FR : Tangent and Normal are given by Frenet trihedron \n -CF : Tangente is given by Frenet, \n     the Normal is computed to minimize the torsion \n -DX : Tangent and Normal are given by Darboux trihedron \n     <path> have to be a 2d curve,\n     <Surf> have to be defined\n -CN dx dy dz : Normal is given by dx dy dz" ,
412                   __FILE__,
413                   sweep, g);
414
415   theCommands.Add("ruled",
416                   "ruled result C1 C2",
417                   __FILE__,
418                   ruled,g);
419
420   theCommands.Add("appsurf",
421                   "appsurf result C1 C2 C3 .....: \n\tCreate a surface passing through the curves",
422                   __FILE__,
423                   appsurf,g);
424  
425  theCommands.Add("fillcurves",
426                   "fillcurves result C1 C2 C3 C4 [style 1/2/3]: \n\tCreate a surface filling frame of 4 curves",
427                   __FILE__,
428                   fillcurves,g);
429
430  theCommands.Add("getsurfcontinuity",
431                   "getsurfcontinuity surface: \n\tReturns the continuity of the given surface",
432                   __FILE__,
433                   GetSurfaceContinuity,g);
434
435
436 }
437
438
439
440