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