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