26964eda81a26de21c74fa4a2cb41d1186321ad6
[occt.git] / src / BRepTest / BRepTest_FeatureCommands.cxx
1 // File:        BRepTest_FeatureCommands.cxx
2 // Created:     Fri Jun 16 14:28:00 1995
3 // Author:      Jacques GOUSSARD
4 //              <jag@bravox>
5
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9
10 #include <Draw_Interpretor.hxx>
11 #include <Draw_Appli.hxx>
12 #include <DrawTrSurf.hxx>
13
14 #include <TopTools_ListOfShape.hxx>
15 #include <TopTools_ListIteratorOfListOfShape.hxx>
16 #include <TopTools_MapOfShape.hxx>
17 #include <TopTools_MapIteratorOfMapOfShape.hxx>
18 #include <TopExp_Explorer.hxx>
19 #include <TopoDS_Face.hxx>
20 #include <TopoDS_Wire.hxx>
21 #include <TopoDS_Shell.hxx>
22 #include <TopoDS_Compound.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS.hxx>
25
26 #include <Geom_RectangularTrimmedSurface.hxx>
27 #include <Geom_Plane.hxx>
28 #include <Geom_CylindricalSurface.hxx>
29 #include <gp_Lin.hxx>
30 #include <gp_Pln.hxx>
31 #include <gp_Cylinder.hxx>
32
33 #include <BRepFeat_LocalOperation.hxx>
34 #include <BRepFeat_MakeCylindricalHole.hxx>
35 #include <BRepFeat_SplitShape.hxx>
36 #include <BRepFeat_Gluer.hxx>
37
38 #include <BRepFeat.hxx>
39 #include <BRepFeat_MakePrism.hxx>
40 #include <BRepFeat_MakeRevol.hxx>
41 #include <BRepFeat_MakePipe.hxx>
42 #include <BRepFeat_MakeDPrism.hxx>
43 #include <BRepFeat_MakeLinearForm.hxx>
44 #include <BRepFeat_MakeRevolutionForm.hxx>
45
46 #include <LocOpe_FindEdges.hxx>
47 #include <LocOpe_FindEdgesInFace.hxx>
48
49 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
50 #include <BRepOffsetAPI_MakeThickSolid.hxx>
51 #include <BRep_Tool.hxx>
52 #include <BRep_Builder.hxx>
53 #include <DBRep.hxx>
54 #include <DBRep_DrawableShape.hxx>
55 #include <BRepTest.hxx>
56
57 #include <BRepFilletAPI_MakeFillet.hxx>
58 #include <ChFi3d_FilletShape.hxx>
59
60 #include <Precision.hxx>
61
62 #ifdef WNT
63 //#define strcasecmp _stricmp Already defined
64 Standard_IMPORT Draw_Viewer dout;
65 #endif
66 #ifdef HAVE_STRINGS_H
67 # include <strings.h>
68 #endif
69
70 static BRepFeat_MakeCylindricalHole theHole;
71 static Standard_Boolean WithControl = Standard_True;
72
73 Standard_Boolean DownCastingEnforcing = Standard_False;
74
75 static BRepFeat_MakePrism thePrism;
76 static BRepFeat_MakeDPrism theDPrism;
77 static BRepFeat_MakeRevol theRevol;
78 static BRepFeat_MakePipe  thePipe;
79 static BRepFeat_MakeLinearForm  theLF;
80 static BRepFeat_MakeRevolutionForm  theRF;
81
82 static Standard_Boolean dprdef = Standard_False;
83 static Standard_Boolean prdef = Standard_False;
84 static Standard_Boolean rvdef = Standard_False;
85 static Standard_Boolean pidef = Standard_False;
86 static Standard_Boolean lfdef = Standard_False;
87 static Standard_Boolean rfdef = Standard_False;
88
89 static Standard_Real t3d = 1.e-4;
90 static Standard_Real t2d = 1.e-5;
91 static Standard_Real ta  = 1.e-2;
92 static Standard_Real fl  = 1.e-3;
93 static Standard_Real tapp_angle = 1.e-2;
94 static GeomAbs_Shape blend_cont = GeomAbs_C1;
95 static BRepFilletAPI_MakeFillet* Rakk = 0;
96
97
98
99 static void Print(Draw_Interpretor& di,
100                   const BRepFeat_Status St)
101 {
102   di << "  Error Status : ";
103   switch (St) {
104   case BRepFeat_NoError:
105     di << "No error";
106     break;
107
108   case BRepFeat_InvalidPlacement:
109     di << "Invalid placement";
110     break;
111
112   case BRepFeat_HoleTooLong:
113     di << "Hole too long";
114     break;
115   }
116 }
117
118 static Standard_Integer Loc(Draw_Interpretor& theCommands,
119                             Standard_Integer narg, const char** a)
120 {
121   if (narg<6) return 1;
122   TopoDS_Shape S = DBRep::Get(a[2]);
123   TopoDS_Shape T = DBRep::Get(a[3]);
124
125   Standard_Boolean Fuse;
126   if (!strcasecmp("F",a[4])) {
127     Fuse = Standard_True;
128   }
129   else if (!strcasecmp("C",a[4])) {
130     Fuse = Standard_False;
131   }
132   else {
133     return 1;
134   }
135
136   TopTools_ListOfShape LF;
137   for (Standard_Integer i=0; i<= narg-6; i++) {
138     TopoDS_Shape aLocalShape(DBRep::Get(a[i+5],TopAbs_FACE));
139     LF.Append(aLocalShape);
140 //    LF.Append(TopoDS::Face(DBRep::Get(a[i+5],TopAbs_FACE)));
141   }
142
143   BRepFeat_LocalOperation BLoc(S);
144   BLoc.Perform(T,LF,Fuse);
145   BLoc.BuildPartsOfTool();
146
147 #if 0
148   char newname[1024];
149   strcpy(newname,a[1]);
150   char* p = newname;
151   while (*p != '\0') p++;
152   *p = '_';
153   p++;
154   TopTools_ListIteratorOfListOfShape its(BLoc.PartsOfTool());
155   dout.Clear();
156   i = 0;
157   for (; its.More(); its.Next()) {
158     i++;
159     sprintf(p,"%d",i);
160     DBRep::Set(newname,its.Value());
161   }
162   if (i >= 2) {
163     dout.Flush();
164     Standard_Integer qq,ww,ee,button;
165     TopoDS_Shell S;
166     do {
167       TopoDS_Shape aLocalShape(DBRep::Get(".",TopAbs_SHELL));
168       S = TopoDS::Shell(aLocalShape);
169 //      S = TopoDS::Shell(DBRep::Get(".",TopAbs_SHELL));
170       Draw::LastPick(qq,ww,ee,button);
171       if (!S.IsNull()) {
172
173         switch (button) {
174         case 1:
175           BLoc.RemovePart(S);
176           break;
177         case 2:
178           BLoc.ActivatePart(S);
179           break;
180         default:
181           {}
182         }
183       }
184       else {
185         button = 3;
186       }
187
188     } while (button != 3);
189   }
190 #endif
191   BLoc.Build();
192   if (BLoc.IsDone()) {
193 //    dout.Clear();
194     DBRep::Set(a[1],BLoc);
195     dout.Flush();
196     return 0;
197   }
198   theCommands << "Local operation not done" ;
199   return 1;
200 }
201
202
203
204 static Standard_Integer HOLE1(Draw_Interpretor& theCommands,
205                               Standard_Integer narg, const char** a)
206 {
207   if (narg<10 || narg == 11) return 1;
208   TopoDS_Shape S = DBRep::Get(a[2]);
209
210   gp_Pnt Or(atof(a[3]),atof(a[4]),atof(a[5]));
211   gp_Dir Di(atof(a[6]),atof(a[7]),atof(a[8]));
212
213   Standard_Real Radius = atof(a[9]);
214
215   theHole.Init(S,gp_Ax1(Or,Di));
216
217   if (narg <= 10) {
218     theHole.Perform(Radius);
219   }
220   else {
221     Standard_Real pfrom = atof(a[10]);
222     Standard_Real pto   = atof(a[11]);
223     theHole.Perform(Radius,pfrom,pto,WithControl);
224   }
225
226   theHole.Build();
227   if (theHole.IsDone()) {
228 //    dout.Clear();
229     DBRep::Set(a[1],theHole);
230     dout.Flush();
231     return 0;
232   }
233   theCommands << "Echec de MakeCylindricalHole";
234   Print(theCommands,theHole.Status());
235   return 1;
236 }
237
238 static Standard_Integer HOLE2(Draw_Interpretor& theCommands,
239                               Standard_Integer narg, const char** a)
240 {
241   if (narg<10) return 1;
242   TopoDS_Shape S = DBRep::Get(a[2]);
243
244   gp_Pnt Or(atof(a[3]),atof(a[4]),atof(a[5]));
245   gp_Dir Di(atof(a[6]),atof(a[7]),atof(a[8]));
246
247   Standard_Real Radius = atof(a[9]);
248
249   theHole.Init(S,gp_Ax1(Or,Di));
250   theHole.PerformThruNext(Radius,WithControl);
251
252   theHole.Build();
253   if (theHole.IsDone()) {
254 //    dout.Clear();
255     DBRep::Set(a[1],theHole);
256     dout.Flush();
257     return 0;
258   }
259   theCommands << "Echec de MakeCylindricalHole";
260   Print(theCommands,theHole.Status());
261   return 1;
262 }
263
264 static Standard_Integer HOLE3(Draw_Interpretor& theCommands,
265                               Standard_Integer narg, const char** a)
266 {
267   if (narg<10) return 1;
268   TopoDS_Shape S = DBRep::Get(a[2]);
269
270   gp_Pnt Or(atof(a[3]),atof(a[4]),atof(a[5]));
271   gp_Dir Di(atof(a[6]),atof(a[7]),atof(a[8]));
272
273   Standard_Real Radius = atof(a[9]);
274
275   theHole.Init(S,gp_Ax1(Or,Di));
276   theHole.PerformUntilEnd(Radius,WithControl);
277   theHole.Build();
278   if (theHole.IsDone()) {
279 //    dout.Clear();
280     DBRep::Set(a[1],theHole);
281     dout.Flush();
282     return 0;
283   }
284   theCommands << "Echec de MakeCylindricalHole";
285   Print(theCommands,theHole.Status());
286   return 1;
287 }
288
289
290 static Standard_Integer HOLE4(Draw_Interpretor& theCommands,
291                               Standard_Integer narg, const char** a)
292 {
293   if (narg<11) return 1;
294   TopoDS_Shape S = DBRep::Get(a[2]);
295
296   gp_Pnt Or(atof(a[3]),atof(a[4]),atof(a[5]));
297   gp_Dir Di(atof(a[6]),atof(a[7]),atof(a[8]));
298
299   Standard_Real Radius = atof(a[9]);
300   Standard_Real Length = atof(a[10]);
301
302   theHole.Init(S,gp_Ax1(Or,Di));
303   theHole.PerformBlind(Radius,Length,WithControl);
304   theHole.Build();
305   if (theHole.IsDone()) {
306 //    dout.Clear();
307     DBRep::Set(a[1],theHole);
308     dout.Flush();
309     return 0;
310   }
311   theCommands << "Echec de MakeCylindricalHole";
312   Print(theCommands,theHole.Status());
313   return 1;
314 }
315
316 static Standard_Integer CONTROL(Draw_Interpretor& theCommands,
317                                 Standard_Integer narg, const char** a)
318 {
319   if (narg >= 2) {
320     WithControl = strcmp("0",a[1]);
321   }
322   if (WithControl) {
323     theCommands << "Mode avec controle";
324   }
325   else {
326     theCommands << "Mode sans controle";
327   }
328   return 0;
329 }
330       
331
332 //=======================================================================
333 //function : PRW
334 //purpose  : 
335 //=======================================================================
336
337 static Standard_Integer PRW(Draw_Interpretor& theCommands,
338                             Standard_Integer narg, const char** a)
339 {
340   if (narg<9) return 1;
341   TopoDS_Shape S = DBRep::Get(a[3]);
342   BRepFeat_MakePrism thePFace;
343   gp_Vec V;
344   TopoDS_Shape FFrom,FUntil;
345   Standard_Integer borne;
346   Standard_Boolean fuse;
347   if (a[1][0] == 'f' || a[1][0] == 'F') {
348     fuse = Standard_True;
349   }
350   else if (a[1][0] == 'c' || a[1][0] == 'C') {
351     fuse = Standard_False;
352   }
353   else {
354     return 1;
355   }
356
357   if (a[4][0] == '.' || IsAlphabetic(a[4][0])) {
358     if (narg < 10) {
359       return 1;
360     }
361     if (a[5][0] == '.' || IsAlphabetic(a[5][0])) {
362       if (narg < 11) {
363         return 1;
364       }
365       V.SetCoord(atof(a[6]),atof(a[7]),atof(a[8]));
366       FFrom   = DBRep::Get(a[4],TopAbs_SHAPE);
367       FUntil  = DBRep::Get(a[5],TopAbs_SHAPE);
368       borne = 9;
369     }
370     else {
371       V.SetCoord(atof(a[5]),atof(a[6]),atof(a[7]));
372       FUntil  = DBRep::Get(a[4],TopAbs_SHAPE);
373       borne = 8;
374     }
375   }
376   else {
377     V.SetCoord(atof(a[4]),atof(a[5]),atof(a[6]));
378     borne = 7;
379   }
380   Standard_Real Length = V.Magnitude();
381   if (Length < Precision::Confusion()) {
382     return 1;
383   }
384
385   TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
386   TopoDS_Face F  = TopoDS::Face(aLocalShape);
387 //  TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
388   BRepFeat_SplitShape Spls(F);
389   for (Standard_Integer i = borne+1; i<narg; i++) {
390     TopoDS_Wire wir;
391     if (a[i][0] !='-') {
392       aLocalShape = DBRep::Get(a[i],TopAbs_WIRE);
393       wir = TopoDS::Wire(aLocalShape);
394 //      wir = TopoDS::Wire(DBRep::Get(a[i],TopAbs_WIRE));
395     }
396     else {
397       if (a[i][1] == '\0')
398         return 1;
399       const char* Temp = a[i]+1;
400       aLocalShape = DBRep::Get(Temp,TopAbs_WIRE);
401       wir = TopoDS::Wire(aLocalShape);
402 //      wir = TopoDS::Wire(DBRep::Get(Temp,TopAbs_WIRE));
403       wir.Reverse();
404     }
405     Spls.Add(wir,F);
406   }
407   Spls.Build();
408
409   TopoDS_Shape ToPrism;
410   const TopTools_ListOfShape& lleft = Spls.DirectLeft();
411   if (lleft.Extent() == 1) {
412     thePFace.Init(S,lleft.First(),F,V,fuse,Standard_True);
413     ToPrism = lleft.First();
414   }
415   else {
416     BRep_Builder B;
417     TopoDS_Shell Sh;
418     B.MakeShell(Sh);
419     TopTools_ListIteratorOfListOfShape it;
420     for (it.Initialize(lleft);it.More();it.Next()) {
421       B.Add(Sh,TopoDS::Face(it.Value()));
422     }
423     thePFace.Init(S,Sh,F,V,fuse,Standard_True);
424     ToPrism = Sh;
425   }
426
427   // Recherche des faces de glissement, si on n`a pas sketche sur une face
428   // du shape de depart
429
430 //  for (TopExp_Explorer exp(S,TopAbs_FACE);exp.More();exp.Next()) {
431   TopExp_Explorer exp(S,TopAbs_FACE) ;
432   for ( ;exp.More();exp.Next()) {
433     if (exp.Current().IsSame(F)) {
434       break;
435     }
436   }
437
438   if (!exp.More()) {
439     LocOpe_FindEdgesInFace FEIF;
440     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
441       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
442       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
443       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
444         Su = Handle(Geom_RectangularTrimmedSurface)::
445         DownCast(Su)->BasisSurface();
446       }
447       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
448         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
449         if (pl.Contains(gp_Lin(pl.Location(),V),
450                         Precision::Confusion(),
451                         Precision::Angular())) {
452           FEIF.Set(ToPrism,fac);
453           for (FEIF.Init();FEIF.More();FEIF.Next()) {
454             thePFace.Add(FEIF.Edge(),fac);
455           }
456         }
457       }
458       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
459         gp_Cylinder cy = 
460           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
461         if (V.IsParallel(cy.Axis().Direction(),Precision::Angular())) {
462           FEIF.Set(ToPrism,fac);
463           for (FEIF.Init();FEIF.More();FEIF.Next()) {
464             thePFace.Add(FEIF.Edge(),fac);
465           }
466         }
467       }
468     }
469   }
470
471   if (borne == 7) {
472     thePFace.Perform(Length);
473   }
474   else if (borne == 8) {
475     thePFace.Perform(FUntil);
476   }
477   else if (borne == 9) {
478     if (!(FFrom.IsNull() || FUntil.IsNull())) {
479       thePFace.Perform(FFrom,FUntil);
480     }
481     else if (FFrom.IsNull()) {
482       if (!FUntil.IsNull()) {
483         thePFace.PerformFromEnd(FUntil);
484       }
485       else {
486         thePFace.PerformThruAll();
487       }
488     }
489     else {
490       // il faudrait inverser V et appeler PerfomFromEnd...
491       //cout << "Not Implemented" << endl;
492       theCommands << "Not Implemented" << "\n";
493     }
494   }
495   if (!thePFace.IsDone()) {
496     theCommands << "Local operation not done";
497     return 1;
498   }
499
500   DBRep::Set(a[2],thePFace);
501   dout.Flush();
502   return 0;
503 }
504
505
506 //=======================================================================
507 //function : PRF
508 //purpose  : 
509 //=======================================================================
510
511 static Standard_Integer PRF(Draw_Interpretor& theCommands,
512                             Standard_Integer narg, const char** a)
513 {
514   if (narg<8) return 1;
515   TopoDS_Shape S = DBRep::Get(a[3]);
516   BRepFeat_MakePrism thePFace;
517   Standard_Integer borne;
518   gp_Vec V;
519   TopoDS_Shape FFrom,FUntil;
520   Standard_Boolean fuse;
521   if (a[1][0] == 'f' || a[1][0] == 'F') {
522     fuse = Standard_True;
523   }
524   else if (a[1][0] == 'c' || a[1][0] == 'C') {
525     fuse = Standard_False;
526   }
527   else {
528     return 1;
529   }
530
531
532   if (a[4][0] == '.' || IsAlphabetic(a[4][0])) {
533     if (narg < 9) {
534       return 1;
535     }
536     if (a[5][0] == '.' || IsAlphabetic(a[5][0])) {
537       if (narg < 10) {
538         return 1;
539       }
540       borne = 9;
541       V.SetCoord(atof(a[6]),atof(a[7]),atof(a[8]));
542       FFrom  = DBRep::Get(a[4],TopAbs_SHAPE);
543       FUntil  = DBRep::Get(a[5],TopAbs_SHAPE);
544     }
545     else {
546       borne = 8;
547       V.SetCoord(atof(a[5]),atof(a[6]),atof(a[7]));
548       FUntil  = DBRep::Get(a[4],TopAbs_SHAPE);
549     }
550   }
551   else {
552     borne = 7;
553     V.SetCoord(atof(a[4]),atof(a[5]),atof(a[6]));
554   }
555   Standard_Real Length = V.Magnitude();
556   if (Length < Precision::Confusion()) {
557     return 1;
558   }
559
560   TopoDS_Shape ToPrism;
561   if (narg == borne+1) {
562     TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
563     TopoDS_Face F  = TopoDS::Face(aLocalShape);
564 //    TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
565     thePFace.Init(S,F,F,V,fuse,Standard_True);
566     ToPrism = F;
567   }
568   else {
569     TopoDS_Shell She;
570     BRep_Builder B;
571     B.MakeShell(She);
572     for (Standard_Integer i=borne; i<narg; i++) {
573       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
574       TopoDS_Face F  = TopoDS::Face(aLocalShape);
575 //      TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
576       if (!F.IsNull()) {
577         B.Add(She,F);
578       }
579     }
580     thePFace.Init(S,She,TopoDS_Face(),V,fuse,Standard_False);
581     ToPrism = She;
582   }
583   
584   // Recherche des faces de glissement, on ne prisme pas une face
585   // du shape de depart
586
587 //  for (TopExp_Explorer exp(ToPrism,TopAbs_FACE);exp.More();exp.Next()) {
588   TopExp_Explorer exp(ToPrism,TopAbs_FACE) ;
589   for ( ;exp.More();exp.Next()) {
590 //    for (TopExp_Explorer exp2(S,TopAbs_FACE);exp2.More();exp2.Next()) {
591     TopExp_Explorer exp2(S,TopAbs_FACE) ;
592     for ( ;exp2.More();exp2.Next()) {
593       if (exp2.Current().IsSame(exp.Current())) {
594         break;
595       }
596     }
597     if (exp2.More()) {
598       break;
599     }
600   }
601
602   if (!exp.More()) {
603     LocOpe_FindEdgesInFace FEIF;
604     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
605       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
606       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
607       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
608         Su = Handle(Geom_RectangularTrimmedSurface)::
609         DownCast(Su)->BasisSurface();
610       }
611       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
612         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
613         if (pl.Contains(gp_Lin(pl.Location(),V),
614                         Precision::Confusion(),
615                         Precision::Angular())) {
616           FEIF.Set(ToPrism,fac);
617           for (FEIF.Init();FEIF.More();FEIF.Next()) {
618             thePFace.Add(FEIF.Edge(),fac);
619           }
620         }
621       }
622       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
623         gp_Cylinder cy = 
624           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
625         if (V.IsParallel(cy.Axis().Direction(),Precision::Angular())) {
626           FEIF.Set(ToPrism,fac);
627           for (FEIF.Init();FEIF.More();FEIF.Next()) {
628             thePFace.Add(FEIF.Edge(),fac);
629           }
630         }
631       }
632     }
633   }
634
635   if (borne == 7) {
636     thePFace.Perform(Length);
637   }
638   else if (borne == 8) {
639     thePFace.Perform(FUntil);
640   }
641   else if (borne == 9) {
642     if (!(FFrom.IsNull() || FUntil.IsNull())) {
643       thePFace.Perform(FFrom,FUntil);
644     }
645     else if (FFrom.IsNull()) {
646       if (!FUntil.IsNull()) {
647         thePFace.PerformFromEnd(FUntil);
648       }
649       else {
650         thePFace.PerformThruAll();
651       }
652     }
653     else { //FUntil.IsNull()
654       // il faudrait inverser V et appeler PerfomFromEnd...
655       //cout << "Not Implemented" << endl;
656       theCommands << "Not Implemented" << "\n";
657     }
658   }
659   if (!thePFace.IsDone()) {
660     theCommands << "Local operation not done";
661     return 1;
662   }
663
664   DBRep::Set(a[2],thePFace);
665   dout.Flush();
666   return 0;
667 }
668
669
670
671 //=======================================================================
672 //function : SPLS
673 //purpose  : 
674 //=======================================================================
675
676 static Standard_Integer SPLS(Draw_Interpretor& ,
677                              Standard_Integer narg, const char** a)
678 {
679   Standard_Integer newnarg ;
680
681   if (narg<3) return 1;
682   TopoDS_Shape S = DBRep::Get(a[2]);
683   BRepFeat_SplitShape Spls(S);
684   Standard_Boolean pick = Standard_False;
685   TopoDS_Shape EF;
686   Standard_Real u,v;
687   Standard_Integer i = 3;
688
689   for ( newnarg=3; newnarg<narg; newnarg++) {
690     if (a[newnarg][0] == '@') {
691       break;
692     }
693   }
694
695   if (newnarg == 3 || 
696       (newnarg !=narg && ((narg-newnarg)<=2 || (narg-newnarg)%2 != 1))) {
697     return 1;
698   }
699
700   if (i<newnarg) {
701     pick = (a[i][0] == '.');
702     EF = DBRep::Get(a[i],TopAbs_FACE);
703     if (EF.IsNull()) return 1;
704   }
705   
706   while (i < newnarg) {
707     if (pick) {
708       DBRep_DrawableShape::LastPick(EF,u,v);
709     }
710     if (EF.ShapeType() == TopAbs_FACE) {
711       // face wire/edge ...
712       i++;
713       while (i < newnarg) {
714         TopoDS_Shape W;
715         Standard_Boolean rever = Standard_False;
716         if (a[i][0] == '-') {
717           if (a[i][1] == '\0')
718             return 1;
719           pick = (a[i][1] == '.');
720           const char* Temp = a[i]+1;
721           W = DBRep::Get(Temp,TopAbs_SHAPE,Standard_False);
722           rever = Standard_True;
723         }
724         else {
725           pick = (a[i][0] == '.');
726           W = DBRep::Get(a[i],TopAbs_SHAPE,Standard_False);
727         }
728         if (W.IsNull()) {
729           return 1; // on n`a rien recupere
730         }
731         TopAbs_ShapeEnum wtyp = W.ShapeType();
732         if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && pick) {
733           Standard_Real u,v;
734           DBRep_DrawableShape::LastPick(W,u,v);
735           wtyp = W.ShapeType();
736         }
737         if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE) {
738           EF = DBRep::Get(a[i]);
739           break;
740         }
741         else {
742           if (rever) {
743             W.Reverse();
744           }
745           if (wtyp == TopAbs_WIRE) {
746             Spls.Add(TopoDS::Wire(W),TopoDS::Face(EF));
747           }
748           else {
749             Spls.Add(TopoDS::Edge(W),TopoDS::Face(EF));
750           }
751         }
752         i++;
753       }
754     }
755     else
756       return 1;
757   }
758   
759   // ici, i vaut newnarg
760   for (i++; i<narg; i+=2) {
761     TopoDS_Shape Ew,Es;
762     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
763     Es = TopoDS::Edge(aLocalShape);
764 //    Es = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
765     if (Es.IsNull()) {
766       return 1;
767     }
768     aLocalShape = DBRep::Get(a[i+1],TopAbs_EDGE);
769     Ew = TopoDS::Edge(aLocalShape);
770 //    Ew = TopoDS::Edge(DBRep::Get(a[i+1],TopAbs_EDGE));
771     if (Ew.IsNull()) {
772       return 1;
773     }
774     Spls.Add(TopoDS::Edge(Ew),TopoDS::Edge(Es));
775   }
776
777
778   DBRep::Set(a[1],Spls);
779   return 0;
780 }
781
782 //=======================================================================
783 //function : thickshell
784 //purpose  : 
785 //=======================================================================
786
787 Standard_Integer thickshell(Draw_Interpretor& ,
788                             Standard_Integer n, const char** a)
789 {
790
791   //OSD_Chronometer Clock;
792   
793   if ( n < 4) return 1;
794   TopoDS_Shape  S  = DBRep::Get(a[2]);
795   if (S.IsNull()) return 1;
796
797   Standard_Real    Of    = atof(a[3]);
798
799   GeomAbs_JoinType JT= GeomAbs_Arc;
800   if (n > 4)
801     {
802       if (!strcmp(a[4],"i"))
803         JT = GeomAbs_Intersection;
804       if (!strcmp(a[4],"t"))
805         JT = GeomAbs_Tangent;
806     }
807   
808   Standard_Boolean Inter = Standard_False; //Standard_True;
809   Standard_Real    Tol = Precision::Confusion();
810   if (n > 5)
811     Tol = atof(a[5]);
812
813   BRepOffset_MakeOffset B;
814   B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_True);
815
816 //  Clock.Start();
817
818   B.MakeOffsetShape();
819   //B.MakeThickSolid ();
820
821 //  Clock.Show();
822
823   DBRep::Set(a[1],B.Shape());
824
825   return 0;
826 }
827
828 //=======================================================================
829 //function : offsetshape
830 //purpose  : 
831 //=======================================================================
832
833 Standard_Integer offsetshape(Draw_Interpretor& ,
834                              Standard_Integer n, const char** a)
835 {
836
837   //OSD_Chronometer Clock;
838   
839   if ( n < 4) return 1;
840   TopoDS_Shape  S  = DBRep::Get(a[2]);
841   if (S.IsNull()) return 1;
842
843   Standard_Real    Of    = atof(a[3]);
844   Standard_Boolean Inter = (!strcmp(a[0],"offsetcompshape"));
845   GeomAbs_JoinType JT= GeomAbs_Arc;
846   if (!strcmp(a[0],"offsetinter")) {
847     JT    = GeomAbs_Intersection;
848     Inter = Standard_True;
849   }
850   
851   BRepOffset_MakeOffset B;
852   Standard_Integer      IB  = 4;
853   Standard_Real         Tol = Precision::Confusion();
854   if (n > 4) {
855     TopoDS_Shape  SF  = DBRep::Get(a[4],TopAbs_FACE);
856     if (SF.IsNull()) {
857       IB  = 5;
858       Tol = atof(a[4]);
859     }
860   }
861   B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT);
862   //------------------------------------------
863   // recuperation et chargement des bouchons.
864   //----------------------------------------
865   Standard_Boolean YaBouchon = Standard_False;
866
867   for (Standard_Integer i = IB ; i < n; i++) {
868     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
869     if (!SF.IsNull()) {
870       YaBouchon = Standard_True;
871       B.AddFace(TopoDS::Face(SF));
872     }
873   }
874
875 //  Clock.Start();
876
877   if (!YaBouchon)  B.MakeOffsetShape();
878   else             B.MakeThickSolid ();
879 //  Clock.Show();
880
881   DBRep::Set(a[1],B.Shape());
882
883   return 0;
884 }
885
886 static BRepOffset_MakeOffset TheOffset;
887 static Standard_Real         TheRadius;
888 static Standard_Boolean      theYaBouchon;
889 static Standard_Real         TheTolerance = Precision::Confusion();
890 static Standard_Boolean      TheInter     = Standard_False;
891 static GeomAbs_JoinType      TheJoin      = GeomAbs_Arc;
892
893 Standard_Integer offsetparameter(Draw_Interpretor& di,
894                                  Standard_Integer n, const char** a)
895 {
896   if ( n == 1 ) { 
897     //cout << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << endl;
898     //cout << " Current Values" << endl;
899     //cout << "   --> Tolerance :" << TheTolerance << endl;
900     //cout << "   --> TheInter  :";
901     di << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << "\n";
902     di << " Current Values" << "\n";
903     di << "   --> Tolerance :" << TheTolerance << "\n";
904     di << "   --> TheInter  :";
905     if ( TheInter) {
906       //cout << "Complet" ;
907       di << "Complet" ;
908     } else {
909       //cout << "Partial";
910       di << "Partial";
911     }
912     //cout << endl << "   --> TheJoin   :";
913     di << "\n" << "   --> TheJoin   :";
914     
915     switch (TheJoin) {
916     //case GeomAbs_Arc:          cout << " Arc";          break;
917     //case GeomAbs_Intersection: cout << " Intersection"; break;
918     case GeomAbs_Arc:          di << " Arc";          break;
919     case GeomAbs_Intersection: di << " Intersection"; break;
920 #ifndef DEB
921     default:
922       break ;
923 #endif
924     }
925     //cout << endl;
926     di << "\n";
927
928     return 0;
929   }
930
931   if ( n < 4 ) return 1;
932   
933   TheTolerance = atof(a[1]);
934   TheInter     = strcmp(a[2],"p");
935   
936   if      ( !strcmp(a[3],"a")) TheJoin = GeomAbs_Arc;
937   else if ( !strcmp(a[3],"i")) TheJoin = GeomAbs_Intersection;
938   else if ( !strcmp(a[3],"t")) TheJoin = GeomAbs_Tangent;
939     
940   return 0;    
941 }
942
943
944 //=======================================================================
945 //function : offsetinit
946 //purpose  : 
947 //=======================================================================
948
949 Standard_Integer offsetload(Draw_Interpretor& ,
950                             Standard_Integer n, const char** a)
951 {
952   if ( n < 2) return 1;
953   TopoDS_Shape  S  = DBRep::Get(a[1]);
954   if (S.IsNull()) return 1;
955
956   Standard_Real    Of    = atof(a[2]);
957   TheRadius = Of;
958 //  Standard_Boolean Inter = Standard_True;
959   
960   TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin);
961   //------------------------------------------
962   // recuperation et chargement des bouchons.
963   //----------------------------------------
964   for (Standard_Integer i = 3 ; i < n; i++) {
965     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
966     if (!SF.IsNull()) {
967       TheOffset.AddFace(TopoDS::Face(SF));
968     }
969   }
970   if (n < 4)  theYaBouchon = Standard_False; //B.MakeOffsetShape();
971   else        theYaBouchon = Standard_True;  //B.MakeThickSolid ();
972
973   return 0;
974 }
975
976
977 //=======================================================================
978 //function : offsetonface
979 //purpose  : 
980 //=======================================================================
981
982 Standard_Integer offsetonface(Draw_Interpretor&, Standard_Integer n, const char** a)
983 {
984   if ( n < 3) return 1;
985
986   for (Standard_Integer i = 1 ; i < n; i+=2) {
987     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
988     if (!SF.IsNull()) {
989       Standard_Real Of = atof(a[i+1]);
990       TheOffset.SetOffsetOnFace(TopoDS::Face(SF),Of);
991     }
992   }
993   
994   return 0;
995 }
996
997 //=======================================================================
998 //function : offsetperform
999 //purpose  : 
1000 //=======================================================================
1001
1002 Standard_Integer offsetperform(Draw_Interpretor&,
1003                                Standard_Integer n, const char** a)
1004 {
1005   if ( n < 2) return 1;
1006
1007   if (theYaBouchon) TheOffset.MakeThickSolid ();
1008   else              TheOffset.MakeOffsetShape();
1009
1010   DBRep::Set(a[1],TheOffset.Shape());
1011   
1012   return 0;
1013 }
1014
1015
1016 //=======================================================================
1017 //function : Debou
1018 //purpose  : 
1019 //=======================================================================
1020
1021 static Standard_Integer Debou(Draw_Interpretor& theCommands,
1022                               Standard_Integer narg, const char** a)
1023 {
1024   Standard_Integer i ;
1025   Standard_Integer newnarg ;
1026
1027   if (narg<7) return 1;
1028   
1029   TopoDS_Shape S = DBRep::Get(a[2]);
1030
1031   Standard_Boolean Fuse;
1032   if (!strcasecmp("F",a[3])) {
1033     Fuse = Standard_True;
1034   }
1035   else if (!strcasecmp("C",a[3])) {
1036     Fuse = Standard_False;
1037   }
1038   else {
1039     return 1;
1040   }
1041
1042   for ( newnarg = 4; newnarg < narg; newnarg++) {
1043     if (a[newnarg][0] == '@') {
1044       break;
1045     }
1046   }
1047   if (newnarg >= narg-1 || newnarg == 4) {
1048     return 1;
1049   }
1050
1051
1052   TopTools_ListOfShape LF,LF2;
1053   for ( i=4; i<newnarg; i++) {
1054     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1055     LF.Append(aLocalShape);
1056 //    LF.Append(TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE)));
1057   }
1058
1059   for (i=newnarg+1; i<narg; i++) {
1060     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1061     LF2.Append(aLocalShape);
1062 //    LF2.Append(TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE)));
1063   }
1064
1065   BRepFeat_LocalOperation BLoc(S);
1066   BLoc.Perform(LF,LF2,Fuse);
1067   BLoc.Build();
1068   if (BLoc.IsDone()) {
1069 //    dout.Clear();
1070     DBRep::Set(a[1],BLoc);
1071     dout.Flush();
1072     return 0;
1073   }
1074   theCommands << "Local operation not done" ;
1075   return 1;
1076 }
1077
1078
1079 //=======================================================================
1080 //function : ROW
1081 //purpose  : 
1082 //=======================================================================
1083
1084 static Standard_Integer ROW(Draw_Interpretor& theCommands,
1085                             Standard_Integer narg, const char** a)
1086 {
1087   if (narg<13) return 1;
1088   TopoDS_Shape S = DBRep::Get(a[3]);
1089   BRepFeat_MakeRevol theRFace;
1090   gp_Dir D;
1091   gp_Pnt Or;
1092   Standard_Real Angle=0;
1093   TopoDS_Shape FFrom,FUntil;
1094   Standard_Integer i,borne;
1095   Standard_Boolean fuse;
1096
1097   if (a[1][0] == 'f' || a[1][0] == 'F') {
1098     fuse = Standard_True;
1099   }
1100   else if (a[1][0] == 'c' || a[1][0] == 'C') {
1101     fuse = Standard_False;
1102   }
1103   else {
1104     return 1;
1105   }
1106
1107   FFrom   = DBRep::Get(a[4],TopAbs_SHAPE);
1108   if (FFrom.IsNull()) {
1109     Angle = atof(a[4]);
1110     Angle *=PI/180.;
1111     i = 5;
1112   }
1113   else {
1114     FUntil = DBRep::Get(a[5],TopAbs_SHAPE);
1115     if (FUntil.IsNull()) {
1116       i = 5;
1117       FUntil = FFrom;
1118       FFrom.Nullify();
1119       
1120     }
1121     else {
1122       if (narg < 14) {
1123         return 1;
1124       }
1125       i = 6;
1126     }
1127   }
1128   borne = i+6;
1129
1130   Or.SetCoord(atof(a[i]),atof(a[i+1]),atof(a[i+2]));
1131   D.SetCoord(atof(a[i+3]),atof(a[i+4]),atof(a[i+5]));
1132   gp_Ax1 theAxis(Or,D);
1133
1134   TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
1135   TopoDS_Face F  = TopoDS::Face(aLocalShape);
1136 //  TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1137   BRepFeat_SplitShape Spls(F);
1138   for (i = borne+1; i<narg; i++) {
1139     TopoDS_Wire wir;
1140     if (a[i][0] !='-') {
1141       aLocalShape = DBRep::Get(a[i],TopAbs_WIRE);
1142       wir = TopoDS::Wire(aLocalShape);
1143 //      wir = TopoDS::Wire(DBRep::Get(a[i],TopAbs_WIRE));
1144     }
1145     else {
1146       if (a[i][1] == '\0')
1147         return 1;
1148       const char* Temp = a[i]+1;
1149       aLocalShape = DBRep::Get(Temp,TopAbs_WIRE);
1150       wir = TopoDS::Wire(aLocalShape);
1151 //      wir = TopoDS::Wire(DBRep::Get(Temp,TopAbs_WIRE));
1152       wir.Reverse();
1153     }
1154     Spls.Add(wir,F);
1155   }
1156   Spls.Build();
1157
1158   TopoDS_Shape ToRotate;
1159   const TopTools_ListOfShape& lleft = Spls.DirectLeft();
1160   if (lleft.Extent() == 1) {
1161     theRFace.Init(S,lleft.First(),F,theAxis,fuse,Standard_True);
1162     ToRotate = lleft.First();
1163   }
1164   else {
1165     BRep_Builder B;
1166     TopoDS_Shell Sh;
1167     B.MakeShell(Sh);
1168     TopTools_ListIteratorOfListOfShape it;
1169     for (it.Initialize(lleft);it.More();it.Next()) {
1170       B.Add(Sh,TopoDS::Face(it.Value()));
1171     }
1172     theRFace.Init(S,Sh,F,theAxis,fuse,Standard_True);
1173     ToRotate = Sh;
1174   }
1175
1176   // Recherche des faces de glissement
1177 //  for (TopExp_Explorer exp(S,TopAbs_FACE);exp.More();exp.Next()) {
1178   TopExp_Explorer exp(S,TopAbs_FACE) ;
1179   for ( ;exp.More();exp.Next()) {
1180     if (exp.Current().IsSame(F)) {
1181       break;
1182     }
1183   }
1184
1185   if (!exp.More()) {
1186     LocOpe_FindEdgesInFace FEIF;
1187     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1188       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1189       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1190       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1191         Su = Handle(Geom_RectangularTrimmedSurface)::
1192           DownCast(Su)->BasisSurface();
1193       }
1194       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1195         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1196         if (pl.Axis().IsParallel(theAxis,Precision::Angular())) {
1197           FEIF.Set(ToRotate,fac);
1198           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1199             theRFace.Add(FEIF.Edge(),fac);
1200           }
1201         }
1202       }
1203       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1204         gp_Cylinder cy = 
1205           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1206         if (cy.Axis().IsCoaxial(theAxis,
1207                                 Precision::Angular(),Precision::Confusion())) {
1208           FEIF.Set(ToRotate,fac);
1209           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1210             theRFace.Add(FEIF.Edge(),fac);
1211           }
1212         }
1213       }
1214     }
1215   }
1216
1217   if (borne == 11) {
1218     if (FUntil.IsNull()) {
1219       theRFace.Perform(Angle);
1220     }
1221     else {
1222       theRFace.Perform(FUntil);
1223     }
1224   }
1225   else { // borne == 12
1226     theRFace.Perform(FFrom,FUntil);
1227   }
1228
1229   if (!theRFace.IsDone()) {
1230     theCommands << "Local operation not done";
1231     return 1;
1232   }
1233
1234   DBRep::Set(a[2],theRFace);
1235   dout.Flush();
1236   return 0;
1237 }
1238
1239
1240 //=======================================================================
1241 //function : ROF
1242 //purpose  : 
1243 //=======================================================================
1244
1245 static Standard_Integer ROF(Draw_Interpretor& theCommands,
1246                             Standard_Integer narg, const char** a)
1247 {
1248   if (narg<12) return 1;
1249   TopoDS_Shape S = DBRep::Get(a[3]);
1250   BRepFeat_MakeRevol theRFace;
1251   gp_Dir D;
1252   gp_Pnt Or;
1253   Standard_Real Angle=0;
1254   TopoDS_Shape FFrom,FUntil;
1255   Standard_Integer i,borne;
1256   Standard_Boolean fuse;
1257
1258   if (a[1][0] == 'f' || a[1][0] == 'F') {
1259     fuse = Standard_True;
1260   }
1261   else if (a[1][0] == 'c' || a[1][0] == 'C') {
1262     fuse = Standard_False;
1263   }
1264   else {
1265     return 1;
1266   }
1267
1268   FFrom   = DBRep::Get(a[4],TopAbs_SHAPE);
1269   if (FFrom.IsNull()) {
1270     Angle = atof(a[4]);
1271     Angle *=PI/180.;
1272     i = 5;
1273   }
1274   else {
1275     FUntil = DBRep::Get(a[5],TopAbs_SHAPE);
1276     if (FUntil.IsNull()) {
1277       i = 5;
1278       FUntil = FFrom;
1279       FFrom.Nullify();
1280       
1281     }
1282     else {
1283       if (narg < 13) {
1284         return 1;
1285       }
1286       i = 6;
1287     }
1288   }
1289
1290   borne = i+6;
1291   Or.SetCoord(atof(a[i]),atof(a[i+1]),atof(a[i+2]));
1292   D.SetCoord(atof(a[i+3]),atof(a[i+4]),atof(a[i+5]));
1293   gp_Ax1 theAxis(Or,D);
1294
1295   TopoDS_Shape ToRotate;
1296   if (narg == borne+1) {
1297     TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
1298     TopoDS_Face F  = TopoDS::Face(aLocalShape);
1299 //    TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1300     theRFace.Init(S,F,F,theAxis,fuse,Standard_True);
1301     ToRotate = F;
1302   }
1303   else {
1304     TopoDS_Shell She;
1305     BRep_Builder B;
1306     B.MakeShell(She);
1307     
1308     for (i=borne; i<narg; i++) {
1309       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1310       TopoDS_Face F  = TopoDS::Face(aLocalShape);
1311 //      TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
1312       if (!F.IsNull()) {
1313         B.Add(She,F);
1314       }
1315     }
1316     theRFace.Init(S,She,TopoDS_Face(),theAxis,fuse,Standard_False);
1317     ToRotate = She;
1318   }
1319
1320 //  for (TopExp_Explorer exp(ToRotate,TopAbs_FACE);exp.More();exp.Next()) {
1321   TopExp_Explorer exp(ToRotate,TopAbs_FACE) ;
1322   for ( ;exp.More();exp.Next()) {
1323 //    for (TopExp_Explorer exp2(S,TopAbs_FACE);exp2.More();exp2.Next()) {
1324     TopExp_Explorer exp2(S,TopAbs_FACE) ;
1325     for ( ;exp2.More();exp2.Next()) {
1326       if (exp2.Current().IsSame(exp.Current())) {
1327         break;
1328       }
1329     }
1330     if (exp2.More()) {
1331       break;
1332     }
1333   }
1334
1335   if (!exp.More()) {
1336     LocOpe_FindEdgesInFace FEIF;
1337     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1338       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1339       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1340       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1341         Su = Handle(Geom_RectangularTrimmedSurface)::
1342           DownCast(Su)->BasisSurface();
1343       }
1344       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1345         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1346         if (pl.Axis().IsParallel(theAxis,Precision::Angular())) {
1347           FEIF.Set(ToRotate,fac);
1348           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1349             theRFace.Add(FEIF.Edge(),fac);
1350           }
1351         }
1352       }
1353       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1354         gp_Cylinder cy = 
1355           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1356         if (cy.Axis().IsCoaxial(theAxis,
1357                                 Precision::Angular(),Precision::Confusion())) {
1358           FEIF.Set(ToRotate,fac);
1359           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1360             theRFace.Add(FEIF.Edge(),fac);
1361           }
1362         }
1363       }
1364     }
1365   }
1366
1367   if (borne == 11) {
1368     if (FUntil.IsNull()) {
1369       theRFace.Perform(Angle);
1370     }
1371     else {
1372       theRFace.Perform(FUntil);
1373     }
1374   }
1375   else { // borne == 12
1376     theRFace.Perform(FFrom,FUntil);
1377   }
1378
1379   if (!theRFace.IsDone()) {
1380     theCommands << "Local operation not done";
1381     return 1;
1382   }
1383
1384   DBRep::Set(a[2],theRFace);
1385   dout.Flush();
1386   return 0;
1387 }
1388
1389
1390 //=======================================================================
1391 //function : GLU
1392 //purpose  : Commande glue
1393 //=======================================================================
1394
1395 static Standard_Integer GLU(Draw_Interpretor& ,
1396                             Standard_Integer narg, const char** a)
1397 {
1398   if (narg<6 || narg%2 != 0) return 1;
1399   TopoDS_Shape Sne = DBRep::Get(a[2]);
1400   TopoDS_Shape Sba = DBRep::Get(a[3]);
1401   
1402   Standard_Boolean pick;
1403   
1404   BRepFeat_Gluer theGl(Sne,Sba);
1405   TopoDS_Shape Fne,Fba;
1406   
1407   LocOpe_FindEdges fined;
1408
1409   Standard_Integer i = 4;
1410   Standard_Boolean first = Standard_True;
1411   while (i<narg) {
1412     pick = (a[i][0] == '.');
1413     Fne = DBRep::Get(a[i]);
1414     if (Fne.IsNull()) {
1415       return 1;
1416     }
1417     TopAbs_ShapeEnum sht = Fne.ShapeType();
1418     if (pick && sht != TopAbs_FACE && sht != TopAbs_EDGE) {
1419       Standard_Real u,v;
1420       DBRep_DrawableShape::LastPick(Fne,u,v);
1421       sht = Fne.ShapeType();
1422     }
1423     if (first && sht != TopAbs_FACE) {
1424       return 1;
1425     }
1426     first = Standard_False;
1427     pick = (a[i+1][0] == '.');
1428     Fba = DBRep::Get(a[i+1]);
1429     if (Fba.IsNull()) {
1430       return 1;
1431     }
1432     if (pick && Fba.ShapeType() != sht) {
1433       Standard_Real u,v;
1434       DBRep_DrawableShape::LastPick(Fba,u,v);
1435     }
1436     if (Fba.ShapeType() != sht) {
1437       return 1;
1438     }
1439     if (sht == TopAbs_FACE) {
1440       const TopoDS_Face& f1 = TopoDS::Face(Fne);
1441       const TopoDS_Face& f2 = TopoDS::Face(Fba);
1442       theGl.Bind(f1,f2);
1443       fined.Set(Fne,Fba);
1444       for (fined.InitIterator(); fined.More(); fined.Next()) {
1445         theGl.Bind(fined.EdgeFrom(),fined.EdgeTo());
1446       }
1447     }
1448     else {
1449       theGl.Bind(TopoDS::Edge(Fne),TopoDS::Edge(Fba));
1450     }
1451     i +=2;
1452   }
1453   
1454   DBRep::Set(a[1],theGl);
1455   dout.Flush();
1456   return 0;
1457 }
1458
1459 static Standard_Integer DEFIN(Draw_Interpretor& theCommands,
1460                               Standard_Integer narg, const char** a)
1461 {
1462
1463   if (strcasecmp(a[0],"FEATPRISM") &&
1464       strcasecmp(a[0],"FEATDPRISM") &&
1465       strcasecmp(a[0],"FEATREVOL") &&
1466       strcasecmp(a[0],"FEATPIPE") &&
1467       strcasecmp(a[0],"FEATLF")  &&
1468       strcasecmp(a[0],"FEATRF")) {
1469     return 1;
1470   }
1471
1472   if ((!strcasecmp(a[0],"FEATPRISM") && narg !=9) ||
1473       (!strcasecmp(a[0],"FEATREVOL") && narg != 12) ||
1474       (!strcasecmp(a[0],"FEATDPRISM") && narg != 7) ||
1475       (!strcasecmp(a[0],"FEATPIPE") && narg != 7) ||
1476       (!strcasecmp(a[0],"FEATLF") && narg != 12) ||
1477       (!strcasecmp(a[0],"FEATRF") && narg != 14)) {
1478     theCommands << "invalid number of arguments";
1479     return 1;
1480   }
1481
1482   TopoDS_Shape Sbase = DBRep::Get(a[1]);
1483   if (Sbase.IsNull()) {
1484     theCommands << "null basis shape";
1485     return 1;
1486   }
1487   Standard_Integer Ifuse  = atoi(a[narg-2]);
1488   Standard_Integer Imodif = atoi(a[narg-1]);
1489   
1490   Standard_Integer Fuse = Ifuse;
1491   Standard_Boolean Modify = (Imodif!=0);
1492
1493   TopoDS_Shape Pbase;
1494   TopoDS_Face Skface;
1495   TopoDS_Wire W;
1496
1497   Handle(Geom_Plane) P;
1498
1499   BRepFeat_StatusError se;
1500
1501   if (strcasecmp(a[0],"FEATLF") && strcasecmp(a[0],"FEATRF")) {
1502     Pbase = DBRep::Get(a[2]);
1503     if (Pbase.IsNull()) {
1504       theCommands << "null shape to transform";
1505       return 1;
1506     }
1507     TopoDS_Shape aLocalShape(DBRep::Get(a[3],TopAbs_FACE));
1508     Skface = TopoDS::Face(aLocalShape);
1509 //    Skface = TopoDS::Face(DBRep::Get(a[3],TopAbs_FACE));
1510     if (Skface.IsNull()) {
1511       theCommands << "null face of Sketch";
1512       return 1;
1513     }
1514   }
1515   else {
1516     TopoDS_Shape aLocalShape(DBRep::Get(a[2], TopAbs_WIRE));
1517     W = TopoDS::Wire(aLocalShape);
1518 //    W = TopoDS::Wire(DBRep::Get(a[2], TopAbs_WIRE));
1519     if(W.IsNull()) {
1520       theCommands << "null profile for rib or slot";
1521       return 1;
1522     }
1523     Handle(Geom_Surface) s = DrawTrSurf::GetSurface(a[3]);
1524     P = Handle(Geom_Plane)::DownCast(s);
1525     if(P.IsNull()) {
1526       theCommands << "null plane to transform";
1527       return 1;
1528     }
1529   }
1530   if (narg == 9 || narg == 12 || narg == 14) {
1531 //    Standard_Real X,Y,Z,X1,Y1,Z1;
1532     Standard_Real X,Y,Z;
1533     X = atof(a[4]);
1534     Y = atof(a[5]);
1535     Z = atof(a[6]);
1536     
1537     if (narg == 9) { // prism
1538       prdef = Standard_True;      
1539       thePrism.Init(Sbase,Pbase,Skface,gp_Dir(X,Y,Z),Fuse,Modify);
1540     }
1541     else if(narg == 14) {
1542       rfdef = Standard_True;
1543       gp_Pnt Or(X, Y, Z);
1544       X = atof(a[7]);
1545       Y = atof(a[8]);
1546       Z = atof(a[9]);
1547       Standard_Real H1 = atof(a[10]);
1548       Standard_Real H2 = atof(a[11]);
1549       gp_Ax1 ax1(Or, gp_Dir(X, Y, Z));
1550       theRF.Init(Sbase, W, P, ax1, H1, H2, Fuse, Modify);
1551       if (!theRF.IsDone()) {
1552         se = theRF.CurrentStatusError();
1553         //BRepFeat::Print(se,cout) << endl;
1554         Standard_SStream aSStream;
1555         BRepFeat::Print(se,aSStream);
1556         theCommands << aSStream << "\n";
1557         return 1;
1558       }
1559     }
1560     else if(narg == 12 && strcasecmp(a[0],"FEATLF")) {
1561       rvdef = Standard_True;
1562       gp_Pnt Or(X,Y,Z);
1563       X = atof(a[7]);
1564       Y = atof(a[8]);
1565       Z = atof(a[9]);
1566       theRevol.Init(Sbase,Pbase,Skface,gp_Ax1(Or,gp_Dir(X,Y,Z)),
1567                     Fuse,Modify);
1568     }
1569     else {
1570       lfdef = Standard_True;
1571       gp_Vec Direct(X,Y,Z);
1572       X = atof(a[7]);
1573       Y = atof(a[8]);
1574       Z = atof(a[9]);
1575       theLF.Init(Sbase, W, P, Direct, gp_Vec(X,Y,Z), Fuse,Modify);
1576       if (!theLF.IsDone()) {
1577         se = theLF.CurrentStatusError();
1578         //BRepFeat::Print(se,cout) << endl;
1579         Standard_SStream aSStream;
1580         BRepFeat::Print(se,aSStream);
1581         theCommands << aSStream << "\n";
1582         return 1;
1583       }
1584     }
1585   }
1586   else if (narg == 7) {
1587     if (!strcasecmp(a[0],"FEATDPRISM")) {
1588       if (Pbase.ShapeType() != TopAbs_FACE) {
1589         theCommands << "Invalid DPrism base";
1590         return 1;
1591       }
1592       Standard_Real Angle = atof(a[4])*PI/360; 
1593       dprdef = Standard_True;
1594       theDPrism.Init(Sbase,TopoDS::Face(Pbase),Skface,Angle,Fuse,Modify);
1595     }
1596     else { // FEATPIPE
1597       TopoDS_Shape aLocalShape(DBRep::Get(a[4],TopAbs_WIRE));
1598       TopoDS_Wire Spine = TopoDS::Wire(aLocalShape);
1599 //      TopoDS_Wire Spine = TopoDS::Wire(DBRep::Get(a[4],TopAbs_WIRE));
1600       if (Spine.IsNull()) {
1601         TopoDS_Shape Edspine =DBRep::Get(a[4],TopAbs_EDGE);
1602         if (Edspine.IsNull()) {
1603           theCommands << "null spine";
1604           return 1;
1605         }
1606         BRep_Builder B;
1607         B.MakeWire(Spine);
1608         B.Add(Spine,Edspine);
1609       }
1610       pidef = Standard_True;
1611       thePipe.Init(Sbase,Pbase,Skface,Spine,Fuse,Modify);
1612     }
1613   }
1614   return 0;
1615 }
1616
1617
1618
1619 static Standard_Integer ADD(Draw_Interpretor& ,
1620                             Standard_Integer narg, const char** a)
1621 {
1622   Standard_Integer i ;
1623   if (narg < 4 || narg%2 != 0) {
1624     return 1;
1625   }
1626   if (!strcasecmp("PRISM",a[1])) {
1627     if (!prdef) {
1628       return 1;
1629     }
1630     for ( i=2; i<narg; i+=2) {
1631       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1632       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1633 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1634       if (edg.IsNull()) {
1635         return 1;
1636       }
1637       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1638       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1639 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1640       if (fac.IsNull()) {
1641         return 1;
1642       }
1643       thePrism.Add(edg,fac);
1644     }
1645   }
1646   else if (!strcasecmp("REVOL",a[1])) {
1647     if (!rvdef) {
1648       return 1;
1649     }
1650     for ( i=2; i<narg; i+=2) {
1651       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1652       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1653 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1654       if (edg.IsNull()) {
1655         return 1;
1656       }
1657       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1658       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1659 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1660       if (fac.IsNull()) {
1661         return 1;
1662       }
1663       theRevol.Add(edg,fac);
1664     }
1665   }
1666   else if (!strcasecmp("PIPE",a[1])) {
1667     if (!pidef) {
1668       return 1;
1669     }
1670     for ( i=2; i<narg; i+=2) {
1671       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1672       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1673 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1674       if (edg.IsNull()) {
1675         return 1;
1676       }
1677       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1678       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1679 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1680       if (fac.IsNull()) {
1681         return 1;
1682       }
1683       thePipe.Add(edg,fac);
1684     }
1685   }
1686   else {
1687     return 1;
1688   }
1689   return 0;
1690 }
1691
1692
1693
1694 static Standard_Integer PERF(Draw_Interpretor& theCommands,
1695                             Standard_Integer narg, const char** a)
1696 {
1697   if (narg < 3) {
1698     return 1;
1699   }
1700   if (strcasecmp(a[0],"FEATPERFORM") &&
1701       strcasecmp(a[0],"FEATPERFORMVAL")) {
1702     return 1;
1703   }
1704
1705   Standard_Integer Kas;
1706   if (!strcasecmp("PRISM",a[1])) {
1707     Kas = 1;
1708     if (!prdef) {
1709       theCommands << "prism not defined";
1710       return 1;
1711     }
1712   }
1713   else if (!strcasecmp("REVOL",a[1])) {
1714     Kas = 2;
1715     if (!rvdef) {
1716       theCommands << "revol not defined";
1717       return 1;
1718     }
1719   }
1720   else if (!strcasecmp("PIPE",a[1])) {
1721     Kas = 3;
1722     if (!pidef) {
1723       theCommands << "pipe not defined";
1724       return 1;
1725     }
1726     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1727       theCommands << "invalid command for pipe";
1728       return 1;
1729     }
1730   }
1731   else if (!strcasecmp("DPRISM",a[1])) {
1732     Kas = 4;
1733     if (!dprdef) {
1734       theCommands << "dprism not defined";
1735       return 1;
1736     }
1737   }
1738   else if (!strcasecmp("LF",a[1])) {
1739     Kas = 5;
1740     if (!lfdef) {
1741       theCommands << "lf not defined";
1742       return 1;
1743     }
1744     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1745       theCommands << "invalid command for lf";
1746       return 1;
1747     }
1748   }
1749   else if (!strcasecmp("RF",a[1])) {
1750     Kas = 6;
1751     if (!rfdef) {
1752       theCommands << "rf not defined";
1753       return 1;
1754     }
1755     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1756       theCommands << "invalid command for rf";
1757       return 1;
1758     }
1759   }
1760   else {
1761     theCommands << "unknown argument : " << a[1];
1762     return 1;
1763   }
1764
1765   if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1766     if (narg !=4 && narg != 5) {
1767       theCommands << "invalid number of arguments";
1768       return 1;
1769     }
1770     if (narg == 4) {
1771       Standard_Real Val = atof(a[3]);
1772       if (Kas == 1) {
1773         thePrism.Perform(Val);
1774       }
1775       else if (Kas == 2) {
1776         Val *=(PI/180.);
1777         theRevol.Perform(Val);
1778       }
1779       else if (Kas == 4) {
1780         theDPrism.Perform(Val);
1781       }
1782       else if (Kas == 5) {
1783         theCommands << "invalid command for lf";
1784         return 1;
1785       }
1786       else if (Kas == 6) {
1787         theCommands << "invalid command for rf";
1788         return 1;
1789       }
1790     }
1791     else if(narg == 5) {
1792       Standard_Real Val = atof(a[3]);
1793       TopoDS_Shape FUntil = DBRep::Get(a[4],TopAbs_SHAPE);
1794       if (Kas == 1) {
1795         thePrism.PerformUntilHeight(FUntil, Val);
1796       }
1797       else if (Kas == 2) {
1798         Val *=(PI/180.);
1799         theRevol.PerformUntilAngle(FUntil, Val);
1800       }
1801       else if (Kas == 4) {
1802         theDPrism.PerformUntilHeight(FUntil, Val);
1803       } 
1804       else {
1805         theCommands << "invalid command for ribs or slots";
1806         return 1;
1807       }
1808     }
1809   }
1810   else if (!strcasecmp(a[0],"FEATPERFORM")) {
1811     if (narg == 3) { // Thru all
1812       switch (Kas) {
1813       case 1:
1814         thePrism.PerformThruAll();
1815         break;
1816       case 2:
1817         theRevol.PerformThruAll();
1818         break;
1819       case 3:
1820         thePipe.Perform();
1821         break;
1822       case 4:
1823         theDPrism.PerformThruAll();
1824         break;
1825       case 5:
1826         theLF.Perform();
1827         break;
1828       case 6:
1829         theRF.Perform();
1830         break;
1831       default:
1832
1833         return 1;
1834       }
1835     }
1836     else if (narg == 4) { // Until
1837       TopoDS_Shape Funtil = DBRep::Get(a[3],TopAbs_SHAPE);
1838       switch (Kas) {
1839       case 1:
1840         {
1841           if (Funtil.IsNull()) {
1842             thePrism.PerformUntilEnd();
1843           }
1844           else {
1845             thePrism.Perform(Funtil);
1846           }
1847         }
1848         break;
1849       case 2:
1850         {
1851           if (!Funtil.IsNull()) {
1852             theRevol.Perform(Funtil);
1853           }
1854           else {
1855             return 1;
1856           }
1857         }
1858         break;
1859       case 3:
1860         {
1861           if (!Funtil.IsNull()) {
1862             thePipe.Perform(Funtil);
1863           }
1864           else {
1865             theCommands << "invalid command for ribs pipe";
1866             return 1;
1867           }
1868         }
1869         break;
1870       case 4:
1871         {
1872           if (!Funtil.IsNull()) {
1873             theDPrism.Perform(Funtil);
1874           }
1875           else {
1876             theDPrism.PerformUntilEnd();
1877           }
1878         }
1879         break;
1880       case 5:
1881         {  
1882           theCommands << "invalid command for lf";
1883           return 1;
1884         }
1885         break;
1886       case 6:
1887         {  
1888           theCommands << "invalid command for rf";
1889           return 1;
1890         }
1891         break;
1892       default:
1893         return 1;
1894       }
1895     }
1896     else if (narg == 5) {
1897       TopoDS_Shape Ffrom = DBRep::Get(a[3],TopAbs_SHAPE);
1898       TopoDS_Shape Funtil = DBRep::Get(a[4],TopAbs_SHAPE);
1899       if (Funtil.IsNull()) {
1900         return 1;
1901       }
1902       switch (Kas) {
1903       case 1:
1904         {
1905           if (Ffrom.IsNull()) {
1906             thePrism.PerformFromEnd(Funtil);
1907           }
1908           else {
1909             thePrism.Perform(Ffrom,Funtil);
1910           }
1911         }
1912         break;
1913       case 2:
1914         {
1915           if (Ffrom.IsNull()) {
1916             return 1;
1917           }
1918           theRevol.Perform(Ffrom,Funtil);
1919         }
1920         break;
1921       case 3:
1922         {
1923           if (Ffrom.IsNull()) {
1924             return 1;
1925           }
1926           thePipe.Perform(Ffrom,Funtil);
1927         }
1928         break;
1929       case 4:
1930         {
1931           if (Ffrom.IsNull()) {
1932             theDPrism.PerformFromEnd(Funtil);
1933           }
1934           else {
1935             theDPrism.Perform(Ffrom,Funtil);
1936           }
1937         }
1938         break;
1939
1940       default:
1941         return 1;
1942       }
1943     }
1944   }
1945
1946   BRepFeat_StatusError se;
1947   switch (Kas) {
1948   case 1:
1949     if (!thePrism.IsDone()) {
1950       se = thePrism.CurrentStatusError();
1951       //BRepFeat::Print(se,cout) << endl;
1952       Standard_SStream aSStream;
1953       BRepFeat::Print(se,aSStream);
1954       theCommands << aSStream << "\n";
1955       return 1;
1956     }
1957     DBRep::Set(a[2],thePrism);
1958     dout.Flush();
1959     return 0;
1960   case 2:
1961     if (!theRevol.IsDone()) {
1962       se = theRevol.CurrentStatusError();
1963       //BRepFeat::Print(se,cout) << endl;
1964       Standard_SStream aSStream;
1965       BRepFeat::Print(se,aSStream);
1966       theCommands << aSStream << "\n";
1967       return 1;
1968     }
1969     DBRep::Set(a[2],theRevol);
1970     dout.Flush();
1971     return 0;
1972   case 3:
1973     if (!thePipe.IsDone()) {
1974       se = thePipe.CurrentStatusError();
1975       //BRepFeat::Print(se,cout) << endl;
1976       Standard_SStream aSStream;
1977       BRepFeat::Print(se,aSStream);
1978       theCommands << aSStream << "\n";
1979       return 1;
1980     }
1981     DBRep::Set(a[2],thePipe);
1982     dout.Flush();
1983     return 0;
1984   case 4:
1985     if (!theDPrism.IsDone()) {
1986       se = theDPrism.CurrentStatusError();
1987       //BRepFeat::Print(se,cout) << endl;
1988       Standard_SStream aSStream;
1989       BRepFeat::Print(se,aSStream);
1990       theCommands << aSStream << "\n";
1991       return 1;
1992     }
1993     DBRep::Set(a[2],theDPrism);
1994     dout.Flush();
1995     return 0;
1996   case 5:
1997     if (!theLF.IsDone()) {
1998       se = theLF.CurrentStatusError();
1999       //BRepFeat::Print(se,cout) << endl;
2000       Standard_SStream aSStream;
2001       BRepFeat::Print(se,aSStream);
2002       theCommands << aSStream << "\n";
2003       return 1;
2004     }
2005     DBRep::Set(a[2],theLF);
2006     dout.Flush();
2007     return 0;
2008   case 6:
2009     if (!theRF.IsDone()) {
2010       se = theRF.CurrentStatusError();
2011       //BRepFeat::Print(se,cout) << endl;
2012       Standard_SStream aSStream;
2013       BRepFeat::Print(se,aSStream);
2014       theCommands << aSStream << "\n";
2015       return 1;
2016     }
2017     DBRep::Set(a[2],theRF);
2018     dout.Flush();
2019     return 0;
2020   default:
2021     return 1;
2022   }
2023 }
2024
2025
2026 static Standard_Integer BOSS(Draw_Interpretor& theCommands,
2027                              Standard_Integer narg, const char** a)
2028 {
2029   if (strcasecmp(a[0],"ENDEDGES") && strcasecmp(a[0],"FILLET")
2030       && strcasecmp(a[0],"BOSSAGE")) {
2031     return 1;
2032   }
2033
2034   if ((!strcasecmp(a[0],"ENDEDGES") && narg !=5) ||
2035       (!strcasecmp(a[0],"FILLET") && narg <5 &&  narg%2 != 1) ||
2036       (!strcasecmp(a[0],"BOSSAGE") && narg != 6)) {
2037     theCommands << "invalid number of arguments";
2038     return 1;
2039   }
2040
2041   Standard_Integer Kas=0;
2042   Standard_Integer dprsig=0;
2043   if (!strcasecmp("ENDEDGES",a[0])) {
2044     Kas = 1;
2045     dprsig = atoi(a[4]);
2046   }
2047   else if (!strcasecmp("FILLET",a[0])) {
2048     Kas = 2;
2049   }
2050   else if (!strcasecmp("BOSSAGE",a[0])) {
2051     Kas = 3;
2052     dprsig = atoi(a[5]);
2053   }
2054  
2055   TopoDS_Shape theShapeTop; 
2056   TopoDS_Shape theShapeBottom;
2057
2058   if (Kas == 1 || Kas == 3) {
2059     if (!strcasecmp("DPRISM",a[1])) {
2060       if (!dprdef) {
2061         theCommands << "dprism not defined";
2062         return 1;
2063       }
2064     }
2065     else {
2066       theCommands << "unknown argument : " << a[1];
2067       return 1;
2068     }
2069
2070     theDPrism.BossEdges(dprsig);
2071    
2072     TopTools_ListOfShape theTopEdges, theLatEdges;
2073     theTopEdges = theDPrism.TopEdges();
2074     theLatEdges = theDPrism.LatEdges();
2075
2076     TopTools_ListIteratorOfListOfShape it;
2077     BRep_Builder B;
2078
2079     B.MakeCompound(TopoDS::Compound(theShapeTop));
2080     it.Initialize(theTopEdges);
2081     for(; it.More(); it.Next()) {
2082       TopExp_Explorer exp;
2083       for (exp.Init(it.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
2084         B.Add(theShapeTop,exp.Current());
2085       }
2086     }
2087     DBRep::Set(a[2],theShapeTop);
2088     dout.Flush();
2089
2090     B.MakeCompound(TopoDS::Compound(theShapeBottom));
2091     it.Initialize(theLatEdges);
2092     for(; it.More(); it.Next()) {
2093       B.Add(theShapeBottom,it.Value());
2094     }
2095     DBRep::Set(a[3],theShapeBottom);
2096     dout.Flush();
2097     if (Kas == 1) return 0;
2098   }
2099
2100   if (Kas == 2 || Kas == 3) {
2101     
2102 //    Standard_Integer nrad;
2103     TopoDS_Shape V;
2104     if (Kas == 2) {
2105       V = DBRep::Get(a[2],TopAbs_SHAPE);
2106     }
2107     else if (Kas == 3) {
2108       V = theDPrism;
2109     }
2110
2111     if(V.IsNull()) return 1;
2112     ChFi3d_FilletShape FSh = ChFi3d_Rational;
2113     Rakk = new BRepFilletAPI_MakeFillet(V,FSh);
2114     Rakk->SetParams(ta,t3d,t2d,t3d,t2d,fl);
2115     Rakk->SetContinuity(blend_cont, tapp_angle);
2116     Standard_Real Rad;
2117     TopoDS_Shape S;
2118     TopoDS_Edge E;
2119     Standard_Integer nbedge = 0;
2120
2121     if (Kas == 2) {
2122       for (Standard_Integer ii = 1; ii < (narg-1)/2; ii++){
2123         Rad = atof(a[2*ii + 1]);
2124         if (Rad == 0.) continue;
2125         S = DBRep::Get(a[(2*ii+2)],TopAbs_SHAPE);
2126         TopExp_Explorer exp;
2127         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2128           E = TopoDS::Edge(exp.Current());
2129           if(!E.IsNull()){
2130             Rakk->Add(Rad,E);
2131             nbedge++;
2132           }
2133         }
2134       }
2135     }
2136     else if (Kas == 3) {
2137       Rad = atof(a[3]);
2138       if (Rad != 0.) {
2139         S = theShapeTop;
2140         TopExp_Explorer exp;
2141         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2142           E = TopoDS::Edge(exp.Current());
2143           if(!E.IsNull()){
2144             Rakk->Add(Rad,E);
2145             nbedge++;
2146           }
2147         } 
2148       }
2149       Rad = atof(a[4]);
2150       if (Rad != 0.) {
2151         S = theShapeBottom;
2152         TopExp_Explorer exp;
2153         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2154           E = TopoDS::Edge(exp.Current());
2155           if(!E.IsNull()){
2156             Rakk->Add(Rad,E);
2157             nbedge++;
2158           }
2159         } 
2160       }
2161     }
2162     
2163     if(!nbedge) return 1;
2164     Rakk->Build();
2165     if(!Rakk->IsDone()) return 1;
2166     TopoDS_Shape res = Rakk->Shape();
2167
2168     if (Kas == 2) {
2169       DBRep::Set(a[1],res);
2170     } 
2171     else if (Kas == 3) {
2172       DBRep::Set(a[2],res);
2173     }
2174     dout.Flush();
2175     return 0;
2176   }
2177
2178   return 1;
2179 }
2180
2181
2182 //=======================================================================
2183 //function : FeatureCommands
2184 //purpose  : 
2185 //=======================================================================
2186
2187 void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
2188 {
2189   static Standard_Boolean done = Standard_False;
2190   if (done) return;
2191   done = Standard_True;
2192
2193   DBRep::BasicCommands(theCommands);
2194
2195   const char* g = "TOPOLOGY Feature commands";
2196
2197   theCommands.Add("localope", 
2198                   " Performs a local top. operation : localope result shape tool F/C (fuse/cut) face [face...]",
2199                   __FILE__,Loc,g);
2200
2201   theCommands.Add("hole",
2202                   " Performs a hole : hole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius [Pfrom Pto]",
2203                   __FILE__,HOLE1,g);
2204
2205   theCommands.Add("firsthole",
2206                   " Performs the first hole : firsthole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2207                   __FILE__,HOLE2,g);
2208
2209   theCommands.Add("holend",
2210                   " Performs the hole til end : holend result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2211                   __FILE__,HOLE3,g);
2212
2213   theCommands.Add("blindhole", 
2214                   " Performs the blind hole : blindhole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius Length",
2215                   __FILE__,HOLE4,g);
2216
2217   theCommands.Add("holecontrol",
2218                   "Sets/Unsets or display controls on holes : holecontrol [0/1]",
2219                   __FILE__,CONTROL,g);
2220
2221   theCommands.Add("wprism",
2222                   "Prisms wires on a face : wprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ  SkecthFace wire1 [wire2 ....]",
2223                   __FILE__,PRW,g);
2224
2225
2226   theCommands.Add("fprism", 
2227                   "Prisms a set of faces of a shape : fprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ face1 [face2...]",
2228                   __FILE__,PRF,g);
2229
2230
2231   theCommands.Add("wrotate",
2232                   "Rotates wires on a face : wrotate f[use]/c[ut] result shape Angle/[FFrom] FUntil OX OY OZ DX DY DZ SkecthFace wire1 [wire2 ....]",
2233                   __FILE__,ROW,g);
2234
2235
2236   theCommands.Add("frotate", 
2237                   "Rotates a set of faces of a shape : frotate f[use]/c[ut] result shape Angle/[FaceFrom] FaceUntil OX OY OZ DX DY DZ face1 [face2...]",
2238                   __FILE__,ROF,g);
2239
2240
2241   theCommands.Add("splitshape",
2242                   "splitshape result shape face wire/edge [wire/edge ...][face wire/edge [wire/edge...] ...] [@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]",
2243                   __FILE__,SPLS,g);
2244
2245
2246   theCommands.Add("thickshell",
2247                   "thickshell r shape offset [jointype [tol] ]",
2248                   __FILE__,thickshell,g);
2249   
2250   theCommands.Add("offsetshape",
2251                   "offsetshape r shape offset [tol] [face ...]",
2252                   __FILE__,offsetshape,g);
2253   
2254   theCommands.Add("offsetcompshape",
2255                   "offsetcompshape r shape offset [face ...]",
2256                   __FILE__,offsetshape,g);
2257
2258   theCommands.Add("offsetparameter",
2259                   "offsetparameter tol inter(a/i) join(a/i)",
2260                   __FILE__,offsetparameter);
2261
2262   theCommands.Add("offsetload",
2263                   "offsetload shape offset bouchon1 bouchon2 ...",
2264                   __FILE__,offsetload,g);
2265
2266   theCommands.Add("offsetonface",
2267                   "offsetonface face1 offset1 face2 offset2 ...",
2268                   __FILE__,offsetonface,g);
2269
2270   theCommands.Add("offsetperform",
2271                   "offsetperform result",
2272                   __FILE__,offsetperform,g);
2273
2274
2275   theCommands.Add("deboucle", 
2276                   " Essai de debouclage partiel: deboucle result shape F/C face [face...] @ face [face...]",
2277                   __FILE__,Debou,g);
2278
2279
2280   theCommands.Add("glue", 
2281                   "glue result shapenew shapebase facenew facebase [facenew facebase...] [edgenew edgebase [edgenew edgebase...]]",
2282                   __FILE__,GLU,g);
2283
2284
2285   theCommands.Add("featprism", 
2286                   "Defines the arguments for a prism : featprism shape element skface  Dirx Diry Dirz Fuse(0/1/2) Modify(0/1)",
2287                   __FILE__,DEFIN);
2288
2289   theCommands.Add("featrevol", 
2290                   "Defines the arguments for a revol : featrevol shape element skface  Ox Oy Oz Dx Dy Dz Fuse(0/1/2) Modify(0/1)",
2291                   __FILE__,DEFIN);
2292
2293   theCommands.Add("featpipe", 
2294                   "Defines the arguments for a pipe : featpipe shape element skface  spine Fuse(0/1/2) Modify(0/1)",
2295                   __FILE__,DEFIN);
2296
2297   theCommands.Add("featdprism", 
2298                   "Defines the arguments for a drafted prism : featdprism shape face skface angle Fuse(0/1/2) Modify(0/1)",
2299                   __FILE__,DEFIN);
2300
2301   theCommands.Add("featlf", 
2302                   "Defines the arguments for a linear rib or slot : featlf shape wire plane DirX DirY DirZ DirX DirY DirZ Fuse(0/1/2) Modify(0/1)",
2303                   __FILE__,DEFIN);
2304
2305   theCommands.Add("featrf", 
2306                   "Defines the arguments for a rib or slot of revolution : featrf shape wire plane X Y Z DirX DirY DirZ Size Size Fuse(0/1/2) Modify(0/1)",
2307                   __FILE__,DEFIN);
2308
2309   theCommands.Add("addslide", 
2310                   " Adds sliding elements : addslide prism/revol/pipe edge face [edge face...]",
2311                   __FILE__,ADD);
2312
2313   theCommands.Add("featperform", 
2314                   " Performs the prism revol dprism linform or pipe :featperform prism/revol/pipe/dprism/lf result [[Ffrom] Funtil]",
2315                   __FILE__,PERF);
2316
2317   theCommands.Add("featperformval", 
2318                   " Performs the prism revol dprism or linform with a value :featperformval prism/revol/dprism/lf result value",
2319                   __FILE__,PERF);
2320
2321   theCommands.Add("endedges", 
2322                   " Return top and bottom edges of dprism :endedges dprism shapetop shapebottom First/LastShape (1/2)",
2323                   __FILE__,BOSS);
2324
2325   theCommands.Add("fillet", 
2326                   " Perform fillet on compounds of edges :fillet result object rad1 comp1 rad2 comp2 ...",
2327                   __FILE__,BOSS);
2328
2329   theCommands.Add("bossage", 
2330                   " Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)",
2331                   __FILE__,BOSS);
2332
2333 }