0031147: Modeling Algorithms - BRepOffsetAPI_MakePipeShell null access
[occt.git] / src / BRepTest / BRepTest_SweepCommands.cxx
1 // Created on: 1993-07-22
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-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 <BRepTest.hxx>
18
19 #include <BRepTest_Objects.hxx>
20
21 #include <DBRep.hxx>
22 #include <Draw_Interpretor.hxx>
23 #include <Draw_Appli.hxx>
24
25 #include <BRepFill.hxx>
26 #include <BRepBuilderAPI_PipeError.hxx>
27 #include <BRepFill_Generator.hxx>
28 #include <BRepPrimAPI_MakePrism.hxx>
29 #include <BRepPrimAPI_MakeRevol.hxx>
30 #include <BRepOffsetAPI_MakePipe.hxx>
31 #include <BRepOffsetAPI_MakeEvolved.hxx>
32 #include <BRepOffsetAPI_ThruSections.hxx>
33 #include <BRepOffsetAPI_MakePipeShell.hxx>
34 #include <BRepOffsetAPI_MiddlePath.hxx>
35
36 #include <BRepLib_MakeWire.hxx>
37 #include <TopoDS.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopExp_Explorer.hxx>
40
41 #include <Precision.hxx>
42 #include <Law_Interpol.hxx>
43 #include <gp_Ax1.hxx>
44 #include <gp_Ax2.hxx>
45 #include <gp_Pnt2d.hxx>
46 #include <TColgp_Array1OfPnt2d.hxx>
47
48 static BRepOffsetAPI_MakePipeShell* Sweep = 0;
49 static BRepOffsetAPI_ThruSections* Generator = 0;
50
51 #include <stdio.h>
52 #include <Geom_Curve.hxx>
53 #include <GeomAdaptor_Curve.hxx>
54 #include <GeomFill_Pipe.hxx>
55 #include <Geom_Surface.hxx>
56 #include <BRepBuilderAPI_MakeFace.hxx>
57 #include <BRep_Tool.hxx>
58 #include <gp_Pnt.hxx>
59 #include <gp_Vec.hxx>
60 #include <Geom_Circle.hxx>
61 #include <gp_Ax2.hxx>
62 #include <Message.hxx>
63
64 //=======================================================================
65 // prism
66 //=======================================================================
67
68 static Standard_Integer prism(Draw_Interpretor&, Standard_Integer n, const char** a)
69 {
70   if (n < 6) return 1;
71
72   TopoDS_Shape base = DBRep::Get(a[2]);
73   if (base.IsNull()) return 1;
74
75   gp_Vec V(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
76
77   Standard_Boolean copy = Standard_False;
78   Standard_Boolean inf = Standard_False;
79   Standard_Boolean sinf = Standard_False;
80
81   if (n > 6) {
82     copy = (*a[6] == 'c') || (*a[6] == 'C');
83     inf = (*a[6] == 'i') || (*a[6] == 'I');
84     sinf = (*a[6] == 's') || (*a[6] == 'S');
85   }
86
87   TopoDS_Shape res;
88
89   BRepPrimAPI_MakePrism* Prism;
90   if (inf || sinf)
91   {
92     Prism = new BRepPrimAPI_MakePrism(base, gp_Dir(V), inf);
93   }
94   else
95   {
96     Prism = new BRepPrimAPI_MakePrism(base, V, copy);
97   }
98
99   res = Prism->Shape();
100
101   DBRep::Set(a[1], res);
102
103   //History 
104   TopTools_ListOfShape anArgs;
105   anArgs.Append(base);
106   BRepTest_Objects::SetHistory(anArgs, *Prism);
107
108   delete Prism;
109
110   return 0;
111 }
112
113
114 //=======================================================================
115 // revol
116 //=======================================================================
117 static Standard_Integer revol(Draw_Interpretor& di,
118   Standard_Integer n, const char** a)
119 {
120   if (n < 10) return 1;
121
122   TopoDS_Shape base = DBRep::Get(a[2]);
123   if (base.IsNull()) return 1;
124
125   gp_Pnt P(Draw::Atof(a[3]), Draw::Atof(a[4]), Draw::Atof(a[5]));
126   gp_Dir D(Draw::Atof(a[6]), Draw::Atof(a[7]), Draw::Atof(a[8]));
127   gp_Ax1 A(P, D);
128
129   Standard_Real angle = Draw::Atof(a[9]) * (M_PI / 180.0);
130
131   Standard_Boolean copy = n > 10;
132
133
134   BRepPrimAPI_MakeRevol Revol(base, A, angle, copy);
135
136   if (Revol.IsDone())
137   {
138     TopoDS_Shape res = Revol.Shape();
139
140     DBRep::Set(a[1], res);
141
142     //History 
143     TopTools_ListOfShape anArgs;
144     anArgs.Append(base);
145     BRepTest_Objects::SetHistory(anArgs, Revol);
146   }
147   else
148   {
149     di << "Revol not done \n";
150   }
151
152   return 0;
153 }
154
155
156 //=======================================================================
157 // pipe
158 //=======================================================================
159
160 static Standard_Integer pipe(Draw_Interpretor& di,
161   Standard_Integer n, const char** a)
162 {
163   if (n == 1)
164   {
165     di << "pipe result Wire_spine Profile [Mode [Approx]]\n";
166     di << "Mode = 0 - CorrectedFrenet,\n";
167     di << "     = 1 - Frenet,\n";
168     di << "     = 2 - DiscreteTrihedron\n";
169     di << "Approx - force C1-approximation if result is C0\n";
170     return 0;
171   }
172
173   if (n > 1 && n < 4) return 1;
174
175   TopoDS_Shape Spine = DBRep::Get(a[2], TopAbs_WIRE);
176   if (Spine.IsNull()) return 1;
177
178   TopoDS_Shape Profile = DBRep::Get(a[3]);
179   if (Profile.IsNull()) return 1;
180
181   GeomFill_Trihedron Mode = GeomFill_IsCorrectedFrenet;
182   if (n >= 5)
183   {
184     Standard_Integer iMode = atoi(a[4]);
185     if (iMode == 1)
186       Mode = GeomFill_IsFrenet;
187     else if (iMode == 2)
188       Mode = GeomFill_IsDiscreteTrihedron;
189   }
190
191   Standard_Boolean ForceApproxC1 = Standard_False;
192   if (n >= 6)
193     ForceApproxC1 = Standard_True;
194
195   BRepOffsetAPI_MakePipe PipeBuilder(TopoDS::Wire(Spine),
196     Profile,
197     Mode,
198     ForceApproxC1);
199   TopoDS_Shape S = PipeBuilder.Shape();
200
201   DBRep::Set(a[1], S);
202
203   // Save history of pipe
204   if (BRepTest_Objects::IsHistoryNeeded())
205   {
206     TopTools_ListOfShape aList;
207     aList.Append(Profile);
208     aList.Append(Spine);
209     BRepTest_Objects::SetHistory(aList, PipeBuilder);
210   }
211
212   return 0;
213 }
214
215 //=======================================================================
216
217 static Standard_Integer geompipe(Draw_Interpretor&,
218   Standard_Integer n, const char** a)
219 {
220   TopoDS_Shape Spine = DBRep::Get(a[2], TopAbs_EDGE);
221   if (Spine.IsNull()) return 1;
222   if (n < 5) return 1;
223   TopoDS_Shape Profile = DBRep::Get(a[3], TopAbs_EDGE);
224   if (Profile.IsNull()) return 1;
225   Standard_Real aSpFirst, aSpLast, aPrFirst, aPrLast;
226   Handle(Geom_Curve) SpineCurve = BRep_Tool::Curve(TopoDS::Edge(Spine), aSpFirst, aSpLast);
227   Handle(Geom_Curve) ProfileCurve = BRep_Tool::Curve(TopoDS::Edge(Profile), aPrFirst, aPrLast);
228   Handle(GeomAdaptor_Curve) aAdaptCurve = new GeomAdaptor_Curve(SpineCurve, aSpFirst, aSpLast);
229   Standard_Boolean ByACR = Standard_False;
230   Standard_Boolean rotate = Standard_False;
231   Standard_Real Radius = Draw::Atof(a[4]);
232   gp_Pnt ctr;
233   gp_Vec norm;
234   ProfileCurve->D1(aSpFirst, ctr, norm);
235   gp_Vec xAxisStart(ctr, SpineCurve->Value(aSpFirst));
236   gp_Ax2 aAx2Start(ctr, norm, xAxisStart);
237   Handle(Geom_Circle) cStart = new Geom_Circle(aAx2Start, Radius);
238   Standard_Integer k = 5;
239   if (n > k)
240     ByACR = (Draw::Atoi(a[k++]) == 1);
241   if (n > k)
242     rotate = (Draw::Atoi(a[k++]) == 1);
243   GeomFill_Pipe aPipe(ProfileCurve, aAdaptCurve, cStart, ByACR, rotate);
244   aPipe.Perform(Standard_True);
245   if (!aPipe.IsDone())
246   {
247     Message::SendFail() << "GeomFill_Pipe cannot make a surface";
248     return 1;
249   }
250
251   Standard_Real Accuracy = aPipe.ErrorOnSurf();
252   std::cout << "Accuracy of approximation = " << Accuracy << std::endl;
253   
254   Handle(Geom_Surface) Sur = aPipe.Surface();
255   TopoDS_Face F;
256   if (!Sur.IsNull())
257     F = BRepBuilderAPI_MakeFace(Sur, Precision::Confusion());
258   DBRep::Set(a[1], F);
259   return 0;
260 }
261
262 //=======================================================================
263 //function : evolved
264 //purpose  : 
265 //=======================================================================
266
267 Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char** a)
268 {
269   if (n == 1) {
270     di << " evolved result -s spine -p profile [-solid] [-v] [-a] [-t toler] [-parallel] : \n";
271     di << "   Make evolved profile on spine.\n";
272     di << "   -solid means make closed solid.\n";
273     di << "   -v means use alternative algorithm (volume mode).\n";
274     di << "   -a means referential CS is automatically computed, otherwise global CS is used. \n";
275     di << "   -t sets the tolerance.\n";
276     di << "   -parallel turns on parallel execution.\n";
277     return 0;
278   }
279
280   if (n < 4) return 1;
281   Standard_Boolean Solid   = Standard_False;  
282   Standard_Boolean isVolume = Standard_False;
283   Standard_Boolean hasToComputeAxes = Standard_False;
284   Standard_Real aTolerance = 0.0;
285   TopoDS_Shape Base;
286   TopoDS_Wire Prof;
287   Standard_Boolean isParallel = Standard_True;
288
289   for (Standard_Integer i = 2; i < n; i++)
290   {
291     if (a[i][0] != '-')
292     {
293       di << "Error: wrong option!\n";
294       return 1;
295     }
296
297     if (!Solid && !strcmp(a[i], "-solid"))
298     {
299       Solid = Standard_True;
300       continue;
301     }
302
303     if (!strcmp(a[i], "-stm"))
304     {
305       isParallel = Standard_False;
306       continue;
307     }
308
309     switch (a[i][1])
310     {
311       case 's':
312       {
313         Base = DBRep::Get(a[++i], TopAbs_WIRE, Standard_False);
314         if (Base.IsNull())
315         {
316           Base = DBRep::Get(a[i], TopAbs_FACE, Standard_False);
317         }
318       }
319       break;
320
321       case 'p':
322       {
323         Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False));
324       }
325       break;
326
327       case 'v':
328       {
329         isVolume = Standard_True;
330       }
331       break;
332
333       case 'a':
334       {
335         hasToComputeAxes = Standard_True;
336       }
337       break;
338
339       case 't':
340       {
341         aTolerance = Draw::Atof(a[++i]);
342       }
343       break;
344
345       default: 
346         di << "Error: Unknown option!\n";
347         break;
348     }
349   }
350  
351   if (Base.IsNull() || Prof.IsNull())
352   {
353     di << "spine (face or wire) and profile (wire) are expected\n";
354     return 1;
355   }
356
357   TopoDS_Shape Volevo = BRepOffsetAPI_MakeEvolved(Base, Prof, GeomAbs_Arc, !hasToComputeAxes,
358                                                   Solid, Standard_False, 
359                                                   aTolerance, isVolume, isParallel);
360
361   DBRep::Set(a[1],Volevo);
362
363   return 0;
364 }
365
366
367 //=======================================================================
368 //function : pruled
369 //purpose  : 
370 //=======================================================================
371
372 static Standard_Integer pruled(Draw_Interpretor&,
373   Standard_Integer n, const char** a)
374 {
375   if (n != 4) return 1;
376
377   Standard_Boolean YaWIRE = Standard_False;
378   TopoDS_Shape S1 = DBRep::Get(a[2], TopAbs_EDGE);
379   if (S1.IsNull()) {
380     S1 = DBRep::Get(a[2], TopAbs_WIRE);
381     if (S1.IsNull()) return 1;
382     YaWIRE = Standard_True;
383   }
384
385   TopoDS_Shape S2 = DBRep::Get(a[3], TopAbs_EDGE);
386   if (S2.IsNull()) {
387     S2 = DBRep::Get(a[3], TopAbs_WIRE);
388     if (S2.IsNull()) return 1;
389     if (!YaWIRE) {
390       S1 = BRepLib_MakeWire(TopoDS::Edge(S1));
391       YaWIRE = Standard_True;
392     }
393   }
394   else if (YaWIRE) {
395     S2 = BRepLib_MakeWire(TopoDS::Edge(S2));
396   }
397
398   TopoDS_Shape Result;
399   if (YaWIRE) {
400     Result = BRepFill::Shell(TopoDS::Wire(S1), TopoDS::Wire(S2));
401   }
402   else {
403     Result = BRepFill::Face(TopoDS::Edge(S1), TopoDS::Edge(S2));
404   }
405
406   DBRep::Set(a[1], Result);
407   return 0;
408 }
409
410
411 //=======================================================================
412 //function : gener
413 //purpose  : Create a surface between generating wires
414 //=======================================================================
415
416 Standard_Integer gener(Draw_Interpretor&, Standard_Integer n, const char** a)
417 {
418   if (n < 4) return 1;
419
420   TopoDS_Shape Shape;
421
422   BRepFill_Generator aGenerator;
423
424   for (Standard_Integer i = 2; i <= n - 1; i++) {
425     Shape = DBRep::Get(a[i], TopAbs_WIRE);
426     if (Shape.IsNull())
427       return 1;
428
429     aGenerator.AddWire(TopoDS::Wire(Shape));
430   }
431
432   aGenerator.Perform();
433
434   TopoDS_Shell Shell = aGenerator.Shell();
435
436   DBRep::Set(a[1], Shell);
437
438
439   return 0;
440 }
441
442
443 //=======================================================================
444 //function : thrusections
445 //purpose  : 
446 //=======================================================================
447
448 Standard_Integer thrusections(Draw_Interpretor&, Standard_Integer n, const char** a)
449 {
450   if (n < 6) return 1;
451
452   Standard_Boolean check = Standard_True;
453   Standard_Boolean samenumber = Standard_True;
454   Standard_Integer index = 2;
455   // Lecture option
456   if (!strcmp(a[1], "-N")) {
457     if (n < 7) return 1;
458     check = Standard_False;
459     index++;
460   }
461
462   TopoDS_Shape Shape;
463
464   Standard_Boolean issolid = (Draw::Atoi(a[index]) == 1);
465   Standard_Boolean isruled = (Draw::Atoi(a[index + 1]) == 1);
466
467   if (Generator != 0)
468   {
469     delete Generator;
470     Generator = 0;
471   }
472   Generator = new BRepOffsetAPI_ThruSections(issolid, isruled);
473
474   Standard_Integer NbEdges = 0;
475   Standard_Boolean IsFirstWire = Standard_False;
476   for (Standard_Integer i = index + 2; i <= n - 1; i++) {
477     Standard_Boolean IsWire = Standard_True;
478     Shape = DBRep::Get(a[i], TopAbs_WIRE);
479     if (!Shape.IsNull())
480     {
481       Generator->AddWire(TopoDS::Wire(Shape));
482       if (!IsFirstWire)
483         IsFirstWire = Standard_True;
484       else
485         IsFirstWire = Standard_False;
486     }
487     else
488     {
489       Shape = DBRep::Get(a[i], TopAbs_VERTEX);
490       IsWire = Standard_False;
491       if (!Shape.IsNull())
492         Generator->AddVertex(TopoDS::Vertex(Shape));
493       else
494         return 1;
495     }
496
497     Standard_Integer cpt = 0;
498     TopExp_Explorer PE;
499     for (PE.Init(Shape, TopAbs_EDGE); PE.More(); PE.Next()) {
500       cpt++;
501     }
502     if (IsFirstWire)
503       NbEdges = cpt;
504     else
505       if (IsWire && cpt != NbEdges)
506         samenumber = Standard_False;
507
508   }
509
510   check = (check || !samenumber);
511   Generator->CheckCompatibility(check);
512
513   Generator->Build();
514
515   if (Generator->IsDone()) {
516     TopoDS_Shape Shell = Generator->Shape();
517     DBRep::Set(a[index - 1], Shell);
518     // Save history of the lofting
519     if (BRepTest_Objects::IsHistoryNeeded())
520       BRepTest_Objects::SetHistory(Generator->Wires(), *Generator);
521   }
522   else {
523     std::cout << "Algorithm is not done" << std::endl;
524   }
525
526   return 0;
527 }
528
529 //=======================================================================
530 //  mksweep
531 //=======================================================================
532 static Standard_Integer mksweep(Draw_Interpretor&,
533   Standard_Integer n, const char** a)
534 {
535   if (n != 2) return 1;
536   TopoDS_Shape Spine = DBRep::Get(a[1], TopAbs_WIRE);
537   if (Spine.IsNull()) return 1;
538   if (Sweep != 0)  {
539     delete Sweep;
540     Sweep = 0;
541   }
542   Sweep = new BRepOffsetAPI_MakePipeShell(TopoDS::Wire(Spine));
543   return 0;
544 }
545
546 //=======================================================================
547 //  setsweep
548 //=======================================================================
549 static Standard_Integer setsweep(Draw_Interpretor& di,
550   Standard_Integer n, const char** a)
551 {
552   if (n == 1) {
553     di << "setsweep options [arg1 [arg2 [...]]] : options are :\n";
554     di << "   -FR : Tangent and Normal are given by Frenet trihedron\n";
555     di << "   -CF : Tangente is given by Frenet,\n";
556     di << "         the Normal is computed to minimize the torsion \n";
557     di << "   -DT : discrete trihedron\n";
558     di << "   -DX Surf : Tangent and Normal are given by Darboux trihedron,\n";
559     di << "       Surf have to be a shell or a face\n";
560     di << "   -CN dx dy dz : BiNormal is given by dx dy dz\n";
561     di << "   -FX Tx Ty TZ [Nx Ny Nz] : Tangent and Normal are fixed\n";
562     di << "   -G guide  0|1(Plan|ACR)  0|1|2(no contact|contact|contact on border) : with guide\n";
563     di << "   -SM : Set the maximum degree of approximation\n";
564     di << "         paramvalue more then 0 (100 by default)\n";
565     di << "   -DM : Set the maximum number of span of approximation\n";
566     di << "         paramvalue [1; 14] (11 by default)\n";
567     return 0;
568   }
569
570   if (Sweep == 0) {
571     di << "You have forgotten the <<mksweep>> command  !\n";
572     return 1;
573   }
574   if (!strcmp(a[1], "-FR")) {
575     Sweep->SetMode(Standard_True);
576   }
577   else if (!strcmp(a[1], "-CF")) {
578     Sweep->SetMode(Standard_False);
579   }
580   else if (!strcmp(a[1], "-DT")) {
581     Sweep->SetDiscreteMode();
582   }
583   else if (!strcmp(a[1], "-DX")) {
584     if (n != 3) {
585       di << "bad arguments !\n";
586       return 1;
587     }
588     TopoDS_Shape Surf;
589     Surf = DBRep::Get(a[2], TopAbs_SHAPE);
590     if (Surf.IsNull()) {
591       di << a[2] << "is not a shape !\n";
592       return 1;
593     }
594     Sweep->SetMode(Surf);
595   }
596   else if (!strcmp(a[1], "-CN")) {
597     if (n != 5) {
598       di << "bad arguments !\n";
599       return 1;
600     }
601     gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
602     Sweep->SetMode(D);
603   }
604   else if (!strcmp(a[1], "-FX")) {
605     if ((n != 5) && (n != 8)) {
606       di << "bad arguments !\n";
607       return 1;
608     }
609     gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
610     if (n == 8) {
611       gp_Dir DN(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
612       gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D, DN);
613       Sweep->SetMode(Axe);
614     }
615     else {
616       gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D);
617       Sweep->SetMode(Axe);
618     }
619   }
620   else if (!strcmp(a[1], "-G"))  // contour guide
621   {
622     if (n != 5)
623     {
624       di << "bad arguments !\n";
625       return 1;
626     }
627     else
628     {
629       TopoDS_Shape Guide = DBRep::Get(a[2], TopAbs_WIRE);
630       Standard_Boolean CurvilinearEquivalence = Draw::Atoi(a[3]) != 0;
631       Standard_Integer KeepContact = Draw::Atoi(a[4]);
632       Sweep->SetMode(TopoDS::Wire(Guide),
633         CurvilinearEquivalence,
634         (BRepFill_TypeOfContact)KeepContact);
635     }
636   }
637   else if (!strcmp(a[1], "-DM"))
638   {
639     if (n != 3)
640     {
641       di << "bad arguments !\n";
642       return 1;
643     }
644
645     if (Draw::Atoi(a[2]) > 0 && Draw::Atoi(a[2]) < 15)
646     {
647       Sweep->SetMaxDegree(Draw::Atoi(a[2]));
648     }
649     else
650     {
651       di << " -DM paramvalue must be [1; 14]\n";
652       return 1;
653     }
654   }
655   else if (!strcmp(a[1], "-SM"))
656   {
657     if (n != 3)
658     {
659       di << "bad arguments !\n";
660       return 1;
661     }
662
663     if (Draw::Atoi(a[2]) > 0)
664     {
665       Sweep->SetMaxSegments(Draw::Atoi(a[2]));
666     }
667     else
668     {
669       di << " -SM paramvalue must be more then 0\n";
670       return 1;
671     }
672   }
673
674   else {
675     di << "The option " << a[1] << " is unknown !\n";
676     return 1;
677   }
678   return 0;
679 }
680
681 //=======================================================================
682 //  addsweep
683 //=======================================================================
684 static Standard_Integer addsweep(Draw_Interpretor& di,
685   Standard_Integer n, const char** a)
686 {
687   if (n == 1) {
688     di << "addsweep wire/vertex [Vertex] [-T] [-R] [u0 v0 u1 v1 [...[uN vN]]] : options are :\n";
689     di << "   -T : the wire/vertex have to be translated to assume contact\n";
690     di << "        with the spine\n";
691     di << "   -R : the wire have to be rotated to assume orthogonality\n";
692     di << "        with the spine's tangent\n";
693     return 0;
694   }
695
696   if (Sweep == 0) {
697     di << "You have forgotten the <<mksweep>> command  !\n";
698     return 1;
699   }
700
701   TopoDS_Shape  Section;
702   TopoDS_Vertex Vertex;
703   Handle(Law_Interpol) thelaw;
704
705   Section = DBRep::Get(a[1], TopAbs_SHAPE);
706   if (Section.IsNull() ||
707     (Section.ShapeType() != TopAbs_WIRE &&
708     Section.ShapeType() != TopAbs_VERTEX))
709   {
710     di << a[1] << " is not a wire and is not a vertex!\n";
711     return 1;
712   }
713
714   Standard_Boolean HasVertex = Standard_False,
715     isT = Standard_False,
716     isR = Standard_False;
717
718   if (n > 2) {
719     Standard_Integer cur = 2;
720     // Reading of Vertex
721     TopoDS_Shape InputVertex(DBRep::Get(a[cur], TopAbs_VERTEX));
722     Vertex = TopoDS::Vertex(InputVertex);
723     if (!Vertex.IsNull()) {
724       cur++;
725       HasVertex = Standard_True;
726     }
727
728     // Reading of the translation option
729     if ((n > cur) && !strcmp(a[cur], "-T")) {
730       cur++;
731       isT = Standard_True;
732     }
733
734     // Reading of the rotation option
735     if ((n > cur) && !strcmp(a[cur], "-R")) {
736       cur++;
737       isR = Standard_True;
738     }
739
740     // law ?
741     if (n > cur) {
742       Standard_Integer nbreal = n - cur;
743       if ((nbreal < 4) || (nbreal % 2 != 0)) {
744         //std::cout << "bad arguments ! :" <<a[cur] << std::endl;
745         di << "bad arguments ! :" << a[cur] << "\n";
746       }
747       else { //law of interpolation
748         Standard_Integer ii, L = nbreal / 2;
749         TColgp_Array1OfPnt2d ParAndRad(1, L);
750         for (ii = 1; ii <= L; ii++, cur += 2) {
751           ParAndRad(ii).SetX(Draw::Atof(a[cur]));
752           ParAndRad(ii).SetY(Draw::Atof(a[cur + 1]));
753         }
754         thelaw = new (Law_Interpol)();
755         thelaw->Set(ParAndRad,
756           Abs(ParAndRad(1).Y() - ParAndRad(L).Y()) < Precision::Confusion());
757       }
758     }
759   }
760
761   if (thelaw.IsNull()) {
762     if (HasVertex) Sweep->Add(Section, Vertex, isT, isR);
763     else           Sweep->Add(Section, isT, isR);
764   }
765   else {
766     if (HasVertex) Sweep->SetLaw(Section, thelaw, Vertex, isT, isR);
767     else           Sweep->SetLaw(Section, thelaw, isT, isR);
768   }
769
770   return 0;
771 }
772
773 //=======================================================================
774 //  deletesweep
775 //=======================================================================
776 static Standard_Integer deletesweep(Draw_Interpretor& di,
777   Standard_Integer n, const char** a)
778 {
779   if (n != 2) {
780     return 1;
781   }
782   TopoDS_Wire Section;
783   TopoDS_Shape InputShape(DBRep::Get(a[1], TopAbs_SHAPE));
784   Section = TopoDS::Wire(InputShape);
785   if (Section.IsNull()) {
786     di << a[1] << "is not a wire !\n";
787     return 1;
788   }
789
790   Sweep->Delete(Section);
791   return 0;
792 }
793
794 //=======================================================================
795 //  buildsweep
796 //=======================================================================
797 static Standard_Integer buildsweep(Draw_Interpretor& di,
798   Standard_Integer n, const char** a)
799 {
800   if (n == 1) {
801     di << "build sweep result [-M/-C/-R] [-S] [tol] : options are\n";
802     di << "   -M : Discontinuities are treated by Modification of\n";
803     di << "        the sweeping mode : it is the default\n";
804     di << "   -C : Discontinuities are treated like Right Corner\n";
805     di << "        Treatment is Extent && Intersect\n";
806     di << "   -R : Discontinuities are treated like Round Corner\n";
807     di << "        Treatment is Intersect and Fill\n";
808     di << "   -S : To build a Solid\n";
809     return 0;
810   }
811
812   Standard_Boolean mksolid = Standard_False;
813   if (Sweep == 0) {
814     di << "You have forgotten the <<mksweep>> command  !\n";
815     return 1;
816   }
817
818   if (!Sweep->IsReady()) {
819     di << "You have forgotten the <<addsweep>> command  !\n";
820     return 1;
821   }
822
823   TopoDS_Shape result;
824   Standard_Integer cur = 2;
825   if (n > cur) {
826     BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
827
828     // Reading Transition
829     if (!strcmp(a[cur], "-C")) {
830       Transition = BRepBuilderAPI_RightCorner;
831       cur++;
832     }
833     else if (!strcmp(a[cur], "-R")) {
834       Transition = BRepBuilderAPI_RoundCorner;
835       cur++;
836     }
837     Sweep->SetTransitionMode(Transition);
838   }
839   // Reading solid ?
840   if ((n > cur) && (!strcmp(a[cur], "-S"))) mksolid = Standard_True;
841
842   // Calcul le resultat
843   Sweep->Build();
844   if (!Sweep->IsDone()) {
845     di << "Buildsweep : Not Done\n";
846     BRepBuilderAPI_PipeError Stat = Sweep->GetStatus();
847     if (Stat == BRepBuilderAPI_PlaneNotIntersectGuide) {
848       di << "Buildsweep : One Plane not intersect the guide\n";
849     }
850     if (Stat == BRepBuilderAPI_ImpossibleContact) {
851       di << "BuildSweep : One section can not be in contact with the guide\n";
852     }
853   }
854   else {
855     if (mksolid) {
856       Standard_Boolean B;
857       B = Sweep->MakeSolid();
858       if (!B) di << " BuildSweep : It is impossible to make a solid !\n";
859     }
860     result = Sweep->Shape();
861     DBRep::Set(a[1], result);
862     // Save history of sweep
863     if (BRepTest_Objects::IsHistoryNeeded())
864     {
865       TopTools_ListOfShape aList;
866       Sweep->Profiles(aList);
867       TopoDS_Shape aSpine = Sweep->Spine();
868       aList.Append(aSpine);
869       BRepTest_Objects::SetHistory(aList, *Sweep);
870     }
871   }
872
873   return 0;
874 }
875
876 //=======================================================================
877 //function : errorsweep
878 //purpose  : returns the summary error on resulting surfaces
879 //           reached by Sweep
880 //=======================================================================
881 static Standard_Integer errorsweep(Draw_Interpretor& di,
882   Standard_Integer, const char**)
883 {
884   if (!Sweep->IsDone())
885   {
886     di << "Sweep is not done\n";
887     return 1;
888   }
889   Standard_Real ErrorOnSurfaces = Sweep->ErrorOnSurface();
890   di << "Tolerance on surfaces = " << ErrorOnSurfaces << "\n";
891   return 0;
892 }
893
894 //=======================================================================
895 //  simulsweep
896 //=======================================================================
897 static Standard_Integer simulsweep(Draw_Interpretor& di,
898   Standard_Integer n, const char** a)
899 {
900   if ((n != 3) && (n != 4)) return 1;
901
902   if (Sweep == 0) {
903     di << "You have forgotten the <<mksweep>> command  !\n";
904     return 1;
905   }
906
907   if (!Sweep->IsReady()) {
908     di << "You have forgotten the <<addsweep>> command  !\n";
909     return 1;
910   }
911
912   char name[100];
913   TopTools_ListOfShape List;
914   TopTools_ListIteratorOfListOfShape it;
915   Standard_Integer N, ii;
916   N = Draw::Atoi(a[2]);
917
918   if (n > 3) {
919     BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
920     // Lecture Transition
921     if (!strcmp(a[3], "-C")) {
922       Transition = BRepBuilderAPI_RightCorner;
923     }
924     else if (!strcmp(a[3], "-R")) {
925       Transition = BRepBuilderAPI_RoundCorner;
926     }
927     Sweep->SetTransitionMode(Transition);
928   }
929
930   // Calculate the result
931   Sweep->Simulate(N, List);
932   for (ii = 1, it.Initialize(List); it.More(); it.Next(), ii++) {
933     Sprintf(name, "%s_%d", a[1], ii);
934     DBRep::Set(name, it.Value());
935   }
936
937   return 0;
938 }
939
940 //=======================================================================
941 //  middlepath
942 //=======================================================================
943 static Standard_Integer middlepath(Draw_Interpretor& /*di*/,
944   Standard_Integer n, const char** a)
945 {
946   if (n < 5) return 1;
947
948   TopoDS_Shape aShape = DBRep::Get(a[2]);
949   if (aShape.IsNull()) return 1;
950
951   TopoDS_Shape StartShape = DBRep::Get(a[3]);
952   if (StartShape.IsNull()) return 1;
953
954   TopoDS_Shape EndShape = DBRep::Get(a[4]);
955   if (EndShape.IsNull()) return 1;
956
957   BRepOffsetAPI_MiddlePath Builder(aShape, StartShape, EndShape);
958   Builder.Build();
959
960   TopoDS_Shape Result = Builder.Shape();
961   DBRep::Set(a[1], Result);
962
963   return 0;
964 }
965
966 //=======================================================================
967 //function : SweepCommands
968 //purpose  : 
969 //=======================================================================
970
971 void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
972 {
973   static Standard_Boolean done = Standard_False;
974   if (done) return;
975   done = Standard_True;
976
977   DBRep::BasicCommands(theCommands);
978
979   const char* g = "Sweep commands";
980
981   theCommands.Add("prism",
982     "prism result base dx dy dz [Copy | Inf | Seminf]",
983     __FILE__, prism, g);
984
985   theCommands.Add("revol",
986     "revol result base px py pz dx dy dz angle [Copy]",
987     __FILE__, revol, g);
988
989   theCommands.Add("pipe",
990     "pipe result Wire_spine Profile [Mode [Approx]], no args to get help",
991     __FILE__, pipe, g);
992
993   theCommands.Add("evolved",
994     "evolved , no args to get help",
995     __FILE__, evolved, g);
996
997   theCommands.Add("pruled",
998     "pruled result Edge1/Wire1 Edge2/Wire2",
999     __FILE__, pruled, g);
1000
1001   theCommands.Add("gener", "gener result wire1 wire2 [..wire..]",
1002     __FILE__, gener, g);
1003
1004   theCommands.Add("thrusections", "thrusections [-N] result issolid isruled shape1 shape2 [..shape..], the option -N means no check on wires, shapes must be wires or vertices (only first or last)",
1005     __FILE__, thrusections, g);
1006
1007   theCommands.Add("mksweep", "mksweep wire",
1008     __FILE__, mksweep, g);
1009
1010   theCommands.Add("setsweep", "setsweep  no args to get help",
1011     __FILE__, setsweep, g);
1012
1013   theCommands.Add("addsweep",
1014     "addsweep wire [vertex] [-M ] [-C] [auxiilaryshape]:no args to get help",
1015     __FILE__, addsweep, g);
1016
1017   theCommands.Add("deletesweep",
1018     "deletesweep wire, To delete a section",
1019     __FILE__, deletesweep, g);
1020
1021   theCommands.Add("buildsweep", "builsweep [r] [option] [Tol] , no args to get help",
1022     __FILE__, buildsweep, g);
1023
1024   theCommands.Add("errorsweep", "errorsweep: returns the summary error on resulting surfaces reached by Sweep",
1025     __FILE__, errorsweep, g);
1026
1027   theCommands.Add("simulsweep", "simulsweep r [n] [option]",
1028     __FILE__, simulsweep, g);
1029   theCommands.Add("geompipe", "geompipe r spineedge profileedge radius [byACR [byrotate]]",
1030     __FILE__, geompipe, g);
1031
1032   theCommands.Add("middlepath", "middlepath res shape startshape endshape",
1033     __FILE__, middlepath, g);
1034 }
1035