0029694: Geom2dGcc_Circ2dTanCenGeo crash
[occt.git] / src / GeometryTest / GeometryTest_ConstraintCommands.cxx
1 // Created on: 1993-08-12
2 // Created by: Bruno DUMORTIER
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 // JPI : Commande smooth transferee dans GeomliteTest
18 // PMN : Ajout de la commande smooth
19 // JCT : Correction d'un trap dans la commande gcarc
20
21 #include <Standard_Stream.hxx>
22
23 #include <GeometryTest.hxx>
24 #include <DrawTrSurf.hxx>
25 #include <Draw.hxx>
26 #include <Draw_Appli.hxx>
27 #include <Draw_Interpretor.hxx>
28 #include <Geom2dGcc_Circ2d2TanRad.hxx>
29 #include <Geom2dGcc_Circ2d3Tan.hxx>
30 #include <Geom2dGcc_Circ2d2TanOn.hxx>
31 #include <Geom2dGcc_Circ2dTanOnRad.hxx>
32 #include <Geom2dGcc_Circ2dTanCen.hxx>
33 #include <Geom2dGcc_Lin2d2Tan.hxx>
34 #include <Geom2dGcc_Lin2dTanObl.hxx>
35 #include <Geom2dGcc.hxx>
36 #include <Geom2dGcc_QualifiedCurve.hxx>
37 #include <Geom2d_CartesianPoint.hxx>
38 #include <Geom2d_Circle.hxx>
39 #include <Geom2d_Line.hxx>
40 #include <Precision.hxx>
41 #include <GeomAPI_Interpolate.hxx>
42 #include <Draw_Marker3D.hxx>
43 #include <Geom2dAPI_Interpolate.hxx>
44 #include <Draw_Marker2D.hxx>
45 #include <TColgp_HArray1OfPnt.hxx>
46 #include <Geom_BSplineCurve.hxx>
47 #include <TColgp_HArray1OfPnt2d.hxx>
48 #include <Geom2d_BSplineCurve.hxx>
49 #include <Geom_TrimmedCurve.hxx>
50 #include <DrawTrSurf_BSplineCurve.hxx>
51 #include <DrawTrSurf_BSplineCurve2d.hxx>
52 #include <TColgp_HArray1OfPnt.hxx>
53 #include <TColgp_Array1OfPnt.hxx>
54 #include <TColgp_Array1OfPnt2d.hxx>
55 #include <TColgp_HArray1OfVec.hxx>
56 #include <TColgp_Array1OfVec.hxx>
57 #include <TColStd_Array1OfReal.hxx>
58 #include <TColStd_HArray1OfReal.hxx>
59 #include <TColStd_HArray1OfBoolean.hxx>
60 #include <AppParCurves_MultiBSpCurve.hxx>
61 #include <AppDef_MultiLine.hxx>
62 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
63 #include <AppParCurves_ConstraintCouple.hxx>
64 #include <GC_MakeSegment.hxx>
65 #include <GC_MakeArcOfCircle.hxx>
66
67 #include <stdio.h>
68 #ifdef _WIN32
69 Standard_IMPORT Draw_Viewer dout;
70 #endif
71 Standard_IMPORT Draw_Color DrawTrSurf_CurveColor(const Draw_Color);
72
73
74 static Standard_Integer solutions(Draw_Interpretor& di,
75                                   Geom2dGcc_Circ2d2TanRad& ct3, const char* name) 
76 {
77   char solname[200];
78
79   Draw_Color col = DrawTrSurf_CurveColor(Draw_Color(Draw_vert));
80   DrawTrSurf_CurveColor(col);
81
82   if (ct3.IsDone()) {
83     for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
84       Handle(Geom2d_Circle) C = new Geom2d_Circle(ct3.ThisSolution(i));
85       Sprintf(solname,"%s_%d",name,i);
86       DrawTrSurf::Set(solname, C);
87       di << solname << " ";
88     }
89     return 0;
90   }
91   else {
92     di << "Circ2d2TanRad Not done";
93     return 1;
94   }
95 }
96
97 static Standard_Integer solutions(Draw_Interpretor& di,
98                                   Geom2dGcc_Circ2d3Tan& ct3, const char* name) 
99 {
100   char solname[200];
101
102   Draw_Color col = DrawTrSurf_CurveColor(Draw_Color(Draw_vert));
103   DrawTrSurf_CurveColor(col);
104
105   if (ct3.IsDone()) {
106     for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
107       Handle(Geom2d_Circle) C = new Geom2d_Circle(ct3.ThisSolution(i));
108       Sprintf(solname,"%s_%d",name,i);
109       DrawTrSurf::Set(solname, C);
110       di << solname << " ";
111     }
112     return 0;
113   }
114   else {
115     di << "Circ2d3Tan Not done";
116     return 1;
117   }
118 }
119
120 //=======================================================================
121 //function : solutions
122 //purpose  : 
123 //=======================================================================
124 static Standard_Integer solutions(Draw_Interpretor& theDI,
125                                   Geom2dGcc_Circ2dTanCen& theCt2,
126                                   const char* theName)
127 {
128   char solname[200];
129
130   Draw_Color col = DrawTrSurf_CurveColor(Draw_Color(Draw_vert));
131   DrawTrSurf_CurveColor(col);
132
133   if (theCt2.IsDone())
134   {
135     for (Standard_Integer i = 1; i <= theCt2.NbSolutions(); i++)
136     {
137       Handle(Geom2d_Circle) C = new Geom2d_Circle(theCt2.ThisSolution(i));
138       Sprintf(solname, "%s_%d", theName, i);
139       DrawTrSurf::Set(solname, C);
140       theDI << solname << " ";
141     }
142     return 0;
143   }
144   else
145   {
146     theDI << "Circ2dTanCen Not done";
147     return 1;
148   }
149 }
150
151 //=======================================================================
152 //function : Cirtang
153 //purpose  : 
154 //=======================================================================
155 static Standard_Integer Cirtang(Draw_Interpretor& theDI,
156                                 Standard_Integer theNArgs,
157                                 const char** theArgVals)
158 {
159   if (theNArgs < 3)
160   {
161     theDI << "Use: " << theArgVals[0] << "result [-t <Tolerance>] -c <curve> -p <point> -r <Radius>...\n";
162     return 1;
163   }
164
165   Standard_Real aTol = Precision::Confusion();
166   Handle(Geom2d_Curve) aC[3];
167   gp_Pnt2d aP[3];
168   Standard_Real aRadius = -1.0;
169
170   Standard_Integer aNbCurves = 0, aNbPnts = 0;
171
172   for (Standard_Integer anArgID = 2; anArgID < theNArgs; anArgID++)
173   {
174     if (theArgVals[anArgID][0] != '-')
175     {
176       theDI << "Cannot interpret the argument #" << anArgID << " (" << theArgVals[anArgID] << ")\n";
177       return 1;
178     }
179     else if (!strcmp(theArgVals[anArgID], "-c"))
180     {
181       if (aNbCurves >= 3)
182       {
183         theDI << "A lot of curves are given (not greater than 3 ones are expected)\n";
184         return 1;
185       }
186
187       aC[aNbCurves] = DrawTrSurf::GetCurve2d(theArgVals[++anArgID]);
188       if (aC[aNbCurves].IsNull())
189       {
190         theDI << "Error: " << theArgVals[anArgID] << " is not a curve\n";
191         return 1;
192       }
193
194       aNbCurves++;
195     }
196     else if (!strcmp(theArgVals[anArgID], "-p"))
197     {
198       if (aNbPnts >= 3)
199       {
200         theDI << "A lot of points are given (not greater than 3 ones are expected)\n";
201         return 1;
202       }
203
204       if (!DrawTrSurf::GetPoint2d(theArgVals[++anArgID], aP[aNbPnts]))
205       {
206         theDI << "Error: " << theArgVals[anArgID] << " is not a point\n";
207         return 1;
208       }
209
210       aNbPnts++;
211     }
212     else if (!strcmp(theArgVals[anArgID], "-r"))
213     {
214       aRadius = Draw::Atof(theArgVals[++anArgID]);
215     }
216     else if (!strcmp(theArgVals[anArgID], "-t"))
217     {
218       aTol = Draw::Atof(theArgVals[++anArgID]);
219     }
220     else
221     {
222       theDI << "Unknown option " << theArgVals[anArgID] << "\n";
223       return 1;
224     }
225   }
226
227   if (aNbCurves == 3)
228   {
229     // C-C-C
230     Geom2dGcc_Circ2d3Tan aCt3(Geom2dGcc::Unqualified(aC[0]),
231                               Geom2dGcc::Unqualified(aC[1]),
232                               Geom2dGcc::Unqualified(aC[2]),
233                               aTol, 0, 0, 0);
234     theDI << "Solution of type C-C-C is: ";
235     return solutions(theDI, aCt3, theArgVals[1]);
236   }
237   else if (aNbCurves == 2)
238   {
239     if (aNbPnts >= 1)
240     {
241       // C-C-P
242       Geom2dGcc_Circ2d3Tan aCt3(Geom2dGcc::Unqualified(aC[0]),
243                                 Geom2dGcc::Unqualified(aC[1]),
244                                 new Geom2d_CartesianPoint(aP[0]),
245                                 aTol, 0, 0);
246       theDI << "Solution of type C-C-P is: ";
247       return solutions(theDI, aCt3, theArgVals[1]);
248     }
249     else if (aRadius > 0)
250     {
251       // C-C-R
252       Geom2dGcc_Circ2d2TanRad aCt3(Geom2dGcc::Unqualified(aC[0]),
253                                    Geom2dGcc::Unqualified(aC[1]),
254                                    aRadius, aTol);
255       theDI << "Solution of type C-C-R is: ";
256       return solutions(theDI, aCt3, theArgVals[1]);
257     }
258
259     theDI << "Error: Unsupported set of input data!\n";
260     return 1;
261   }
262   else if (aNbCurves == 1)
263   {
264     if (aNbPnts == 2)
265     {
266       //C-P-P
267       Geom2dGcc_Circ2d3Tan aCt3(Geom2dGcc::Unqualified(aC[0]),
268                                 new Geom2d_CartesianPoint(aP[0]),
269                                 new Geom2d_CartesianPoint(aP[1]),
270                                 aTol,0);
271       theDI << "Solution of type C-P-P is: ";
272       return solutions(theDI, aCt3, theArgVals[1]);
273     }
274     else if (aNbPnts == 1)
275     {
276       if (aRadius > 0.0)
277       {
278         //C-P-R
279         Geom2dGcc_Circ2d2TanRad aCt3(Geom2dGcc::Unqualified(aC[0]),
280                                      new Geom2d_CartesianPoint(aP[0]),
281                                      aRadius, aTol);
282         theDI << "Solution of type C-P-R is: ";
283         return solutions(theDI, aCt3, theArgVals[1]);
284       }
285       else
286       {
287         // C-P
288         Geom2dGcc_Circ2dTanCen aCt2(Geom2dGcc::Unqualified(aC[0]),
289                                     new Geom2d_CartesianPoint(aP[0]), aTol);
290         theDI << "Solution of type C-P is: ";
291         return solutions(theDI, aCt2, theArgVals[1]);
292       }
293     }
294
295     theDI << "Error: Unsupported set of input data!\n";
296     return 1;
297   }
298   else if (aNbPnts >= 2)
299   {
300     if (aNbPnts == 3)
301     {
302       //P-P-P
303       Geom2dGcc_Circ2d3Tan aCt3(new Geom2d_CartesianPoint(aP[0]),
304                                 new Geom2d_CartesianPoint(aP[1]),
305                                 new Geom2d_CartesianPoint(aP[2]),
306                                 aTol);
307       theDI << "Solution of type P-P-P is: ";
308       return solutions(theDI, aCt3, theArgVals[1]);
309     }
310     else if (aRadius > 0)
311     {
312       //P-P-R
313       Geom2dGcc_Circ2d2TanRad aCt3(new Geom2d_CartesianPoint(aP[0]),
314                                    new Geom2d_CartesianPoint(aP[1]),
315                                    aRadius, aTol);
316       theDI << "Solution of type P-P-R is: ";
317       return solutions(theDI, aCt3, theArgVals[1]);
318     }
319
320     theDI << "Error: Unsupported set of input data!\n";
321     return 1;
322   }
323
324   theDI << "Error: Unsupported set of input data!\n";
325   return 1;
326 }
327
328
329 //=======================================================================
330 //function : lintang
331 //purpose  : 
332 //=======================================================================
333
334 static Standard_Integer lintang (Draw_Interpretor& di,Standard_Integer n, const char** a)
335 {
336   if (n < 4) return 1;
337
338   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[2]);
339   Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[3]);
340
341   char solname[200];
342
343   if (C1.IsNull() || C2.IsNull())
344     return 1;
345
346   Draw_Color col = DrawTrSurf_CurveColor(Draw_Color(Draw_vert));
347
348   if (n >= 5) {
349     Handle(Geom2d_Line) L = Handle(Geom2d_Line)::DownCast(C2);
350     if (L.IsNull()) {
351       di << "Second argument must be a line";
352       return 1;
353     }
354     Standard_Real ang = Draw::Atof(a[4]) * (M_PI / 180.0);
355     Geom2dGcc_Lin2dTanObl ct3(Geom2dGcc::Unqualified(C1),
356       L->Lin2d(),
357       Precision::Angular(),
358       (C1->FirstParameter()+C1->LastParameter())/2.,
359       ang);
360     if (ct3.IsDone()) {
361       for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
362         Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
363         Sprintf(solname,"%s_%d",a[1],i);
364         char* temp = solname; // pour portage WNT
365         DrawTrSurf::Set(temp,LS);
366         di << solname << " ";
367       }
368     }
369     else
370       di << "Lin2dTanObl Not done\n";
371   }
372   else {
373     Geom2dGcc_Lin2d2Tan ct3(Geom2dGcc::Unqualified(C1),
374       Geom2dGcc::Unqualified(C2),
375       Precision::Angular(),
376       (C1->FirstParameter()+C1->LastParameter())/2.,
377       (C2->FirstParameter()+C2->LastParameter())/2.);
378     if (ct3.IsDone()) {
379       for (Standard_Integer i = 1 ; i <= ct3.NbSolutions() ; i++) {
380         Handle(Geom2d_Line) LS = new Geom2d_Line(ct3.ThisSolution(i));
381         Sprintf(solname,"%s_%d",a[1],i);
382         char* temp = solname; // pour portage WNT
383         DrawTrSurf::Set(temp,LS);
384         di << solname << " ";
385       }
386     }
387     else
388       di << "Lin2d2Tan Not done\n";
389   }
390
391   DrawTrSurf_CurveColor(col);
392
393   return 0;
394 }
395
396 //==================================================================================
397 static Standard_Integer interpol (Draw_Interpretor& di,Standard_Integer n, const char** a)
398 //==================================================================================
399 {
400   if (n == 1) {
401     di <<"give a name to your curve !\n";
402     return 0;
403   }
404   if (n == 2) {
405     Standard_Integer id,XX,YY,b, i, j;
406     di << "Pick points \n";
407     dout.Select(id, XX, YY, b);
408     Standard_Real zoom = dout.Zoom(id);
409     if (b != 1) return 0;
410     if (id < 0) return 0;
411     gp_Pnt P;
412     gp_Pnt2d P2d;
413     Standard_Boolean newcurve;
414
415     if (dout.Is3D(id)) {
416       Handle(Draw_Marker3D) mark;
417       Handle(TColgp_HArray1OfPnt) Points = new TColgp_HArray1OfPnt(1, 1);
418       P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
419       Points->SetValue(1 , P);
420       Handle(TColgp_HArray1OfPnt) ThePoints = new TColgp_HArray1OfPnt(1, 2);
421       ThePoints->SetValue(1 , P);
422       mark = new Draw_Marker3D(Points->Value(1), Draw_X, Draw_vert);
423       dout << mark;
424       dout.Flush();
425       Handle(Geom_BSplineCurve) C;
426       i = 1;
427
428       while (b != 3) {
429         dout.Select(id,XX,YY,b, Standard_False);
430         P.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom, 0.0);
431         ThePoints->SetValue(i+1, P);
432         newcurve = Standard_False;
433         if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
434           if (b == 1) { 
435             i++;
436             mark = new Draw_Marker3D(ThePoints->Value(i), Draw_X, Draw_vert);
437             dout << mark;
438             dout.Flush();
439             Points = 
440               new TColgp_HArray1OfPnt(ThePoints->Lower(),ThePoints->Upper());
441             Points->ChangeArray1() = ThePoints->Array1();
442             newcurve = Standard_True;
443           }
444           GeomAPI_Interpolate anInterpolator(ThePoints,
445             Standard_False,
446             1.0e-5);
447           anInterpolator.Perform() ;
448           if (anInterpolator.IsDone()) {
449             C = anInterpolator.Curve() ;
450             Handle(DrawTrSurf_BSplineCurve) 
451               DC = new DrawTrSurf_BSplineCurve(C);
452             DC->ClearPoles();
453             DC->ClearKnots();
454             Draw::Set(a[1], DC);
455             dout.RepaintView(id);
456           }
457           if (newcurve) {
458             ThePoints = new TColgp_HArray1OfPnt(1, i+1);
459             for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
460           }
461         }
462       }
463       GeomAPI_Interpolate anInterpolator(ThePoints,
464         Standard_False,
465         1.0e-5);
466       anInterpolator.Perform() ;
467       if (anInterpolator.IsDone()) {
468         C = anInterpolator.Curve() ;
469         DrawTrSurf::Set(a[1], C);
470         dout.RepaintView(id);
471       }      
472     }
473     else {
474       Handle(Draw_Marker2D) mark;
475       Handle(TColgp_HArray1OfPnt2d) Points = new TColgp_HArray1OfPnt2d(1, 1);
476       P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
477       Points->SetValue(1 , P2d);
478       Handle(TColgp_HArray1OfPnt2d) ThePoints = new TColgp_HArray1OfPnt2d(1, 2);
479       ThePoints->SetValue(1, P2d);
480       mark = new Draw_Marker2D(P2d, Draw_X, Draw_vert);
481       dout << mark;
482       dout.Flush();
483       Handle(Geom2d_BSplineCurve) C;
484       i = 1;
485
486       while (b != 3) {
487         dout.Select(id,XX,YY,b, Standard_False);
488         P2d.SetCoord((Standard_Real)XX/zoom,(Standard_Real)YY/zoom);
489         ThePoints->SetValue(i+1, P2d);
490         newcurve = Standard_False;
491         if (!(ThePoints->Value(i)).IsEqual(ThePoints->Value(i+1), 1.e-06)) {
492           if (b == 1) { 
493             i++;
494             mark = new Draw_Marker2D(P2d, Draw_X, Draw_vert);
495             dout << mark;
496             dout.Flush();
497             Points = 
498               new TColgp_HArray1OfPnt2d(ThePoints->Lower(),ThePoints->Upper());
499             Points->ChangeArray1() = ThePoints->Array1();
500             newcurve = Standard_True;
501           }
502           Geom2dAPI_Interpolate    a2dInterpolator(ThePoints,
503             Standard_False,
504             1.0e-5) ;
505           a2dInterpolator.Perform() ;
506           if (a2dInterpolator.IsDone()) { 
507             C = a2dInterpolator.Curve() ;
508
509             Handle(DrawTrSurf_BSplineCurve2d) 
510               DC = new DrawTrSurf_BSplineCurve2d(C);
511             DC->ClearPoles();
512             DC->ClearKnots();
513             Draw::Set(a[1], DC);
514             dout.RepaintView(id);
515           }
516
517           if (newcurve) {
518             ThePoints = new TColgp_HArray1OfPnt2d(1, i+1);
519             for (j = 1; j <= i; j++) ThePoints->SetValue(j, Points->Value(j));
520           }
521         }
522       }
523       Geom2dAPI_Interpolate    a2dInterpolator(Points,
524         Standard_False,
525         1.0e-5) ;
526       a2dInterpolator.Perform() ;
527       if (a2dInterpolator.IsDone()) { 
528         C = a2dInterpolator.Curve() ;
529
530         DrawTrSurf::Set(a[1], C);
531         dout.RepaintView(id); 
532       }
533
534     }
535   }
536   else if (n == 3) {
537     // lecture du fichier.
538     // nbpoints, 2d ou 3d, puis valeurs.
539     const char* nomfic = a[2];
540     ifstream iFile(nomfic, ios::in);
541     if (!iFile) return 1;
542     Standard_Integer nbp, i;
543     Standard_Real x, y, z;
544     iFile >> nbp;
545     char dimen[3];
546     iFile >> dimen;
547     if (!strcmp(dimen,"3d")) {
548       Handle(TColgp_HArray1OfPnt) Point =
549         new TColgp_HArray1OfPnt(1, nbp);
550       for (i = 1; i <= nbp; i++) {
551         iFile >> x >> y >> z;
552         Point->SetValue(i, gp_Pnt(x, y, z));
553       }
554       GeomAPI_Interpolate  anInterpolator(Point,
555         Standard_False,
556         1.0e-5) ;
557       anInterpolator.Perform() ;
558       if (anInterpolator.IsDone()) { 
559         Handle(Geom_BSplineCurve) C = 
560           anInterpolator.Curve();
561         DrawTrSurf::Set(a[1], C);
562       }
563     }
564     else if (!strcmp(dimen,"2d")) {
565       Handle(TColgp_HArray1OfPnt2d)  PointPtr = 
566         new TColgp_HArray1OfPnt2d(1, nbp);
567       for (i = 1; i <= nbp; i++) {
568         iFile >> x >> y;
569         PointPtr->SetValue(i, gp_Pnt2d(x, y));
570       }
571       Geom2dAPI_Interpolate   a2dInterpolator(PointPtr,
572         Standard_False,
573         1.0e-5);
574       a2dInterpolator.Perform() ;
575       if (a2dInterpolator.IsDone()) {
576         Handle(Geom2d_BSplineCurve) C = a2dInterpolator.Curve() ;
577         DrawTrSurf::Set(a[1], C);
578       }
579     }
580   }
581   return 0;
582 }
583
584 static Standard_Integer tanginterpol (Draw_Interpretor& di,
585                                       Standard_Integer n, 
586                                       const char** a)
587 {
588
589
590   if (n < 4)
591     return 1;
592
593   Standard_Integer 
594     ii,
595     jj,
596     //    num_knots,
597     //    degree,
598     num_tangents,
599     num_read,
600     num_start,
601     num_parameters ;
602
603
604   Standard_Real 
605     //    delta,
606     tolerance;
607   //    parameter ;
608
609   Standard_Boolean periodic_flag = Standard_False ;
610   gp_Pnt a_point ;
611   gp_Vec a_vector ;
612   tolerance = 1.0e-5 ;
613
614
615
616
617   Handle(Geom_BSplineCurve) NewCurvePtr ;
618
619
620
621
622   num_read = 2 ;
623   if (strcmp(a[num_read],"p") == 0) {
624     periodic_flag = Standard_True ;
625     num_read += 1 ;
626   }
627   num_parameters = Draw::Atoi(a[num_read]) ;
628
629   if (num_parameters < 2) {
630     num_parameters = 2 ;
631   }
632   if ( n <  num_parameters * 3 + num_read) {
633     return 1 ;
634   }
635   Handle(TColgp_HArray1OfPnt)   PointsArrayPtr=
636     new TColgp_HArray1OfPnt(1,num_parameters) ;
637
638   num_tangents = ((n - num_read) / 3)  - num_parameters ;
639   num_tangents = Max (0,num_tangents) ; 
640   num_tangents = Min (num_parameters, num_tangents) ;
641   ii = 1 ;
642   num_start = num_read ;
643   num_read += 1 ;
644   while (num_read <= num_parameters * 3 + num_start ) {
645     for (jj = 1 ; jj <= 3 ; jj++) {
646       a_point.SetCoord(jj,Draw::Atof(a[num_read])) ;
647       num_read += 1 ;
648     }
649     PointsArrayPtr->SetValue(ii,a_point) ;
650     ii += 1 ;
651   }
652   GeomAPI_Interpolate anInterpolator(PointsArrayPtr,
653     periodic_flag,
654     tolerance) ; 
655
656   if (num_tangents > 0) {
657     TColgp_Array1OfVec TangentsArray(1,num_parameters) ;
658     Handle(TColStd_HArray1OfBoolean) 
659       TangentFlagsPtr =
660       new TColStd_HArray1OfBoolean(1,num_parameters) ;
661
662     for (ii = 1 ; ii <= num_tangents ; ii++) {
663       TangentFlagsPtr->SetValue(ii,Standard_True) ;
664     }
665     for (ii = num_tangents + 1 ; ii <= num_parameters ; ii++) {
666       TangentFlagsPtr->SetValue(ii,Standard_False) ;
667     }
668     ii = 1 ;
669     while (ii <= num_tangents) {
670       for (jj = 1 ; jj <= 3 ; jj++) {
671         a_vector.SetCoord(jj,Draw::Atof(a[num_read])) ;
672         num_read += 1 ;
673       }
674       TangentsArray.SetValue(ii,a_vector) ;
675       ii += 1 ;
676     }
677
678
679     anInterpolator.Load(TangentsArray,
680       TangentFlagsPtr) ;
681   }
682   anInterpolator.Perform() ;
683   if (anInterpolator.IsDone()) {
684     NewCurvePtr =
685       anInterpolator.Curve() ;
686
687     DrawTrSurf::Set(a[1],
688       NewCurvePtr) ;
689     di << a[2] << " " ;
690
691   }
692   return 0 ;
693 }
694
695 //==================================================================================
696 static Standard_Integer gcarc (Draw_Interpretor& di,Standard_Integer n, const char** a)
697 //==================================================================================
698 {
699   if (n >= 5) {
700     gp_Pnt P1,P2,P3,P4;
701     if (!strcmp(a[2], "seg")) {
702       if (DrawTrSurf::GetPoint(a[3], P1)) {
703         if (DrawTrSurf::GetPoint(a[4], P2)) {
704           Handle(Geom_Curve) theline (GC_MakeSegment(P1,P2).Value());
705           DrawTrSurf::Set(a[1], theline);
706           return 1;
707         }
708       }
709     }
710     else if (!strcmp(a[2], "cir")) {
711       if (DrawTrSurf::GetPoint(a[3], P1)) {
712         if (DrawTrSurf::GetPoint(a[4], P2)) {
713           if (DrawTrSurf::GetPoint(a[5], P3)) {
714             //      if (DrawTrSurf::GetPoint(a[6], P4)) {
715             if (n>6) {
716               DrawTrSurf::GetPoint(a[6], P4);
717               gp_Vec V1 = gp_Vec(P2,P3);                                                    
718               Handle(Geom_Curve)thearc (GC_MakeArcOfCircle(P1,V1,P4).Value());
719               DrawTrSurf::Set(a[1], thearc);
720               return 1;
721             }
722             else {
723               Handle(Geom_Curve)thearc (GC_MakeArcOfCircle(P1,P2,P3).Value());
724               DrawTrSurf::Set(a[1], thearc);
725               return 1;
726             }
727           }
728         }
729       }
730     }
731   }
732   di <<"give a name for arc and the type seg or cir then\n";
733   di <<"give passing points p1 p2 for seg    p1 p2 p3 or p1 p2 p3 p4 for cir (p2 p3 is a tgtvec)!\n";
734   return 0;
735 }
736
737 //=======================================================================
738 //function : ConstraintCommands
739 //purpose  : 
740 //=======================================================================
741
742
743 void  GeometryTest::ConstraintCommands(Draw_Interpretor& theCommands)
744 {
745
746   static Standard_Boolean loaded = Standard_False;
747   if (loaded) return;
748   loaded = Standard_True;
749
750   DrawTrSurf::BasicCommands(theCommands);
751
752   const char* g;
753   // constrained constructs
754   g = "GEOMETRY Constraints";
755
756   theCommands.Add("cirtang",
757     "cirtang cname [-t <Tolerance>] -c <curve> -p <point> -r <Radius>...",
758     __FILE__,
759     Cirtang, g);
760
761   theCommands.Add("lintan",
762     "lintan lname curve1 curve2 [angle]",
763     __FILE__,
764     lintang,g);
765
766
767   theCommands.Add("interpol",
768     "interpol cname [fic]", 
769     __FILE__,
770     interpol, g);
771   theCommands.Add("tanginterpol",
772     "tanginterpol curve [p] num_points points [tangents] modifier  p = periodic",
773     __FILE__,
774     tanginterpol,g);
775
776   theCommands.Add("gcarc",
777     "gcarc name seg/cir p1 p2 p3 p4",
778     __FILE__,
779     gcarc,g);
780 }