0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / BRepTest / BRepTest_CurveCommands.cxx
1 // File:        DBRep_3.cxx
2 // Created:     Thu Jul 22 16:38:58 1993
3 // Author:      Remi LEQUETTE
4 //              <rle@nonox>
5
6
7 #include <BRepTest.hxx>
8 #include <GeometryTest.hxx>
9 #include <gp_Pnt2d.hxx>
10 #include <gp_Pln.hxx>
11 #include <gp_Ax2.hxx>
12 #include <gp_Vec.hxx>
13 #include <gp_Vec2d.hxx>
14 #include <TColgp_HArray1OfPnt2d.hxx>
15 #include <TColgp_Array1OfPnt2d.hxx>
16 #include <BRepBuilderAPI.hxx>
17 #include <BRepBuilderAPI_MakeVertex.hxx>
18 #include <BRepBuilderAPI_MakeEdge.hxx>
19 #include <BRepBuilderAPI_MakeEdge2d.hxx>
20 #include <BRepBuilderAPI_MakeFace.hxx>
21 #include <BRepBuilderAPI_MakeWire.hxx>
22 #include <BRepBuilderAPI_MakePolygon.hxx>
23 #include <BRepOffsetAPI_MakeOffset.hxx>
24 #include <BRepLib.hxx>
25 #include <BRepAlgo.hxx>
26 #include <BRepAdaptor_Curve.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepTools.hxx>
30 #include <Geom_Curve.hxx>
31 #include <Geom_TrimmedCurve.hxx>
32 #include <Geom2d_BSplineCurve.hxx>
33 #include <Geom_Surface.hxx>
34 #include <Geom_RectangularTrimmedSurface.hxx>
35 #include <Geom_Plane.hxx>
36 #include <Geom2d_Line.hxx>
37 #include <Geom2d_Circle.hxx>
38 #include <Geom2dAPI_Interpolate.hxx>
39 #include <Geom2d_TrimmedCurve.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Wire.hxx>
43
44 #include <DBRep.hxx>
45 #include <DBRep_DrawableShape.hxx>
46 #include <Draw_Interpretor.hxx>
47 #include <Draw_Appli.hxx>
48 #include <DrawTrSurf.hxx>
49 #include <DrawTrSurf_BSplineCurve2d.hxx>
50
51 #include <gp.hxx>
52 #include <Precision.hxx>
53 #include <GeomAPI.hxx>
54 #include <TopAbs_Orientation.hxx>
55 #include <TopExp_Explorer.hxx>
56 #include <TopOpeBRep_EdgesIntersector.hxx>
57 #include <TopOpeBRep_Point2d.hxx>
58 #include <TopOpeBRepDS_Transition.hxx>
59
60 //#ifdef WNT
61 #include <stdio.h>
62 #ifdef WNT
63 Standard_IMPORT Draw_Viewer dout;
64 #endif
65
66 //=======================================================================
67 // vertex
68 //=======================================================================
69
70 static Standard_Integer vertex(Draw_Interpretor& , Standard_Integer n, const char** a)
71 {
72   if (n < 4) return 1;
73   if (n >= 5) {
74     DBRep::Set(a[1],
75                BRepBuilderAPI_MakeVertex(gp_Pnt(atof(a[2]),atof(a[3]),atof(a[4]))));
76     }
77   else {
78     TopoDS_Shape S = DBRep::Get(a[3]);
79     if (S.IsNull()) return 0;
80     if (S.ShapeType() != TopAbs_EDGE) return 0;
81     BRepAdaptor_Curve C(TopoDS::Edge(S));
82     gp_Pnt P;
83     C.D0(atof(a[2]),P);
84     DBRep::Set(a[1], BRepBuilderAPI_MakeVertex(P));
85   }
86   return 0;
87 }
88
89 //=======================================================================
90 // range
91 //=======================================================================
92
93 static Standard_Integer range(Draw_Interpretor& , Standard_Integer n, const char** a)
94 {
95   if (n < 4) return 1;
96   TopoDS_Shape aLocalShape(DBRep::Get(a[1],TopAbs_EDGE));
97   TopoDS_Edge E = TopoDS::Edge(aLocalShape);
98 //  TopoDS_Edge E = TopoDS::Edge(DBRep::Get(a[1],TopAbs_EDGE));
99   if (E.IsNull()) return 1;
100   Standard_Real f = atof(a[n-2]);
101   Standard_Real l = atof(a[n-1]);
102   BRep_Builder B;
103   if (n == 4)
104     B.Range(E,f,l);
105   else {
106     aLocalShape = DBRep::Get(a[2],TopAbs_FACE);
107     TopoDS_Face F = TopoDS::Face(aLocalShape);
108 //    TopoDS_Face F = TopoDS::Face(DBRep::Get(a[2],TopAbs_FACE));
109     if (F.IsNull()) return 1;
110     B.Range(E,F,f,l);
111   }
112   return 0;
113 }
114
115 //=======================================================================
116 // trim
117 //=======================================================================
118
119 static Standard_Integer trim(Draw_Interpretor& di, Standard_Integer n, const char** a)
120 {
121   if (n < 3) return 1;
122   TopoDS_Shape e = DBRep::Get(a[1]);
123   if (e.IsNull()) return 1;
124   if (e.ShapeType() != TopAbs_EDGE) return 1;
125   TopoDS_Shape v1 = DBRep::Get(a[2]);
126   if (v1.IsNull()) return 1;
127   if (v1.ShapeType() != TopAbs_VERTEX) return 1;
128   TopoDS_Shape v2;
129   if (n > 3) {
130     v2 = DBRep::Get(a[3]);
131     if (v2.IsNull()) return 1;
132     if (v2.ShapeType() != TopAbs_VERTEX) return 1;
133   }
134   TopLoc_Location L;
135   Standard_Real f,l;
136   const Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(e),L,f,l);
137   TopLoc_Location LI = L.Inverted();
138   e.Orientation(TopAbs_FORWARD);
139   e.Move(LI);
140   v1.Move(LI);
141   v2.Move(LI);
142   TopoDS_Edge ne;
143   if (v2.IsNull()) {
144     if (v1.Orientation() == TopAbs_REVERSED) {
145       v2 = v1;
146       v1 = TopoDS_Shape();
147     }
148   }
149   BRepBuilderAPI_MakeEdge ME(C,TopoDS::Vertex(v1),TopoDS::Vertex(v2));
150   if (ME.IsDone()) {
151     ne = ME;
152     ne.Move(L);
153     DBRep::Set(a[1],ne);
154   }
155   else {
156     //cout <<"Error creating edge"<<endl;
157     di <<"Error creating edge"<<"\n";
158   }
159   return 0;
160 }
161
162
163 //=======================================================================
164 // polyline
165 //=======================================================================
166
167 static Standard_Integer polyline(Draw_Interpretor& , Standard_Integer n, const char** a)
168 {
169   if (n < 8) return 1;
170   if (((n-2) % 3) != 0) return 1;
171   Standard_Integer i, j, np = (n-2) / 3;
172   BRepBuilderAPI_MakePolygon W;
173   j = 2;
174   for (i = 1; i <= np; i ++) {
175     W.Add(gp_Pnt(atof(a[j]),atof(a[j+1]),atof(a[j+2])));
176     j += 3;
177   }
178   DBRep::Set(a[1],W.Wire());
179   return 0;
180 }
181
182 //=======================================================================
183 // polyvertex
184 //=======================================================================
185
186 static Standard_Integer polyvertex(Draw_Interpretor& , Standard_Integer n, const char** a)
187 {
188   if (n < 4) return 1;
189   Standard_Integer i;
190   BRepBuilderAPI_MakePolygon W;
191   for (i = 2; i < n; i ++) {
192     TopoDS_Shape S = DBRep::Get(a[i]);
193     if (S.IsNull()) return 1;
194     if (S.ShapeType() != TopAbs_VERTEX) return 1;
195     W.Add(TopoDS::Vertex(S));
196   }
197   DBRep::Set(a[1],W.Wire());
198   return 0;
199 }
200
201 //=======================================================================
202 // wire
203 //=======================================================================
204
205 static Standard_Integer wire(Draw_Interpretor& di, Standard_Integer n, const char** a)
206 {
207   if (n < 3) return 1;
208   Standard_Integer i;
209   BRepBuilderAPI_MakeWire MW;
210   for (i = 2; i < n; i ++) {
211     TopoDS_Shape S = DBRep::Get(a[i]);
212     if (S.IsNull()) continue;
213     if (S.ShapeType() == TopAbs_EDGE)
214       MW.Add(TopoDS::Edge(S));
215     else if (S.ShapeType() == TopAbs_WIRE)
216       MW.Add(TopoDS::Wire(S));
217     else
218       continue;
219   }
220   if (!MW.IsDone()) {
221     //cout << "Wire not done" << endl;
222     di << "Wire not done" << "\n";
223     return 0;
224   }
225   DBRep::Set(a[1],MW);
226   return 0;
227 }
228
229 //=======================================================================
230 // mkedge
231 //=======================================================================
232
233 static Standard_Integer mkedge(Draw_Interpretor& di, Standard_Integer n, const char** a)
234 {
235   if (n < 3) return 1;
236   
237   Handle(Geom_Curve)   C   = DrawTrSurf::GetCurve(a[2]);
238   Handle(Geom2d_Curve) C2d = DrawTrSurf::GetCurve2d(a[2]);
239   if (C.IsNull() && C2d.IsNull()) {
240     //cout << a[2] << " is not a curve" << endl;
241     di << a[2] << " is not a curve" << "\n";
242     return 1;
243   }
244   
245   TopoDS_Edge edge;
246
247   if (n == 3) {
248     if (!C.IsNull())   edge = BRepBuilderAPI_MakeEdge(C);
249     else               edge = BRepBuilderAPI_MakeEdge2d(C2d);
250   }
251   else {
252     Handle(Geom_Surface) S;
253     Standard_Integer i = 0;
254     if (!C2d.IsNull()) {
255       S = DrawTrSurf::GetSurface(a[3]);
256       if (!S.IsNull()) i = 1;
257     }
258     TopoDS_Shape aLocalShape(DBRep::Get(a[3+i],TopAbs_VERTEX));
259     TopoDS_Vertex V1 = TopoDS::Vertex(aLocalShape);
260 //    TopoDS_Vertex V1 = TopoDS::Vertex(DBRep::Get(a[3+i],TopAbs_VERTEX));
261     if (n == 5+i) {
262       if (V1.IsNull()) {
263         if (!C.IsNull())   
264           edge = BRepBuilderAPI_MakeEdge(C,atof(a[3]),atof(a[4]));
265         else if (S.IsNull())              
266           edge = BRepBuilderAPI_MakeEdge2d(C2d,atof(a[3]),atof(a[4]));
267         else
268           edge = BRepBuilderAPI_MakeEdge(C2d,S,atof(a[4]),atof(a[5]));
269       }
270       else {
271         aLocalShape = DBRep::Get(a[4+i],TopAbs_VERTEX);
272         TopoDS_Vertex V2 = TopoDS::Vertex(aLocalShape);
273 //      TopoDS_Vertex V2 = TopoDS::Vertex(DBRep::Get(a[4+i],TopAbs_VERTEX));
274         if (!C.IsNull())   
275           edge = BRepBuilderAPI_MakeEdge(C,V1,V2);
276         else if (S.IsNull())              
277           edge = BRepBuilderAPI_MakeEdge2d(C2d,V1,V2);
278         else
279           edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2);
280       }
281     }  
282     else if (n == 7+i) {
283       aLocalShape = DBRep::Get(a[5+i],TopAbs_VERTEX);
284       TopoDS_Vertex V2 = TopoDS::Vertex(aLocalShape);
285 //      TopoDS_Vertex V2 = TopoDS::Vertex(DBRep::Get(a[5+i],TopAbs_VERTEX));
286       if (!C.IsNull())   
287         edge = BRepBuilderAPI_MakeEdge(C,V1,V2,atof(a[4]),atof(a[6]));
288       else if (S.IsNull())         
289         edge = BRepBuilderAPI_MakeEdge2d(C2d,V1,V2,atof(a[4]),atof(a[6]));
290       else              
291         edge = BRepBuilderAPI_MakeEdge(C2d,S,V1,V2,atof(a[5]),atof(a[7]));
292     }
293     else
294       return 1;
295   }
296
297   DBRep::Set(a[1],edge);
298   return 0;
299 }
300
301 //=======================================================================
302 // mkcurve
303 //=======================================================================
304 Standard_IMPORT Draw_Color DrawTrSurf_CurveColor(const Draw_Color col);
305 Standard_IMPORT void DBRep_WriteColorOrientation ();
306 Standard_IMPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or);
307
308 static Standard_Integer mkcurve(Draw_Interpretor& di, Standard_Integer n, const char** a)
309 {
310   if (n < 3) return 1;
311
312   Standard_Boolean DispOrientation = !strcmp(a[0],"mkoricurve");
313
314   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_EDGE);
315   if (S.IsNull()) return 1;
316   TopLoc_Location L;
317   Standard_Real f,l;
318
319   Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(S),L,f,l);
320   if (C.IsNull()) {
321     //cout << a[2] << " has no 3d curve" << endl;
322     di << a[2] << " has no 3d curve" << "\n";
323     return 1;
324   }
325   C = new Geom_TrimmedCurve(C,f,l);
326   
327   Draw_Color col,savecol;
328   
329   if ( DispOrientation) {
330     DBRep_WriteColorOrientation ();
331     col = DBRep_ColorOrientation(TopoDS::Edge(S).Orientation());
332     savecol = DrawTrSurf_CurveColor(col);
333   }
334   DrawTrSurf::Set(a[1],C->Transformed(L.Transformation()));
335   if ( DispOrientation) {
336     DrawTrSurf_CurveColor(savecol);
337   }
338
339   return 0;
340 }
341
342 //=======================================================================
343 //function : mkpoint
344 //purpose  : 
345 //=======================================================================
346
347 static Standard_Integer mkpoint(Draw_Interpretor& , 
348                                 Standard_Integer n, const char** a)
349 {
350   if (n < 3) return 1;
351
352   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_VERTEX);
353   if ( S.IsNull()) return 1;
354
355   TopoDS_Vertex V = TopoDS::Vertex(S);
356   
357   gp_Pnt P = BRep_Tool::Pnt(V);
358   DrawTrSurf::Set(a[1],P);
359
360   return 0;
361 }
362
363 //=======================================================================
364 // mk2dcurve
365 //=======================================================================
366
367 static Standard_Integer mk2dcurve(Draw_Interpretor& di, 
368                                   Standard_Integer na, const char** a)
369 {
370   if (na < 3) return 1;
371
372   TopoDS_Shape S;
373   S = DBRep::Get(a[2],TopAbs_EDGE); if (S.IsNull()) return 1;
374   TopoDS_Edge E = TopoDS::Edge(S);
375
376   TopLoc_Location L;
377   Standard_Real f,l;
378   Handle(Geom2d_Curve) C;
379   Handle(Geom_Surface) Surf;
380   
381   if ( na == 3 ) {
382     // get the first PCurve connected to edge E
383     BRep_Tool::CurveOnSurface(E,C,Surf,L,f,l);
384   }
385   else if ( na == 4 ) {
386     S = DBRep::Get(a[3],TopAbs_FACE); if (S.IsNull()) return 1;
387     TopoDS_Face F = TopoDS::Face(S);
388     C = BRep_Tool::CurveOnSurface(E,F,f,l);
389   }
390
391   if (C.IsNull()) {
392     //cout << a[2] << " has no 2d curve"; if (na == 4) cout << " on " << a[3];
393     //cout << endl;
394     di << a[2] << " has no 2d curve"; if (na == 4) di << " on " << a[3];
395     di << "\n";
396     return 1;
397   }
398   C = new Geom2d_TrimmedCurve(C,f,l);
399   DrawTrSurf::Set(a[1],C);
400
401   return 0;
402 }
403
404 //=======================================================================
405 // edge
406 //=======================================================================
407
408 static Standard_Integer edge(Draw_Interpretor& , Standard_Integer n, const char** a)
409 {
410   if (n < 4) return 1;
411   TopoDS_Shape V1 = DBRep::Get(a[2],TopAbs_VERTEX);
412   TopoDS_Shape V2 = DBRep::Get(a[3],TopAbs_VERTEX);
413   if (V1.IsNull() || V2.IsNull()) return 1;
414   TopoDS_Edge E = BRepBuilderAPI_MakeEdge(TopoDS::Vertex(V1),
415                                    TopoDS::Vertex(V2));
416   DBRep::Set(a[1],E);
417   return 0;
418 }
419
420 //=======================================================================
421 // isoedge
422 //=======================================================================
423
424 static Standard_Integer isoedge(Draw_Interpretor& , Standard_Integer n, const char** a)
425 {
426   if (n < 6) return 1;
427
428   Standard_Boolean uiso = *a[0] == 'u';
429   Standard_Real p = atof(a[3]);
430   Standard_Real p1 = atof(a[4]);
431   Standard_Real p2 = atof(a[5]);
432   TopoDS_Shape Sh = DBRep::Get(a[2],TopAbs_FACE);
433   if (Sh.IsNull()) return 1;
434   TopLoc_Location Loc;
435   const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopoDS::Face(Sh),Loc);
436   Standard_Real UMin,UMax,VMin,VMax;
437   BRepTools::UVBounds(TopoDS::Face(Sh),UMin,UMax,VMin,VMax);
438   if (uiso) {
439      VMin = Min (VMin , Min (p1,p2));
440      VMax = Max (VMax , Max (p1,p2));
441    }
442   else{
443      UMin = Min (UMin , Min (p1,p2));
444      UMax = Max (VMax , Max (p1,p2));
445    }
446     
447   Handle(Geom_RectangularTrimmedSurface) TS = new Geom_RectangularTrimmedSurface(S,UMin,UMax,VMin,VMax);
448   Handle(Geom_Curve) C;
449   Handle(Geom2d_Line) L;
450   if (uiso) {
451     C = TS->UIso(p);
452     L = new Geom2d_Line(gp_Pnt2d(p,0),gp_Dir2d(0,1));
453   }
454   else {
455     C = TS->VIso(p);
456     L = new Geom2d_Line(gp_Pnt2d(0,p),gp_Dir2d(1,0));
457   }
458
459   TopoDS_Edge E = BRepBuilderAPI_MakeEdge(C,p1,p2);
460   E.Location(Loc);
461   BRep_Builder B;
462   B.UpdateEdge(E,L,TopoDS::Face(Sh),0.);
463
464   DBRep::Set(a[1],E);
465   return 0;
466 }
467
468 //=======================================================================
469 // transfert
470 //=======================================================================
471
472 static Standard_Integer transfert(Draw_Interpretor& , Standard_Integer n, const char** a)
473 {
474   if (n < 3) return 1;
475
476   TopoDS_Shape E1 = DBRep::Get(a[1],TopAbs_EDGE);
477   TopoDS_Shape E2 = DBRep::Get(a[2],TopAbs_EDGE);
478   if (E1.IsNull() || E2.IsNull()) return 1;
479   
480   BRep_Builder B;
481   B.Transfert(TopoDS::Edge(E1),TopoDS::Edge(E2));
482   return 0;
483 }
484
485 //=======================================================================
486 // profile
487 // command to build a profile
488 //=======================================================================
489
490 static Standard_Integer profile(Draw_Interpretor& di,
491                                 Standard_Integer n,
492                                 const char** a)
493 {
494   // this command build a profile
495   // from a moving point
496
497   if (n == 1) {
498     // print help
499
500     //cout << "profile name [code values] [code values] ...\n";
501     //cout << "  Build a profile in the XY plane from a moving point and direction\n";
502     //cout << "  The original point and direction are 0 0 and 1 0\n";
503     //cout << "  Codes and values describe the point or direction change\n";
504     //cout << "  When the point change the direction becomes the tangent\n";
505     //cout << "  All angles are in degree (may be negative)\n";
506     //cout << "  By default the profile is closed and a face is built\n";
507     //cout << "\n";
508     //cout << "  Instruction Parameters         Action\n";
509     //cout << "  O           X Y Z              Set the origin of the plane\n";
510     //cout << "  P           DX DY DZ UX UY UZ  Set the normal and X of the plane\n";
511     //cout << "  S           Face               Set the Plane (Face must be a Face)\n";
512     //cout << "  F           X Y                Set the first point\n";
513     //cout << "  X           DX                 Translate point along X\n";
514     //cout << "  Y           DY                 Translate point along Y\n";
515     //cout << "  L           DL                 Translate point along direction\n";
516     //cout << "  XX          X                  Set point X coordinate\n";
517     //cout << "  YY          Y                  Set point Y coordinate\n";
518     //cout << "  T           DX DY              Translate point\n";
519     //cout << "  TT          X Y                Set point\n";
520     //cout << "  R           Angle              Rotate direction\n";
521     //cout << "  RR          Angle              Set direction\n";
522     //cout << "  D           DX DY              Set direction\n";
523     //cout << "  IX          X                  Intersect with vertical\n";
524     //cout << "  IY          Y                  Intersect with horizontal\n";
525     //cout << "  C           Radius Angle       Arc of circle tangent to direction\n";
526     //cout << "  W                              Make a closed wire\n";
527     //cout << "  WW                             Make an open wire\n";
528     //cout << endl;
529     di << "profile name [code values] [code values] ...\n";
530     di << "  Build a profile in the XY plane from a moving point and direction\n";
531     di << "  The original point and direction are 0 0 and 1 0\n";
532     di << "  Codes and values describe the point or direction change\n";
533     di << "  When the point change the direction becomes the tangent\n";
534     di << "  All angles are in degree (may be negative)\n";
535     di << "  By default the profile is closed and a face is built\n";
536     di << "\n";
537     di << "  Instruction Parameters         Action\n";
538     di << "  O           X Y Z              Set the origin of the plane\n";
539     di << "  P           DX DY DZ UX UY UZ  Set the normal and X of the plane\n";
540     di << "  S           Face               Set the Plane (Face must be a Face)\n";
541     di << "  F           X Y                Set the first point\n";
542     di << "  X           DX                 Translate point along X\n";
543     di << "  Y           DY                 Translate point along Y\n";
544     di << "  L           DL                 Translate point along direction\n";
545     di << "  XX          X                  Set point X coordinate\n";
546     di << "  YY          Y                  Set point Y coordinate\n";
547     di << "  T           DX DY              Translate point\n";
548     di << "  TT          X Y                Set point\n";
549     di << "  R           Angle              Rotate direction\n";
550     di << "  RR          Angle              Set direction\n";
551     di << "  D           DX DY              Set direction\n";
552     di << "  IX          X                  Intersect with vertical\n";
553     di << "  IY          Y                  Intersect with horizontal\n";
554     di << "  C           Radius Angle       Arc of circle tangent to direction\n";
555     di << "  W                              Make a closed wire\n";
556     di << "  WW                             Make an open wire\n";
557     di << "\n";
558     return 0;
559   }
560
561   Standard_Integer i = 2;
562   Standard_Real x0 = 0, y0 = 0, x = 0, y = 0, dx = 1, dy = 0;
563   BRepBuilderAPI_MakeWire MW;
564   gp_Ax3 DummyHP(gp::XOY());
565   gp_Pln P(DummyHP);
566   enum {line , circle, none} move;
567   Standard_Boolean face  = Standard_True;
568   Standard_Boolean close = Standard_True;
569   Standard_Boolean first = Standard_True;
570   Standard_Boolean stayfirst = Standard_False;
571   Standard_Boolean isplanar  = Standard_True;
572   TopoDS_Shape S;
573   TopLoc_Location TheLocation;
574   Handle(Geom_Surface) Surface;
575   while (i < n) {
576
577     Standard_Real length=0,radius=0,angle=0;
578     move = none;
579
580     switch (a[i][0]) {
581
582     case 'F':
583     case 'f':
584       i += 2;
585       if (i >= n) goto badargs;
586       if (!first) {
587         di << "profile: The F instruction must precede all moves";
588         return 1;
589       }
590       x0 = x = atof(a[i-1]);
591       y0 = y = atof(a[i]);
592       stayfirst = Standard_True;
593       break;
594
595     case 'O':
596     case 'o':
597       i += 3;
598       if (i >= n) goto badargs;
599       P.SetLocation(gp_Pnt(atof(a[i-2]),atof(a[i-1]),atof(a[i])));
600       stayfirst = Standard_True;
601       break;
602
603     case 'P':
604     case 'p':
605       i += 6;
606       if (i >= n) goto badargs;
607       {
608         gp_Vec vn(atof(a[i-5]),atof(a[i-4]),atof(a[i-3]));
609         gp_Vec vx(atof(a[i-2]),atof(a[i-1]),atof(a[i]));
610         if (vn.Magnitude() <= Precision::Confusion()) {
611           di << "profile : null direction";
612           return 1;
613         }
614         if (vx.Magnitude() <= Precision::Confusion()) {
615           di << "profile : null direction";
616           return 1;
617         }
618         gp_Ax2 ax(P.Location(),vn,vx);
619         P.SetPosition(ax);
620       }
621       stayfirst = Standard_True;
622       break;
623
624     case 'S':
625     case 's':
626       i += 1;
627       if (i >= n) goto badargs;
628       {
629         TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
630         TopoDS_Face Face = TopoDS::Face(aLocalShape);
631 //      TopoDS_Face Face = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
632         if (Face.IsNull()) {
633           di << "profile : no face found";
634           return 1;
635         }
636         Surface = BRep_Tool::Surface(Face,TheLocation);
637         Handle(Geom_Plane) Plane = Handle(Geom_Plane)::DownCast(Surface);
638         if ( Plane.IsNull()) {
639           isplanar = Standard_False;
640         }
641         else 
642           P = Plane->Pln();
643       }
644       stayfirst = Standard_True;
645       break;
646
647     case 'X':
648     case 'x':
649       i++;
650       if (i >= n) goto badargs;
651       length = atof(a[i]);
652       if ((a[i-1][1] == 'X') || (a[i-1][1] == 'x')) {
653         length -= x;
654       }
655       dx = 1; dy = 0;
656       move = line;
657       break;
658       
659     case 'Y':
660     case 'y':
661       i++;
662       if (i >= n) goto badargs;
663       length = atof(a[i]);
664       if ((a[i-1][1] == 'Y') || (a[i-1][1] == 'y')) {
665         length -= y;
666       }
667       dx = 0; dy = 1;
668       move = line;
669       break;
670       
671     case 'L':
672     case 'l':
673       i++;
674       if (i >= n) goto badargs;
675       length = atof(a[i]);
676       move = line;
677       break;
678
679     case 'T':
680     case 't':
681       i += 2;
682       if (i >= n) goto badargs;
683       {
684         Standard_Real vx = atof(a[i-1]);
685         Standard_Real vy = atof(a[i]);
686         if ((a[i-2][1] == 'T') || (a[i-2][1] == 't')) {
687           vx -= x;
688           vy -= y;
689         }
690         length = Sqrt(vx*vx+vy*vy);
691         if (length > Precision::Confusion()) {
692           move = line;
693           dx = vx / length;
694           dy = vy / length;
695         }
696       }
697       break;
698
699     case 'R':
700     case 'r':
701       i++;
702       if (i >= n) goto badargs;
703       angle = atof(a[i]) * (M_PI / 180.0);
704       if ((a[i-1][1] == 'R') || (a[i-1][1] == 'r')) {
705         dx = Cos(angle);
706         dy = Sin(angle);
707       }
708       else {
709         Standard_Real c = Cos(angle);
710         Standard_Real s = Sin(angle);
711         Standard_Real t = c * dx - s * dy;
712         dy = s * dx + c * dy;
713         dx = t;
714       }
715       break;
716
717     case 'D':
718     case 'd':
719       i += 2;
720       if (i >= n) goto badargs;
721       {
722         Standard_Real vx = atof(a[i-1]);
723         Standard_Real vy = atof(a[i]);
724         length = Sqrt(vx*vx+vy*vy);
725         if (length > Precision::Confusion()) {
726           // move = line; DUB
727           dx = vx / length;
728           dy = vy / length;
729         }
730       }
731       break;
732
733     case 'C':
734     case 'c':
735       i += 2;
736       if (i >= n) goto badargs;
737       radius = atof(a[i-1]);
738       if (Abs(radius) > Precision::Confusion()) {
739         angle = atof(a[i]) * (M_PI / 180.0);
740         move = circle;
741       }
742       break;
743
744     case 'I':
745     case 'i':
746       i++;
747       if (i >= n) goto badargs;
748       length = atof(a[i]);
749       if ((a[i-1][1] == 'X') || (a[i-1][1] == 'x')) {
750         if (Abs(dx) < Precision::Confusion()) {
751           di << "Profile : cannot intersect, arg " << i-1;
752           return 1;
753         }
754         length = (length - x) / dx;
755         move = line;
756       }
757       else if ((a[i-1][1] == 'Y') || (a[i-1][1] == 'y')) {
758         if (Abs(dy) < Precision::Confusion()) {
759           di << "Profile : cannot intersect, arg " << i-1;
760           return 1;
761         }
762         length = (length - y) / dy;
763         move = line;
764       }
765      
766       break;
767
768     case 'W':
769     case 'w':
770       face = Standard_False;
771       if ((a[i][1] == 'W') || (a[i][1] == 'w')) {
772         close = Standard_False;
773       }
774       i = n-1;
775       break;
776
777     default:
778       di <<"profile : unknown code " << a[i];
779       return 1;
780     }
781
782   again:
783
784     switch (move) {
785       
786     case line :
787       {
788         if (length < 0) {
789           length = -length;
790           dx = -dx;
791           dy = -dy;
792         }
793         Handle(Geom2d_Line) l = 
794           new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
795         if (isplanar)
796           MW.Add(BRepBuilderAPI_MakeEdge(GeomAPI::To3d(l,P),0,length));
797         else 
798           MW.Add(BRepBuilderAPI_MakeEdge(l,Surface,0,length));
799         x += length*dx;
800         y += length*dy;
801       }
802       break;
803
804     case circle :
805       {
806         Standard_Boolean sense = Standard_True;
807         if (radius < 0) {
808           radius = -radius;
809           sense = !sense;
810           dx = -dx;
811           dy = -dy;
812         }
813         gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx));
814         if (angle < 0) {
815           angle = -angle;
816           sense = !sense;
817         }
818         Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense);
819         if (isplanar)
820           MW.Add(BRepBuilderAPI_MakeEdge(GeomAPI::To3d(c,P),0,angle));
821         else
822           MW.Add(BRepBuilderAPI_MakeEdge(c,Surface,0,angle));
823         gp_Pnt2d p;
824         gp_Vec2d v;
825         c->D1(angle,p,v);
826         x = p.X();
827         y = p.Y();
828         dx = v.X() / radius;
829         dy = v.Y() / radius;
830       }
831       break;
832
833     case none:
834       break;
835     }
836
837     // update first
838     first = stayfirst;
839     stayfirst = Standard_False;
840
841     // next segment....
842     i++;
843     if ((i == n) && close) {
844       // the closing segment
845       dx = x0-x;
846       dy = y0-y;
847       length = Sqrt(dx*dx+dy*dy);
848       if (length > Precision::Confusion()) {
849         move = line;
850         dx = dx / length;
851         dy = dy / length;
852         goto again;
853       }
854     }
855   }
856
857
858   // get the result, face or wire
859
860   if (face) {
861     if ( isplanar)
862       S = BRepBuilderAPI_MakeFace(P,MW.Wire());
863     else {
864       BRepBuilderAPI_MakeFace MFace;
865       MFace.Init(Surface,Standard_False,Precision::Confusion());
866       MFace.Add(MW.Wire());
867       S = MFace.Face();
868     }
869   }
870   else {
871     S = MW;
872   }
873   
874   if (!TheLocation.IsIdentity())
875     S.Move(TheLocation);
876
877   if ( !isplanar) {
878     Standard_Real Tol = 1.e-5;
879     BRepLib::BuildCurves3d(S,Tol);
880   }
881
882   DBRep::Set(a[1],S);
883
884   return 0;
885
886  badargs:
887   di << "profile : bad number of arguments";
888   return 1;
889 }
890 //=======================================================================
891 // profile
892 // command to build a profile
893 //=======================================================================
894
895 static Standard_Integer bsplineprof(Draw_Interpretor& di,
896                                     Standard_Integer n,
897                                     const char** a)
898 {
899   // this command build a profile
900   // from a moving point
901
902   if (n == 1) {
903     // print help
904
905     //cout << " bsplineprof name [S face] [W WW]  "              << endl;
906     //cout << " for an edge : <digitizes> ... <mouse button 2> " << endl ;
907     //cout << " to end profile : <mouse button 3> "              << endl ;
908     //cout << "  Build a profile in the XY plane from digitizes" << endl ;
909     //cout << "  By default the profile is closed and a face is built\n";
910     //cout << "\n";
911     //cout << "  W                              Make a closed wire\n";
912     //cout << "  WW                             Make an open wire\n";
913     //cout << endl;
914     di << " bsplineprof name [S face] [W WW]  "              << "\n";
915     di << " for an edge : <digitizes> ... <mouse button 2> " <<  "\n";
916     di << " to end profile : <mouse button 3> "              <<  "\n";
917     di << "  Build a profile in the XY plane from digitizes" <<  "\n";
918     di << "  By default the profile is closed and a face is built\n";
919     di << "\n";
920     di << "  W                              Make a closed wire\n";
921     di << "  WW                             Make an open wire\n";
922     di << "\n";
923     return 0;
924   }
925
926   gp_Pnt2d last_point(0.0e0,
927                     0.0e0) ;
928   gp_Pnt2d first_point(0.0e0,
929                        0.0e0) ;
930   Standard_Integer i = 2,
931   wait = 1 ;
932 //  Standard_Real x0 = 0, y0 = 0, x = 0, y = 0, dx = 1, dy = 0;
933   Standard_Real x = 0, y = 0, dx = 1, dy = 0;
934   BRepBuilderAPI_MakeWire MW;
935   gp_Ax3 DummyHP(gp::XOY());
936   gp_Pln P(DummyHP);
937   Standard_Boolean face  = Standard_True;
938   Standard_Boolean close = Standard_True;
939 //  Standard_Boolean first = Standard_True;
940   Standard_Boolean stayfirst = Standard_False;
941   Standard_Boolean isplanar  = Standard_True;
942   Standard_Real  length ; 
943   TopoDS_Shape S;
944   TopLoc_Location TheLocation;
945   Handle(Geom_Surface) Surface;
946   if (n > 2) {
947     while (i < n) {
948       
949       switch (a[i][0]) {
950         
951       case 'S':
952       case 's':
953         i += 1;
954         {
955           TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
956           TopoDS_Face Face = TopoDS::Face(aLocalShape);
957 //        TopoDS_Face Face = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
958           if (Face.IsNull()) {
959             di << "profile : no face found";
960             return 1;
961           }
962           Surface = BRep_Tool::Surface(Face,TheLocation);
963           Handle(Geom_Plane) Plane = Handle(Geom_Plane)::DownCast(Surface);
964           if ( Plane.IsNull()) {
965             isplanar = Standard_False;
966           }
967           else 
968             P = Plane->Pln();
969         }
970         stayfirst = Standard_True;
971         i += 1 ;
972         break;
973         
974       case 'W':
975       case 'w':
976         face = Standard_False;
977         if ((a[i][1] == 'W') || (a[i][1] == 'w')) {
978           close = Standard_False;
979         }
980         i = n-1;
981         break;
982
983       default:
984         di <<"profile : unknown code " << a[i];
985         return 1;
986       }
987     }
988   }
989 //
990 //  to be done : close the profile using the first point of the contour
991 //               and the point taken with mouse button 3 
992 //
993  Handle(Geom2d_BSplineCurve) C ;
994  Handle(Geom_Curve) curve3d_ptr ;
995  Standard_Integer id, ii;
996  Standard_Integer X,Y,b, not_done;
997  Standard_Integer num_points = 0  ;
998  gp_Pnt2d a_point(  0.0e0,
999                   0.0e0) ;
1000   Handle(TColgp_HArray1OfPnt2d) points_array_ptr = 
1001     new TColgp_HArray1OfPnt2d(1, 1);               
1002   Handle(TColgp_HArray1OfPnt2d) new_points_array_ptr ;
1003
1004   not_done = 1 ;
1005   while (not_done) {
1006    
1007    dout.Select(id,X,Y,b,wait);
1008    Standard_Real z = dout.Zoom(id);
1009    a_point.SetCoord(1,(Standard_Real)X /z) ;
1010    a_point.SetCoord(2,(Standard_Real)Y /z) ;
1011    if (num_points == 0) {
1012      points_array_ptr = 
1013        new TColgp_HArray1OfPnt2d(1, 1); 
1014      points_array_ptr->ChangeArray1()(1) = a_point ;
1015      first_point = a_point ;
1016
1017    }
1018    num_points += 1 ;
1019    if (num_points >= 2) {
1020      new_points_array_ptr = 
1021      new TColgp_HArray1OfPnt2d(1, num_points);
1022      for (ii = 1 ; ii <= num_points -1 ; ii++) {
1023        new_points_array_ptr->ChangeArray1()(ii) =
1024          points_array_ptr->Array1()(ii) ;
1025      }
1026      new_points_array_ptr->ChangeArray1()(num_points) = a_point ;
1027      Geom2dAPI_Interpolate    a2dInterpolator(new_points_array_ptr,
1028                                               Standard_False,
1029                                               1.0e-5) ;
1030      a2dInterpolator.Perform() ;
1031      if (a2dInterpolator.IsDone()) { 
1032             C = a2dInterpolator.Curve() ;
1033             curve3d_ptr =
1034             GeomAPI::To3d(C,P) ;
1035             DrawTrSurf::Set(a[1], curve3d_ptr);
1036             dout.RepaintView(id);
1037      }
1038      points_array_ptr = new_points_array_ptr ;
1039
1040    }
1041        
1042    if (b == 2 || b == 3) {
1043      if (num_points == 2)  {
1044         x = last_point.Coord(1) ;
1045         y = last_point.Coord(2) ;
1046         dx = a_point.Coord(1) - x ;
1047         dy = a_point.Coord(2) - y ;
1048         gp_Vec2d a_vector(dx,
1049                           dy) ;
1050         length = a_vector.Magnitude() ;
1051         Handle(Geom2d_Line) l = 
1052           new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
1053         if (isplanar) {
1054           MW.Add(BRepBuilderAPI_MakeEdge(GeomAPI::To3d(l,P),0,length));
1055         }
1056         else { 
1057           MW.Add(BRepBuilderAPI_MakeEdge(l,Surface,0,length));
1058         }
1059
1060       }
1061     else if (num_points > 2) {
1062         if (isplanar) {
1063           MW.Add(BRepBuilderAPI_MakeEdge(curve3d_ptr,
1064                                   curve3d_ptr->FirstParameter(),
1065                                   curve3d_ptr->LastParameter()));
1066         }
1067         else { 
1068           MW.Add(BRepBuilderAPI_MakeEdge(C,
1069                                   Surface,
1070                                   C->FirstParameter(),
1071                                   C->LastParameter()));
1072         }
1073       }
1074      if (num_points >= 2) {
1075        last_point = a_point ;
1076        points_array_ptr->ChangeArray1()(1) = a_point ;
1077        num_points = 1 ;
1078        DBRep::Set(a[1], MW.Wire()) ;
1079      }      
1080     
1081   
1082    }
1083    if (b == 3) {
1084      not_done = 0 ; 
1085    }
1086  }
1087   a_point = first_point ;
1088   if (close) {
1089     
1090     x = last_point.Coord(1) ;
1091     y = last_point.Coord(2) ;
1092     dx = a_point.Coord(1) - x ;
1093     dy = a_point.Coord(2) - y ;
1094     gp_Vec2d a_vector(dx,
1095                       dy) ;
1096     length = a_vector.Magnitude() ;
1097     Handle(Geom2d_Line) l = 
1098       new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
1099     if (isplanar)
1100       MW.Add(BRepBuilderAPI_MakeEdge(GeomAPI::To3d(l,P),0,length));
1101     else 
1102       MW.Add(BRepBuilderAPI_MakeEdge(l,Surface,0,length));
1103   }
1104   if (face) {
1105     if ( isplanar)
1106       S = BRepBuilderAPI_MakeFace(P,MW.Wire());
1107     else {
1108       BRepBuilderAPI_MakeFace MFace;
1109       MFace.Init(Surface,Standard_False,Precision::Confusion());
1110       MFace.Add(MW.Wire());
1111       S = MFace.Face();
1112     }
1113   }
1114   else {
1115     S = MW;
1116   }
1117   
1118   if (!TheLocation.IsIdentity())
1119     S.Move(TheLocation);
1120   
1121   if ( !isplanar) {
1122     Standard_Real Tol = 1.e-5;
1123     BRepLib::BuildCurves3d(S,Tol);
1124   }
1125   
1126   DBRep::Set(a[1],S);
1127   
1128   return 0;
1129
1130 #ifdef DEB  
1131   di << "profile : bad number of arguments";
1132   return 1;
1133 #endif
1134 }
1135
1136
1137
1138 //=======================================================================
1139 // 2dprofile
1140 // command to build a profile
1141 //=======================================================================
1142
1143 static Standard_Integer profile2d(Draw_Interpretor& di, 
1144                                   Standard_Integer n, 
1145                                   const char** a)
1146 {
1147   // this command build a profile with 2d curves.
1148   // from a moving point
1149
1150   if (n == 1) {
1151     // print help
1152
1153     //cout << "profile name [code values] [code values] ...\n";
1154     //cout << "  Build a profile in the UV plane from a moving point and direction\n";
1155     //cout << "  The original point and direction are 0 0 and 1 0\n";
1156     //cout << "  Codes and values describe the point or direction change\n";
1157     //cout << "  When the point change the direction becomes the tangent\n";
1158     //cout << "  All angles are in degree (may be negative)\n";
1159     //cout << "  By default the profile is closed \n";
1160     //cout << "\n";
1161     //cout << "  Instruction Parameters         Action\n";
1162     //cout << "  F           X Y                Set the first point\n";
1163     //cout << "  X           DX                 Translate point along X\n";
1164     //cout << "  Y           DY                 Translate point along Y\n";
1165     //cout << "  L           DL                 Translate point along direction\n";
1166     //cout << "  XX          X                  Set point X coordinate\n";
1167     //cout << "  YY          Y                  Set point Y coordinate\n";
1168     //cout << "  T           DX DY              Translate point\n";
1169     //cout << "  TT          X Y                Set point\n";
1170     //cout << "  R           Angle              Rotate direction\n";
1171     //cout << "  RR          Angle              Set direction\n";
1172     //cout << "  D           DX DY              Set direction\n";
1173     //cout << "  IX          X                  Intersect with vertical\n";
1174     //cout << "  IY          Y                  Intersect with horizontal\n";
1175     //cout << "  C           Radius Angle       Arc of circle tangent to direction\n";
1176     //cout << "  W                              Make a closed wire\n";
1177     //cout << endl;
1178     di << "profile name [code values] [code values] ...\n";
1179     di << "  Build a profile in the UV plane from a moving point and direction\n";
1180     di << "  The original point and direction are 0 0 and 1 0\n";
1181     di << "  Codes and values describe the point or direction change\n";
1182     di << "  When the point change the direction becomes the tangent\n";
1183     di << "  All angles are in degree (may be negative)\n";
1184     di << "  By default the profile is closed \n";
1185     di << "\n";
1186     di << "  Instruction Parameters         Action\n";
1187     di << "  F           X Y                Set the first point\n";
1188     di << "  X           DX                 Translate point along X\n";
1189     di << "  Y           DY                 Translate point along Y\n";
1190     di << "  L           DL                 Translate point along direction\n";
1191     di << "  XX          X                  Set point X coordinate\n";
1192     di << "  YY          Y                  Set point Y coordinate\n";
1193     di << "  T           DX DY              Translate point\n";
1194     di << "  TT          X Y                Set point\n";
1195     di << "  R           Angle              Rotate direction\n";
1196     di << "  RR          Angle              Set direction\n";
1197     di << "  D           DX DY              Set direction\n";
1198     di << "  IX          X                  Intersect with vertical\n";
1199     di << "  IY          Y                  Intersect with horizontal\n";
1200     di << "  C           Radius Angle       Arc of circle tangent to direction\n";
1201     di << "  W                              Make a closed wire\n";
1202     di << "\n";
1203     return 0;
1204   }
1205
1206   Standard_Integer i = 2, NbCurves = 0;
1207   Standard_Real x0 = 0, y0 = 0, x = 0, y = 0, dx = 1, dy = 0;
1208   enum {line , circle, none} move;
1209   Standard_Boolean close = Standard_True;
1210   Standard_Boolean first = Standard_True;
1211   Standard_Boolean stayfirst = Standard_False;
1212   char*  name = new char[100];
1213
1214   while (i < n) {
1215
1216     Standard_Real length=0,radius=0,angle=0;
1217     move = none;
1218
1219     switch (a[i][0]) {
1220
1221     case 'F':
1222     case 'f':
1223       i += 2;
1224       if (i >= n) goto badargs;
1225       if (!first) {
1226         di << "profile: The F instruction must precede all moves";
1227         return 1;
1228       }
1229       x0 = x = atof(a[i-1]);
1230       y0 = y = atof(a[i]);
1231       stayfirst = Standard_True;
1232       break;
1233
1234     case 'X':
1235     case 'x':
1236       i++;
1237       if (i >= n) goto badargs;
1238       length = atof(a[i]);
1239       if ((a[i-1][1] == 'X') || (a[i-1][1] == 'x')) {
1240         length -= x;
1241       }
1242       dx = 1; dy = 0;
1243       move = line;
1244       break;
1245       
1246     case 'Y':
1247     case 'y':
1248       i++;
1249       if (i >= n) goto badargs;
1250       length = atof(a[i]);
1251       if ((a[i-1][1] == 'Y') || (a[i-1][1] == 'y')) {
1252         length -= y;
1253       }
1254       dx = 0; dy = 1;
1255       move = line;
1256       break;
1257       
1258     case 'L':
1259     case 'l':
1260       i++;
1261       if (i >= n) goto badargs;
1262       length = atof(a[i]);
1263       move = line;
1264       break;
1265
1266     case 'T':
1267     case 't':
1268       i += 2;
1269       if (i >= n) goto badargs;
1270       {
1271         Standard_Real vx = atof(a[i-1]);
1272         Standard_Real vy = atof(a[i]);
1273         if ((a[i-2][1] == 'T') || (a[i-2][1] == 't')) {
1274           vx -= x;
1275           vy -= y;
1276         }
1277         length = Sqrt(vx*vx+vy*vy);
1278         if (length > Precision::Confusion()) {
1279           move = line;
1280           dx = vx / length;
1281           dy = vy / length;
1282         }
1283       }
1284       break;
1285
1286     case 'R':
1287     case 'r':
1288       i++;
1289       if (i >= n) goto badargs;
1290       angle = atof(a[i]) * (M_PI / 180.0);
1291       if ((a[i-1][1] == 'R') || (a[i-1][1] == 'r')) {
1292         dx = Cos(angle);
1293         dy = Sin(angle);
1294       }
1295       else {
1296         Standard_Real c = Cos(angle);
1297         Standard_Real s = Sin(angle);
1298         Standard_Real t = c * dx - s * dy;
1299         dy = s * dx + c * dy;
1300         dx = t;
1301       }
1302       break;
1303
1304     case 'D':
1305     case 'd':
1306       i += 2;
1307       if (i >= n) goto badargs;
1308       {
1309         Standard_Real vx = atof(a[i-1]);
1310         Standard_Real vy = atof(a[i]);
1311         length = Sqrt(vx*vx+vy*vy);
1312         if (length > Precision::Confusion()) {
1313           // move = line; DUB
1314           dx = vx / length;
1315           dy = vy / length;
1316         }
1317       }
1318       break;
1319
1320     case 'C':
1321     case 'c':
1322       i += 2;
1323       if (i >= n) goto badargs;
1324       radius = atof(a[i-1]);
1325       if (Abs(radius) > Precision::Confusion()) {
1326         angle = atof(a[i]) * (M_PI / 180.0);
1327         move = circle;
1328       }
1329       break;
1330
1331     case 'I':
1332     case 'i':
1333       i++;
1334       if (i >= n) goto badargs;
1335       length = atof(a[i]);
1336       if ((a[i-1][1] == 'X') || (a[i-1][1] == 'x')) {
1337         if (Abs(dx) < Precision::Confusion()) {
1338           di << "Profile : cannot intersect, arg " << i-1;
1339           return 1;
1340         }
1341         length = (length - x) / dx;
1342         move = line;
1343       }
1344       else if ((a[i-1][1] == 'Y') || (a[i-1][1] == 'y')) {
1345         if (Abs(dy) < Precision::Confusion()) {
1346           di << "Profile : cannot intersect, arg " << i-1;
1347           return 1;
1348         }
1349         length = (length - y) / dy;
1350         move = line;
1351       }
1352      
1353       break;
1354
1355     case 'W':
1356     case 'w':
1357       close = Standard_False;
1358       i = n-1;
1359       break;
1360       
1361     default:
1362       di <<"profile : unknown code " << a[i];
1363       return 1;
1364     }
1365
1366   again:
1367     
1368     switch (move) {
1369       
1370     case line :
1371       {
1372         if (length < 0) {
1373           length = -length;
1374           dx = -dx;
1375           dy = -dy;
1376         }
1377         Handle(Geom2d_Line) l = new Geom2d_Line(gp_Pnt2d(x,y),gp_Dir2d(dx,dy));
1378         Handle(Geom2d_TrimmedCurve) ct = 
1379           new Geom2d_TrimmedCurve(l,0,length);
1380         NbCurves++;
1381         sprintf(name,"%s_%d",a[1],NbCurves);
1382         DrawTrSurf::Set(name,ct);
1383         di.AppendElement(name);
1384         x += length*dx;
1385         y += length*dy;
1386       }
1387       break;
1388
1389     case circle :
1390       {
1391         Standard_Boolean sense = Standard_True;
1392         if (radius < 0) {
1393           radius = -radius;
1394           sense = !sense;
1395           dx = -dx;
1396           dy = -dy;
1397         }
1398         gp_Ax2d ax(gp_Pnt2d(x-radius*dy,y+radius*dx),gp_Dir2d(dy,-dx));
1399         if (angle < 0) {
1400           angle = -angle;
1401           sense = !sense;
1402         }
1403         Handle(Geom2d_Circle) c = new Geom2d_Circle(ax,radius,sense);
1404         Handle(Geom2d_TrimmedCurve) ct = 
1405           new Geom2d_TrimmedCurve(c,0,angle);
1406         NbCurves++;
1407         sprintf(name,"%s_%d",a[1],NbCurves);
1408         DrawTrSurf::Set(name,ct);       
1409         di.AppendElement(name);
1410         gp_Pnt2d p;
1411         gp_Vec2d v;
1412         c->D1(angle,p,v);
1413         x = p.X();
1414         y = p.Y();
1415         dx = v.X() / radius;
1416         dy = v.Y() / radius;
1417       }
1418       break;
1419
1420     case none:
1421       break;
1422     }
1423
1424     // update first
1425     first = stayfirst;
1426     stayfirst = Standard_False;
1427
1428     // next segment....
1429     i++;
1430     if ((i == n) && close) {
1431       // the closing segment
1432       dx = x0-x;
1433       dy = y0-y;
1434       length = Sqrt(dx*dx+dy*dy);
1435       if (length > Precision::Confusion()) {
1436         move = line;
1437         dx = dx / length;
1438         dy = dy / length;
1439         goto again;
1440       }
1441     }
1442   }
1443   const char* aName;
1444   aName = "CurX";
1445   Draw::Set(aName, x);
1446   aName = "CurY";
1447   Draw::Set(aName, y);
1448   aName = "CurDX";
1449   Draw::Set(aName, dx);
1450   aName = "CurDY";
1451   Draw::Set(aName, dy);
1452
1453   return 0;
1454
1455  badargs:
1456   di << "profile : bad number of arguments";
1457   return 1;
1458 }
1459
1460
1461
1462 //=======================================================================
1463 //function : mkoffset
1464 //purpose  : 
1465 //=======================================================================
1466
1467 Standard_Integer mkoffset(Draw_Interpretor& di, 
1468                           Standard_Integer n, const char** a)
1469 {
1470   if (n < 5) return 1;
1471   char name[100];
1472
1473   BRepOffsetAPI_MakeOffset Paral;  
1474   TopoDS_Shape Base = DBRep::Get(a[2],TopAbs_FACE);
1475
1476   if ( Base.IsNull()) {
1477     Base = DBRep::Get(a[2]);
1478     if (Base.IsNull()) return 1;
1479     Paral.Init(GeomAbs_Arc);
1480     TopExp_Explorer exp;
1481     for (exp.Init(Base,TopAbs_WIRE); exp.More(); exp.Next()) {
1482       TopoDS_Wire aLocalShape = TopoDS::Wire(exp.Current());
1483       Paral.AddWire(aLocalShape);
1484 //      Paral.AddWire(TopoDS::Wire(exp.Current()));
1485     }
1486   }
1487   else {
1488     Base.Orientation(TopAbs_FORWARD);
1489 //    Base = TopoDS::Face(Base.Oriented(TopAbs_FORWARD));
1490     Paral.Init(TopoDS::Face(Base));
1491   }
1492
1493   Standard_Real U, dU;
1494   Standard_Integer Nb;
1495   dU = atof(a[4]);
1496   Nb = atoi(a[3]);
1497
1498   Standard_Real Alt = 0.;
1499   if ( n == 6) Alt = atof(a[5]);
1500   Standard_Integer Compt = 1;
1501
1502   for ( Standard_Integer i = 1; i <= Nb; i++) {
1503     U = i * dU;
1504     Paral.Perform(U,Alt);
1505     if ( !Paral.IsDone()) {
1506       //cout << " Parali aux fraises" << endl;
1507       di << " Parali aux fraises" << "\n";
1508     }
1509     else {
1510       sprintf(name,"%s_%d", a[1], Compt++);
1511       char* temp = name; // portage WNT
1512       DBRep::Set(temp,Paral.Shape());
1513     }
1514   }
1515   return 0;
1516 }
1517
1518 //=======================================================================
1519 //function : pickface
1520 //purpose  : 
1521 //=======================================================================
1522
1523 Standard_Integer pickface(Draw_Interpretor& di, 
1524                           Standard_Integer , const char** )
1525 {
1526   Standard_CString pick_name=".";
1527   
1528   TopoDS_Shape S = DBRep::Get(pick_name,TopAbs_FACE);
1529   if (S.IsNull()) return 1;
1530   
1531   char* name = new char[100];
1532   sprintf(name,"PickedFace %s",pick_name);
1533   DBRep::Set(name,S);
1534   di.AppendElement(name);
1535   return 0;
1536 }
1537
1538
1539 Standard_Integer edgeintersector(Draw_Interpretor& di,
1540                                  Standard_Integer n, const char** a)
1541 {
1542   if (n < 5) return 1;
1543
1544   TopoDS_Edge E[2];
1545   TopoDS_Shape aLocalShape(DBRep::Get(a[2],TopAbs_EDGE));
1546   E[0] = TopoDS::Edge(aLocalShape);
1547 //  E[0] = TopoDS::Edge(DBRep::Get(a[2],TopAbs_EDGE));
1548   if ( E[0].IsNull()) return 1;
1549   aLocalShape = DBRep::Get(a[3],TopAbs_EDGE);
1550   E[1] = TopoDS::Edge(aLocalShape);
1551 //  E[1] = TopoDS::Edge(DBRep::Get(a[3],TopAbs_EDGE));
1552   if ( E[1].IsNull()) return 1;
1553   aLocalShape = DBRep::Get(a[4],TopAbs_FACE);
1554   TopoDS_Face F  = TopoDS::Face(aLocalShape);
1555 //  TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[4],TopAbs_FACE));
1556   if ( F.IsNull()) return 1;
1557   
1558   TopOpeBRep_EdgesIntersector EInter;
1559   char name[100];
1560   //------------------------------------------------------
1561   // Calculate point of intersection 2D
1562   //-----------------------------------------------------
1563   EInter.SetFaces(F,F);
1564   Standard_Real TolInter = 1.e-7;
1565   if (n == 6) TolInter = atof(a[5]);
1566   EInter.ForceTolerances(TolInter,TolInter);
1567   Standard_Boolean reducesegments = Standard_True;
1568   EInter.Perform (E[0],E[1],reducesegments);
1569   
1570   if (EInter.IsEmpty()) {
1571     //cout << " No intersection found" << endl;
1572     di << " No intersection found" << "\n";
1573     return 0;
1574   }
1575
1576   BRep_Builder B;
1577
1578   Standard_Integer NbV = 0;
1579   Standard_Real Tol = Precision::PConfusion();
1580
1581   Standard_Boolean rejectreducedsegmentpoints = Standard_True;
1582   EInter.InitPoint(rejectreducedsegmentpoints);
1583   for (;EInter.MorePoint();EInter.NextPoint()) {
1584     const TopOpeBRep_Point2d& P2D = EInter.Point();
1585     gp_Pnt           P    = P2D.Value();
1586     TopoDS_Vertex    V    = BRepLib_MakeVertex(P);
1587     NbV ++;
1588     sprintf(name,"%s_%d",a[1],NbV);
1589     DBRep::Set(name,V);
1590     for (Standard_Integer i = 1; i <= 2; i++) {
1591       //---------------------------------------------------------------
1592       // to be able to rank parameter on edge
1593       // it is necessary to code it internally
1594       //---------------------------------------------------------------
1595       Standard_Real U = P2D.Parameter(i);
1596       
1597       V.Orientation(TopAbs_INTERNAL);
1598       B.UpdateVertex(V,U,E[i-1],Tol);
1599 //      B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
1600 //                   U,E[i-1],Tol);
1601       //---------------------------------------------------------------
1602       // Orientation of vertex in the transition.
1603       //---------------------------------------------------------------
1604       TopAbs_Orientation OO = TopAbs_REVERSED;
1605       if (P2D.IsVertex(i)) {
1606         OO = P2D.Vertex(i).Orientation();
1607       }
1608       else if (P2D.Transition(i).Before() == TopAbs_OUT) {
1609         OO = TopAbs_FORWARD;
1610       }
1611       //cout << " Orientation of vertex " << NbV << " on " << a[i+1] << ": ";
1612       di << " Orientation of vertex " << NbV << " on " << a[i+1] << ": ";
1613       if (OO == TopAbs_FORWARD) {
1614         //cout << "FORWARD" << endl;
1615         di << "FORWARD" << "\n";
1616       } else {
1617         //cout << "REVERSED" << endl;
1618         di << "REVERSED" << "\n";
1619       }
1620     }
1621   }
1622   //POP pour NT
1623   return 0;
1624
1625 }
1626 //=======================================================================
1627 //function : concatwire
1628 //purpose  : reduce the multiply degree of the knots to the minimum without
1629 //           changing the geometry
1630 //=======================================================================
1631
1632 static Standard_Integer concatwire(Draw_Interpretor&, Standard_Integer n, const char** c)
1633 { GeomAbs_Shape Option=GeomAbs_C1;
1634
1635   if ( n < 3 ) return 1;                               
1636   
1637   if(n==4)                                              //check if it's C1 or G1
1638     if (! strcmp(c[3],"G1"))
1639       Option=GeomAbs_G1;
1640   
1641   TopoDS_Shape S = DBRep::Get(c[2],TopAbs_WIRE) ;
1642
1643   if (S.IsNull()) return 1 ;                            //test if the shape is empty
1644   
1645   TopoDS_Wire W = TopoDS::Wire(S) ;
1646   TopoDS_Wire res;
1647
1648
1649   res=BRepAlgo::ConcatenateWire(W,Option);              //processing
1650   DBRep::Set(c[1],res);
1651   return 0;
1652 }
1653
1654 //=======================================================================
1655 //function : build3d
1656 //purpose  : 
1657 //=======================================================================
1658
1659 Standard_Integer  build3d(Draw_Interpretor& di, 
1660                           Standard_Integer n, const char** a)
1661 {
1662
1663   if ( (n <2) || (n>3) ) {
1664     //cout << " 1 or 2 arguments expected" << endl;
1665     di << " 1 or 2 arguments expected" << "\n";
1666     return 1;
1667   }
1668     
1669   Standard_Boolean Ok;
1670   TopoDS_Shape S = DBRep::Get(a[1],TopAbs_FACE);
1671   if (S.IsNull()) return 1;
1672   
1673   if (n==2) { Ok = BRepLib::BuildCurves3d(S); }
1674   else      { Ok = BRepLib::BuildCurves3d(S,atof(a[2])); }
1675   //if (!Ok) {cout << " one of the computation failed" << endl;}
1676   if (!Ok) {di << " one of the computation failed" << "\n";}
1677
1678   return 0;
1679 }
1680
1681 //=======================================================================
1682 //function : reducepcurves
1683 //purpose  : remove pcurves that are unused in this shape
1684 //=======================================================================
1685
1686 Standard_Integer reducepcurves(Draw_Interpretor& di, 
1687                                Standard_Integer n, const char** a)
1688 {
1689   if (n < 2) return 1;
1690
1691   Standard_Integer i;
1692   for (i = 1; i < n; i++)
1693   {
1694     TopoDS_Shape aShape = DBRep::Get(a[i]);
1695     if (aShape.IsNull())
1696       //cout << a[i] << " is not a valid shape" << endl;
1697       di << a[i] << " is not a valid shape" << "\n";
1698     else
1699       BRepTools::RemoveUnusedPCurves(aShape);
1700   }
1701   
1702   return 0;
1703 }
1704
1705 //=======================================================================
1706 //function : CurveCommands
1707 //purpose  : 
1708 //=======================================================================
1709
1710 void  BRepTest::CurveCommands(Draw_Interpretor& theCommands)
1711 {
1712   static Standard_Boolean done = Standard_False;
1713   if (done) return;
1714   done = Standard_True;
1715
1716   DBRep::BasicCommands(theCommands);
1717   GeometryTest::CurveCommands(theCommands);
1718
1719   const char* g = "TOPOLOGY Curve topology commands";
1720
1721   theCommands.Add("vertex",
1722                   "vertex name [x y z / p edge]",__FILE__,
1723                   vertex,g);
1724
1725   theCommands.Add("etrim",
1726                   "etrim edge v1 [v2]",__FILE__,
1727                   trim,g);
1728
1729   theCommands.Add("range",
1730                   "range edge [face] first last",__FILE__,
1731                   range,g);
1732
1733   theCommands.Add("polyline",
1734                   "polyline name x1 y1 z1 x2 y2 z2 ...",__FILE__,
1735                   polyline,g);
1736
1737   theCommands.Add("polyvertex",
1738                   "polyvertex name v1 v2 ...",__FILE__,
1739                   polyvertex,g);
1740
1741   theCommands.Add("wire",
1742                   "wire wirename e1/w1 [e2/w2 ...]",__FILE__,
1743                   wire,g);
1744
1745   theCommands.Add("profile",
1746                   "profile, no args to get help",__FILE__,
1747                   profile,g);
1748
1749   theCommands.Add("bsplineprof",
1750                   "bsplineprof, no args to get help",__FILE__,
1751                   bsplineprof,g);
1752
1753   theCommands.Add("2dprofile",
1754                   "2dprofile, no args to get help",__FILE__,
1755                   profile2d,g);
1756
1757   theCommands.Add("mkoffset",
1758                   "mkoffset result face/compound of wires  nboffset stepoffset [alt]",__FILE__,
1759                   mkoffset);
1760
1761
1762   theCommands.Add("mkedge",
1763                   "mkedge edge curve [surface] [pfirst plast] [vfirst [pfirst] vlast [plast]] ",__FILE__,
1764                   mkedge,g);
1765   
1766   theCommands.Add("mkcurve",
1767                   "mkcurve curve edge",__FILE__,
1768                   mkcurve,g);
1769
1770   theCommands.Add("mkoricurve",
1771                   "mkoricurve curve edge: \n  the curve is colored according to the orientation of the edge",
1772                   __FILE__,
1773                   mkcurve,g);
1774
1775   theCommands.Add("mk2dcurve",
1776                   "mk2dcurve curve edge [face]",__FILE__,
1777                   mk2dcurve,g);
1778
1779   theCommands.Add("mkpoint",
1780                   "mkpoint point vertex",__FILE__,
1781                   mkpoint,g);
1782
1783   theCommands.Add("uisoedge",
1784                   "uisoedge edge face u v1 v2",__FILE__,
1785                   isoedge,g);
1786   
1787   theCommands.Add("edge",
1788                   "edge edgename v1 v2",__FILE__,
1789                   edge,g);
1790   
1791   theCommands.Add("visoedge",
1792                   "visoedge edge face v u1 u2",__FILE__,
1793                   isoedge,g);
1794
1795   theCommands.Add("transfert",
1796                   "transfert edge1 edge2",__FILE__,
1797                   transfert,g);
1798
1799   theCommands.Add("pickface",
1800                   "pickface",__FILE__,
1801                   pickface,g);
1802
1803   theCommands.Add("edgeintersector",
1804                   "edgeintersector r E1 E2 F [Tol]",__FILE__,
1805                   edgeintersector,g);
1806
1807   theCommands.Add("build3d",
1808                   "build3d S [tol]",
1809                   build3d, g);
1810
1811   theCommands.Add("reducepcurves",
1812                   "reducepcurves shape1 shape2 ...",
1813                   reducepcurves, g);
1814
1815   theCommands.Add("concatwire",
1816                   "concatwire result wire [option](G1/C1)",
1817                   __FILE__,
1818                   concatwire,
1819                   g);
1820 }
1821
1822