e7abdd9b8b0a6c7b5a3c2792b645c3c23a625e1e
[occt.git] / src / GeometryTest / GeometryTest_CurveCommands.cxx
1 // Created on: 1993-08-12
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1993-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 // 09/06/97 : JPI : suppression des commandes redondantes suite a la creation de GeomliteTest
22
23 #include <GeometryTest.hxx>
24 #include <Draw_Appli.hxx>
25 #include <DrawTrSurf.hxx>
26 #include <DrawTrSurf_Curve.hxx>
27 #include <DrawTrSurf_Curve2d.hxx>
28 #include <DrawTrSurf_BezierCurve.hxx>
29 #include <DrawTrSurf_BSplineCurve.hxx>
30 #include <DrawTrSurf_BezierCurve2d.hxx>
31 #include <DrawTrSurf_BSplineCurve2d.hxx>
32 #include <Draw_Marker3D.hxx>
33 #include <Draw_Marker2D.hxx>
34 #include <Draw.hxx>
35 #include <Draw_Interpretor.hxx>
36 #include <Draw_Color.hxx>
37 #include <Draw_Display.hxx>
38
39 #include <GeomAPI.hxx>
40 #include <GeomAPI_IntCS.hxx>
41 #include <GeomAPI_IntSS.hxx>
42
43 //#include <GeomLProp.hxx>
44 #include <GeomProjLib.hxx>
45 #include <BSplCLib.hxx>
46
47 #include <gp.hxx>
48 #include <gp_Pln.hxx>
49 #include <gp_Parab2d.hxx>
50 #include <gp_Elips2d.hxx>
51 #include <gp_Hypr2d.hxx>
52
53 #include <Geom_Line.hxx>
54 #include <Geom_Circle.hxx>
55 #include <Geom_Ellipse.hxx>
56 #include <Geom_Parabola.hxx>
57 #include <Geom_Hyperbola.hxx>
58 #include <Geom2d_Line.hxx>
59 #include <Geom2d_Circle.hxx>
60 #include <Geom2d_Ellipse.hxx>
61 #include <Geom2d_Parabola.hxx>
62 #include <Geom2d_Hyperbola.hxx>
63 #include <Geom2d_BSplineCurve.hxx>
64 #include <Geom2d_Curve.hxx>
65
66 #include <GccAna_Lin2dBisec.hxx>
67 #include <GccAna_Circ2dBisec.hxx>
68 #include <GccAna_CircLin2dBisec.hxx>
69 #include <GccAna_CircPnt2dBisec.hxx>
70 #include <GccAna_LinPnt2dBisec.hxx>
71 #include <GccAna_Pnt2dBisec.hxx>
72 #include <GccInt_Bisec.hxx>
73 #include <GccInt_IType.hxx>
74
75 #include <Geom_Plane.hxx>
76 #include <Geom_Curve.hxx>
77 #include <Geom2d_Curve.hxx>
78 #include <Geom2d_TrimmedCurve.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80
81 #include <Law_BSpline.hxx>
82
83 #include <TColgp_Array1OfPnt.hxx>
84 #include <TColgp_Array1OfPnt2d.hxx>
85 #include <TColStd_Array1OfReal.hxx>
86 #include <TColStd_Array1OfInteger.hxx>
87
88 #include <Adaptor3d_HCurve.hxx>
89 #include <Adaptor3d_HSurface.hxx>
90 #include <Adaptor3d_CurveOnSurface.hxx>
91
92 #include <GeomAdaptor_HCurve.hxx>
93 #include <GeomAdaptor_HSurface.hxx>
94 #include <GeomAdaptor.hxx>
95 #include <Geom2dAdaptor_HCurve.hxx>
96
97 #include <GeomAbs_SurfaceType.hxx>
98 #include <GeomAbs_CurveType.hxx>
99
100 #include <ProjLib_CompProjectedCurve.hxx>
101 #include <ProjLib_HCompProjectedCurve.hxx>
102 #include <Approx_CurveOnSurface.hxx>
103 #include <Precision.hxx>
104 #include <Geom2dAdaptor.hxx>
105
106
107 #include <Precision.hxx>
108
109 #include <Geom_Surface.hxx>
110 #include <Adaptor2d_HCurve2d.hxx>
111 #include <stdio.h>
112 #include <BSplCLib.hxx>
113 #include <Geom_BSplineSurface.hxx>
114 #include <Geom_BSplineCurve.hxx>
115 #include <GCPnts_QuasiUniformDeflection.hxx>
116 #include <GCPnts_UniformDeflection.hxx>
117 #include <GCPnts_TangentialDeflection.hxx>
118 #include <GeomAPI_ExtremaCurveCurve.hxx>
119 #include <gce_MakeLin.hxx>
120 #include <TColStd_Array1OfBoolean.hxx>
121 #include <GeomAdaptor_HSurface.hxx>
122 #include <Adaptor3d_TopolTool.hxx>
123 #include <TColgp_Array2OfPnt.hxx>
124 #include <Geom_BSplineSurface.hxx>
125 #include <DrawTrSurf_BSplineSurface.hxx>
126 #include <TColStd_HArray1OfReal.hxx>
127
128 //epa test
129 #include <BRepBuilderAPI_MakeEdge.hxx>
130 #include <AIS_Shape.hxx>
131 #include <TopoDS_Edge.hxx>
132 #include <GeomLProp_CLProps.hxx>
133 #include <GCPnts_AbscissaPoint.hxx>
134 #include <GCPnts_UniformAbscissa.hxx>
135 #include <DBRep.hxx>
136
137 #ifdef WNT
138 Standard_IMPORT Draw_Viewer dout;
139 #endif
140
141 //=======================================================================
142 //function : polecurve2d
143 //purpose  : 
144 //=======================================================================
145
146 static Standard_Integer polelaw (Draw_Interpretor& , Standard_Integer n, const char** a)
147 {
148   Standard_Integer k,
149   jj,
150   qq,
151   i;
152
153
154   if (n < 3) return 1;
155   Standard_Boolean periodic = Standard_False ;
156   Standard_Integer deg = atoi(a[2]);
157   Standard_Integer nbk = atoi(a[3]);
158   
159   TColStd_Array1OfReal    knots(1, nbk);
160   TColStd_Array1OfInteger mults(1, nbk);
161   k = 4;
162   Standard_Integer Sigma = 0;
163   for (i = 1; i<=nbk; i++) {
164     knots( i) = atof(a[k]);
165     k++;
166     mults( i) = atoi(a[k]);
167     Sigma += mults(i);
168     k++;
169   }
170
171   Standard_Integer np;
172   np = Sigma - deg  -1;
173   TColStd_Array1OfReal flat_knots(1, Sigma) ;
174   jj = 1 ;
175   for (i = 1 ; i <= nbk ; i++) {
176     for(qq = 1 ; qq <= mults(i) ; qq++) {
177       flat_knots(jj) = knots(i) ;
178       jj ++ ;
179     }
180   }
181   
182   TColgp_Array1OfPnt2d poles  (1, np);
183   TColStd_Array1OfReal schoenberg_points(1,np) ;
184   BSplCLib::BuildSchoenbergPoints(deg,
185                                   flat_knots,
186                                   schoenberg_points) ;
187   for (i = 1; i <= np; i++) {
188     poles(i).SetCoord(schoenberg_points(i),atof(a[k]));
189     k++;
190   }
191     
192   Handle(Geom2d_BSplineCurve) result =
193     new Geom2d_BSplineCurve(poles, knots, mults, deg, periodic);
194   DrawTrSurf::Set(a[1],result);
195
196   
197   return 0;
198 }
199 //=======================================================================
200 //function : to2d
201 //purpose  : 
202 //=======================================================================
203
204 static Standard_Integer to2d (Draw_Interpretor& , Standard_Integer n, const char** a)
205 {
206   if (n < 3) return 1;
207
208   // get the curve
209   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
210   if (C.IsNull())
211     return 1;
212
213   Handle(Geom_Surface) S;
214   if (n >= 4) {
215     S = DrawTrSurf::GetSurface(a[3]);
216     if (S.IsNull()) return 1;
217   }
218   else
219     S = new Geom_Plane(gp::XOY());
220   
221   Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(S);
222   if (P.IsNull()) return 1;
223   Handle(Geom2d_Curve) r = GeomAPI::To2d(C,P->Pln());
224   DrawTrSurf::Set(a[1],r);
225   return 0;
226 }
227
228 //=======================================================================
229 //function : to3d
230 //purpose  : 
231 //=======================================================================
232
233 static Standard_Integer to3d (Draw_Interpretor& , Standard_Integer n, const char** a)
234 {
235   if (n < 3) return 1;
236   
237   Handle(Geom2d_Curve) C = DrawTrSurf::GetCurve2d(a[2]);
238   if (C.IsNull()) return 1;
239   
240   Handle(Geom_Surface) S;
241   if (n >= 4) {
242     S = DrawTrSurf::GetSurface(a[3]);
243     if (S.IsNull()) return 1;
244   }
245   else
246     S = new Geom_Plane(gp::XOY());
247   
248   Handle(Geom_Plane) P = Handle(Geom_Plane)::DownCast(S);
249   if (P.IsNull()) return 1;
250   Handle(Geom_Curve) r = GeomAPI::To3d(C,P->Pln());
251   
252   DrawTrSurf::Set(a[1],r);
253   return 0;
254 }
255
256 //=======================================================================
257 //function : gproject
258 //purpose  : 
259 //=======================================================================
260
261
262 static Standard_Integer gproject(Draw_Interpretor& di, Standard_Integer n, const char** a)
263 {
264   
265   char newname[1024];
266   char* temp = newname;
267   char newname1[10];
268   char* temp1 = newname1;
269   char name[100];
270   Standard_Integer ONE = 1;
271
272   if (n == 3)
273     sprintf(name,"p");
274   else if (n == 4) {
275     sprintf(name,"%s",a[1]);
276     ONE = 2;
277   }
278   else {
279    di << "gproject wait 2 or 3 arguments" << "\n";
280    return 1;
281   } 
282
283   Handle(Geom_Curve) Cur = DrawTrSurf::GetCurve(a[ONE]);
284   Handle(Geom_Surface) Sur = DrawTrSurf::GetSurface(a[ONE+1]);
285   if (Cur.IsNull() || Sur.IsNull()) return 1;
286
287   Handle(GeomAdaptor_HCurve) hcur = new GeomAdaptor_HCurve(Cur);
288   Handle(GeomAdaptor_HSurface) hsur = new GeomAdaptor_HSurface(Sur);
289
290
291   Standard_Real myTol3d = 1.e-6;
292   GeomAbs_Shape myContinuity = GeomAbs_C2;
293   Standard_Integer myMaxDegree = 14, myMaxSeg = 16;
294
295
296   ProjLib_CompProjectedCurve Projector(hsur, hcur, myTol3d/10, myTol3d/10);
297   Handle(ProjLib_HCompProjectedCurve) HProjector = new ProjLib_HCompProjectedCurve();
298   HProjector->Set(Projector);
299
300   Standard_Integer k;
301   Standard_Real Udeb, Ufin, UIso, VIso;
302   Standard_Integer Only2d, Only3d;
303   gp_Pnt2d P2d, Pdeb, Pfin;
304   gp_Pnt P;
305   Handle(Adaptor2d_HCurve2d) HPCur;
306   Handle(Geom2d_Curve) PCur2d; // Only for isoparametric projection
307
308   for(k = 1; k <= Projector.NbCurves(); k++){
309     sprintf(newname,"%s_%d",name,k);
310     sprintf(newname1,"%s2d_%d",name,k);
311     if(Projector.IsSinglePnt(k, P2d)){
312 //      cout<<"Part "<<k<<" of the projection is punctual"<<endl;
313       Projector.GetSurface()->D0(P2d.X(), P2d.Y(), P);
314       DrawTrSurf::Set(temp, P);
315       DrawTrSurf::Set(temp1, P2d);
316       di<<temp<<" is 3d projected curve"<<"\n";
317       di<<temp1<<" is pcurve"<<"\n";
318     }
319     else {
320       Only2d = Only3d = Standard_False;
321       Projector.Bounds(k, Udeb, Ufin);
322       gp_Dir2d Dir; // Only for isoparametric projection
323       
324       if (Projector.IsUIso(k, UIso)) {
325 //      cout<<"Part "<<k<<" of the projection is U-isoparametric curve"<<endl;
326         Projector.D0(Udeb, Pdeb);
327         Projector.D0(Ufin, Pfin);
328         Udeb = Pdeb.Y();
329         Ufin = Pfin.Y();
330         if (Udeb > Ufin) {
331           Dir = gp_Dir2d(0, -1);
332           Udeb = - Udeb;
333           Ufin = - Ufin;
334         }
335         else Dir = gp_Dir2d(0, 1);
336         PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(UIso, 0), Dir), Udeb, Ufin);
337         HPCur = new Geom2dAdaptor_HCurve(PCur2d);
338         Only3d = Standard_True;
339       }
340       else if(Projector.IsVIso(k, VIso)) {
341 //      cout<<"Part "<<k<<" of the projection is V-isoparametric curve"<<endl;
342         Projector.D0(Udeb, Pdeb);
343         Projector.D0(Ufin, Pfin);
344         Udeb = Pdeb.X();
345         Ufin = Pfin.X();
346         if (Udeb > Ufin) {
347           Dir = gp_Dir2d(-1, 0);
348           Udeb = - Udeb;
349           Ufin = - Ufin;
350         }
351         else Dir = gp_Dir2d(1, 0);
352         PCur2d = new Geom2d_TrimmedCurve(new Geom2d_Line(gp_Pnt2d(0, VIso), Dir), Udeb, Ufin);
353         HPCur = new Geom2dAdaptor_HCurve(PCur2d);
354         Only3d = Standard_True;
355       }
356       else HPCur = HProjector;
357       
358       if(Projector.MaxDistance(k) <= myTol3d)
359         Only2d = Standard_True;
360       
361       if(Only2d && Only3d) {
362         Handle(Geom_Curve) OutCur = new Geom_TrimmedCurve(GeomAdaptor::MakeCurve(hcur->Curve()), Ufin, Udeb);
363         DrawTrSurf::Set(temp, OutCur);
364         DrawTrSurf::Set(temp1, PCur2d);
365         di<<temp<<" is 3d projected curve"<<"\n";
366         di<<temp1<<" is pcurve"<<"\n";
367         return 0;
368         }
369       else {
370         Approx_CurveOnSurface appr(HPCur, hsur, Udeb, Ufin, myTol3d, 
371                                    myContinuity, myMaxDegree, myMaxSeg, 
372                                    Only3d, Only2d);
373         if(!Only3d) {
374           PCur2d = appr.Curve2d();
375           di << " Error in 2d is " << appr.MaxError2dU()
376                << ";  "  << appr.MaxError2dV() << "\n"; 
377         }
378         if(Only2d) {
379           Handle(Geom_Curve) OutCur = 
380             new Geom_TrimmedCurve(GeomAdaptor::MakeCurve(hcur->Curve()), 
381                                   Ufin, Udeb);
382           DrawTrSurf::Set(temp, OutCur);
383           }
384         else {
385           di << " Error in 3d is " <<  appr.MaxError3d() << "\n";
386           DrawTrSurf::Set(temp, appr.Curve3d());
387         }
388         DrawTrSurf::Set(temp1, PCur2d);
389         di<<temp<<" is 3d projected curve"<<"\n";
390         di<<temp1<<" is pcurve"<<"\n";
391       }
392     }
393   }
394 return 0;
395 }
396 //=======================================================================
397 //function : project
398 //purpose  : 
399 //=======================================================================
400
401 static Standard_Integer project (Draw_Interpretor& di, 
402                                  Standard_Integer n, const char** a)
403 {
404   if ( n == 1) {
405     
406     di << "project result2d c3d surf [-e p] [-v n] [-t tol]" << "\n";
407     di << "   -e p   : extent the surface of <p>%" << "\n";
408     di << "   -v n   : verify the projection at <n> points." << "\n";
409     di << "   -t tol : set the tolerance for approximation" << "\n";
410     return 0;
411   }
412
413   if (n < 4) return 1;
414   Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[3]);
415   if (GS.IsNull()) return 1;
416     
417   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[2]);
418   if (GC.IsNull()) return 1;
419
420   Standard_Real tolerance = Precision::Confusion() ;
421
422   Standard_Real U1,U2,V1,V2;
423   GS->Bounds(U1,U2,V1,V2);
424
425   Standard_Boolean Verif = Standard_False, Extent = Standard_False;
426   Standard_Integer NbPoints=0;
427
428   Standard_Integer index = 4;
429   while ( index+1 < n) {
430     if ( a[index][0] != '-') return 1;
431
432     if ( a[index][1] == 'e') {
433       Standard_Real p = atof(a[index+1]);
434       Standard_Real dU = p * (U2 - U1) / 100.;
435       Standard_Real dV = p * (V2 - V1) / 100.;
436       U1 -= dU; U2 += dU; V1 -= dV; V2 += dV;
437       Extent = Standard_True;
438     }
439     else if ( a[index][1] == 'v') {
440       Verif = Standard_True;
441       NbPoints = atoi(a[index+1]);
442     }
443     else if ( a[index][1] == 't') {
444       tolerance = atof(a[index+1]);
445     }
446     index += 2;
447   }
448   
449   Handle(Geom2d_Curve) G2d = 
450     GeomProjLib::Curve2d(GC, GS, U1, U2, V1, V2, tolerance);
451
452   if ( G2d.IsNull() ) {
453     di << "\n" << "Projection Failed" << "\n";
454     return 1;
455   }
456   else {
457     DrawTrSurf::Set(a[1],G2d);
458   }
459   if ( Verif) {  // verify the projection on n points
460     if ( NbPoints <= 0) { 
461       di << " n must be positive" << "\n";
462       return 0;
463     }
464     gp_Pnt P1,P2;
465     gp_Pnt2d P2d;
466     
467     Standard_Real U, dU;
468     Standard_Real Dist,DistMax = -1.;
469     U1 = GC->FirstParameter();
470     U2 = GC->LastParameter();
471     dU = ( U2 - U1) / (NbPoints + 1);
472     for ( Standard_Integer i = 0 ; i <= NbPoints +1; i++) {
473       U = U1 + i *dU;
474       P1 = GC->Value(U);
475       P2d = G2d->Value(U);
476       P2 = GS->Value(P2d.X(), P2d.Y());
477       Dist = P1.Distance(P2);
478       di << " Parameter = " << U << "\tDistance = " << Dist << "\n";
479       if ( Dist > DistMax) DistMax = Dist;
480     }
481     di << " **** Distance Maximale : " << DistMax << "\n";
482   }
483
484   return 0;
485 }
486
487 //=======================================================================
488 //function : projonplane
489 //purpose  : 
490 //=======================================================================
491
492 Standard_Integer projonplane(Draw_Interpretor& di, 
493                              Standard_Integer n, const char** a)
494 {
495   if ( n < 4 ) return 1;
496
497   Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[3]);
498   if ( S.IsNull()) return 1;
499
500   Handle(Geom_Plane)   Pl = Handle(Geom_Plane)::DownCast(S);
501   if ( Pl.IsNull()) {
502     di << " The surface must be a plane" << "\n";
503     return 1;
504   }
505
506   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
507   if ( C.IsNull()) return 1;
508   
509   Standard_Boolean Param = Standard_True;
510   if ((n == 5 && atoi(a[4]) == 0) ||
511       (n == 8 && atoi(a[7]) == 0)) Param = Standard_False;
512
513   gp_Dir D;
514   
515   if ( n == 8) {
516     D = gp_Dir(atof(a[4]),atof(a[5]),atof(a[6]));
517   }
518   else { 
519     D = Pl->Pln().Position().Direction();
520   }
521
522   Handle(Geom_Curve) Res = 
523     GeomProjLib::ProjectOnPlane(C,Pl,D,Param);
524
525   DrawTrSurf::Set(a[1],Res);
526   return 0;
527
528 }
529
530
531 //=======================================================================
532 //function : bisec
533 //purpose  : 
534 //=======================================================================
535
536 static void solution(const Handle(GccInt_Bisec)& Bis,
537                      const char* name,
538                      const Standard_Integer i)
539 {
540   char solname[200];
541   if ( i == 0) 
542     sprintf(solname,"%s",name);
543   else
544     sprintf(solname,"%s_%d",name,i);
545   const char* temp = solname; // pour portage WNT
546
547   switch ( Bis->ArcType()) {
548   case GccInt_Lin:
549     DrawTrSurf::Set(temp, new Geom2d_Line(Bis->Line()));
550     break;
551   case GccInt_Cir:
552     DrawTrSurf::Set(temp, new Geom2d_Circle(Bis->Circle()));
553     break;
554   case GccInt_Ell:
555     DrawTrSurf::Set(temp, new Geom2d_Ellipse(Bis->Ellipse()));
556     break;
557   case GccInt_Par:
558     DrawTrSurf::Set(temp, new Geom2d_Parabola(Bis->Parabola()));
559     break;
560   case GccInt_Hpr:
561     DrawTrSurf::Set(temp, new Geom2d_Hyperbola(Bis->Hyperbola()));
562     break;
563   case GccInt_Pnt:
564     DrawTrSurf::Set(temp, Bis->Point());
565     break;
566   }
567 }
568
569 static Standard_Integer bisec (Draw_Interpretor& di, 
570                                Standard_Integer n, const char** a)
571 {
572   if (n < 4) return 1;
573   
574   Handle(Geom2d_Curve) C1 = DrawTrSurf::GetCurve2d(a[2]);
575   Handle(Geom2d_Curve) C2 = DrawTrSurf::GetCurve2d(a[3]);
576   gp_Pnt2d P1,P2;
577   Standard_Boolean ip1 = DrawTrSurf::GetPoint2d(a[2],P1);
578   Standard_Boolean ip2 = DrawTrSurf::GetPoint2d(a[3],P2);
579   Standard_Integer i, Compt = 0;
580   Standard_Integer NbSol = 0;
581
582   if ( !C1.IsNull()) {
583     Handle(Standard_Type) Type1 = C1->DynamicType();
584     if ( !C2.IsNull()) {
585       Handle(Standard_Type) Type2 = C2->DynamicType();
586       if ( Type1 == STANDARD_TYPE(Geom2d_Line) && 
587            Type2 == STANDARD_TYPE(Geom2d_Line)   ) {
588         GccAna_Lin2dBisec Bis(Handle(Geom2d_Line)::DownCast(C1)->Lin2d(),
589                               Handle(Geom2d_Line)::DownCast(C2)->Lin2d());
590         if ( Bis.IsDone()) {
591           char solname[200];
592           NbSol = Bis.NbSolutions();
593           for ( i = 1; i <= NbSol; i++) {
594             sprintf(solname,"%s_%d",a[1],i);
595             const char* temp = solname; // pour portage WNT
596             DrawTrSurf::Set(temp,new Geom2d_Line(Bis.ThisSolution(i)));
597           }
598         }
599         else {
600           di << " Bisec has failed !!" << "\n";
601           return 1;
602         }
603       }
604       else if ( Type1 == STANDARD_TYPE(Geom2d_Line) && 
605                 Type2 == STANDARD_TYPE(Geom2d_Circle) ) {
606         GccAna_CircLin2dBisec 
607           Bis(Handle(Geom2d_Circle)::DownCast(C2)->Circ2d(),
608               Handle(Geom2d_Line)::DownCast(C1)->Lin2d());
609         if ( Bis.IsDone()) {
610           NbSol= Bis.NbSolutions();
611           if ( NbSol >= 2) Compt = 1;
612           for ( i = 1; i <= NbSol; i++) {
613             solution(Bis.ThisSolution(i),a[1],Compt);
614             Compt++;
615           }
616         }
617         else {
618           di << " Bisec has failed !!" << "\n";
619           return 1;
620         }
621       }
622       else if ( Type2 == STANDARD_TYPE(Geom2d_Line) && 
623                 Type1 == STANDARD_TYPE(Geom2d_Circle) ) {
624         GccAna_CircLin2dBisec 
625           Bis(Handle(Geom2d_Circle)::DownCast(C1)->Circ2d(), 
626               Handle(Geom2d_Line)::DownCast(C2)->Lin2d());
627         if ( Bis.IsDone()) {
628 //        char solname[200];
629           NbSol = Bis.NbSolutions();
630           if ( NbSol >= 2) Compt = 1;
631           for ( i = 1; i <= NbSol; i++) {
632             solution(Bis.ThisSolution(i),a[1],Compt);
633             Compt++;
634           }
635         }
636         else {
637           di << " Bisec has failed !!" << "\n";
638           return 1;
639         }
640       }
641       else if ( Type2 == STANDARD_TYPE(Geom2d_Circle) && 
642                 Type1 == STANDARD_TYPE(Geom2d_Circle) ) {
643         GccAna_Circ2dBisec 
644           Bis(Handle(Geom2d_Circle)::DownCast(C1)->Circ2d(), 
645               Handle(Geom2d_Circle)::DownCast(C2)->Circ2d());
646         if ( Bis.IsDone()) {
647 //        char solname[200];
648           NbSol = Bis.NbSolutions();
649           if ( NbSol >= 2) Compt = 1;
650           for ( i = 1; i <= NbSol; i++) {
651             solution(Bis.ThisSolution(i),a[1],Compt);
652             Compt++;
653           }
654         }
655         else {
656           di << " Bisec has failed !!" << "\n";
657           return 1;
658         }
659       }
660       else {
661         di << " args must be line/circle/point line/circle/point" << "\n";
662         return 1;
663       }
664     }
665     else if (ip2) {
666       if ( Type1 == STANDARD_TYPE(Geom2d_Circle)) {
667         GccAna_CircPnt2dBisec Bis
668           (Handle(Geom2d_Circle)::DownCast(C1)->Circ2d(),P2);
669         if ( Bis.IsDone()) {
670           NbSol = Bis.NbSolutions();
671           if ( NbSol >= 2) Compt = 1;
672           for ( i = 1; i <= NbSol; i++) {
673             solution(Bis.ThisSolution(i),a[1],Compt);
674             Compt++;
675           }
676         }
677         else {
678           di << " Bisec has failed !!" << "\n";
679           return 1;
680         }
681       }
682       else if ( Type1 == STANDARD_TYPE(Geom2d_Line)) {
683         GccAna_LinPnt2dBisec Bis
684           (Handle(Geom2d_Line)::DownCast(C1)->Lin2d(),P2);
685         if ( Bis.IsDone()) {
686           NbSol = 1;
687           solution(Bis.ThisSolution(),a[1],0);
688         }
689         else {
690           di << " Bisec has failed !!" << "\n";
691           return 1;
692         }
693       }
694     }
695     else {
696       di << " the second arg must be line/circle/point " << "\n";
697     }
698   }
699   else if ( ip1) {
700     if ( !C2.IsNull()) {
701       Handle(Standard_Type) Type2 = C2->DynamicType();
702       if ( Type2 == STANDARD_TYPE(Geom2d_Circle)) {
703         GccAna_CircPnt2dBisec Bis
704           (Handle(Geom2d_Circle)::DownCast(C2)->Circ2d(),P1);
705         if ( Bis.IsDone()) {
706           NbSol = Bis.NbSolutions();
707           if ( NbSol >= 2) Compt = 1;
708           for ( i = 1; i <= Bis.NbSolutions(); i++) {
709             solution(Bis.ThisSolution(i),a[1],Compt);
710             Compt++;
711           }
712         }
713         else {
714           di << " Bisec has failed !!" << "\n";
715           return 1;
716         }
717       }
718       else if ( Type2 == STANDARD_TYPE(Geom2d_Line)) {
719         GccAna_LinPnt2dBisec Bis
720           (Handle(Geom2d_Line)::DownCast(C2)->Lin2d(),P1);
721         if ( Bis.IsDone()) {
722           NbSol = 1;
723           solution(Bis.ThisSolution(),a[1],0);
724         }
725         else {
726           di << " Bisec has failed !!" << "\n";
727           return 1;
728         }
729       }
730     }
731     else if (ip2) {
732       GccAna_Pnt2dBisec Bis(P1,P2);
733       if ( Bis.HasSolution()) {
734         NbSol = 1;
735         DrawTrSurf::Set(a[1],new Geom2d_Line(Bis.ThisSolution()));
736       }
737       else {
738         di << " Bisec has failed !!" << "\n";
739         return 1;
740       }
741     }
742     else {
743       di << " the second arg must be line/circle/point " << "\n";
744       return 1;
745     }
746   }
747   else {
748     di << " args must be line/circle/point line/circle/point" << "\n";
749     return 1;
750   }
751
752   if ( NbSol >= 2) {
753     di << "There are " << NbSol << " Solutions." << "\n";
754   }
755   else {
756     di << "There is " << NbSol << " Solution." << "\n";
757   }
758
759   return 0;
760 }
761
762 //=======================================================================
763 //function : cmovetangent
764 //purpose  : 
765 //=======================================================================
766
767 static Standard_Integer movelaw (Draw_Interpretor& di, Standard_Integer n, const char** a)
768 {
769   Standard_Integer dimension,
770   ii,
771   condition=0,
772   error_status ;
773   Standard_Real u,
774   x,
775   tolerance,
776   tx ;
777
778   u = atof(a[2]);
779   x = atof(a[3]);
780   tolerance = 1.0e-5 ;
781   dimension = 2 ;
782   if (n < 5) {
783       return 1 ;
784   }
785   Handle(Geom2d_BSplineCurve) G2 = DrawTrSurf::GetBSplineCurve2d(a[1]);
786   if (!G2.IsNull()) {
787       tx = atof(a[4]) ;
788       if (n == 6) {
789         condition = Max(atoi(a[5]), -1)  ;
790         condition = Min(condition, G2->Degree()-1) ;
791       }
792       TColgp_Array1OfPnt2d   curve_poles(1,G2->NbPoles()) ;
793       TColStd_Array1OfReal    law_poles(1,G2->NbPoles()) ;
794       TColStd_Array1OfReal    law_knots(1,G2->NbKnots()) ;
795       TColStd_Array1OfInteger law_mults(1,G2->NbKnots()) ;
796
797       G2->Knots(law_knots) ;
798       G2->Multiplicities(law_mults) ;
799       G2->Poles(curve_poles) ;
800       for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
801         law_poles(ii) = curve_poles(ii).Coord(2) ;
802       }
803
804       Law_BSpline  a_law(law_poles,
805                          law_knots,
806                          law_mults,
807                          G2->Degree(),
808                          Standard_False) ;
809
810       a_law.MovePointAndTangent(u, 
811                               x, 
812                               tx,
813                               tolerance,
814                               condition,
815                               condition,
816                               error_status) ;
817
818       for (ii = 1 ; ii <= G2->NbPoles() ; ii++) {
819         curve_poles(ii).SetCoord(2,a_law.Pole(ii)) ;
820         G2->SetPole(ii,curve_poles(ii)) ;
821       }
822
823         
824       if (! error_status) {
825         Draw::Repaint();
826         }
827       else {
828         di << "Not enought degree of freedom increase degree please" << "\n";
829       }
830       
831     
832     }
833   return 0;
834
835
836
837 //Static method computing deviation of curve and polyline
838
839 static void ComputeDeviation(const Handle(Geom_Curve)& theCurve,
840                              const Handle(Geom_BSplineCurve)& thePnts,
841                              Standard_Real& theDmax,
842                              Standard_Real& theUfMax,
843                              Standard_Real& theUlMax,
844                              Standard_Integer& theImax)
845 {
846   theDmax = 0.;
847   theUfMax = 0.;
848   theUlMax = 0.;
849   theImax = 0;
850   Standard_Real ufmax = 0., ulmax = 0.;
851
852   //take knots
853   Standard_Integer nbp = thePnts->NbKnots();
854   TColStd_Array1OfReal aKnots(1, nbp);
855   thePnts->Knots(aKnots);
856
857   Standard_Integer i;
858   for(i = 1; i < nbp; ++i) {
859     Standard_Real uf = aKnots(i);
860     Standard_Real ul = aKnots(i+1);
861
862     GeomAPI_ExtremaCurveCurve ECC(theCurve, thePnts, uf, ul, uf, ul);
863
864     Standard_Integer nbe = ECC.NbExtrema();
865     if(nbe > 0) {
866       Standard_Integer k;
867       Standard_Real d = 0.;
868       for(k = 1; k <= nbe; k++) {
869         if(ECC.Distance(k) > d) d = ECC.Distance(k);
870       }
871
872       if(d > theDmax) {
873         theDmax = d;
874               theUfMax = uf;
875               theUlMax = ul;
876               theImax = i;
877       }
878     }
879   }
880 }
881
882
883 //=======================================================================
884 //function : crvpoints
885 //purpose  : 
886 //=======================================================================
887
888 static Standard_Integer crvpoints (Draw_Interpretor& di, Standard_Integer /*n*/, const char** a)
889 {
890   Standard_Integer i, nbp;
891   Standard_Real defl;
892
893   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
894   defl = atof(a[3]);
895
896   GeomAdaptor_Curve GAC(C);
897   GCPnts_QuasiUniformDeflection PntGen(GAC, defl);
898     
899   if(!PntGen.IsDone()) {
900     di << "Points generation failed" << "\n";
901     return 1;
902   }
903
904   nbp = PntGen.NbPoints();
905   di << "Nb points : " << nbp << "\n";
906
907   TColgp_Array1OfPnt aPoles(1, nbp);
908   TColStd_Array1OfReal aKnots(1, nbp);
909   TColStd_Array1OfInteger aMults(1, nbp);
910
911   for(i = 1; i <= nbp; ++i) {
912     aPoles(i) = PntGen.Value(i);
913     aKnots(i) = PntGen.Parameter(i);
914     aMults(i) = 1;
915   }
916   
917   aMults(1) = 2;
918   aMults(nbp) = 2;
919
920   Handle(Geom_BSplineCurve) aPnts = new Geom_BSplineCurve(aPoles, aKnots, aMults, 1);
921   Handle(DrawTrSurf_BSplineCurve) aDrCrv = new DrawTrSurf_BSplineCurve(aPnts);
922
923   aDrCrv->ClearPoles();
924   Draw_Color aKnColor(Draw_or);
925   aDrCrv->SetKnotsColor(aKnColor);
926   aDrCrv->SetKnotsShape(Draw_Plus);
927
928   Draw::Set(a[1], aDrCrv);
929
930   Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
931   Standard_Integer imax = 0;
932
933   //check deviation
934   ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
935   di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << i << "\n"; 
936
937   return 0;
938
939
940 //=======================================================================
941 //function : crvtpoints
942 //purpose  : 
943 //=======================================================================
944
945 static Standard_Integer crvtpoints (Draw_Interpretor& di, Standard_Integer n, const char** a)
946 {
947   Standard_Integer i, nbp;
948   Standard_Real defl, angle = Precision::Angular();
949
950   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
951   defl = atof(a[3]);
952
953   if(n > 3)
954     angle = atof(a[4]);
955
956   GeomAdaptor_Curve GAC(C);
957   GCPnts_TangentialDeflection PntGen(GAC, angle, defl, 2);
958   
959   nbp = PntGen.NbPoints();
960   di << "Nb points : " << nbp << "\n";
961
962   TColgp_Array1OfPnt aPoles(1, nbp);
963   TColStd_Array1OfReal aKnots(1, nbp);
964   TColStd_Array1OfInteger aMults(1, nbp);
965
966   for(i = 1; i <= nbp; ++i) {
967     aPoles(i) = PntGen.Value(i);
968     aKnots(i) = PntGen.Parameter(i);
969     aMults(i) = 1;
970   }
971   
972   aMults(1) = 2;
973   aMults(nbp) = 2;
974
975   Handle(Geom_BSplineCurve) aPnts = new Geom_BSplineCurve(aPoles, aKnots, aMults, 1);
976   Handle(DrawTrSurf_BSplineCurve) aDrCrv = new DrawTrSurf_BSplineCurve(aPnts);
977
978   aDrCrv->ClearPoles();
979   Draw_Color aKnColor(Draw_or);
980   aDrCrv->SetKnotsColor(aKnColor);
981   aDrCrv->SetKnotsShape(Draw_Plus);
982
983   Draw::Set(a[1], aDrCrv);
984
985   Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
986   Standard_Integer imax = 0;
987
988   //check deviation
989   ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
990   di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << i << "\n"; 
991
992   return 0;
993
994 //=======================================================================
995 //function : uniformAbscissa
996 //purpose  : epa test (TATA-06-002 (Problem with GCPnts_UniformAbscissa class)
997 //=======================================================================
998 static Standard_Integer uniformAbscissa (Draw_Interpretor& di, Standard_Integer n, const char** a)
999 {
1000   if( n != 3 )
1001     return 1;
1002   
1003   /*Handle(Geom_BSplineCurve) ellip;
1004   ellip = DrawTrSurf::GetBSplineCurve(a[1]);
1005   if (ellip.IsNull())
1006   {
1007     di << " BSpline is NULL  "<<"\n";     
1008     return 1;
1009   }*/
1010
1011   Handle(Geom_Curve) ellip;
1012   ellip = DrawTrSurf::GetCurve(a[1]);
1013   if (ellip.IsNull())
1014   {
1015     di << " Curve is NULL  "<<"\n";     
1016     return 1;
1017   }
1018
1019   Standard_Integer nocp;
1020   nocp = atoi(a[2]);
1021   if(nocp < 2)
1022     return 1;
1023
1024
1025   //test nbPoints for Geom_Ellipse
1026
1027   try
1028   {
1029     GeomLProp_CLProps Prop(ellip,2,Precision::Intersection());
1030     Prop.SetCurve(ellip);
1031
1032     GeomAdaptor_Curve GAC(ellip);
1033     di<<"Type Of curve: "<<GAC.GetType()<<"\n";
1034     Standard_Real Tol = Precision::Confusion();
1035     Standard_Real L;
1036
1037     L = GCPnts_AbscissaPoint::Length(GAC, GAC.FirstParameter(), GAC.LastParameter(), Tol);
1038     di<<"Ellipse length = "<<L<<"\n";
1039     Standard_Real Abscissa = L/(nocp-1);
1040     di << " CUR : Abscissa " << Abscissa << "\n";
1041
1042     GCPnts_UniformAbscissa myAlgo(GAC, Abscissa, ellip->FirstParameter(), ellip->LastParameter());
1043     if ( myAlgo.IsDone() )
1044     {
1045       di << " CasCurve  - nbpoints " << myAlgo.NbPoints() << "\n";
1046       for(Standard_Integer i = 1; i<= myAlgo.NbPoints(); i++ )
1047         di << i <<" points = " << myAlgo.Parameter( i ) << "\n";
1048     }
1049   }
1050
1051   catch (Standard_Failure )
1052   {
1053     di << " Standard Failure  " <<"\n";
1054   }
1055   return 0;
1056 }
1057
1058 //=======================================================================
1059 //function : EllipsUniformAbscissa
1060 //purpose  : epa test (TATA-06-002 (Problem with GCPnts_UniformAbscissa class)
1061 //=======================================================================
1062 static Standard_Integer EllipsUniformAbscissa (Draw_Interpretor& di, Standard_Integer n, const char** a)
1063 {
1064   if( n != 4 )
1065     return 1;  
1066   
1067   Standard_Real R1;
1068   R1 = atof(a[1]);
1069   Standard_Real R2;
1070   R2 = atof(a[2]);
1071
1072   Standard_Integer nocp;
1073   nocp = atoi(a[3]);
1074   if(nocp < 2)
1075     return 1;
1076   
1077   //test nbPoints for Geom_Ellipse
1078   Handle_Geom_Ellipse ellip;
1079
1080
1081   try
1082   {
1083     gp_Pnt location;
1084     location = gp_Pnt( 0.0, 0.0, 0.0);
1085     gp_Dir main_direction(0.0, 0.0, 1.0);
1086
1087     gp_Dir x_direction(1.0, 0.0, 0.0);
1088     gp_Ax2 mainaxis( location, main_direction);
1089
1090     mainaxis.SetXDirection(x_direction);
1091     ellip = new Geom_Ellipse(mainaxis,R1, R2);
1092
1093     BRepBuilderAPI_MakeEdge curve_edge(ellip);
1094     TopoDS_Edge edge_curve = curve_edge.Edge();
1095
1096     DBRep::Set("Ellipse",edge_curve);
1097   }
1098   
1099   catch(Standard_Failure)
1100   {
1101     di << " Standard Failure  "<<"\n";     
1102   }
1103
1104   try
1105   {
1106     GeomLProp_CLProps Prop(ellip,2,Precision::Intersection());
1107     Prop.SetCurve(ellip);
1108
1109     GeomAdaptor_Curve GAC(ellip);
1110     di<<"Type Of curve: "<<GAC.GetType()<<"\n";
1111     Standard_Real Tol = Precision::Confusion();
1112     Standard_Real L;
1113
1114     L = GCPnts_AbscissaPoint::Length(GAC, GAC.FirstParameter(), GAC.LastParameter(), Tol);
1115     di<<"Ellipse length = "<<L<<"\n";
1116     Standard_Real Abscissa = L/(nocp-1);
1117     di << " CUR : Abscissa " << Abscissa << "\n";
1118
1119     GCPnts_UniformAbscissa myAlgo(GAC, Abscissa, ellip->FirstParameter(), ellip->LastParameter());
1120     if ( myAlgo.IsDone() )
1121     {
1122       di << " CasCurve  - nbpoints " << myAlgo.NbPoints() << "\n";
1123       for(Standard_Integer i = 1; i<= myAlgo.NbPoints(); i++ )
1124         di << i <<" points = " << myAlgo.Parameter( i ) << "\n";
1125     }
1126   }
1127
1128   catch (Standard_Failure )
1129   {
1130     di << " Standard Failure  " <<"\n";
1131   }
1132   return 0;
1133 }
1134
1135 //=======================================================================
1136 //function : mypoints
1137 //purpose  : 
1138 //=======================================================================
1139
1140 static Standard_Integer mypoints (Draw_Interpretor& di, Standard_Integer /*n*/, const char** a)
1141 {
1142   Standard_Integer i, nbp;
1143   Standard_Real defl;
1144
1145   Handle(Geom_Curve) C = DrawTrSurf::GetCurve(a[2]);
1146   defl = atof(a[3]);
1147   const Handle(Geom_BSplineCurve)& aBS = Handle(Geom_BSplineCurve)::DownCast(C);
1148
1149   if(aBS.IsNull()) return 1;
1150
1151   Standard_Integer ui1 = aBS->FirstUKnotIndex();
1152   Standard_Integer ui2 = aBS->LastUKnotIndex();
1153
1154   Standard_Integer nbsu = ui2-ui1+1; nbsu += (nbsu - 1) * (aBS->Degree()-1);
1155
1156   TColStd_Array1OfReal anUPars(1, nbsu);
1157   TColStd_Array1OfBoolean anUFlg(1, nbsu);
1158
1159   Standard_Integer j, k, nbi;
1160   Standard_Real t1, t2, dt;
1161
1162   //Filling of sample parameters
1163   nbi = aBS->Degree();
1164   k = 0;
1165   t1 = aBS->Knot(ui1);
1166   for(i = ui1+1; i <= ui2; ++i) {
1167     t2 = aBS->Knot(i);
1168     dt = (t2 - t1)/nbi;
1169     j = 1;
1170     do { 
1171       ++k;
1172       anUPars(k) = t1;
1173       anUFlg(k) = Standard_False;
1174       t1 += dt; 
1175     }
1176     while (++j <= nbi);
1177     t1 = t2;
1178   }
1179   ++k;
1180   anUPars(k) = t1;
1181
1182   Standard_Integer l;
1183   defl *= defl;
1184
1185   j = 1;
1186   anUFlg(1) = Standard_True;
1187   anUFlg(nbsu) = Standard_True;
1188   Standard_Boolean bCont = Standard_True;
1189   while (j < nbsu-1 && bCont) {
1190     t2 = anUPars(j);
1191     gp_Pnt p1 = aBS->Value(t2);
1192     for(k = j+2; k <= nbsu; ++k) {
1193       t2 = anUPars(k);
1194       gp_Pnt p2 = aBS->Value(t2);
1195       gce_MakeLin MkLin(p1, p2);
1196       const gp_Lin& lin = MkLin.Value();
1197       Standard_Boolean ok = Standard_True;
1198       for(l = j+1; l < k; ++l) {
1199         if(anUFlg(l)) continue;
1200         gp_Pnt pp =  aBS->Value(anUPars(l));
1201         Standard_Real d = lin.SquareDistance(pp);
1202           
1203         if(d <= defl) continue;
1204
1205         ok = Standard_False;
1206         break;
1207       }
1208
1209
1210       if(!ok) {
1211         j = k - 1;
1212         anUFlg(j) = Standard_True;
1213         break;
1214       }
1215
1216     }
1217
1218     if(k >= nbsu) bCont = Standard_False;
1219   }
1220
1221   nbp = 0;
1222   for(i = 1; i <= nbsu; ++i) {
1223     if(anUFlg(i)) nbp++;
1224   }
1225
1226   TColgp_Array1OfPnt aPoles(1, nbp);
1227   TColStd_Array1OfReal aKnots(1, nbp);
1228   TColStd_Array1OfInteger aMults(1, nbp);
1229   j = 0;
1230   for(i = 1; i <= nbsu; ++i) {
1231     if(anUFlg(i)) {
1232       ++j;
1233       aKnots(j) = anUPars(i);
1234       aMults(j) = 1;
1235       aPoles(j) = aBS->Value(aKnots(j));
1236     }
1237   }
1238   
1239   aMults(1) = 2;
1240   aMults(nbp) = 2;
1241
1242   Handle(Geom_BSplineCurve) aPnts = new Geom_BSplineCurve(aPoles, aKnots, aMults, 1);
1243   Handle(DrawTrSurf_BSplineCurve) aDrCrv = new DrawTrSurf_BSplineCurve(aPnts);
1244
1245   aDrCrv->ClearPoles();
1246   Draw_Color aKnColor(Draw_or);
1247   aDrCrv->SetKnotsColor(aKnColor);
1248   aDrCrv->SetKnotsShape(Draw_Plus);
1249
1250   Draw::Set(a[1], aDrCrv);
1251
1252   Standard_Real dmax = 0., ufmax = 0., ulmax = 0.;
1253   Standard_Integer imax = 0;
1254
1255   ComputeDeviation(C,aPnts,dmax,ufmax,ulmax,imax);
1256   di << "Max defl: " << dmax << " " << ufmax << " " << ulmax << " " << imax << "\n"; 
1257
1258   return 0;
1259
1260
1261
1262
1263 //=======================================================================
1264 //function : surfpoints
1265 //purpose  : 
1266 //=======================================================================
1267
1268 static Standard_Integer surfpoints (Draw_Interpretor& /*di*/, Standard_Integer /*n*/, const char** a)
1269 {
1270   Standard_Integer i;
1271   Standard_Real defl;
1272
1273   Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[2]);
1274   defl = atof(a[3]);
1275
1276   Handle(GeomAdaptor_HSurface) AS = new GeomAdaptor_HSurface(S);
1277
1278   Handle(Adaptor3d_TopolTool) aTopTool = new Adaptor3d_TopolTool(AS);
1279
1280   aTopTool->SamplePnts(defl, 10, 10);
1281
1282   Standard_Integer nbpu = aTopTool->NbSamplesU();
1283   Standard_Integer nbpv = aTopTool->NbSamplesV();
1284   TColStd_Array1OfReal Upars(1, nbpu), Vpars(1, nbpv);
1285   aTopTool->UParameters(Upars);
1286   aTopTool->VParameters(Vpars);
1287
1288   TColgp_Array2OfPnt aPoles(1, nbpu, 1, nbpv);
1289   TColStd_Array1OfReal anUKnots(1, nbpu);
1290   TColStd_Array1OfReal aVKnots(1, nbpv);
1291   TColStd_Array1OfInteger anUMults(1, nbpu);
1292   TColStd_Array1OfInteger aVMults(1, nbpv);
1293
1294   Standard_Integer j;
1295   for(i = 1; i <= nbpu; ++i) {
1296     anUKnots(i) = Upars(i);
1297     anUMults(i) = 1;
1298     for(j = 1; j <= nbpv; ++j) {
1299       aVKnots(j) = Vpars(j);
1300       aVMults(j) = 1;
1301       aPoles(i,j) = S->Value(anUKnots(i),aVKnots(j));
1302     }
1303   }
1304   
1305   anUMults(1) = 2;
1306   anUMults(nbpu) = 2;
1307   aVMults(1) = 2;
1308   aVMults(nbpv) = 2;
1309
1310   Handle(Geom_BSplineSurface) aPnts = new Geom_BSplineSurface(aPoles, anUKnots,  aVKnots, 
1311                                                               anUMults, aVMults, 1, 1);
1312   Handle(DrawTrSurf_BSplineSurface) aDrSurf = new DrawTrSurf_BSplineSurface(aPnts);
1313
1314   aDrSurf->ClearPoles();
1315   Draw_Color aKnColor(Draw_or);
1316   aDrSurf->SetKnotsColor(aKnColor);
1317   aDrSurf->SetKnotsShape(Draw_Plus);
1318
1319   Draw::Set(a[1], aDrSurf);
1320
1321
1322   return 0;
1323
1324
1325
1326
1327 //=======================================================================
1328 //function : intersect
1329 //purpose  : 
1330 //=======================================================================
1331 static Standard_Integer intersection (Draw_Interpretor& di, Standard_Integer n, const char** a)
1332 {
1333   if (n < 4) {
1334     return 1;
1335   }
1336   //
1337   Handle(Geom_Curve) GC1;
1338   Handle(Geom_Surface) GS1 = DrawTrSurf::GetSurface(a[2]);
1339   if (GS1.IsNull()) {
1340     GC1 = DrawTrSurf::GetCurve(a[2]);
1341     if (GC1.IsNull())
1342       return 1;
1343   }
1344   //
1345   Handle(Geom_Surface) GS2 = DrawTrSurf::GetSurface(a[3]);
1346   if (GS2.IsNull()) {
1347     return 1;
1348   }
1349   //
1350   Standard_Real tol = Precision::Confusion();
1351   if (n == 5 || n == 9 || n == 13 || n == 17) tol = atof(a[n-1]);
1352   //
1353   Handle(Geom_Curve) Result;
1354   gp_Pnt             Point;
1355   //
1356   if (GC1.IsNull()) {
1357     GeomInt_IntSS Inters;
1358     //
1359     // Surface Surface
1360     if (n <= 5) {
1361       // General case
1362       Inters.Perform(GS1,GS2,tol,Standard_True);
1363     }
1364     else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17) {
1365       Standard_Boolean useStart = Standard_True, useBnd = Standard_True;
1366       Standard_Integer ista1=0,ista2=0,ibnd1=0,ibnd2=0;
1367       Standard_Real UVsta[4];
1368       Handle(GeomAdaptor_HSurface) AS1,AS2;
1369       //
1370       if (n <= 9) {        // user starting point
1371         useBnd = Standard_False;
1372         ista1 = 4; ista2 = 7;
1373       }
1374       else if (n <= 13) {        // user bounding
1375         useStart = Standard_False;
1376         ibnd1 = 4; ibnd2 = 11;
1377       }
1378       else {        // both user starting point and bounding
1379         ista1 = 4; ista2 = 7;
1380         ibnd1 = 8; ibnd2 = 15;
1381       }
1382       if (useStart)
1383         for (Standard_Integer i=ista1; i <= ista2; i++)
1384           UVsta[i-ista1] = atof(a[i]);
1385       if (useBnd) {
1386         Standard_Real UVbnd[8];
1387         for (Standard_Integer i=ibnd1; i <= ibnd2; i++)
1388           UVbnd[i-ibnd1] = atof(a[i]);
1389         AS1 = new GeomAdaptor_HSurface(GS1,UVbnd[0],UVbnd[1],UVbnd[2],UVbnd[3]);
1390         AS2 = new GeomAdaptor_HSurface(GS2,UVbnd[4],UVbnd[5],UVbnd[6],UVbnd[7]);
1391       }
1392       //
1393       if (useStart && !useBnd) {
1394         Inters.Perform(GS1,GS2,tol,UVsta[0],UVsta[1],UVsta[2],UVsta[3]);
1395       }
1396       else if (!useStart && useBnd) {
1397         Inters.Perform(AS1,AS2,tol);
1398       }
1399       else {
1400         Inters.Perform(AS1,AS2,tol,UVsta[0],UVsta[1],UVsta[2],UVsta[3]);
1401       }
1402     }//else if (n == 8 || n == 9 || n == 12 || n == 13 || n == 16 || n == 17) {
1403     else {
1404       di<<"incorrect number of arguments"<<"\n";
1405       return 1;
1406     }
1407     //
1408     if (!Inters.IsDone()) {
1409       return 1;
1410     }
1411     //
1412     char buf[1024];
1413     Standard_Integer i, aNbLines, aNbPoints; 
1414       //
1415     aNbLines = Inters.NbLines();
1416     if (aNbLines >= 2) {
1417       for (i=1; i<=aNbLines; ++i) {
1418         sprintf(buf, "%s_%d",a[1],i);
1419         Result = Inters.Line(i);
1420         const char* temp = buf; 
1421         DrawTrSurf::Set(temp,Result);
1422       }
1423     }
1424     else if (aNbLines == 1) {
1425       Result = Inters.Line(1);
1426       DrawTrSurf::Set(a[1],Result);
1427     }
1428     //
1429     aNbPoints=Inters.NbPoints();
1430     for (i=1; i<=aNbPoints; ++i) {
1431       Point=Inters.Point(i);
1432       sprintf(buf,"%s_p_%d",a[1],i);
1433       const char* temp =buf;
1434       DrawTrSurf::Set(temp, Point);
1435     }
1436   }// if (GC1.IsNull()) {
1437   //
1438   else {
1439     // Curve Surface
1440     GeomAPI_IntCS Inters(GC1,GS2);
1441     //
1442     if (!Inters.IsDone()) return 1;
1443     
1444     Standard_Integer nblines = Inters.NbSegments();
1445     Standard_Integer nbpoints = Inters.NbPoints();
1446     if ( (nblines+nbpoints) >= 2) {
1447       char newname[1024];
1448       Standard_Integer i;
1449       Standard_Integer Compt = 1;
1450       for (i = 1; i <= nblines; i++, Compt++) {
1451         sprintf(newname,"%s_%d",a[1],Compt);
1452         Result = Inters.Segment(i);
1453         const char* temp = newname; // pour portage WNT
1454         DrawTrSurf::Set(temp,Result);
1455       }
1456       for (i = 1; i <= nbpoints; i++, Compt++) {
1457         sprintf(newname,"%s_%d",a[1],i);
1458         Point = Inters.Point(i);
1459         const char* temp = newname; // pour portage WNT
1460         DrawTrSurf::Set(temp,Point);
1461       }
1462     }
1463     else if (nblines == 1) {
1464       Result = Inters.Segment(1);
1465       DrawTrSurf::Set(a[1],Result);
1466     }
1467     else if (nbpoints == 1) {
1468       Point = Inters.Point(1);
1469       DrawTrSurf::Set(a[1],Point);
1470     }
1471   }
1472
1473   dout.Flush();
1474   return 0;
1475 }
1476
1477 //=======================================================================
1478 //function : CurveCommands
1479 //purpose  : 
1480 //=======================================================================
1481 void  GeometryTest::CurveCommands(Draw_Interpretor& theCommands)
1482 {
1483   
1484   static Standard_Boolean loaded = Standard_False;
1485   if (loaded) return;
1486   loaded = Standard_True;
1487   
1488   DrawTrSurf::BasicCommands(theCommands);
1489   
1490   const char* g;
1491   
1492   g = "GEOMETRY curves creation";
1493
1494   theCommands.Add("law",
1495                   "law  name degree nbknots  knot, umult  value",
1496                   __FILE__,
1497                   polelaw,g);
1498
1499   theCommands.Add("to2d","to2d c2dname c3d [plane (XOY)]",
1500                   __FILE__,
1501                   to2d,g);
1502
1503   theCommands.Add("to3d","to3d c3dname c2d [plane (XOY)]",
1504                   __FILE__,
1505                   to3d,g);
1506
1507   theCommands.Add("gproject",
1508                   "gproject : [projectname] curve surface",
1509                   __FILE__,
1510                   gproject,g);
1511   
1512   theCommands.Add("project",
1513                   "project : no args to have help",
1514                   __FILE__,
1515                   project,g);
1516   
1517   theCommands.Add("projonplane",
1518                   "projonplane r C3d Plane [dx dy dz] [0/1]",
1519                   projonplane);
1520
1521   theCommands.Add("bisec",
1522                   "bisec result line/circle/point line/circle/point",
1523                   __FILE__,
1524                   bisec, g);
1525
1526   g = "GEOMETRY Curves and Surfaces modification";
1527
1528
1529   theCommands.Add("movelaw",
1530                   "movelaw name u  x  tx [ constraint = 0]",
1531                   __FILE__,
1532                   movelaw,g) ;
1533
1534
1535
1536   g = "GEOMETRY intersections";
1537
1538   theCommands.Add("intersect",
1539                   "intersect result surf1/curv1 surf2 [tolerance]\n\t\t  "
1540                   "intersect result surf1 surf2 [u1 v1 u2 v2] [U1F U1L V1F V1L U2F U2L V2F V2L] [tolerance]",
1541                   __FILE__,
1542                   intersection,g);
1543
1544   theCommands.Add("crvpoints",
1545                   "crvpoints result curv deflection",
1546                   __FILE__,
1547                   crvpoints,g);
1548
1549   theCommands.Add("crvtpoints",
1550                   "crvtpoints result curv deflection angular deflection - tangential deflection points",
1551                   __FILE__,
1552                   crvtpoints,g);
1553   
1554   theCommands.Add("uniformAbscissa",
1555                   "uniformAbscissa Curve nbPnt",
1556                   __FILE__,
1557                   uniformAbscissa,g);
1558
1559   theCommands.Add("uniformAbscissaEl",
1560                   "uniformAbscissaEl maxR minR nbPnt",
1561                   __FILE__,  EllipsUniformAbscissa,g);
1562
1563   theCommands.Add("mypoints",
1564                   "mypoints result curv deflection",
1565                   __FILE__,
1566                   mypoints,g);
1567   theCommands.Add("surfpoints",
1568                   "surfoints result surf deflection",
1569                   __FILE__,
1570                   surfpoints,g);
1571
1572 }
1573