0023367: New functionality restoring the middle path of pipe-like shape
[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 && wtyp != TopAbs_COMPOUND && pick) {
749           Standard_Real u,v;
750           DBRep_DrawableShape::LastPick(W,u,v);
751           wtyp = W.ShapeType();
752         }
753         if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && wtyp != TopAbs_COMPOUND) {
754           EF = DBRep::Get(a[i]);
755           break;
756         }
757         else {
758           if (rever) {
759             W.Reverse();
760           }
761           if (wtyp == TopAbs_WIRE) {
762             Spls.Add(TopoDS::Wire(W),TopoDS::Face(EF));
763           }
764           else if (wtyp == TopAbs_EDGE) {
765             Spls.Add(TopoDS::Edge(W),TopoDS::Face(EF));
766           }
767           else {
768             Spls.Add(TopoDS::Compound(W),TopoDS::Face(EF));
769           }
770         }
771         i++;
772       }
773     }
774     else
775       return 1;
776   }
777   
778   // ici, i vaut newnarg
779   for (i++; i<narg; i+=2) {
780     TopoDS_Shape Ew,Es;
781     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
782     Es = TopoDS::Edge(aLocalShape);
783 //    Es = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
784     if (Es.IsNull()) {
785       return 1;
786     }
787     aLocalShape = DBRep::Get(a[i+1],TopAbs_EDGE);
788     Ew = TopoDS::Edge(aLocalShape);
789 //    Ew = TopoDS::Edge(DBRep::Get(a[i+1],TopAbs_EDGE));
790     if (Ew.IsNull()) {
791       return 1;
792     }
793     Spls.Add(TopoDS::Edge(Ew),TopoDS::Edge(Es));
794   }
795
796
797   DBRep::Set(a[1],Spls);
798   return 0;
799 }
800
801 //=======================================================================
802 //function : thickshell
803 //purpose  : 
804 //=======================================================================
805
806 Standard_Integer thickshell(Draw_Interpretor& ,
807                             Standard_Integer n, const char** a)
808 {
809
810   //OSD_Chronometer Clock;
811   
812   if ( n < 4) return 1;
813   TopoDS_Shape  S  = DBRep::Get(a[2]);
814   if (S.IsNull()) return 1;
815
816   Standard_Real    Of    = atof(a[3]);
817
818   GeomAbs_JoinType JT= GeomAbs_Arc;
819   if (n > 4)
820     {
821       if (!strcmp(a[4],"i"))
822         JT = GeomAbs_Intersection;
823       if (!strcmp(a[4],"t"))
824         JT = GeomAbs_Tangent;
825     }
826   
827   Standard_Boolean Inter = Standard_False; //Standard_True;
828   Standard_Real    Tol = Precision::Confusion();
829   if (n > 5)
830     Tol = atof(a[5]);
831
832   BRepOffset_MakeOffset B;
833   B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_True);
834
835 //  Clock.Start();
836
837   B.MakeOffsetShape();
838   //B.MakeThickSolid ();
839
840 //  Clock.Show();
841
842   DBRep::Set(a[1],B.Shape());
843
844   return 0;
845 }
846
847 //=======================================================================
848 //function : offsetshape
849 //purpose  : 
850 //=======================================================================
851
852 Standard_Integer offsetshape(Draw_Interpretor& ,
853                              Standard_Integer n, const char** a)
854 {
855
856   //OSD_Chronometer Clock;
857   
858   if ( n < 4) return 1;
859   TopoDS_Shape  S  = DBRep::Get(a[2]);
860   if (S.IsNull()) return 1;
861
862   Standard_Real    Of    = atof(a[3]);
863   Standard_Boolean Inter = (!strcmp(a[0],"offsetcompshape"));
864   GeomAbs_JoinType JT= GeomAbs_Arc;
865   if (!strcmp(a[0],"offsetinter")) {
866     JT    = GeomAbs_Intersection;
867     Inter = Standard_True;
868   }
869   
870   BRepOffset_MakeOffset B;
871   Standard_Integer      IB  = 4;
872   Standard_Real         Tol = Precision::Confusion();
873   if (n > 4) {
874     TopoDS_Shape  SF  = DBRep::Get(a[4],TopAbs_FACE);
875     if (SF.IsNull()) {
876       IB  = 5;
877       Tol = atof(a[4]);
878     }
879   }
880   B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT);
881   //------------------------------------------
882   // recuperation et chargement des bouchons.
883   //----------------------------------------
884   Standard_Boolean YaBouchon = Standard_False;
885
886   for (Standard_Integer i = IB ; i < n; i++) {
887     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
888     if (!SF.IsNull()) {
889       YaBouchon = Standard_True;
890       B.AddFace(TopoDS::Face(SF));
891     }
892   }
893
894 //  Clock.Start();
895
896   if (!YaBouchon)  B.MakeOffsetShape();
897   else             B.MakeThickSolid ();
898 //  Clock.Show();
899
900   DBRep::Set(a[1],B.Shape());
901
902   return 0;
903 }
904
905 static BRepOffset_MakeOffset TheOffset;
906 static Standard_Real         TheRadius;
907 static Standard_Boolean      theYaBouchon;
908 static Standard_Real         TheTolerance = Precision::Confusion();
909 static Standard_Boolean      TheInter     = Standard_False;
910 static GeomAbs_JoinType      TheJoin      = GeomAbs_Arc;
911
912 Standard_Integer offsetparameter(Draw_Interpretor& di,
913                                  Standard_Integer n, const char** a)
914 {
915   if ( n == 1 ) { 
916     //cout << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << endl;
917     //cout << " Current Values" << endl;
918     //cout << "   --> Tolerance :" << TheTolerance << endl;
919     //cout << "   --> TheInter  :";
920     di << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << "\n";
921     di << " Current Values" << "\n";
922     di << "   --> Tolerance :" << TheTolerance << "\n";
923     di << "   --> TheInter  :";
924     if ( TheInter) {
925       //cout << "Complet" ;
926       di << "Complet" ;
927     } else {
928       //cout << "Partial";
929       di << "Partial";
930     }
931     //cout << endl << "   --> TheJoin   :";
932     di << "\n" << "   --> TheJoin   :";
933     
934     switch (TheJoin) {
935     //case GeomAbs_Arc:          cout << " Arc";          break;
936     //case GeomAbs_Intersection: cout << " Intersection"; break;
937     case GeomAbs_Arc:          di << " Arc";          break;
938     case GeomAbs_Intersection: di << " Intersection"; break;
939 #ifndef DEB
940     default:
941       break ;
942 #endif
943     }
944     //cout << endl;
945     di << "\n";
946
947     return 0;
948   }
949
950   if ( n < 4 ) return 1;
951   
952   TheTolerance = atof(a[1]);
953   TheInter     = strcmp(a[2],"p");
954   
955   if      ( !strcmp(a[3],"a")) TheJoin = GeomAbs_Arc;
956   else if ( !strcmp(a[3],"i")) TheJoin = GeomAbs_Intersection;
957   else if ( !strcmp(a[3],"t")) TheJoin = GeomAbs_Tangent;
958     
959   return 0;    
960 }
961
962
963 //=======================================================================
964 //function : offsetinit
965 //purpose  : 
966 //=======================================================================
967
968 Standard_Integer offsetload(Draw_Interpretor& ,
969                             Standard_Integer n, const char** a)
970 {
971   if ( n < 2) return 1;
972   TopoDS_Shape  S  = DBRep::Get(a[1]);
973   if (S.IsNull()) return 1;
974
975   Standard_Real    Of    = atof(a[2]);
976   TheRadius = Of;
977 //  Standard_Boolean Inter = Standard_True;
978   
979   TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin);
980   //------------------------------------------
981   // recuperation et chargement des bouchons.
982   //----------------------------------------
983   for (Standard_Integer i = 3 ; i < n; i++) {
984     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
985     if (!SF.IsNull()) {
986       TheOffset.AddFace(TopoDS::Face(SF));
987     }
988   }
989   if (n < 4)  theYaBouchon = Standard_False; //B.MakeOffsetShape();
990   else        theYaBouchon = Standard_True;  //B.MakeThickSolid ();
991
992   return 0;
993 }
994
995
996 //=======================================================================
997 //function : offsetonface
998 //purpose  : 
999 //=======================================================================
1000
1001 Standard_Integer offsetonface(Draw_Interpretor&, Standard_Integer n, const char** a)
1002 {
1003   if ( n < 3) return 1;
1004
1005   for (Standard_Integer i = 1 ; i < n; i+=2) {
1006     TopoDS_Shape  SF  = DBRep::Get(a[i],TopAbs_FACE);
1007     if (!SF.IsNull()) {
1008       Standard_Real Of = atof(a[i+1]);
1009       TheOffset.SetOffsetOnFace(TopoDS::Face(SF),Of);
1010     }
1011   }
1012   
1013   return 0;
1014 }
1015
1016 //=======================================================================
1017 //function : offsetperform
1018 //purpose  : 
1019 //=======================================================================
1020
1021 Standard_Integer offsetperform(Draw_Interpretor&,
1022                                Standard_Integer n, const char** a)
1023 {
1024   if ( n < 2) return 1;
1025
1026   if (theYaBouchon) TheOffset.MakeThickSolid ();
1027   else              TheOffset.MakeOffsetShape();
1028
1029   DBRep::Set(a[1],TheOffset.Shape());
1030   
1031   return 0;
1032 }
1033
1034
1035 //=======================================================================
1036 //function : Debou
1037 //purpose  : 
1038 //=======================================================================
1039
1040 static Standard_Integer Debou(Draw_Interpretor& theCommands,
1041                               Standard_Integer narg, const char** a)
1042 {
1043   Standard_Integer i ;
1044   Standard_Integer newnarg ;
1045
1046   if (narg<7) return 1;
1047   
1048   TopoDS_Shape S = DBRep::Get(a[2]);
1049
1050   Standard_Boolean Fuse;
1051   if (!strcasecmp("F",a[3])) {
1052     Fuse = Standard_True;
1053   }
1054   else if (!strcasecmp("C",a[3])) {
1055     Fuse = Standard_False;
1056   }
1057   else {
1058     return 1;
1059   }
1060
1061   for ( newnarg = 4; newnarg < narg; newnarg++) {
1062     if (a[newnarg][0] == '@') {
1063       break;
1064     }
1065   }
1066   if (newnarg >= narg-1 || newnarg == 4) {
1067     return 1;
1068   }
1069
1070
1071   TopTools_ListOfShape LF,LF2;
1072   for ( i=4; i<newnarg; i++) {
1073     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1074     LF.Append(aLocalShape);
1075 //    LF.Append(TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE)));
1076   }
1077
1078   for (i=newnarg+1; i<narg; i++) {
1079     TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1080     LF2.Append(aLocalShape);
1081 //    LF2.Append(TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE)));
1082   }
1083
1084   BRepFeat_LocalOperation BLoc(S);
1085   BLoc.Perform(LF,LF2,Fuse);
1086   BLoc.Build();
1087   if (BLoc.IsDone()) {
1088 //    dout.Clear();
1089     DBRep::Set(a[1],BLoc);
1090     dout.Flush();
1091     return 0;
1092   }
1093   theCommands << "Local operation not done" ;
1094   return 1;
1095 }
1096
1097
1098 //=======================================================================
1099 //function : ROW
1100 //purpose  : 
1101 //=======================================================================
1102
1103 static Standard_Integer ROW(Draw_Interpretor& theCommands,
1104                             Standard_Integer narg, const char** a)
1105 {
1106   if (narg<13) return 1;
1107   TopoDS_Shape S = DBRep::Get(a[3]);
1108   BRepFeat_MakeRevol theRFace;
1109   gp_Dir D;
1110   gp_Pnt Or;
1111   Standard_Real Angle=0;
1112   TopoDS_Shape FFrom,FUntil;
1113   Standard_Integer i,borne;
1114   Standard_Boolean fuse;
1115
1116   if (a[1][0] == 'f' || a[1][0] == 'F') {
1117     fuse = Standard_True;
1118   }
1119   else if (a[1][0] == 'c' || a[1][0] == 'C') {
1120     fuse = Standard_False;
1121   }
1122   else {
1123     return 1;
1124   }
1125
1126   FFrom   = DBRep::Get(a[4],TopAbs_SHAPE);
1127   if (FFrom.IsNull()) {
1128     Angle = atof(a[4]);
1129     Angle *=M_PI/180.;
1130     i = 5;
1131   }
1132   else {
1133     FUntil = DBRep::Get(a[5],TopAbs_SHAPE);
1134     if (FUntil.IsNull()) {
1135       i = 5;
1136       FUntil = FFrom;
1137       FFrom.Nullify();
1138       
1139     }
1140     else {
1141       if (narg < 14) {
1142         return 1;
1143       }
1144       i = 6;
1145     }
1146   }
1147   borne = i+6;
1148
1149   Or.SetCoord(atof(a[i]),atof(a[i+1]),atof(a[i+2]));
1150   D.SetCoord(atof(a[i+3]),atof(a[i+4]),atof(a[i+5]));
1151   gp_Ax1 theAxis(Or,D);
1152
1153   TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
1154   TopoDS_Face F  = TopoDS::Face(aLocalShape);
1155 //  TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1156   BRepFeat_SplitShape Spls(F);
1157   for (i = borne+1; i<narg; i++) {
1158     TopoDS_Wire wir;
1159     if (a[i][0] !='-') {
1160       aLocalShape = DBRep::Get(a[i],TopAbs_WIRE);
1161       wir = TopoDS::Wire(aLocalShape);
1162 //      wir = TopoDS::Wire(DBRep::Get(a[i],TopAbs_WIRE));
1163     }
1164     else {
1165       if (a[i][1] == '\0')
1166         return 1;
1167       const char* Temp = a[i]+1;
1168       aLocalShape = DBRep::Get(Temp,TopAbs_WIRE);
1169       wir = TopoDS::Wire(aLocalShape);
1170 //      wir = TopoDS::Wire(DBRep::Get(Temp,TopAbs_WIRE));
1171       wir.Reverse();
1172     }
1173     Spls.Add(wir,F);
1174   }
1175   Spls.Build();
1176
1177   TopoDS_Shape ToRotate;
1178   const TopTools_ListOfShape& lleft = Spls.DirectLeft();
1179   if (lleft.Extent() == 1) {
1180     theRFace.Init(S,lleft.First(),F,theAxis,fuse,Standard_True);
1181     ToRotate = lleft.First();
1182   }
1183   else {
1184     BRep_Builder B;
1185     TopoDS_Shell Sh;
1186     B.MakeShell(Sh);
1187     TopTools_ListIteratorOfListOfShape it;
1188     for (it.Initialize(lleft);it.More();it.Next()) {
1189       B.Add(Sh,TopoDS::Face(it.Value()));
1190     }
1191     theRFace.Init(S,Sh,F,theAxis,fuse,Standard_True);
1192     ToRotate = Sh;
1193   }
1194
1195   // Recherche des faces de glissement
1196 //  for (TopExp_Explorer exp(S,TopAbs_FACE);exp.More();exp.Next()) {
1197   TopExp_Explorer exp(S,TopAbs_FACE) ;
1198   for ( ;exp.More();exp.Next()) {
1199     if (exp.Current().IsSame(F)) {
1200       break;
1201     }
1202   }
1203
1204   if (!exp.More()) {
1205     LocOpe_FindEdgesInFace FEIF;
1206     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1207       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1208       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1209       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1210         Su = Handle(Geom_RectangularTrimmedSurface)::
1211           DownCast(Su)->BasisSurface();
1212       }
1213       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1214         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1215         if (pl.Axis().IsParallel(theAxis,Precision::Angular())) {
1216           FEIF.Set(ToRotate,fac);
1217           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1218             theRFace.Add(FEIF.Edge(),fac);
1219           }
1220         }
1221       }
1222       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1223         gp_Cylinder cy = 
1224           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1225         if (cy.Axis().IsCoaxial(theAxis,
1226                                 Precision::Angular(),Precision::Confusion())) {
1227           FEIF.Set(ToRotate,fac);
1228           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1229             theRFace.Add(FEIF.Edge(),fac);
1230           }
1231         }
1232       }
1233     }
1234   }
1235
1236   if (borne == 11) {
1237     if (FUntil.IsNull()) {
1238       theRFace.Perform(Angle);
1239     }
1240     else {
1241       theRFace.Perform(FUntil);
1242     }
1243   }
1244   else { // borne == 12
1245     theRFace.Perform(FFrom,FUntil);
1246   }
1247
1248   if (!theRFace.IsDone()) {
1249     theCommands << "Local operation not done";
1250     return 1;
1251   }
1252
1253   DBRep::Set(a[2],theRFace);
1254   dout.Flush();
1255   return 0;
1256 }
1257
1258
1259 //=======================================================================
1260 //function : ROF
1261 //purpose  : 
1262 //=======================================================================
1263
1264 static Standard_Integer ROF(Draw_Interpretor& theCommands,
1265                             Standard_Integer narg, const char** a)
1266 {
1267   if (narg<12) return 1;
1268   TopoDS_Shape S = DBRep::Get(a[3]);
1269   BRepFeat_MakeRevol theRFace;
1270   gp_Dir D;
1271   gp_Pnt Or;
1272   Standard_Real Angle=0;
1273   TopoDS_Shape FFrom,FUntil;
1274   Standard_Integer i,borne;
1275   Standard_Boolean fuse;
1276
1277   if (a[1][0] == 'f' || a[1][0] == 'F') {
1278     fuse = Standard_True;
1279   }
1280   else if (a[1][0] == 'c' || a[1][0] == 'C') {
1281     fuse = Standard_False;
1282   }
1283   else {
1284     return 1;
1285   }
1286
1287   FFrom   = DBRep::Get(a[4],TopAbs_SHAPE);
1288   if (FFrom.IsNull()) {
1289     Angle = atof(a[4]);
1290     Angle *=M_PI/180.;
1291     i = 5;
1292   }
1293   else {
1294     FUntil = DBRep::Get(a[5],TopAbs_SHAPE);
1295     if (FUntil.IsNull()) {
1296       i = 5;
1297       FUntil = FFrom;
1298       FFrom.Nullify();
1299       
1300     }
1301     else {
1302       if (narg < 13) {
1303         return 1;
1304       }
1305       i = 6;
1306     }
1307   }
1308
1309   borne = i+6;
1310   Or.SetCoord(atof(a[i]),atof(a[i+1]),atof(a[i+2]));
1311   D.SetCoord(atof(a[i+3]),atof(a[i+4]),atof(a[i+5]));
1312   gp_Ax1 theAxis(Or,D);
1313
1314   TopoDS_Shape ToRotate;
1315   if (narg == borne+1) {
1316     TopoDS_Shape aLocalShape(DBRep::Get(a[borne],TopAbs_FACE));
1317     TopoDS_Face F  = TopoDS::Face(aLocalShape);
1318 //    TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1319     theRFace.Init(S,F,F,theAxis,fuse,Standard_True);
1320     ToRotate = F;
1321   }
1322   else {
1323     TopoDS_Shell She;
1324     BRep_Builder B;
1325     B.MakeShell(She);
1326     
1327     for (i=borne; i<narg; i++) {
1328       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_FACE));
1329       TopoDS_Face F  = TopoDS::Face(aLocalShape);
1330 //      TopoDS_Face F  = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
1331       if (!F.IsNull()) {
1332         B.Add(She,F);
1333       }
1334     }
1335     theRFace.Init(S,She,TopoDS_Face(),theAxis,fuse,Standard_False);
1336     ToRotate = She;
1337   }
1338
1339 //  for (TopExp_Explorer exp(ToRotate,TopAbs_FACE);exp.More();exp.Next()) {
1340   TopExp_Explorer exp(ToRotate,TopAbs_FACE) ;
1341   for ( ;exp.More();exp.Next()) {
1342 //    for (TopExp_Explorer exp2(S,TopAbs_FACE);exp2.More();exp2.Next()) {
1343     TopExp_Explorer exp2(S,TopAbs_FACE) ;
1344     for ( ;exp2.More();exp2.Next()) {
1345       if (exp2.Current().IsSame(exp.Current())) {
1346         break;
1347       }
1348     }
1349     if (exp2.More()) {
1350       break;
1351     }
1352   }
1353
1354   if (!exp.More()) {
1355     LocOpe_FindEdgesInFace FEIF;
1356     for (exp.Init(S,TopAbs_FACE);exp.More();exp.Next()) {
1357       const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1358       Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1359       if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1360         Su = Handle(Geom_RectangularTrimmedSurface)::
1361           DownCast(Su)->BasisSurface();
1362       }
1363       if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1364         gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1365         if (pl.Axis().IsParallel(theAxis,Precision::Angular())) {
1366           FEIF.Set(ToRotate,fac);
1367           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1368             theRFace.Add(FEIF.Edge(),fac);
1369           }
1370         }
1371       }
1372       else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1373         gp_Cylinder cy = 
1374           Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1375         if (cy.Axis().IsCoaxial(theAxis,
1376                                 Precision::Angular(),Precision::Confusion())) {
1377           FEIF.Set(ToRotate,fac);
1378           for (FEIF.Init();FEIF.More();FEIF.Next()) {
1379             theRFace.Add(FEIF.Edge(),fac);
1380           }
1381         }
1382       }
1383     }
1384   }
1385
1386   if (borne == 11) {
1387     if (FUntil.IsNull()) {
1388       theRFace.Perform(Angle);
1389     }
1390     else {
1391       theRFace.Perform(FUntil);
1392     }
1393   }
1394   else { // borne == 12
1395     theRFace.Perform(FFrom,FUntil);
1396   }
1397
1398   if (!theRFace.IsDone()) {
1399     theCommands << "Local operation not done";
1400     return 1;
1401   }
1402
1403   DBRep::Set(a[2],theRFace);
1404   dout.Flush();
1405   return 0;
1406 }
1407
1408
1409 //=======================================================================
1410 //function : GLU
1411 //purpose  : Commande glue
1412 //=======================================================================
1413
1414 static Standard_Integer GLU(Draw_Interpretor& ,
1415                             Standard_Integer narg, const char** a)
1416 {
1417   if (narg<6 || narg%2 != 0) return 1;
1418   TopoDS_Shape Sne = DBRep::Get(a[2]);
1419   TopoDS_Shape Sba = DBRep::Get(a[3]);
1420   
1421   Standard_Boolean pick;
1422   
1423   BRepFeat_Gluer theGl(Sne,Sba);
1424   TopoDS_Shape Fne,Fba;
1425   
1426   LocOpe_FindEdges fined;
1427
1428   Standard_Integer i = 4;
1429   Standard_Boolean first = Standard_True;
1430   while (i<narg) {
1431     pick = (a[i][0] == '.');
1432     Fne = DBRep::Get(a[i]);
1433     if (Fne.IsNull()) {
1434       return 1;
1435     }
1436     TopAbs_ShapeEnum sht = Fne.ShapeType();
1437     if (pick && sht != TopAbs_FACE && sht != TopAbs_EDGE) {
1438       Standard_Real u,v;
1439       DBRep_DrawableShape::LastPick(Fne,u,v);
1440       sht = Fne.ShapeType();
1441     }
1442     if (first && sht != TopAbs_FACE) {
1443       return 1;
1444     }
1445     first = Standard_False;
1446     pick = (a[i+1][0] == '.');
1447     Fba = DBRep::Get(a[i+1]);
1448     if (Fba.IsNull()) {
1449       return 1;
1450     }
1451     if (pick && Fba.ShapeType() != sht) {
1452       Standard_Real u,v;
1453       DBRep_DrawableShape::LastPick(Fba,u,v);
1454     }
1455     if (Fba.ShapeType() != sht) {
1456       return 1;
1457     }
1458     if (sht == TopAbs_FACE) {
1459       const TopoDS_Face& f1 = TopoDS::Face(Fne);
1460       const TopoDS_Face& f2 = TopoDS::Face(Fba);
1461       theGl.Bind(f1,f2);
1462       fined.Set(Fne,Fba);
1463       for (fined.InitIterator(); fined.More(); fined.Next()) {
1464         theGl.Bind(fined.EdgeFrom(),fined.EdgeTo());
1465       }
1466     }
1467     else {
1468       theGl.Bind(TopoDS::Edge(Fne),TopoDS::Edge(Fba));
1469     }
1470     i +=2;
1471   }
1472   
1473   DBRep::Set(a[1],theGl);
1474   dout.Flush();
1475   return 0;
1476 }
1477
1478 static Standard_Integer DEFIN(Draw_Interpretor& theCommands,
1479                               Standard_Integer narg, const char** a)
1480 {
1481
1482   if (strcasecmp(a[0],"FEATPRISM") &&
1483       strcasecmp(a[0],"FEATDPRISM") &&
1484       strcasecmp(a[0],"FEATREVOL") &&
1485       strcasecmp(a[0],"FEATPIPE") &&
1486       strcasecmp(a[0],"FEATLF")  &&
1487       strcasecmp(a[0],"FEATRF")) {
1488     return 1;
1489   }
1490
1491   if ((!strcasecmp(a[0],"FEATPRISM") && narg !=9) ||
1492       (!strcasecmp(a[0],"FEATREVOL") && narg != 12) ||
1493       (!strcasecmp(a[0],"FEATDPRISM") && narg != 7) ||
1494       (!strcasecmp(a[0],"FEATPIPE") && narg != 7) ||
1495       (!strcasecmp(a[0],"FEATLF") && narg != 12) ||
1496       (!strcasecmp(a[0],"FEATRF") && narg != 14)) {
1497     theCommands << "invalid number of arguments";
1498     return 1;
1499   }
1500
1501   TopoDS_Shape Sbase = DBRep::Get(a[1]);
1502   if (Sbase.IsNull()) {
1503     theCommands << "null basis shape";
1504     return 1;
1505   }
1506   Standard_Integer Ifuse  = atoi(a[narg-2]);
1507   Standard_Integer Imodif = atoi(a[narg-1]);
1508   
1509   Standard_Integer Fuse = Ifuse;
1510   Standard_Boolean Modify = (Imodif!=0);
1511
1512   TopoDS_Shape Pbase;
1513   TopoDS_Face Skface;
1514   TopoDS_Wire W;
1515
1516   Handle(Geom_Plane) P;
1517
1518   BRepFeat_StatusError se;
1519
1520   if (strcasecmp(a[0],"FEATLF") && strcasecmp(a[0],"FEATRF")) {
1521     Pbase = DBRep::Get(a[2]);
1522     if (Pbase.IsNull()) {
1523       theCommands << "null shape to transform";
1524       return 1;
1525     }
1526     TopoDS_Shape aLocalShape(DBRep::Get(a[3],TopAbs_FACE));
1527     Skface = TopoDS::Face(aLocalShape);
1528 //    Skface = TopoDS::Face(DBRep::Get(a[3],TopAbs_FACE));
1529     if (Skface.IsNull()) {
1530       theCommands << "null face of Sketch";
1531       return 1;
1532     }
1533   }
1534   else {
1535     TopoDS_Shape aLocalShape(DBRep::Get(a[2], TopAbs_WIRE));
1536     W = TopoDS::Wire(aLocalShape);
1537 //    W = TopoDS::Wire(DBRep::Get(a[2], TopAbs_WIRE));
1538     if(W.IsNull()) {
1539       theCommands << "null profile for rib or slot";
1540       return 1;
1541     }
1542     Handle(Geom_Surface) s = DrawTrSurf::GetSurface(a[3]);
1543     P = Handle(Geom_Plane)::DownCast(s);
1544     if(P.IsNull()) {
1545       theCommands << "null plane to transform";
1546       return 1;
1547     }
1548   }
1549   if (narg == 9 || narg == 12 || narg == 14) {
1550 //    Standard_Real X,Y,Z,X1,Y1,Z1;
1551     Standard_Real X,Y,Z;
1552     X = atof(a[4]);
1553     Y = atof(a[5]);
1554     Z = atof(a[6]);
1555     
1556     if (narg == 9) { // prism
1557       prdef = Standard_True;      
1558       thePrism.Init(Sbase,Pbase,Skface,gp_Dir(X,Y,Z),Fuse,Modify);
1559     }
1560     else if(narg == 14) {
1561       rfdef = Standard_True;
1562       gp_Pnt Or(X, Y, Z);
1563       X = atof(a[7]);
1564       Y = atof(a[8]);
1565       Z = atof(a[9]);
1566       Standard_Real H1 = atof(a[10]);
1567       Standard_Real H2 = atof(a[11]);
1568       gp_Ax1 ax1(Or, gp_Dir(X, Y, Z));
1569       theRF.Init(Sbase, W, P, ax1, H1, H2, Fuse, Modify);
1570       if (!theRF.IsDone()) {
1571         se = theRF.CurrentStatusError();
1572         //BRepFeat::Print(se,cout) << endl;
1573         Standard_SStream aSStream;
1574         BRepFeat::Print(se,aSStream);
1575         theCommands << aSStream << "\n";
1576         return 1;
1577       }
1578     }
1579     else if(narg == 12 && strcasecmp(a[0],"FEATLF")) {
1580       rvdef = Standard_True;
1581       gp_Pnt Or(X,Y,Z);
1582       X = atof(a[7]);
1583       Y = atof(a[8]);
1584       Z = atof(a[9]);
1585       theRevol.Init(Sbase,Pbase,Skface,gp_Ax1(Or,gp_Dir(X,Y,Z)),
1586                     Fuse,Modify);
1587     }
1588     else {
1589       lfdef = Standard_True;
1590       gp_Vec Direct(X,Y,Z);
1591       X = atof(a[7]);
1592       Y = atof(a[8]);
1593       Z = atof(a[9]);
1594       theLF.Init(Sbase, W, P, Direct, gp_Vec(X,Y,Z), Fuse,Modify);
1595       if (!theLF.IsDone()) {
1596         se = theLF.CurrentStatusError();
1597         //BRepFeat::Print(se,cout) << endl;
1598         Standard_SStream aSStream;
1599         BRepFeat::Print(se,aSStream);
1600         theCommands << aSStream << "\n";
1601         return 1;
1602       }
1603     }
1604   }
1605   else if (narg == 7) {
1606     if (!strcasecmp(a[0],"FEATDPRISM")) {
1607       if (Pbase.ShapeType() != TopAbs_FACE) {
1608         theCommands << "Invalid DPrism base";
1609         return 1;
1610       }
1611       Standard_Real Angle = atof(a[4])*M_PI/360; 
1612       dprdef = Standard_True;
1613       theDPrism.Init(Sbase,TopoDS::Face(Pbase),Skface,Angle,Fuse,Modify);
1614     }
1615     else { // FEATPIPE
1616       TopoDS_Shape aLocalShape(DBRep::Get(a[4],TopAbs_WIRE));
1617       TopoDS_Wire Spine = TopoDS::Wire(aLocalShape);
1618 //      TopoDS_Wire Spine = TopoDS::Wire(DBRep::Get(a[4],TopAbs_WIRE));
1619       if (Spine.IsNull()) {
1620         TopoDS_Shape Edspine =DBRep::Get(a[4],TopAbs_EDGE);
1621         if (Edspine.IsNull()) {
1622           theCommands << "null spine";
1623           return 1;
1624         }
1625         BRep_Builder B;
1626         B.MakeWire(Spine);
1627         B.Add(Spine,Edspine);
1628       }
1629       pidef = Standard_True;
1630       thePipe.Init(Sbase,Pbase,Skface,Spine,Fuse,Modify);
1631     }
1632   }
1633   return 0;
1634 }
1635
1636
1637
1638 static Standard_Integer ADD(Draw_Interpretor& ,
1639                             Standard_Integer narg, const char** a)
1640 {
1641   Standard_Integer i ;
1642   if (narg < 4 || narg%2 != 0) {
1643     return 1;
1644   }
1645   if (!strcasecmp("PRISM",a[1])) {
1646     if (!prdef) {
1647       return 1;
1648     }
1649     for ( i=2; i<narg; i+=2) {
1650       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1651       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1652 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1653       if (edg.IsNull()) {
1654         return 1;
1655       }
1656       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1657       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1658 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1659       if (fac.IsNull()) {
1660         return 1;
1661       }
1662       thePrism.Add(edg,fac);
1663     }
1664   }
1665   else if (!strcasecmp("REVOL",a[1])) {
1666     if (!rvdef) {
1667       return 1;
1668     }
1669     for ( i=2; i<narg; i+=2) {
1670       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1671       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1672 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1673       if (edg.IsNull()) {
1674         return 1;
1675       }
1676       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1677       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1678 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1679       if (fac.IsNull()) {
1680         return 1;
1681       }
1682       theRevol.Add(edg,fac);
1683     }
1684   }
1685   else if (!strcasecmp("PIPE",a[1])) {
1686     if (!pidef) {
1687       return 1;
1688     }
1689     for ( i=2; i<narg; i+=2) {
1690       TopoDS_Shape aLocalShape(DBRep::Get(a[i],TopAbs_EDGE));
1691       TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1692 //      TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1693       if (edg.IsNull()) {
1694         return 1;
1695       }
1696       aLocalShape = DBRep::Get(a[i+1],TopAbs_FACE);
1697       TopoDS_Face fac = TopoDS::Face(aLocalShape);
1698 //      TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1699       if (fac.IsNull()) {
1700         return 1;
1701       }
1702       thePipe.Add(edg,fac);
1703     }
1704   }
1705   else {
1706     return 1;
1707   }
1708   return 0;
1709 }
1710
1711
1712
1713 static Standard_Integer PERF(Draw_Interpretor& theCommands,
1714                             Standard_Integer narg, const char** a)
1715 {
1716   if (narg < 3) {
1717     return 1;
1718   }
1719   if (strcasecmp(a[0],"FEATPERFORM") &&
1720       strcasecmp(a[0],"FEATPERFORMVAL")) {
1721     return 1;
1722   }
1723
1724   Standard_Integer Kas;
1725   if (!strcasecmp("PRISM",a[1])) {
1726     Kas = 1;
1727     if (!prdef) {
1728       theCommands << "prism not defined";
1729       return 1;
1730     }
1731   }
1732   else if (!strcasecmp("REVOL",a[1])) {
1733     Kas = 2;
1734     if (!rvdef) {
1735       theCommands << "revol not defined";
1736       return 1;
1737     }
1738   }
1739   else if (!strcasecmp("PIPE",a[1])) {
1740     Kas = 3;
1741     if (!pidef) {
1742       theCommands << "pipe not defined";
1743       return 1;
1744     }
1745     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1746       theCommands << "invalid command for pipe";
1747       return 1;
1748     }
1749   }
1750   else if (!strcasecmp("DPRISM",a[1])) {
1751     Kas = 4;
1752     if (!dprdef) {
1753       theCommands << "dprism not defined";
1754       return 1;
1755     }
1756   }
1757   else if (!strcasecmp("LF",a[1])) {
1758     Kas = 5;
1759     if (!lfdef) {
1760       theCommands << "lf not defined";
1761       return 1;
1762     }
1763     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1764       theCommands << "invalid command for lf";
1765       return 1;
1766     }
1767   }
1768   else if (!strcasecmp("RF",a[1])) {
1769     Kas = 6;
1770     if (!rfdef) {
1771       theCommands << "rf not defined";
1772       return 1;
1773     }
1774     if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1775       theCommands << "invalid command for rf";
1776       return 1;
1777     }
1778   }
1779   else {
1780     theCommands << "unknown argument : " << a[1];
1781     return 1;
1782   }
1783
1784   if (!strcasecmp(a[0],"FEATPERFORMVAL")) {
1785     if (narg !=4 && narg != 5) {
1786       theCommands << "invalid number of arguments";
1787       return 1;
1788     }
1789     if (narg == 4) {
1790       Standard_Real Val = atof(a[3]);
1791       if (Kas == 1) {
1792         thePrism.Perform(Val);
1793       }
1794       else if (Kas == 2) {
1795         Val *=(M_PI/180.);
1796         theRevol.Perform(Val);
1797       }
1798       else if (Kas == 4) {
1799         theDPrism.Perform(Val);
1800       }
1801       else if (Kas == 5) {
1802         theCommands << "invalid command for lf";
1803         return 1;
1804       }
1805       else if (Kas == 6) {
1806         theCommands << "invalid command for rf";
1807         return 1;
1808       }
1809     }
1810     else if(narg == 5) {
1811       Standard_Real Val = atof(a[3]);
1812       TopoDS_Shape FUntil = DBRep::Get(a[4],TopAbs_SHAPE);
1813       if (Kas == 1) {
1814         thePrism.PerformUntilHeight(FUntil, Val);
1815       }
1816       else if (Kas == 2) {
1817         Val *=(M_PI/180.);
1818         theRevol.PerformUntilAngle(FUntil, Val);
1819       }
1820       else if (Kas == 4) {
1821         theDPrism.PerformUntilHeight(FUntil, Val);
1822       } 
1823       else {
1824         theCommands << "invalid command for ribs or slots";
1825         return 1;
1826       }
1827     }
1828   }
1829   else if (!strcasecmp(a[0],"FEATPERFORM")) {
1830     if (narg == 3) { // Thru all
1831       switch (Kas) {
1832       case 1:
1833         thePrism.PerformThruAll();
1834         break;
1835       case 2:
1836         theRevol.PerformThruAll();
1837         break;
1838       case 3:
1839         thePipe.Perform();
1840         break;
1841       case 4:
1842         theDPrism.PerformThruAll();
1843         break;
1844       case 5:
1845         theLF.Perform();
1846         break;
1847       case 6:
1848         theRF.Perform();
1849         break;
1850       default:
1851
1852         return 1;
1853       }
1854     }
1855     else if (narg == 4) { // Until
1856       TopoDS_Shape Funtil = DBRep::Get(a[3],TopAbs_SHAPE);
1857       switch (Kas) {
1858       case 1:
1859         {
1860           if (Funtil.IsNull()) {
1861             thePrism.PerformUntilEnd();
1862           }
1863           else {
1864             thePrism.Perform(Funtil);
1865           }
1866         }
1867         break;
1868       case 2:
1869         {
1870           if (!Funtil.IsNull()) {
1871             theRevol.Perform(Funtil);
1872           }
1873           else {
1874             return 1;
1875           }
1876         }
1877         break;
1878       case 3:
1879         {
1880           if (!Funtil.IsNull()) {
1881             thePipe.Perform(Funtil);
1882           }
1883           else {
1884             theCommands << "invalid command for ribs pipe";
1885             return 1;
1886           }
1887         }
1888         break;
1889       case 4:
1890         {
1891           if (!Funtil.IsNull()) {
1892             theDPrism.Perform(Funtil);
1893           }
1894           else {
1895             theDPrism.PerformUntilEnd();
1896           }
1897         }
1898         break;
1899       case 5:
1900         {  
1901           theCommands << "invalid command for lf";
1902           return 1;
1903         }
1904         break;
1905       case 6:
1906         {  
1907           theCommands << "invalid command for rf";
1908           return 1;
1909         }
1910         break;
1911       default:
1912         return 1;
1913       }
1914     }
1915     else if (narg == 5) {
1916       TopoDS_Shape Ffrom = DBRep::Get(a[3],TopAbs_SHAPE);
1917       TopoDS_Shape Funtil = DBRep::Get(a[4],TopAbs_SHAPE);
1918       if (Funtil.IsNull()) {
1919         return 1;
1920       }
1921       switch (Kas) {
1922       case 1:
1923         {
1924           if (Ffrom.IsNull()) {
1925             thePrism.PerformFromEnd(Funtil);
1926           }
1927           else {
1928             thePrism.Perform(Ffrom,Funtil);
1929           }
1930         }
1931         break;
1932       case 2:
1933         {
1934           if (Ffrom.IsNull()) {
1935             return 1;
1936           }
1937           theRevol.Perform(Ffrom,Funtil);
1938         }
1939         break;
1940       case 3:
1941         {
1942           if (Ffrom.IsNull()) {
1943             return 1;
1944           }
1945           thePipe.Perform(Ffrom,Funtil);
1946         }
1947         break;
1948       case 4:
1949         {
1950           if (Ffrom.IsNull()) {
1951             theDPrism.PerformFromEnd(Funtil);
1952           }
1953           else {
1954             theDPrism.Perform(Ffrom,Funtil);
1955           }
1956         }
1957         break;
1958
1959       default:
1960         return 1;
1961       }
1962     }
1963   }
1964
1965   BRepFeat_StatusError se;
1966   switch (Kas) {
1967   case 1:
1968     if (!thePrism.IsDone()) {
1969       se = thePrism.CurrentStatusError();
1970       //BRepFeat::Print(se,cout) << endl;
1971       Standard_SStream aSStream;
1972       BRepFeat::Print(se,aSStream);
1973       theCommands << aSStream << "\n";
1974       return 1;
1975     }
1976     DBRep::Set(a[2],thePrism);
1977     dout.Flush();
1978     return 0;
1979   case 2:
1980     if (!theRevol.IsDone()) {
1981       se = theRevol.CurrentStatusError();
1982       //BRepFeat::Print(se,cout) << endl;
1983       Standard_SStream aSStream;
1984       BRepFeat::Print(se,aSStream);
1985       theCommands << aSStream << "\n";
1986       return 1;
1987     }
1988     DBRep::Set(a[2],theRevol);
1989     dout.Flush();
1990     return 0;
1991   case 3:
1992     if (!thePipe.IsDone()) {
1993       se = thePipe.CurrentStatusError();
1994       //BRepFeat::Print(se,cout) << endl;
1995       Standard_SStream aSStream;
1996       BRepFeat::Print(se,aSStream);
1997       theCommands << aSStream << "\n";
1998       return 1;
1999     }
2000     DBRep::Set(a[2],thePipe);
2001     dout.Flush();
2002     return 0;
2003   case 4:
2004     if (!theDPrism.IsDone()) {
2005       se = theDPrism.CurrentStatusError();
2006       //BRepFeat::Print(se,cout) << endl;
2007       Standard_SStream aSStream;
2008       BRepFeat::Print(se,aSStream);
2009       theCommands << aSStream << "\n";
2010       return 1;
2011     }
2012     DBRep::Set(a[2],theDPrism);
2013     dout.Flush();
2014     return 0;
2015   case 5:
2016     if (!theLF.IsDone()) {
2017       se = theLF.CurrentStatusError();
2018       //BRepFeat::Print(se,cout) << endl;
2019       Standard_SStream aSStream;
2020       BRepFeat::Print(se,aSStream);
2021       theCommands << aSStream << "\n";
2022       return 1;
2023     }
2024     DBRep::Set(a[2],theLF);
2025     dout.Flush();
2026     return 0;
2027   case 6:
2028     if (!theRF.IsDone()) {
2029       se = theRF.CurrentStatusError();
2030       //BRepFeat::Print(se,cout) << endl;
2031       Standard_SStream aSStream;
2032       BRepFeat::Print(se,aSStream);
2033       theCommands << aSStream << "\n";
2034       return 1;
2035     }
2036     DBRep::Set(a[2],theRF);
2037     dout.Flush();
2038     return 0;
2039   default:
2040     return 1;
2041   }
2042 }
2043
2044
2045 static Standard_Integer BOSS(Draw_Interpretor& theCommands,
2046                              Standard_Integer narg, const char** a)
2047 {
2048   if (strcasecmp(a[0],"ENDEDGES") && strcasecmp(a[0],"FILLET")
2049       && strcasecmp(a[0],"BOSSAGE")) {
2050     return 1;
2051   }
2052
2053   if ((!strcasecmp(a[0],"ENDEDGES") && narg !=5) ||
2054       (!strcasecmp(a[0],"FILLET") && narg <5 &&  narg%2 != 1) ||
2055       (!strcasecmp(a[0],"BOSSAGE") && narg != 6)) {
2056     theCommands << "invalid number of arguments";
2057     return 1;
2058   }
2059
2060   Standard_Integer Kas=0;
2061   Standard_Integer dprsig=0;
2062   if (!strcasecmp("ENDEDGES",a[0])) {
2063     Kas = 1;
2064     dprsig = atoi(a[4]);
2065   }
2066   else if (!strcasecmp("FILLET",a[0])) {
2067     Kas = 2;
2068   }
2069   else if (!strcasecmp("BOSSAGE",a[0])) {
2070     Kas = 3;
2071     dprsig = atoi(a[5]);
2072   }
2073  
2074   TopoDS_Shape theShapeTop; 
2075   TopoDS_Shape theShapeBottom;
2076
2077   if (Kas == 1 || Kas == 3) {
2078     if (!strcasecmp("DPRISM",a[1])) {
2079       if (!dprdef) {
2080         theCommands << "dprism not defined";
2081         return 1;
2082       }
2083     }
2084     else {
2085       theCommands << "unknown argument : " << a[1];
2086       return 1;
2087     }
2088
2089     theDPrism.BossEdges(dprsig);
2090    
2091     TopTools_ListOfShape theTopEdges, theLatEdges;
2092     theTopEdges = theDPrism.TopEdges();
2093     theLatEdges = theDPrism.LatEdges();
2094
2095     TopTools_ListIteratorOfListOfShape it;
2096     BRep_Builder B;
2097
2098     B.MakeCompound(TopoDS::Compound(theShapeTop));
2099     it.Initialize(theTopEdges);
2100     for(; it.More(); it.Next()) {
2101       TopExp_Explorer exp;
2102       for (exp.Init(it.Value(),TopAbs_EDGE); exp.More(); exp.Next()) {
2103         B.Add(theShapeTop,exp.Current());
2104       }
2105     }
2106     DBRep::Set(a[2],theShapeTop);
2107     dout.Flush();
2108
2109     B.MakeCompound(TopoDS::Compound(theShapeBottom));
2110     it.Initialize(theLatEdges);
2111     for(; it.More(); it.Next()) {
2112       B.Add(theShapeBottom,it.Value());
2113     }
2114     DBRep::Set(a[3],theShapeBottom);
2115     dout.Flush();
2116     if (Kas == 1) return 0;
2117   }
2118
2119   if (Kas == 2 || Kas == 3) {
2120     
2121 //    Standard_Integer nrad;
2122     TopoDS_Shape V;
2123     if (Kas == 2) {
2124       V = DBRep::Get(a[2],TopAbs_SHAPE);
2125     }
2126     else if (Kas == 3) {
2127       V = theDPrism;
2128     }
2129
2130     if(V.IsNull()) return 1;
2131     ChFi3d_FilletShape FSh = ChFi3d_Rational;
2132     Rakk = new BRepFilletAPI_MakeFillet(V,FSh);
2133     Rakk->SetParams(ta,t3d,t2d,t3d,t2d,fl);
2134     Rakk->SetContinuity(blend_cont, tapp_angle);
2135     Standard_Real Rad;
2136     TopoDS_Shape S;
2137     TopoDS_Edge E;
2138     Standard_Integer nbedge = 0;
2139
2140     if (Kas == 2) {
2141       for (Standard_Integer ii = 1; ii < (narg-1)/2; ii++){
2142         Rad = atof(a[2*ii + 1]);
2143         if (Rad == 0.) continue;
2144         S = DBRep::Get(a[(2*ii+2)],TopAbs_SHAPE);
2145         TopExp_Explorer exp;
2146         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2147           E = TopoDS::Edge(exp.Current());
2148           if(!E.IsNull()){
2149             Rakk->Add(Rad,E);
2150             nbedge++;
2151           }
2152         }
2153       }
2154     }
2155     else if (Kas == 3) {
2156       Rad = atof(a[3]);
2157       if (Rad != 0.) {
2158         S = theShapeTop;
2159         TopExp_Explorer exp;
2160         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2161           E = TopoDS::Edge(exp.Current());
2162           if(!E.IsNull()){
2163             Rakk->Add(Rad,E);
2164             nbedge++;
2165           }
2166         } 
2167       }
2168       Rad = atof(a[4]);
2169       if (Rad != 0.) {
2170         S = theShapeBottom;
2171         TopExp_Explorer exp;
2172         for (exp.Init(S,TopAbs_EDGE); exp.More(); exp.Next()) {
2173           E = TopoDS::Edge(exp.Current());
2174           if(!E.IsNull()){
2175             Rakk->Add(Rad,E);
2176             nbedge++;
2177           }
2178         } 
2179       }
2180     }
2181     
2182     if(!nbedge) return 1;
2183     Rakk->Build();
2184     if(!Rakk->IsDone()) return 1;
2185     TopoDS_Shape res = Rakk->Shape();
2186
2187     if (Kas == 2) {
2188       DBRep::Set(a[1],res);
2189     } 
2190     else if (Kas == 3) {
2191       DBRep::Set(a[2],res);
2192     }
2193     dout.Flush();
2194     return 0;
2195   }
2196
2197   return 1;
2198 }
2199
2200
2201 //=======================================================================
2202 //function : FeatureCommands
2203 //purpose  : 
2204 //=======================================================================
2205
2206 void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
2207 {
2208   static Standard_Boolean done = Standard_False;
2209   if (done) return;
2210   done = Standard_True;
2211
2212   DBRep::BasicCommands(theCommands);
2213
2214   const char* g = "TOPOLOGY Feature commands";
2215
2216   theCommands.Add("localope", 
2217                   " Performs a local top. operation : localope result shape tool F/C (fuse/cut) face [face...]",
2218                   __FILE__,Loc,g);
2219
2220   theCommands.Add("hole",
2221                   " Performs a hole : hole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius [Pfrom Pto]",
2222                   __FILE__,HOLE1,g);
2223
2224   theCommands.Add("firsthole",
2225                   " Performs the first hole : firsthole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2226                   __FILE__,HOLE2,g);
2227
2228   theCommands.Add("holend",
2229                   " Performs the hole til end : holend result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2230                   __FILE__,HOLE3,g);
2231
2232   theCommands.Add("blindhole", 
2233                   " Performs the blind hole : blindhole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius Length",
2234                   __FILE__,HOLE4,g);
2235
2236   theCommands.Add("holecontrol",
2237                   "Sets/Unsets or display controls on holes : holecontrol [0/1]",
2238                   __FILE__,CONTROL,g);
2239
2240   theCommands.Add("wprism",
2241                   "Prisms wires on a face : wprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ  SkecthFace wire1 [wire2 ....]",
2242                   __FILE__,PRW,g);
2243
2244
2245   theCommands.Add("fprism", 
2246                   "Prisms a set of faces of a shape : fprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ face1 [face2...]",
2247                   __FILE__,PRF,g);
2248
2249
2250   theCommands.Add("wrotate",
2251                   "Rotates wires on a face : wrotate f[use]/c[ut] result shape Angle/[FFrom] FUntil OX OY OZ DX DY DZ SkecthFace wire1 [wire2 ....]",
2252                   __FILE__,ROW,g);
2253
2254
2255   theCommands.Add("frotate", 
2256                   "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...]",
2257                   __FILE__,ROF,g);
2258
2259
2260   theCommands.Add("splitshape",
2261                   "splitshape result shape face wire/edge/compound [wire/edge/compound ...][face wire/edge/compound [wire/edge/compound...] ...] [@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]",
2262                   __FILE__,SPLS,g);
2263
2264
2265   theCommands.Add("thickshell",
2266                   "thickshell r shape offset [jointype [tol] ]",
2267                   __FILE__,thickshell,g);
2268   
2269   theCommands.Add("offsetshape",
2270                   "offsetshape r shape offset [tol] [face ...]",
2271                   __FILE__,offsetshape,g);
2272   
2273   theCommands.Add("offsetcompshape",
2274                   "offsetcompshape r shape offset [face ...]",
2275                   __FILE__,offsetshape,g);
2276
2277   theCommands.Add("offsetparameter",
2278                   "offsetparameter tol inter(a/i) join(a/i)",
2279                   __FILE__,offsetparameter);
2280
2281   theCommands.Add("offsetload",
2282                   "offsetload shape offset bouchon1 bouchon2 ...",
2283                   __FILE__,offsetload,g);
2284
2285   theCommands.Add("offsetonface",
2286                   "offsetonface face1 offset1 face2 offset2 ...",
2287                   __FILE__,offsetonface,g);
2288
2289   theCommands.Add("offsetperform",
2290                   "offsetperform result",
2291                   __FILE__,offsetperform,g);
2292
2293
2294   theCommands.Add("deboucle", 
2295                   " Essai de debouclage partiel: deboucle result shape F/C face [face...] @ face [face...]",
2296                   __FILE__,Debou,g);
2297
2298
2299   theCommands.Add("glue", 
2300                   "glue result shapenew shapebase facenew facebase [facenew facebase...] [edgenew edgebase [edgenew edgebase...]]",
2301                   __FILE__,GLU,g);
2302
2303
2304   theCommands.Add("featprism", 
2305                   "Defines the arguments for a prism : featprism shape element skface  Dirx Diry Dirz Fuse(0/1/2) Modify(0/1)",
2306                   __FILE__,DEFIN);
2307
2308   theCommands.Add("featrevol", 
2309                   "Defines the arguments for a revol : featrevol shape element skface  Ox Oy Oz Dx Dy Dz Fuse(0/1/2) Modify(0/1)",
2310                   __FILE__,DEFIN);
2311
2312   theCommands.Add("featpipe", 
2313                   "Defines the arguments for a pipe : featpipe shape element skface  spine Fuse(0/1/2) Modify(0/1)",
2314                   __FILE__,DEFIN);
2315
2316   theCommands.Add("featdprism", 
2317                   "Defines the arguments for a drafted prism : featdprism shape face skface angle Fuse(0/1/2) Modify(0/1)",
2318                   __FILE__,DEFIN);
2319
2320   theCommands.Add("featlf", 
2321                   "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)",
2322                   __FILE__,DEFIN);
2323
2324   theCommands.Add("featrf", 
2325                   "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)",
2326                   __FILE__,DEFIN);
2327
2328   theCommands.Add("addslide", 
2329                   " Adds sliding elements : addslide prism/revol/pipe edge face [edge face...]",
2330                   __FILE__,ADD);
2331
2332   theCommands.Add("featperform", 
2333                   " Performs the prism revol dprism linform or pipe :featperform prism/revol/pipe/dprism/lf result [[Ffrom] Funtil]",
2334                   __FILE__,PERF);
2335
2336   theCommands.Add("featperformval", 
2337                   " Performs the prism revol dprism or linform with a value :featperformval prism/revol/dprism/lf result value",
2338                   __FILE__,PERF);
2339
2340   theCommands.Add("endedges", 
2341                   " Return top and bottom edges of dprism :endedges dprism shapetop shapebottom First/LastShape (1/2)",
2342                   __FILE__,BOSS);
2343
2344   theCommands.Add("fillet", 
2345                   " Perform fillet on compounds of edges :fillet result object rad1 comp1 rad2 comp2 ...",
2346                   __FILE__,BOSS);
2347
2348   theCommands.Add("bossage", 
2349                   " Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)",
2350                   __FILE__,BOSS);
2351
2352 }