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