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