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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Draw_Interpretor.hxx>
18 #include <Draw_Appli.hxx>
19 #include <DrawTrSurf.hxx>
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>
33 #include <Geom_RectangularTrimmedSurface.hxx>
34 #include <Geom_Plane.hxx>
35 #include <Geom_CylindricalSurface.hxx>
38 #include <gp_Cylinder.hxx>
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>
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>
54 #include <LocOpe_FindEdges.hxx>
55 #include <LocOpe_FindEdgesInFace.hxx>
57 #include <BRepOffset_MakeOffset.hxx>
58 #include <BRepOffset_MakeSimpleOffset.hxx>
59 #include <BRep_Tool.hxx>
60 #include <BRep_Builder.hxx>
62 #include <DBRep_DrawableShape.hxx>
63 #include <BRepTest.hxx>
64 #include <BRepTest_Objects.hxx>
66 #include <BRepFilletAPI_MakeFillet.hxx>
67 #include <ChFi3d_FilletShape.hxx>
68 #include <Message.hxx>
70 #include <Precision.hxx>
73 //#define strcasecmp _stricmp Already defined
74 Standard_IMPORT Draw_Viewer dout;
77 static BRepFeat_MakeCylindricalHole theHole;
78 static Standard_Boolean WithControl = Standard_True;
80 Standard_Boolean DownCastingEnforcing = Standard_False;
82 static BRepFeat_MakePrism thePrism;
83 static BRepFeat_MakeDPrism theDPrism;
84 static BRepFeat_MakeRevol theRevol;
85 static BRepFeat_MakePipe thePipe;
86 static BRepFeat_MakeLinearForm theLF;
87 static BRepFeat_MakeRevolutionForm theRF;
89 //Input shapes for Prism, DPrism, Revol, Pipe
90 static TopoDS_Shape theSbase, thePbase;
91 static TopoDS_Face theSkface;
93 static Standard_Boolean dprdef = Standard_False;
94 static Standard_Boolean prdef = Standard_False;
95 static Standard_Boolean rvdef = Standard_False;
96 static Standard_Boolean pidef = Standard_False;
97 static Standard_Boolean lfdef = Standard_False;
98 static Standard_Boolean rfdef = Standard_False;
100 static Standard_Real t3d = 1.e-4;
101 static Standard_Real t2d = 1.e-5;
102 static Standard_Real ta = 1.e-2;
103 static Standard_Real fl = 1.e-3;
104 static Standard_Real tapp_angle = 1.e-2;
105 static GeomAbs_Shape blend_cont = GeomAbs_C1;
106 static BRepFilletAPI_MakeFillet* Rakk = 0;
110 static void Print(Draw_Interpretor& di,
111 const BRepFeat_Status St)
113 di << " Error Status : ";
115 case BRepFeat_NoError:
119 case BRepFeat_InvalidPlacement:
120 di << "Invalid placement";
123 case BRepFeat_HoleTooLong:
124 di << "Hole too long";
129 static Standard_Integer Loc(Draw_Interpretor& theCommands,
130 Standard_Integer narg, const char** a)
132 if (narg < 6) return 1;
133 TopoDS_Shape S = DBRep::Get(a[2]);
134 TopoDS_Shape T = DBRep::Get(a[3]);
136 Standard_Boolean Fuse;
137 if (!strcasecmp("F", a[4])) {
138 Fuse = Standard_True;
140 else if (!strcasecmp("C", a[4])) {
141 Fuse = Standard_False;
147 TopTools_ListOfShape LF;
148 for (Standard_Integer i = 0; i <= narg - 6; i++) {
149 TopoDS_Shape aLocalShape(DBRep::Get(a[i + 5], TopAbs_FACE));
150 LF.Append(aLocalShape);
151 // LF.Append(TopoDS::Face(DBRep::Get(a[i+5],TopAbs_FACE)));
154 //BRepFeat_LocalOperation BLoc(S);
155 //BLoc.Perform(T,LF,Fuse);
156 //BLoc.BuildPartsOfTool();
157 TopTools_ListOfShape parts;
158 BRepFeat_Builder BLoc;
160 BLoc.SetOperation(Fuse);
161 //BRepFeat_LocalOperation BLoc;
162 //BLoc.Init(S,T,Fuse);
164 BLoc.PartsOfTool(parts);
168 strcpy(newname, a[1]);
170 while (*p != '\0') p++;
173 TopTools_ListIteratorOfListOfShape its(parts);
176 for (; its.More(); its.Next()) {
179 DBRep::Set(newname, its.Value());
183 Standard_Integer qq, ww, ee, button;
186 TopoDS_Shape aLocalShape(DBRep::Get(".", TopAbs_SHELL));
187 S = TopoDS::Shell(aLocalShape);
188 // S = TopoDS::Shell(DBRep::Get(".",TopAbs_SHELL));
189 Draw::LastPick(qq, ww, ee, button);
194 //BLoc.RemovePart(S);
207 } while (button != 3);
210 BLoc.PerformResult();
211 if (!BLoc.HasErrors()) {
213 DBRep::Set(a[1], BLoc.Shape());
217 theCommands << "Local operation not done";
223 static Standard_Integer HOLE1(Draw_Interpretor& theCommands,
224 Standard_Integer narg, const char** a)
226 if (narg < 10 || narg == 11) return 1;
227 TopoDS_Shape S = DBRep::Get(a[2]);
229 gp_Pnt Or(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
230 gp_Dir Di(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
232 Standard_Real Radius = Draw::Atof(a[9]);
234 theHole.Init(S, gp_Ax1(Or, Di));
237 theHole.Perform(Radius);
240 Standard_Real pfrom = Draw::Atof(a[10]);
241 Standard_Real pto = Draw::Atof(a[11]);
242 theHole.Perform(Radius, pfrom, pto, WithControl);
246 if (!theHole.HasErrors()) {
248 DBRep::Set(a[1], theHole.Shape());
252 theCommands << "Echec de MakeCylindricalHole";
253 Print(theCommands, theHole.Status());
257 static Standard_Integer HOLE2(Draw_Interpretor& theCommands,
258 Standard_Integer narg, const char** a)
260 if (narg < 10) return 1;
261 TopoDS_Shape S = DBRep::Get(a[2]);
263 gp_Pnt Or(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
264 gp_Dir Di(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
266 Standard_Real Radius = Draw::Atof(a[9]);
268 theHole.Init(S, gp_Ax1(Or, Di));
269 theHole.PerformThruNext(Radius, WithControl);
272 if (!theHole.HasErrors()) {
274 DBRep::Set(a[1], theHole.Shape());
278 theCommands << "Echec de MakeCylindricalHole";
279 Print(theCommands, theHole.Status());
283 static Standard_Integer HOLE3(Draw_Interpretor& theCommands,
284 Standard_Integer narg, const char** a)
286 if (narg < 10) return 1;
287 TopoDS_Shape S = DBRep::Get(a[2]);
289 gp_Pnt Or(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
290 gp_Dir Di(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
292 Standard_Real Radius = Draw::Atof(a[9]);
294 theHole.Init(S, gp_Ax1(Or, Di));
295 theHole.PerformUntilEnd(Radius, WithControl);
297 if (!theHole.HasErrors()) {
299 DBRep::Set(a[1], theHole.Shape());
303 theCommands << "Echec de MakeCylindricalHole";
304 Print(theCommands, theHole.Status());
309 static Standard_Integer HOLE4(Draw_Interpretor& theCommands,
310 Standard_Integer narg, const char** a)
312 if (narg < 11) return 1;
313 TopoDS_Shape S = DBRep::Get(a[2]);
315 gp_Pnt Or(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
316 gp_Dir Di(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
318 Standard_Real Radius = Draw::Atof(a[9]);
319 Standard_Real Length = Draw::Atof(a[10]);
321 theHole.Init(S, gp_Ax1(Or, Di));
322 theHole.PerformBlind(Radius, Length, WithControl);
324 if (!theHole.HasErrors()) {
326 DBRep::Set(a[1], theHole.Shape());
330 theCommands << "Echec de MakeCylindricalHole";
331 Print(theCommands, theHole.Status());
335 static Standard_Integer CONTROL(Draw_Interpretor& theCommands,
336 Standard_Integer narg, const char** a)
339 WithControl = strcmp("0", a[1]) != 0;
342 theCommands << "Mode avec controle";
345 theCommands << "Mode sans controle";
350 //=======================================================================
351 //function : reportOffsetState
352 //purpose : Print state of offset operation by error code.
353 //=======================================================================
354 static void reportOffsetState(Draw_Interpretor& theCommands,
355 const BRepOffset_Error theErrorCode)
357 switch (theErrorCode)
359 case BRepOffset_NoError:
361 theCommands << "OK. Offset performed succesfully.";
364 case BRepOffset_BadNormalsOnGeometry:
366 theCommands << "ERROR. Degenerated normal on input data.";
369 case BRepOffset_C0Geometry:
371 theCommands << "ERROR. C0 continuity of input data.";
374 case BRepOffset_NullOffset:
376 theCommands << "ERROR. Null offset of all faces.";
379 case BRepOffset_NotConnectedShell:
381 theCommands << "ERROR. Incorrect set of faces to remove, the remaining shell is not connected.";
384 case BRepOffset_CannotTrimEdges:
386 theCommands << "ERROR. Can not trim edges.";
389 case BRepOffset_CannotFuseVertices:
391 theCommands << "ERROR. Can not fuse vertices.";
394 case BRepOffset_CannotExtentEdge:
396 theCommands << "ERROR. Can not extent edge.";
401 theCommands << "ERROR. offsetperform operation not done.";
407 //=======================================================================
410 //=======================================================================
412 static Standard_Integer PRW(Draw_Interpretor& theCommands,
413 Standard_Integer narg, const char** a)
415 if (narg < 9) return 1;
416 TopoDS_Shape S = DBRep::Get(a[3]);
417 BRepFeat_MakePrism thePFace;
419 TopoDS_Shape FFrom, FUntil;
420 Standard_Integer borne;
421 Standard_Boolean fuse;
422 if (a[1][0] == 'f' || a[1][0] == 'F') {
423 fuse = Standard_True;
425 else if (a[1][0] == 'c' || a[1][0] == 'C') {
426 fuse = Standard_False;
432 if (a[4][0] == '.' || IsAlphabetic(a[4][0])) {
436 if (a[5][0] == '.' || IsAlphabetic(a[5][0])) {
440 V.SetCoord(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
441 FFrom = DBRep::Get(a[4], TopAbs_SHAPE);
442 FUntil = DBRep::Get(a[5], TopAbs_SHAPE);
446 V.SetCoord(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
447 FUntil = DBRep::Get(a[4], TopAbs_SHAPE);
452 V.SetCoord(Draw::Atof(a[4]), Draw::Atof(a[5]), Draw::Atof(a[6]));
455 Standard_Real Length = V.Magnitude();
456 if (Length < Precision::Confusion()) {
460 TopoDS_Shape aLocalShape(DBRep::Get(a[borne], TopAbs_FACE));
461 TopoDS_Face F = TopoDS::Face(aLocalShape);
462 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
463 BRepFeat_SplitShape Spls(F);
464 for (Standard_Integer i = borne + 1; i < narg; i++) {
466 if (a[i][0] != '-') {
467 aLocalShape = DBRep::Get(a[i], TopAbs_WIRE);
468 wir = TopoDS::Wire(aLocalShape);
469 // wir = TopoDS::Wire(DBRep::Get(a[i],TopAbs_WIRE));
474 const char* Temp = a[i] + 1;
475 aLocalShape = DBRep::Get(Temp, TopAbs_WIRE);
476 wir = TopoDS::Wire(aLocalShape);
477 // wir = TopoDS::Wire(DBRep::Get(Temp,TopAbs_WIRE));
484 TopoDS_Shape ToPrism;
485 const TopTools_ListOfShape& lleft = Spls.DirectLeft();
486 if (lleft.Extent() == 1) {
487 thePFace.Init(S, lleft.First(), F, V, fuse, Standard_True);
488 ToPrism = lleft.First();
494 TopTools_ListIteratorOfListOfShape it;
495 for (it.Initialize(lleft); it.More(); it.Next()) {
496 B.Add(Sh, TopoDS::Face(it.Value()));
498 Sh.Closed(BRep_Tool::IsClosed(Sh));
499 thePFace.Init(S, Sh, F, V, fuse, Standard_True);
503 // Recherche des faces de glissement, si on n`a pas sketche sur une face
504 // du shape de depart
506 // for (TopExp_Explorer exp(S,TopAbs_FACE);exp.More();exp.Next()) {
507 TopExp_Explorer exp(S, TopAbs_FACE);
508 for (; exp.More(); exp.Next()) {
509 if (exp.Current().IsSame(F)) {
515 LocOpe_FindEdgesInFace FEIF;
516 for (exp.Init(S, TopAbs_FACE); exp.More(); exp.Next()) {
517 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
518 Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
519 if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
520 Su = Handle(Geom_RectangularTrimmedSurface)::
521 DownCast(Su)->BasisSurface();
523 if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
524 gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
525 if (pl.Contains(gp_Lin(pl.Location(), V),
526 Precision::Confusion(),
527 Precision::Angular())) {
528 FEIF.Set(ToPrism, fac);
529 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
530 thePFace.Add(FEIF.Edge(), fac);
534 else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
536 Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
537 if (V.IsParallel(cy.Axis().Direction(), Precision::Angular())) {
538 FEIF.Set(ToPrism, fac);
539 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
540 thePFace.Add(FEIF.Edge(), fac);
548 thePFace.Perform(Length);
550 else if (borne == 8) {
551 thePFace.Perform(FUntil);
553 else if (borne == 9) {
554 if (!(FFrom.IsNull() || FUntil.IsNull())) {
555 thePFace.Perform(FFrom, FUntil);
557 else if (FFrom.IsNull()) {
558 if (!FUntil.IsNull()) {
559 thePFace.PerformFromEnd(FUntil);
562 thePFace.PerformThruAll();
566 // il faudrait inverser V et appeler PerfomFromEnd...
567 //std::cout << "Not Implemented" << std::endl;
568 theCommands << "Not Implemented\n";
571 if (!thePFace.IsDone()) {
572 theCommands << "Local operation not done";
576 DBRep::Set(a[2], thePFace);
582 //=======================================================================
585 //=======================================================================
587 static Standard_Integer PRF(Draw_Interpretor& theCommands,
588 Standard_Integer narg, const char** a)
590 if (narg < 8) return 1;
591 TopoDS_Shape S = DBRep::Get(a[3]);
592 BRepFeat_MakePrism thePFace;
593 Standard_Integer borne;
595 TopoDS_Shape FFrom, FUntil;
596 Standard_Boolean fuse;
597 if (a[1][0] == 'f' || a[1][0] == 'F') {
598 fuse = Standard_True;
600 else if (a[1][0] == 'c' || a[1][0] == 'C') {
601 fuse = Standard_False;
608 if (a[4][0] == '.' || IsAlphabetic(a[4][0])) {
612 if (a[5][0] == '.' || IsAlphabetic(a[5][0])) {
617 V.SetCoord(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
618 FFrom = DBRep::Get(a[4], TopAbs_SHAPE);
619 FUntil = DBRep::Get(a[5], TopAbs_SHAPE);
623 V.SetCoord(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
624 FUntil = DBRep::Get(a[4], TopAbs_SHAPE);
629 V.SetCoord(Draw::Atof(a[4]), Draw::Atof(a[5]), Draw::Atof(a[6]));
631 Standard_Real Length = V.Magnitude();
632 if (Length < Precision::Confusion()) {
636 TopoDS_Shape ToPrism;
637 if (narg == borne + 1) {
638 TopoDS_Shape aLocalShape(DBRep::Get(a[borne], TopAbs_FACE));
639 TopoDS_Face F = TopoDS::Face(aLocalShape);
640 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
641 thePFace.Init(S, F, F, V, fuse, Standard_True);
648 for (Standard_Integer i = borne; i < narg; i++) {
649 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_FACE));
650 TopoDS_Face F = TopoDS::Face(aLocalShape);
651 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
656 She.Closed(BRep_Tool::IsClosed(She));
657 thePFace.Init(S, She, TopoDS_Face(), V, fuse, Standard_False);
661 // Recherche des faces de glissement, on ne prisme pas une face
662 // du shape de depart
664 // for (TopExp_Explorer exp(ToPrism,TopAbs_FACE);exp.More();exp.Next()) {
665 TopExp_Explorer exp(ToPrism, TopAbs_FACE);
666 for (; exp.More(); exp.Next()) {
667 // for (TopExp_Explorer exp2(S,TopAbs_FACE);exp2.More();exp2.Next()) {
668 TopExp_Explorer exp2(S, TopAbs_FACE);
669 for (; exp2.More(); exp2.Next()) {
670 if (exp2.Current().IsSame(exp.Current())) {
680 LocOpe_FindEdgesInFace FEIF;
681 for (exp.Init(S, TopAbs_FACE); exp.More(); exp.Next()) {
682 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
683 Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
684 if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
685 Su = Handle(Geom_RectangularTrimmedSurface)::
686 DownCast(Su)->BasisSurface();
688 if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
689 gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
690 if (pl.Contains(gp_Lin(pl.Location(), V),
691 Precision::Confusion(),
692 Precision::Angular())) {
693 FEIF.Set(ToPrism, fac);
694 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
695 thePFace.Add(FEIF.Edge(), fac);
699 else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
701 Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
702 if (V.IsParallel(cy.Axis().Direction(), Precision::Angular())) {
703 FEIF.Set(ToPrism, fac);
704 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
705 thePFace.Add(FEIF.Edge(), fac);
713 thePFace.Perform(Length);
715 else if (borne == 8) {
716 thePFace.Perform(FUntil);
718 else if (borne == 9) {
719 if (!(FFrom.IsNull() || FUntil.IsNull())) {
720 thePFace.Perform(FFrom, FUntil);
722 else if (FFrom.IsNull()) {
723 if (!FUntil.IsNull()) {
724 thePFace.PerformFromEnd(FUntil);
727 thePFace.PerformThruAll();
730 else { //FUntil.IsNull()
731 // il faudrait inverser V et appeler PerfomFromEnd...
732 //std::cout << "Not Implemented" << std::endl;
733 theCommands << "Not Implemented\n";
736 if (!thePFace.IsDone()) {
737 theCommands << "Local operation not done";
741 DBRep::Set(a[2], thePFace);
748 //=======================================================================
751 //=======================================================================
753 static Standard_Integer SPLS(Draw_Interpretor&,
754 Standard_Integer narg, const char** a)
756 Standard_Integer newnarg;
760 Message::SendFail() << "Invalid number of arguments. Should be : splitshape result shape [splitedges] "
761 "[face wire/edge/compound [wire/edge/compound ...] "
762 "[face wire/edge/compound [wire/edge/compound...] ...] "
763 "[@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]";
766 TopoDS_Shape S = DBRep::Get(a[2]);
769 Message::SendFail() << "Invalid input shape " << a[2];
772 BRepFeat_SplitShape Spls(S);
773 Standard_Boolean pick = Standard_False;
776 Standard_Integer i = 3;
778 for (newnarg = 3; newnarg < narg; newnarg++) {
779 if (a[newnarg][0] == '@') {
785 (newnarg != narg && ((narg - newnarg) <= 2 || (narg - newnarg) % 2 != 1))) {
788 Standard_Boolean isSplittingEdges = Standard_False;
789 TopTools_SequenceOfShape aSplitEdges;
791 pick = (a[i][0] == '.');
793 TopoDS_Shape aSh = DBRep::Get(a[i]);
796 Message::SendFail() << "Invalid input shape " << a[i];
801 if (aSh.ShapeType() == TopAbs_FACE)
802 EF = TopoDS::Face(aSh);
805 if (aSh.ShapeType() == TopAbs_COMPOUND || aSh.ShapeType() == TopAbs_WIRE || aSh.ShapeType() == TopAbs_EDGE)
807 TopExp_Explorer aExpE(aSh, TopAbs_EDGE, TopAbs_FACE);
808 for (; aExpE.More(); aExpE.Next())
809 aSplitEdges.Append(aExpE.Current());
811 isSplittingEdges = !aSplitEdges.IsEmpty();
817 while (i < newnarg) {
819 DBRep_DrawableShape::LastPick(EF, u, v);
821 if (!isSplittingEdges && !EF.IsNull() && EF.ShapeType() == TopAbs_FACE) {
822 // face wire/edge ...
824 while (i < newnarg) {
826 Standard_Boolean rever = Standard_False;
827 if (a[i][0] == '-') {
830 pick = (a[i][1] == '.');
831 const char* Temp = a[i] + 1;
832 W = DBRep::Get(Temp, TopAbs_SHAPE, Standard_False);
833 rever = Standard_True;
836 pick = (a[i][0] == '.');
837 W = DBRep::Get(a[i], TopAbs_SHAPE, Standard_False);
840 return 1; // on n`a rien recupere
842 TopAbs_ShapeEnum wtyp = W.ShapeType();
843 if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && wtyp != TopAbs_COMPOUND && pick) {
844 DBRep_DrawableShape::LastPick(W, u, v);
845 wtyp = W.ShapeType();
847 if (wtyp != TopAbs_WIRE && wtyp != TopAbs_EDGE && wtyp != TopAbs_COMPOUND) {
848 EF = DBRep::Get(a[i]);
855 if (wtyp == TopAbs_WIRE) {
856 Spls.Add(TopoDS::Wire(W), TopoDS::Face(EF));
858 else if (wtyp == TopAbs_EDGE) {
859 Spls.Add(TopoDS::Edge(W), TopoDS::Face(EF));
862 Spls.Add(TopoDS::Compound(W), TopoDS::Face(EF));
870 if (isSplittingEdges)
872 TopoDS_Shape aSh = DBRep::Get(a[i]);
875 Message::SendFail() << "Invalid input shape " << a[i];
878 TopExp_Explorer aExpE(aSh, TopAbs_EDGE, TopAbs_FACE);
879 for (; aExpE.More(); aExpE.Next())
880 aSplitEdges.Append(aExpE.Current());
884 Message::SendFail() << "Invalid input arguments. Should be : splitshape result shape [splitedges] "
885 "[face wire/edge/compound [wire/edge/compound ...] "
886 "[face wire/edge/compound [wire/edge/compound...] ...] "
887 "[@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]";
894 if (isSplittingEdges)
895 Spls.Add(aSplitEdges);
897 // ici, i vaut newnarg
898 for (; i < narg; i += 2) {
900 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_EDGE));
901 Es = TopoDS::Edge(aLocalShape);
902 // Es = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
906 aLocalShape = DBRep::Get(a[i + 1], TopAbs_EDGE);
907 Ew = TopoDS::Edge(aLocalShape);
908 // Ew = TopoDS::Edge(DBRep::Get(a[i+1],TopAbs_EDGE));
910 Message::SendFail() << "Invalid input shape " << a[i + 1];
913 Spls.Add(TopoDS::Edge(Ew), TopoDS::Edge(Es));
917 DBRep::Set(a[1], Spls);
921 //=======================================================================
922 //function : thickshell
924 //=======================================================================
925 Standard_Integer thickshell(Draw_Interpretor& theCommands,
926 Standard_Integer n, const char** a)
929 TopoDS_Shape S = DBRep::Get(a[2]);
930 if (S.IsNull()) return 1;
932 Standard_Real Of = Draw::Atof(a[3]);
934 GeomAbs_JoinType JT = GeomAbs_Arc;
937 if (!strcmp(a[4], "i"))
938 JT = GeomAbs_Intersection;
939 if (!strcmp(a[4], "t"))
940 JT = GeomAbs_Tangent;
943 Standard_Boolean Inter = Standard_False; //Standard_True;
944 Standard_Real Tol = Precision::Confusion();
946 Tol = Draw::Atof(a[5]);
948 BRepOffset_MakeOffset B;
949 B.Initialize(S, Of, Tol, BRepOffset_Skin, Inter, 0, JT, Standard_True);
953 const BRepOffset_Error aRetCode = B.Error();
954 reportOffsetState(theCommands, aRetCode);
956 DBRep::Set(a[1], B.Shape());
960 //=======================================================================
961 //function : offsetshape
963 //=======================================================================
965 Standard_Integer offsetshape(Draw_Interpretor& theCommands,
966 Standard_Integer n, const char** a)
969 TopoDS_Shape S = DBRep::Get(a[2]);
970 if (S.IsNull()) return 1;
972 Standard_Real Of = Draw::Atof(a[3]);
973 Standard_Boolean Inter = (!strcmp(a[0], "offsetcompshape"));
974 GeomAbs_JoinType JT = GeomAbs_Arc;
975 if (!strcmp(a[0], "offsetinter"))
977 JT = GeomAbs_Intersection;
978 Inter = Standard_True;
981 BRepOffset_MakeOffset B;
982 Standard_Integer IB = 4;
983 Standard_Real Tol = Precision::Confusion();
986 TopoDS_Shape SF = DBRep::Get(a[4], TopAbs_FACE);
990 Tol = Draw::Atof(a[4]);
993 B.Initialize(S, Of, Tol, BRepOffset_Skin, Inter, 0, JT);
994 //------------------------------------------
995 // recuperation et chargement des bouchons.
996 //----------------------------------------
997 Standard_Boolean YaBouchon = Standard_False;
999 for (Standard_Integer i = IB; i < n; i++)
1001 TopoDS_Shape SF = DBRep::Get(a[i], TopAbs_FACE);
1004 YaBouchon = Standard_True;
1005 B.AddFace(TopoDS::Face(SF));
1009 if (!YaBouchon) B.MakeOffsetShape();
1010 else B.MakeThickSolid();
1012 const BRepOffset_Error aRetCode = B.Error();
1013 reportOffsetState(theCommands, aRetCode);
1015 DBRep::Set(a[1], B.Shape());
1020 static BRepOffset_MakeOffset TheOffset;
1021 static Standard_Real TheRadius;
1022 static Standard_Boolean theYaBouchon;
1023 static Standard_Real TheTolerance = Precision::Confusion();
1024 static Standard_Boolean TheInter = Standard_False;
1025 static GeomAbs_JoinType TheJoin = GeomAbs_Arc;
1026 static Standard_Boolean RemoveIntEdges = Standard_False;
1028 Standard_Integer offsetparameter(Draw_Interpretor& di,
1029 Standard_Integer n, const char** a)
1032 di << " offsetparameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k)]\n";
1033 di << " Current Values\n";
1034 di << " --> Tolerance : " << TheTolerance << "\n";
1035 di << " --> TheInter : ";
1042 di << "\n --> TheJoin : ";
1045 case GeomAbs_Arc: di << "Arc"; break;
1046 case GeomAbs_Intersection: di << "Intersection"; break;
1051 di << "\n --> Internal Edges : ";
1052 if (RemoveIntEdges) {
1063 if (n < 4) return 1;
1065 TheTolerance = Draw::Atof(a[1]);
1066 TheInter = strcmp(a[2], "p") != 0;
1068 if (!strcmp(a[3], "a")) TheJoin = GeomAbs_Arc;
1069 else if (!strcmp(a[3], "i")) TheJoin = GeomAbs_Intersection;
1070 else if (!strcmp(a[3], "t")) TheJoin = GeomAbs_Tangent;
1072 RemoveIntEdges = (n >= 5) ? !strcmp(a[4], "r") : Standard_False;
1077 //=======================================================================
1078 //function : offsetinit
1080 //=======================================================================
1082 Standard_Integer offsetload(Draw_Interpretor&,
1083 Standard_Integer n, const char** a)
1085 if (n < 2) return 1;
1086 TopoDS_Shape S = DBRep::Get(a[1]);
1087 if (S.IsNull()) return 1;
1089 Standard_Real Of = Draw::Atof(a[2]);
1091 // Standard_Boolean Inter = Standard_True;
1093 TheOffset.Initialize(S, Of, TheTolerance, BRepOffset_Skin, TheInter, 0, TheJoin,
1094 Standard_False, RemoveIntEdges);
1095 //------------------------------------------
1096 // recuperation et chargement des bouchons.
1097 //----------------------------------------
1098 for (Standard_Integer i = 3; i < n; i++) {
1099 TopoDS_Shape SF = DBRep::Get(a[i], TopAbs_FACE);
1101 TheOffset.AddFace(TopoDS::Face(SF));
1104 if (n < 4) theYaBouchon = Standard_False; //B.MakeOffsetShape();
1105 else theYaBouchon = Standard_True; //B.MakeThickSolid ();
1111 //=======================================================================
1112 //function : offsetonface
1114 //=======================================================================
1116 Standard_Integer offsetonface(Draw_Interpretor&, Standard_Integer n, const char** a)
1118 if (n < 3) return 1;
1120 for (Standard_Integer i = 1; i < n; i += 2) {
1121 TopoDS_Shape SF = DBRep::Get(a[i], TopAbs_FACE);
1123 Standard_Real Of = Draw::Atof(a[i + 1]);
1124 TheOffset.SetOffsetOnFace(TopoDS::Face(SF), Of);
1131 //=======================================================================
1132 //function : offsetperform
1134 //=======================================================================
1136 Standard_Integer offsetperform(Draw_Interpretor& theCommands,
1137 Standard_Integer theNArg, const char** a)
1139 if (theNArg < 2) return 1;
1142 TheOffset.MakeThickSolid();
1144 TheOffset.MakeOffsetShape();
1146 if (TheOffset.IsDone())
1148 DBRep::Set(a[1], TheOffset.Shape());
1152 const BRepOffset_Error aRetCode = TheOffset.Error();
1153 reportOffsetState(theCommands, aRetCode);
1156 // Store the history of Boolean operation into the session
1157 if (BRepTest_Objects::IsHistoryNeeded())
1159 TopTools_ListOfShape aLA;
1160 aLA.Append(TheOffset.InitShape());
1161 BRepTest_Objects::SetHistory<BRepOffset_MakeOffset>(aLA, TheOffset);
1168 //=======================================================================
1171 //=======================================================================
1173 static Standard_Integer ROW(Draw_Interpretor& theCommands,
1174 Standard_Integer narg, const char** a)
1176 if (narg < 13) return 1;
1177 TopoDS_Shape S = DBRep::Get(a[3]);
1178 BRepFeat_MakeRevol theRFace;
1181 Standard_Real Angle = 0;
1182 TopoDS_Shape FFrom, FUntil;
1183 Standard_Integer i, borne;
1184 Standard_Boolean fuse;
1186 if (a[1][0] == 'f' || a[1][0] == 'F') {
1187 fuse = Standard_True;
1189 else if (a[1][0] == 'c' || a[1][0] == 'C') {
1190 fuse = Standard_False;
1196 FFrom = DBRep::Get(a[4], TopAbs_SHAPE);
1197 if (FFrom.IsNull()) {
1198 Angle = Draw::Atof(a[4]);
1199 Angle *= M_PI / 180.;
1203 FUntil = DBRep::Get(a[5], TopAbs_SHAPE);
1204 if (FUntil.IsNull()) {
1219 Or.SetCoord(Draw::Atof(a[i]), Draw::Atof(a[i + 1]), Draw::Atof(a[i + 2]));
1220 D.SetCoord(Draw::Atof(a[i + 3]), Draw::Atof(a[i + 4]), Draw::Atof(a[i + 5]));
1221 gp_Ax1 theAxis(Or, D);
1223 TopoDS_Shape aLocalShape(DBRep::Get(a[borne], TopAbs_FACE));
1224 TopoDS_Face F = TopoDS::Face(aLocalShape);
1225 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1226 BRepFeat_SplitShape Spls(F);
1227 for (i = borne + 1; i < narg; i++) {
1229 if (a[i][0] != '-') {
1230 aLocalShape = DBRep::Get(a[i], TopAbs_WIRE);
1231 wir = TopoDS::Wire(aLocalShape);
1232 // wir = TopoDS::Wire(DBRep::Get(a[i],TopAbs_WIRE));
1235 if (a[i][1] == '\0')
1237 const char* Temp = a[i] + 1;
1238 aLocalShape = DBRep::Get(Temp, TopAbs_WIRE);
1239 wir = TopoDS::Wire(aLocalShape);
1240 // wir = TopoDS::Wire(DBRep::Get(Temp,TopAbs_WIRE));
1247 TopoDS_Shape ToRotate;
1248 const TopTools_ListOfShape& lleft = Spls.DirectLeft();
1249 if (lleft.Extent() == 1) {
1250 theRFace.Init(S, lleft.First(), F, theAxis, fuse, Standard_True);
1251 ToRotate = lleft.First();
1257 TopTools_ListIteratorOfListOfShape it;
1258 for (it.Initialize(lleft); it.More(); it.Next()) {
1259 B.Add(Sh, TopoDS::Face(it.Value()));
1261 Sh.Closed(BRep_Tool::IsClosed(Sh));
1262 theRFace.Init(S, Sh, F, theAxis, fuse, Standard_True);
1266 // Recherche des faces de glissement
1267 // for (TopExp_Explorer exp(S,TopAbs_FACE);exp.More();exp.Next()) {
1268 TopExp_Explorer exp(S, TopAbs_FACE);
1269 for (; exp.More(); exp.Next()) {
1270 if (exp.Current().IsSame(F)) {
1276 LocOpe_FindEdgesInFace FEIF;
1277 for (exp.Init(S, TopAbs_FACE); exp.More(); exp.Next()) {
1278 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1279 Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1280 if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1281 Su = Handle(Geom_RectangularTrimmedSurface)::
1282 DownCast(Su)->BasisSurface();
1284 if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1285 gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1286 if (pl.Axis().IsParallel(theAxis, Precision::Angular())) {
1287 FEIF.Set(ToRotate, fac);
1288 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
1289 theRFace.Add(FEIF.Edge(), fac);
1293 else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1295 Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1296 if (cy.Axis().IsCoaxial(theAxis,
1297 Precision::Angular(), Precision::Confusion())) {
1298 FEIF.Set(ToRotate, fac);
1299 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
1300 theRFace.Add(FEIF.Edge(), fac);
1308 if (FUntil.IsNull()) {
1309 theRFace.Perform(Angle);
1312 theRFace.Perform(FUntil);
1315 else { // borne == 12
1316 theRFace.Perform(FFrom, FUntil);
1319 if (!theRFace.IsDone()) {
1320 theCommands << "Local operation not done";
1324 DBRep::Set(a[2], theRFace);
1330 //=======================================================================
1333 //=======================================================================
1335 static Standard_Integer ROF(Draw_Interpretor& theCommands,
1336 Standard_Integer narg, const char** a)
1338 if (narg < 12) return 1;
1339 TopoDS_Shape S = DBRep::Get(a[3]);
1340 BRepFeat_MakeRevol theRFace;
1343 Standard_Real Angle = 0;
1344 TopoDS_Shape FFrom, FUntil;
1345 Standard_Integer i, borne;
1346 Standard_Boolean fuse;
1348 if (a[1][0] == 'f' || a[1][0] == 'F') {
1349 fuse = Standard_True;
1351 else if (a[1][0] == 'c' || a[1][0] == 'C') {
1352 fuse = Standard_False;
1358 FFrom = DBRep::Get(a[4], TopAbs_SHAPE);
1359 if (FFrom.IsNull()) {
1360 Angle = Draw::Atof(a[4]);
1361 Angle *= M_PI / 180.;
1365 FUntil = DBRep::Get(a[5], TopAbs_SHAPE);
1366 if (FUntil.IsNull()) {
1381 Or.SetCoord(Draw::Atof(a[i]), Draw::Atof(a[i + 1]), Draw::Atof(a[i + 2]));
1382 D.SetCoord(Draw::Atof(a[i + 3]), Draw::Atof(a[i + 4]), Draw::Atof(a[i + 5]));
1383 gp_Ax1 theAxis(Or, D);
1385 TopoDS_Shape ToRotate;
1386 if (narg == borne + 1) {
1387 TopoDS_Shape aLocalShape(DBRep::Get(a[borne], TopAbs_FACE));
1388 TopoDS_Face F = TopoDS::Face(aLocalShape);
1389 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[borne],TopAbs_FACE));
1390 theRFace.Init(S, F, F, theAxis, fuse, Standard_True);
1398 for (i = borne; i < narg; i++) {
1399 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_FACE));
1400 TopoDS_Face F = TopoDS::Face(aLocalShape);
1401 // TopoDS_Face F = TopoDS::Face(DBRep::Get(a[i],TopAbs_FACE));
1406 She.Closed(BRep_Tool::IsClosed(She));
1407 theRFace.Init(S, She, TopoDS_Face(), theAxis, fuse, Standard_False);
1411 // for (TopExp_Explorer exp(ToRotate,TopAbs_FACE);exp.More();exp.Next()) {
1412 TopExp_Explorer exp(ToRotate, TopAbs_FACE);
1413 for (; exp.More(); exp.Next()) {
1414 // for (TopExp_Explorer exp2(S,TopAbs_FACE);exp2.More();exp2.Next()) {
1415 TopExp_Explorer exp2(S, TopAbs_FACE);
1416 for (; exp2.More(); exp2.Next()) {
1417 if (exp2.Current().IsSame(exp.Current())) {
1427 LocOpe_FindEdgesInFace FEIF;
1428 for (exp.Init(S, TopAbs_FACE); exp.More(); exp.Next()) {
1429 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
1430 Handle(Geom_Surface) Su = BRep_Tool::Surface(fac);
1431 if (Su->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1432 Su = Handle(Geom_RectangularTrimmedSurface)::
1433 DownCast(Su)->BasisSurface();
1435 if (Su->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1436 gp_Pln pl = Handle(Geom_Plane)::DownCast(Su)->Pln();
1437 if (pl.Axis().IsParallel(theAxis, Precision::Angular())) {
1438 FEIF.Set(ToRotate, fac);
1439 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
1440 theRFace.Add(FEIF.Edge(), fac);
1444 else if (Su->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
1446 Handle(Geom_CylindricalSurface)::DownCast(Su)->Cylinder();
1447 if (cy.Axis().IsCoaxial(theAxis,
1448 Precision::Angular(), Precision::Confusion())) {
1449 FEIF.Set(ToRotate, fac);
1450 for (FEIF.Init(); FEIF.More(); FEIF.Next()) {
1451 theRFace.Add(FEIF.Edge(), fac);
1459 if (FUntil.IsNull()) {
1460 theRFace.Perform(Angle);
1463 theRFace.Perform(FUntil);
1466 else { // borne == 12
1467 theRFace.Perform(FFrom, FUntil);
1470 if (!theRFace.IsDone()) {
1471 theCommands << "Local operation not done";
1475 DBRep::Set(a[2], theRFace);
1481 //=======================================================================
1483 //purpose : Commande glue
1484 //=======================================================================
1486 static Standard_Integer GLU(Draw_Interpretor&,
1487 Standard_Integer narg, const char** a)
1489 if (narg < 6 || narg % 2 != 0) return 1;
1490 TopoDS_Shape Sne = DBRep::Get(a[2]);
1491 TopoDS_Shape Sba = DBRep::Get(a[3]);
1493 Standard_Boolean pick;
1495 BRepFeat_Gluer theGl(Sne, Sba);
1496 TopoDS_Shape Fne, Fba;
1498 LocOpe_FindEdges fined;
1500 Standard_Integer i = 4;
1501 Standard_Boolean first = Standard_True;
1503 pick = (a[i][0] == '.');
1504 Fne = DBRep::Get(a[i]);
1508 TopAbs_ShapeEnum sht = Fne.ShapeType();
1509 if (pick && sht != TopAbs_FACE && sht != TopAbs_EDGE) {
1511 DBRep_DrawableShape::LastPick(Fne, u, v);
1512 sht = Fne.ShapeType();
1514 if (first && sht != TopAbs_FACE) {
1517 first = Standard_False;
1518 pick = (a[i + 1][0] == '.');
1519 Fba = DBRep::Get(a[i + 1]);
1523 if (pick && Fba.ShapeType() != sht) {
1525 DBRep_DrawableShape::LastPick(Fba, u, v);
1527 if (Fba.ShapeType() != sht) {
1530 if (sht == TopAbs_FACE) {
1531 const TopoDS_Face& f1 = TopoDS::Face(Fne);
1532 const TopoDS_Face& f2 = TopoDS::Face(Fba);
1534 fined.Set(Fne, Fba);
1535 for (fined.InitIterator(); fined.More(); fined.Next()) {
1536 theGl.Bind(fined.EdgeFrom(), fined.EdgeTo());
1540 theGl.Bind(TopoDS::Edge(Fne), TopoDS::Edge(Fba));
1545 DBRep::Set(a[1], theGl);
1550 static Standard_Integer DEFIN(Draw_Interpretor& theCommands,
1551 Standard_Integer narg, const char** a)
1554 if (strcasecmp(a[0], "FEATPRISM") &&
1555 strcasecmp(a[0], "FEATDPRISM") &&
1556 strcasecmp(a[0], "FEATREVOL") &&
1557 strcasecmp(a[0], "FEATPIPE") &&
1558 strcasecmp(a[0], "FEATLF") &&
1559 strcasecmp(a[0], "FEATRF")) {
1563 if ((!strcasecmp(a[0], "FEATPRISM") && narg != 9) ||
1564 (!strcasecmp(a[0], "FEATREVOL") && narg != 12) ||
1565 (!strcasecmp(a[0], "FEATDPRISM") && narg != 7) ||
1566 (!strcasecmp(a[0], "FEATPIPE") && narg != 7) ||
1567 (!strcasecmp(a[0], "FEATLF") && narg != 12) ||
1568 (!strcasecmp(a[0], "FEATRF") && narg != 14)) {
1569 theCommands << "invalid number of arguments";
1573 TopoDS_Shape Sbase = DBRep::Get(a[1]);
1574 if (Sbase.IsNull()) {
1575 theCommands << "null basis shape";
1578 Standard_Integer Ifuse = Draw::Atoi(a[narg - 2]);
1579 Standard_Integer Imodif = Draw::Atoi(a[narg - 1]);
1581 Standard_Integer Fuse = Ifuse;
1582 Standard_Boolean Modify = (Imodif != 0);
1588 Handle(Geom_Plane) P;
1590 BRepFeat_StatusError se;
1592 if (strcasecmp(a[0], "FEATLF") && strcasecmp(a[0], "FEATRF")) {
1593 Pbase = DBRep::Get(a[2]);
1594 if (Pbase.IsNull()) {
1595 theCommands << "null shape to transform";
1598 TopoDS_Shape aLocalShape(DBRep::Get(a[3], TopAbs_FACE));
1599 Skface = TopoDS::Face(aLocalShape);
1600 // Skface = TopoDS::Face(DBRep::Get(a[3],TopAbs_FACE));
1601 if (Skface.IsNull()) {
1602 theCommands << "null face of Sketch";
1607 TopoDS_Shape aLocalShape(DBRep::Get(a[2], TopAbs_WIRE));
1608 W = TopoDS::Wire(aLocalShape);
1609 // W = TopoDS::Wire(DBRep::Get(a[2], TopAbs_WIRE));
1611 theCommands << "null profile for rib or slot";
1614 Handle(Geom_Surface) s = DrawTrSurf::GetSurface(a[3]);
1615 P = Handle(Geom_Plane)::DownCast(s);
1617 theCommands << "null plane to transform";
1621 if (narg == 9 || narg == 12 || narg == 14) {
1622 // Standard_Real X,Y,Z,X1,Y1,Z1;
1623 Standard_Real X, Y, Z;
1624 X = Draw::Atof(a[4]);
1625 Y = Draw::Atof(a[5]);
1626 Z = Draw::Atof(a[6]);
1628 if (narg == 9) { // prism
1629 prdef = Standard_True;
1633 thePrism.Init(Sbase, Pbase, Skface, gp_Dir(X, Y, Z), Fuse, Modify);
1635 else if (narg == 14) {
1636 rfdef = Standard_True;
1638 X = Draw::Atof(a[7]);
1639 Y = Draw::Atof(a[8]);
1640 Z = Draw::Atof(a[9]);
1641 Standard_Real H1 = Draw::Atof(a[10]);
1642 Standard_Real H2 = Draw::Atof(a[11]);
1643 gp_Ax1 ax1(Or, gp_Dir(X, Y, Z));
1644 theRF.Init(Sbase, W, P, ax1, H1, H2, Fuse, Modify);
1645 if (!theRF.IsDone()) {
1646 se = theRF.CurrentStatusError();
1647 //BRepFeat::Print(se,std::cout) << std::endl;
1648 Standard_SStream aSStream;
1649 BRepFeat::Print(se, aSStream);
1650 theCommands << aSStream << "\n";
1654 else if (narg == 12 && strcasecmp(a[0], "FEATLF")) {
1655 rvdef = Standard_True;
1657 X = Draw::Atof(a[7]);
1658 Y = Draw::Atof(a[8]);
1659 Z = Draw::Atof(a[9]);
1663 theRevol.Init(Sbase, Pbase, Skface, gp_Ax1(Or, gp_Dir(X, Y, Z)),
1667 lfdef = Standard_True;
1668 gp_Vec Direct(X, Y, Z);
1669 X = Draw::Atof(a[7]);
1670 Y = Draw::Atof(a[8]);
1671 Z = Draw::Atof(a[9]);
1672 theLF.Init(Sbase, W, P, Direct, gp_Vec(X, Y, Z), Fuse, Modify);
1673 if (!theLF.IsDone()) {
1674 se = theLF.CurrentStatusError();
1675 //BRepFeat::Print(se,std::cout) << std::endl;
1676 Standard_SStream aSStream;
1677 BRepFeat::Print(se, aSStream);
1678 theCommands << aSStream << "\n";
1683 else if (narg == 7) {
1684 if (!strcasecmp(a[0], "FEATDPRISM")) {
1685 if (Pbase.ShapeType() != TopAbs_FACE) {
1686 theCommands << "Invalid DPrism base";
1689 Standard_Real Angle = Draw::Atof(a[4])*M_PI / 360;
1690 dprdef = Standard_True;
1694 theDPrism.Init(Sbase, TopoDS::Face(Pbase), Skface, Angle, Fuse, Modify);
1697 TopoDS_Shape aLocalShape(DBRep::Get(a[4], TopAbs_WIRE));
1698 TopoDS_Wire Spine = TopoDS::Wire(aLocalShape);
1699 // TopoDS_Wire Spine = TopoDS::Wire(DBRep::Get(a[4],TopAbs_WIRE));
1700 if (Spine.IsNull()) {
1701 TopoDS_Shape Edspine = DBRep::Get(a[4], TopAbs_EDGE);
1702 if (Edspine.IsNull()) {
1703 theCommands << "null spine";
1708 B.Add(Spine, Edspine);
1710 pidef = Standard_True;
1714 thePipe.Init(Sbase, Pbase, Skface, Spine, Fuse, Modify);
1722 static Standard_Integer ADD(Draw_Interpretor&,
1723 Standard_Integer narg, const char** a)
1726 if (narg < 4 || narg % 2 != 0) {
1729 if (!strcasecmp("PRISM", a[1])) {
1733 for (i = 2; i < narg; i += 2) {
1734 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_EDGE));
1735 TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1736 // TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1740 aLocalShape = DBRep::Get(a[i + 1], TopAbs_FACE);
1741 TopoDS_Face fac = TopoDS::Face(aLocalShape);
1742 // TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1746 thePrism.Add(edg, fac);
1749 else if (!strcasecmp("REVOL", a[1])) {
1753 for (i = 2; i < narg; i += 2) {
1754 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_EDGE));
1755 TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1756 // TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1760 aLocalShape = DBRep::Get(a[i + 1], TopAbs_FACE);
1761 TopoDS_Face fac = TopoDS::Face(aLocalShape);
1762 // TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1766 theRevol.Add(edg, fac);
1769 else if (!strcasecmp("PIPE", a[1])) {
1773 for (i = 2; i < narg; i += 2) {
1774 TopoDS_Shape aLocalShape(DBRep::Get(a[i], TopAbs_EDGE));
1775 TopoDS_Edge edg = TopoDS::Edge(aLocalShape);
1776 // TopoDS_Edge edg = TopoDS::Edge(DBRep::Get(a[i],TopAbs_EDGE));
1780 aLocalShape = DBRep::Get(a[i + 1], TopAbs_FACE);
1781 TopoDS_Face fac = TopoDS::Face(aLocalShape);
1782 // TopoDS_Face fac = TopoDS::Face(DBRep::Get(a[i+1],TopAbs_FACE));
1786 thePipe.Add(edg, fac);
1797 static Standard_Integer PERF(Draw_Interpretor& theCommands,
1798 Standard_Integer narg, const char** a)
1803 if (strcasecmp(a[0], "FEATPERFORM") &&
1804 strcasecmp(a[0], "FEATPERFORMVAL")) {
1808 TopTools_ListOfShape anArgs;
1809 Standard_Integer Kas;
1810 if (!strcasecmp("PRISM", a[1])) {
1813 theCommands << "prism not defined";
1817 else if (!strcasecmp("REVOL", a[1])) {
1820 theCommands << "revol not defined";
1824 else if (!strcasecmp("PIPE", a[1])) {
1827 theCommands << "pipe not defined";
1830 if (!strcasecmp(a[0], "FEATPERFORMVAL")) {
1831 theCommands << "invalid command for pipe";
1835 else if (!strcasecmp("DPRISM", a[1])) {
1838 theCommands << "dprism not defined";
1842 else if (!strcasecmp("LF", a[1])) {
1845 theCommands << "lf not defined";
1848 if (!strcasecmp(a[0], "FEATPERFORMVAL")) {
1849 theCommands << "invalid command for lf";
1853 else if (!strcasecmp("RF", a[1])) {
1856 theCommands << "rf not defined";
1859 if (!strcasecmp(a[0], "FEATPERFORMVAL")) {
1860 theCommands << "invalid command for rf";
1865 theCommands << "unknown argument : " << a[1];
1869 if (!strcasecmp(a[0], "FEATPERFORMVAL")) {
1870 if (narg != 4 && narg != 5) {
1871 theCommands << "invalid number of arguments";
1875 Standard_Real Val = Draw::Atof(a[3]);
1877 thePrism.Perform(Val);
1879 else if (Kas == 2) {
1880 Val *= (M_PI / 180.);
1881 theRevol.Perform(Val);
1883 else if (Kas == 4) {
1884 theDPrism.Perform(Val);
1886 else if (Kas == 5) {
1887 theCommands << "invalid command for lf";
1890 else if (Kas == 6) {
1891 theCommands << "invalid command for rf";
1895 else if (narg == 5) {
1896 Standard_Real Val = Draw::Atof(a[3]);
1897 TopoDS_Shape FUntil = DBRep::Get(a[4], TopAbs_SHAPE);
1899 thePrism.PerformUntilHeight(FUntil, Val);
1901 else if (Kas == 2) {
1902 Val *= (M_PI / 180.);
1903 theRevol.PerformUntilAngle(FUntil, Val);
1905 else if (Kas == 4) {
1906 theDPrism.PerformUntilHeight(FUntil, Val);
1909 theCommands << "invalid command for ribs or slots";
1914 else if (!strcasecmp(a[0], "FEATPERFORM")) {
1915 if (narg == 3) { // Thru all
1918 thePrism.PerformThruAll();
1921 theRevol.PerformThruAll();
1927 theDPrism.PerformThruAll();
1940 else if (narg == 4) { // Until
1941 TopoDS_Shape Funtil = DBRep::Get(a[3], TopAbs_SHAPE);
1945 if (Funtil.IsNull()) {
1946 thePrism.PerformUntilEnd();
1949 thePrism.Perform(Funtil);
1955 if (!Funtil.IsNull()) {
1956 theRevol.Perform(Funtil);
1965 if (!Funtil.IsNull()) {
1966 thePipe.Perform(Funtil);
1969 theCommands << "invalid command for ribs pipe";
1976 if (!Funtil.IsNull()) {
1977 theDPrism.Perform(Funtil);
1980 theDPrism.PerformUntilEnd();
1986 theCommands << "invalid command for lf";
1992 theCommands << "invalid command for rf";
2000 else if (narg == 5) {
2001 TopoDS_Shape Ffrom = DBRep::Get(a[3], TopAbs_SHAPE);
2002 TopoDS_Shape Funtil = DBRep::Get(a[4], TopAbs_SHAPE);
2003 if (Funtil.IsNull()) {
2009 if (Ffrom.IsNull()) {
2010 thePrism.PerformFromEnd(Funtil);
2013 thePrism.Perform(Ffrom, Funtil);
2019 if (Ffrom.IsNull()) {
2022 theRevol.Perform(Ffrom, Funtil);
2027 if (Ffrom.IsNull()) {
2030 thePipe.Perform(Ffrom, Funtil);
2035 if (Ffrom.IsNull()) {
2036 theDPrism.PerformFromEnd(Funtil);
2039 theDPrism.Perform(Ffrom, Funtil);
2050 BRepFeat_StatusError se;
2053 if (!thePrism.IsDone()) {
2054 se = thePrism.CurrentStatusError();
2055 //BRepFeat::Print(se,std::cout) << std::endl;
2056 Standard_SStream aSStream;
2057 BRepFeat::Print(se, aSStream);
2058 theCommands << aSStream << "\n";
2061 DBRep::Set(a[2], thePrism);
2064 if (BRepTest_Objects::IsHistoryNeeded())
2067 anArgs.Append(theSbase);
2068 anArgs.Append(thePbase);
2069 anArgs.Append(theSkface);
2070 BRepTest_Objects::SetHistory(anArgs, thePrism);
2074 if (!theRevol.IsDone()) {
2075 se = theRevol.CurrentStatusError();
2076 //BRepFeat::Print(se,std::cout) << std::endl;
2077 Standard_SStream aSStream;
2078 BRepFeat::Print(se, aSStream);
2079 theCommands << aSStream << "\n";
2083 if (BRepTest_Objects::IsHistoryNeeded())
2086 anArgs.Append(theSbase);
2087 anArgs.Append(thePbase);
2088 anArgs.Append(theSkface);
2089 BRepTest_Objects::SetHistory(anArgs, theRevol);
2091 DBRep::Set(a[2], theRevol);
2095 if (!thePipe.IsDone()) {
2096 se = thePipe.CurrentStatusError();
2097 //BRepFeat::Print(se,std::cout) << std::endl;
2098 Standard_SStream aSStream;
2099 BRepFeat::Print(se, aSStream);
2100 theCommands << aSStream << "\n";
2104 if (BRepTest_Objects::IsHistoryNeeded())
2107 anArgs.Append(theSbase);
2108 anArgs.Append(thePbase);
2109 anArgs.Append(theSkface);
2110 BRepTest_Objects::SetHistory(anArgs, thePipe);
2112 DBRep::Set(a[2], thePipe);
2116 if (!theDPrism.IsDone()) {
2117 se = theDPrism.CurrentStatusError();
2118 //BRepFeat::Print(se,std::cout) << std::endl;
2119 Standard_SStream aSStream;
2120 BRepFeat::Print(se, aSStream);
2121 theCommands << aSStream << "\n";
2125 if (BRepTest_Objects::IsHistoryNeeded())
2128 anArgs.Append(theSbase);
2129 anArgs.Append(thePbase);
2130 anArgs.Append(theSkface);
2131 BRepTest_Objects::SetHistory(anArgs, theDPrism);
2133 DBRep::Set(a[2], theDPrism);
2137 if (!theLF.IsDone()) {
2138 se = theLF.CurrentStatusError();
2139 //BRepFeat::Print(se,std::cout) << std::endl;
2140 Standard_SStream aSStream;
2141 BRepFeat::Print(se, aSStream);
2142 theCommands << aSStream << "\n";
2145 DBRep::Set(a[2], theLF);
2149 if (!theRF.IsDone()) {
2150 se = theRF.CurrentStatusError();
2151 //BRepFeat::Print(se,std::cout) << std::endl;
2152 Standard_SStream aSStream;
2153 BRepFeat::Print(se, aSStream);
2154 theCommands << aSStream << "\n";
2157 DBRep::Set(a[2], theRF);
2166 static Standard_Integer BOSS(Draw_Interpretor& theCommands,
2167 Standard_Integer narg, const char** a)
2169 if (strcasecmp(a[0], "ENDEDGES") && strcasecmp(a[0], "FILLET")
2170 && strcasecmp(a[0], "BOSSAGE")) {
2174 if ((!strcasecmp(a[0], "ENDEDGES") && narg != 5) ||
2175 (!strcasecmp(a[0], "FILLET") && (narg < 5 || narg % 2 != 1)) ||
2176 (!strcasecmp(a[0], "BOSSAGE") && narg != 6)) {
2177 theCommands.PrintHelp(a[0]);
2181 Standard_Integer Kas = 0;
2182 Standard_Integer dprsig = 0;
2183 if (!strcasecmp("ENDEDGES", a[0])) {
2185 dprsig = Draw::Atoi(a[4]);
2187 else if (!strcasecmp("FILLET", a[0])) {
2190 else if (!strcasecmp("BOSSAGE", a[0])) {
2192 dprsig = Draw::Atoi(a[5]);
2195 TopoDS_Shape theShapeTop;
2196 TopoDS_Shape theShapeBottom;
2198 if (Kas == 1 || Kas == 3) {
2199 if (!strcasecmp("DPRISM", a[1])) {
2201 theCommands << "dprism not defined";
2206 theCommands << "unknown argument : " << a[1];
2210 theDPrism.BossEdges(dprsig);
2212 TopTools_ListOfShape theTopEdges, theLatEdges;
2213 theTopEdges = theDPrism.TopEdges();
2214 theLatEdges = theDPrism.LatEdges();
2216 TopTools_ListIteratorOfListOfShape it;
2219 B.MakeCompound(TopoDS::Compound(theShapeTop));
2220 it.Initialize(theTopEdges);
2221 for (; it.More(); it.Next()) {
2222 TopExp_Explorer exp;
2223 for (exp.Init(it.Value(), TopAbs_EDGE); exp.More(); exp.Next()) {
2224 B.Add(theShapeTop, exp.Current());
2227 DBRep::Set(a[2], theShapeTop);
2230 B.MakeCompound(TopoDS::Compound(theShapeBottom));
2231 it.Initialize(theLatEdges);
2232 for (; it.More(); it.Next()) {
2233 B.Add(theShapeBottom, it.Value());
2235 DBRep::Set(a[3], theShapeBottom);
2237 if (Kas == 1) return 0;
2240 if (Kas == 2 || Kas == 3) {
2242 // Standard_Integer nrad;
2245 V = DBRep::Get(a[2], TopAbs_SHAPE);
2247 else if (Kas == 3) {
2251 if (V.IsNull()) return 1;
2252 ChFi3d_FilletShape FSh = ChFi3d_Rational;
2255 Rakk = new BRepFilletAPI_MakeFillet(V, FSh);
2256 Rakk->SetParams(ta, t3d, t2d, t3d, t2d, fl);
2257 Rakk->SetContinuity(blend_cont, tapp_angle);
2261 Standard_Integer nbedge = 0;
2264 for (Standard_Integer ii = 1; ii < (narg - 1) / 2; ii++) {
2265 Rad = Draw::Atof(a[2 * ii + 1]);
2266 if (Rad == 0.) continue;
2267 S = DBRep::Get(a[(2 * ii + 2)], TopAbs_SHAPE);
2268 TopExp_Explorer exp;
2269 for (exp.Init(S, TopAbs_EDGE); exp.More(); exp.Next()) {
2270 E = TopoDS::Edge(exp.Current());
2278 else if (Kas == 3) {
2279 Rad = Draw::Atof(a[3]);
2282 TopExp_Explorer exp;
2283 for (exp.Init(S, TopAbs_EDGE); exp.More(); exp.Next()) {
2284 E = TopoDS::Edge(exp.Current());
2291 Rad = Draw::Atof(a[4]);
2294 TopExp_Explorer exp;
2295 for (exp.Init(S, TopAbs_EDGE); exp.More(); exp.Next()) {
2296 E = TopoDS::Edge(exp.Current());
2305 if (!nbedge) return 1;
2307 if (!Rakk->IsDone()) return 1;
2308 TopoDS_Shape res = Rakk->Shape();
2311 DBRep::Set(a[1], res);
2313 else if (Kas == 3) {
2314 DBRep::Set(a[2], res);
2318 // Save history for fillet
2319 if (BRepTest_Objects::IsHistoryNeeded())
2321 TopTools_ListOfShape anArg;
2323 BRepTest_Objects::SetHistory(anArg, *Rakk);
2332 //=============================================================================
2333 //function : ComputeSimpleOffset
2334 //purpose : Computes simple offset.
2335 //=============================================================================
2336 static Standard_Integer ComputeSimpleOffset(Draw_Interpretor& theCommands,
2337 Standard_Integer narg,
2342 theCommands << "offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]\n";
2347 TopoDS_Shape aShape = DBRep::Get(a[2]);
2348 if (aShape.IsNull())
2350 theCommands << "Input shape is null";
2353 const Standard_Real anOffsetValue = Draw::Atof(a[3]);
2354 if (Abs(anOffsetValue) < gp::Resolution())
2356 theCommands << "Null offset value";
2360 Standard_Boolean makeSolid = (narg > 4 && !strcasecmp(a[4], "solid"));
2361 int iTolArg = (makeSolid ? 5 : 4);
2362 Standard_Real aTol = (narg > iTolArg ? Draw::Atof(a[iTolArg]) : Precision::Confusion());
2364 BRepOffset_MakeSimpleOffset aMaker(aShape, anOffsetValue);
2365 aMaker.SetTolerance(aTol);
2366 aMaker.SetBuildSolidFlag(makeSolid);
2369 if (!aMaker.IsDone())
2371 theCommands << "ERROR:" << aMaker.GetErrorMessage() << "\n";
2375 DBRep::Set(a[1], aMaker.GetResultShape());
2380 //=======================================================================
2381 //function : FeatureCommands
2383 //=======================================================================
2385 void BRepTest::FeatureCommands(Draw_Interpretor& theCommands)
2387 static Standard_Boolean done = Standard_False;
2389 done = Standard_True;
2391 DBRep::BasicCommands(theCommands);
2393 const char* g = "TOPOLOGY Feature commands";
2395 theCommands.Add("localope",
2396 " Performs a local top. operation : localope result shape tool F/C (fuse/cut) face [face...]",
2399 theCommands.Add("hole",
2400 " Performs a hole : hole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius [Pfrom Pto]",
2401 __FILE__, HOLE1, g);
2403 theCommands.Add("firsthole",
2404 " Performs the first hole : firsthole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2405 __FILE__, HOLE2, g);
2407 theCommands.Add("holend",
2408 " Performs the hole til end : holend result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius",
2409 __FILE__, HOLE3, g);
2411 theCommands.Add("blindhole",
2412 " Performs the blind hole : blindhole result shape Or.X Or.Y Or.Z Dir.X Dir.Y Dir.Z Radius Length",
2413 __FILE__, HOLE4, g);
2415 theCommands.Add("holecontrol",
2416 "Sets/Unsets or display controls on holes : holecontrol [0/1]",
2417 __FILE__, CONTROL, g);
2419 theCommands.Add("wprism",
2420 "Prisms wires on a face : wprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ SkecthFace wire1 [wire2 ....]",
2424 theCommands.Add("fprism",
2425 "Prisms a set of faces of a shape : fprism f[use]/c[ut] result shape [[FaceFrom] FaceUntil] VecX VecY VecZ face1 [face2...]",
2429 theCommands.Add("wrotate",
2430 "Rotates wires on a face : wrotate f[use]/c[ut] result shape Angle/[FFrom] FUntil OX OY OZ DX DY DZ SkecthFace wire1 [wire2 ....]",
2434 theCommands.Add("frotate",
2435 "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...]",
2439 theCommands.Add("splitshape",
2440 "splitshape result shape [splitedges] [face wire/edge/compound [wire/edge/compound ...][face wire/edge/compound [wire/edge/compound...] ...] [@ edgeonshape edgeonwire [edgeonshape edgeonwire...]]",
2444 theCommands.Add("thickshell",
2445 "thickshell r shape offset [jointype [tol] ]",
2446 __FILE__, thickshell, g);
2448 theCommands.Add("offsetshape",
2449 "offsetshape r shape offset [tol] [face ...]",
2450 __FILE__, offsetshape, g);
2452 theCommands.Add("offsetcompshape",
2453 "offsetcompshape r shape offset [face ...]",
2454 __FILE__, offsetshape, g);
2456 theCommands.Add("offsetparameter",
2457 "offsetparameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k)]",
2458 __FILE__, offsetparameter);
2460 theCommands.Add("offsetload",
2461 "offsetload shape offset bouchon1 bouchon2 ...",
2462 __FILE__, offsetload, g);
2464 theCommands.Add("offsetonface",
2465 "offsetonface face1 offset1 face2 offset2 ...",
2466 __FILE__, offsetonface, g);
2468 theCommands.Add("offsetperform",
2469 "offsetperform result",
2470 __FILE__, offsetperform, g);
2472 theCommands.Add("glue",
2473 "glue result shapenew shapebase facenew facebase [facenew facebase...] [edgenew edgebase [edgenew edgebase...]]",
2477 theCommands.Add("featprism",
2478 "Defines the arguments for a prism : featprism shape element skface Dirx Diry Dirz Fuse(0/1/2) Modify(0/1)",
2481 theCommands.Add("featrevol",
2482 "Defines the arguments for a revol : featrevol shape element skface Ox Oy Oz Dx Dy Dz Fuse(0/1/2) Modify(0/1)",
2485 theCommands.Add("featpipe",
2486 "Defines the arguments for a pipe : featpipe shape element skface spine Fuse(0/1/2) Modify(0/1)",
2489 theCommands.Add("featdprism",
2490 "Defines the arguments for a drafted prism : featdprism shape face skface angle Fuse(0/1/2) Modify(0/1)",
2493 theCommands.Add("featlf",
2494 "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)",
2497 theCommands.Add("featrf",
2498 "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)",
2501 theCommands.Add("addslide",
2502 " Adds sliding elements : addslide prism/revol/pipe edge face [edge face...]",
2505 theCommands.Add("featperform",
2506 " Performs the prism revol dprism linform or pipe :featperform prism/revol/pipe/dprism/lf result [[Ffrom] Funtil]",
2509 theCommands.Add("featperformval",
2510 " Performs the prism revol dprism or linform with a value :featperformval prism/revol/dprism/lf result value",
2513 theCommands.Add("endedges",
2514 " Return top and bottom edges of dprism :endedges dprism shapetop shapebottom First/LastShape (1/2)",
2517 theCommands.Add("fillet",
2518 " Perform fillet on compounds of edges :fillet result object rad1 comp1 rad2 comp2 ...",
2521 theCommands.Add("bossage",
2522 " Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)",
2525 theCommands.Add("offsetshapesimple",
2526 "offsetshapesimple result shape offsetvalue [solid] [tolerance=1e-7]",
2527 __FILE__, ComputeSimpleOffset);