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