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