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