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