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