0028966: Coding Rules - remove Adaptor2d_HCurve2d, Adaptor3d_HCurve and Adaptor3d_HSu...
[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 referencial 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     return 0;
564   }
565
566   if (Sweep == 0) {
567     di << "You have forgotten the <<mksweep>> command  !\n";
568     return 1;
569   }
570   if (!strcmp(a[1], "-FR")) {
571     Sweep->SetMode(Standard_True);
572   }
573   else if (!strcmp(a[1], "-CF")) {
574     Sweep->SetMode(Standard_False);
575   }
576   else if (!strcmp(a[1], "-DT")) {
577     Sweep->SetDiscreteMode();
578   }
579   else if (!strcmp(a[1], "-DX")) {
580     if (n != 3) {
581       di << "bad arguments !\n";
582       return 1;
583     }
584     TopoDS_Shape Surf;
585     Surf = DBRep::Get(a[2], TopAbs_SHAPE);
586     if (Surf.IsNull()) {
587       di << a[2] << "is not a shape !\n";
588       return 1;
589     }
590     Sweep->SetMode(Surf);
591   }
592   else if (!strcmp(a[1], "-CN")) {
593     if (n != 5) {
594       di << "bad arguments !\n";
595       return 1;
596     }
597     gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
598     Sweep->SetMode(D);
599   }
600   else if (!strcmp(a[1], "-FX")) {
601     if ((n != 5) && (n != 8)) {
602       di << "bad arguments !\n";
603       return 1;
604     }
605     gp_Dir D(Draw::Atof(a[2]), Draw::Atof(a[3]), Draw::Atof(a[4]));
606     if (n == 8) {
607       gp_Dir DN(Draw::Atof(a[5]), Draw::Atof(a[6]), Draw::Atof(a[7]));
608       gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D, DN);
609       Sweep->SetMode(Axe);
610     }
611     else {
612       gp_Ax2 Axe(gp_Pnt(0., 0., 0.), D);
613       Sweep->SetMode(Axe);
614     }
615   }
616   else if (!strcmp(a[1], "-G"))  // contour guide
617   {
618     if (n != 5)
619     {
620       di << "bad arguments !\n";
621       return 1;
622     }
623     else
624     {
625       TopoDS_Shape Guide = DBRep::Get(a[2], TopAbs_WIRE);
626       Standard_Boolean CurvilinearEquivalence = Draw::Atoi(a[3]) != 0;
627       Standard_Integer KeepContact = Draw::Atoi(a[4]);
628       Sweep->SetMode(TopoDS::Wire(Guide),
629         CurvilinearEquivalence,
630         (BRepFill_TypeOfContact)KeepContact);
631     }
632   }
633
634   else {
635     di << "The option " << a[1] << " is unknown !\n";
636     return 1;
637   }
638   return 0;
639 }
640
641
642 //=======================================================================
643 //  addsweep
644 //=======================================================================
645 static Standard_Integer addsweep(Draw_Interpretor& di,
646   Standard_Integer n, const char** a)
647 {
648   if (n == 1) {
649     di << "addsweep wire/vertex [Vertex] [-T] [-R] [u0 v0 u1 v1 [...[uN vN]]] : options are :\n";
650     di << "   -T : the wire/vertex have to be translated to assume contact\n";
651     di << "        with the spine\n";
652     di << "   -R : the wire have to be rotated to assume orthogonality\n";
653     di << "        with the spine's tangent\n";
654     return 0;
655   }
656
657   if (Sweep == 0) {
658     di << "You have forgotten the <<mksweep>> command  !\n";
659     return 1;
660   }
661
662   TopoDS_Shape  Section;
663   TopoDS_Vertex Vertex;
664   Handle(Law_Interpol) thelaw;
665
666   Section = DBRep::Get(a[1], TopAbs_SHAPE);
667   if (Section.IsNull() ||
668     (Section.ShapeType() != TopAbs_WIRE &&
669     Section.ShapeType() != TopAbs_VERTEX))
670   {
671     di << a[1] << " is not a wire and is not a vertex!\n";
672     return 1;
673   }
674
675   Standard_Boolean HasVertex = Standard_False,
676     isT = Standard_False,
677     isR = Standard_False;
678
679   if (n > 2) {
680     Standard_Integer cur = 2;
681     // Reading of Vertex
682     TopoDS_Shape InputVertex(DBRep::Get(a[cur], TopAbs_VERTEX));
683     Vertex = TopoDS::Vertex(InputVertex);
684     if (!Vertex.IsNull()) {
685       cur++;
686       HasVertex = Standard_True;
687     }
688
689     // Reading of the translation option
690     if ((n > cur) && !strcmp(a[cur], "-T")) {
691       cur++;
692       isT = Standard_True;
693     }
694
695     // Reading of the rotation option
696     if ((n > cur) && !strcmp(a[cur], "-R")) {
697       cur++;
698       isR = Standard_True;
699     }
700
701     // law ?
702     if (n > cur) {
703       Standard_Integer nbreal = n - cur;
704       if ((nbreal < 4) || (nbreal % 2 != 0)) {
705         //std::cout << "bad arguments ! :" <<a[cur] << std::endl;
706         di << "bad arguments ! :" << a[cur] << "\n";
707       }
708       else { //law of interpolation
709         Standard_Integer ii, L = nbreal / 2;
710         TColgp_Array1OfPnt2d ParAndRad(1, L);
711         for (ii = 1; ii <= L; ii++, cur += 2) {
712           ParAndRad(ii).SetX(Draw::Atof(a[cur]));
713           ParAndRad(ii).SetY(Draw::Atof(a[cur + 1]));
714         }
715         thelaw = new (Law_Interpol)();
716         thelaw->Set(ParAndRad,
717           Abs(ParAndRad(1).Y() - ParAndRad(L).Y()) < Precision::Confusion());
718       }
719     }
720   }
721
722   if (thelaw.IsNull()) {
723     if (HasVertex) Sweep->Add(Section, Vertex, isT, isR);
724     else           Sweep->Add(Section, isT, isR);
725   }
726   else {
727     if (HasVertex) Sweep->SetLaw(Section, thelaw, Vertex, isT, isR);
728     else           Sweep->SetLaw(Section, thelaw, isT, isR);
729   }
730
731   return 0;
732 }
733
734 //=======================================================================
735 //  deletesweep
736 //=======================================================================
737 static Standard_Integer deletesweep(Draw_Interpretor& di,
738   Standard_Integer n, const char** a)
739 {
740   if (n != 2) {
741     return 1;
742   }
743   TopoDS_Wire Section;
744   TopoDS_Shape InputShape(DBRep::Get(a[1], TopAbs_SHAPE));
745   Section = TopoDS::Wire(InputShape);
746   if (Section.IsNull()) {
747     di << a[1] << "is not a wire !\n";
748     return 1;
749   }
750
751   Sweep->Delete(Section);
752   return 0;
753 }
754
755 //=======================================================================
756 //  buildsweep
757 //=======================================================================
758 static Standard_Integer buildsweep(Draw_Interpretor& di,
759   Standard_Integer n, const char** a)
760 {
761   if (n == 1) {
762     di << "build sweep result [-M/-C/-R] [-S] [tol] : options are\n";
763     di << "   -M : Discontinuities are treated by Modfication of\n";
764     di << "        the sweeping mode : it is the default\n";
765     di << "   -C : Discontinuities are treated like Right Corner\n";
766     di << "        Treatement is Extent && Intersect\n";
767     di << "   -R : Discontinuities are treated like Round Corner\n";
768     di << "        Treatement is Intersect and Fill\n";
769     di << "   -S : To build a Solid\n";
770     return 0;
771   }
772
773   Standard_Boolean mksolid = Standard_False;
774   if (Sweep == 0) {
775     di << "You have forgotten the <<mksweep>> command  !\n";
776     return 1;
777   }
778
779   if (!Sweep->IsReady()) {
780     di << "You have forgotten the <<addsweep>> command  !\n";
781     return 1;
782   }
783
784   TopoDS_Shape result;
785   Standard_Integer cur = 2;
786   if (n > cur) {
787     BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
788
789     // Reading Transition
790     if (!strcmp(a[cur], "-C")) {
791       Transition = BRepBuilderAPI_RightCorner;
792       cur++;
793     }
794     else if (!strcmp(a[cur], "-R")) {
795       Transition = BRepBuilderAPI_RoundCorner;
796       cur++;
797     }
798     Sweep->SetTransitionMode(Transition);
799   }
800   // Reading solid ?
801   if ((n > cur) && (!strcmp(a[cur], "-S"))) mksolid = Standard_True;
802
803   // Calcul le resultat
804   Sweep->Build();
805   if (!Sweep->IsDone()) {
806     di << "Buildsweep : Not Done\n";
807     BRepBuilderAPI_PipeError Stat = Sweep->GetStatus();
808     if (Stat == BRepBuilderAPI_PlaneNotIntersectGuide) {
809       di << "Buildsweep : One Plane not intersect the guide\n";
810     }
811     if (Stat == BRepBuilderAPI_ImpossibleContact) {
812       di << "BuildSweep : One section can not be in contact with the guide\n";
813     }
814   }
815   else {
816     if (mksolid) {
817       Standard_Boolean B;
818       B = Sweep->MakeSolid();
819       if (!B) di << " BuildSweep : It is impossible to make a solid !\n";
820     }
821     result = Sweep->Shape();
822     DBRep::Set(a[1], result);
823     // Save history of sweep
824     if (BRepTest_Objects::IsHistoryNeeded())
825     {
826       TopTools_ListOfShape aList;
827       Sweep->Profiles(aList);
828       TopoDS_Shape aSpine = Sweep->Spine();
829       aList.Append(aSpine);
830       BRepTest_Objects::SetHistory(aList, *Sweep);
831     }
832   }
833
834   return 0;
835 }
836
837 //=======================================================================
838 //function : errorsweep
839 //purpose  : returns the summary error on resulting surfaces
840 //           reached by Sweep
841 //=======================================================================
842 static Standard_Integer errorsweep(Draw_Interpretor& di,
843   Standard_Integer, const char**)
844 {
845   if (!Sweep->IsDone())
846   {
847     di << "Sweep is not done\n";
848     return 1;
849   }
850   Standard_Real ErrorOnSurfaces = Sweep->ErrorOnSurface();
851   di << "Tolerance on surfaces = " << ErrorOnSurfaces << "\n";
852   return 0;
853 }
854
855 //=======================================================================
856 //  simulsweep
857 //=======================================================================
858 static Standard_Integer simulsweep(Draw_Interpretor& di,
859   Standard_Integer n, const char** a)
860 {
861   if ((n != 3) && (n != 4)) return 1;
862
863   if (Sweep == 0) {
864     di << "You have forgotten the <<mksweep>> command  !\n";
865     return 1;
866   }
867
868   if (!Sweep->IsReady()) {
869     di << "You have forgotten the <<addsweep>> command  !\n";
870     return 1;
871   }
872
873   char name[100];
874   TopTools_ListOfShape List;
875   TopTools_ListIteratorOfListOfShape it;
876   Standard_Integer N, ii;
877   N = Draw::Atoi(a[2]);
878
879   if (n > 3) {
880     BRepBuilderAPI_TransitionMode Transition = BRepBuilderAPI_Transformed;
881     // Lecture Transition
882     if (!strcmp(a[3], "-C")) {
883       Transition = BRepBuilderAPI_RightCorner;
884     }
885     else if (!strcmp(a[3], "-R")) {
886       Transition = BRepBuilderAPI_RoundCorner;
887     }
888     Sweep->SetTransitionMode(Transition);
889   }
890
891   // Calculate the result
892   Sweep->Simulate(N, List);
893   for (ii = 1, it.Initialize(List); it.More(); it.Next(), ii++) {
894     Sprintf(name, "%s_%d", a[1], ii);
895     DBRep::Set(name, it.Value());
896   }
897
898   return 0;
899 }
900
901 //=======================================================================
902 //  middlepath
903 //=======================================================================
904 static Standard_Integer middlepath(Draw_Interpretor& /*di*/,
905   Standard_Integer n, const char** a)
906 {
907   if (n < 5) return 1;
908
909   TopoDS_Shape aShape = DBRep::Get(a[2]);
910   if (aShape.IsNull()) return 1;
911
912   TopoDS_Shape StartShape = DBRep::Get(a[3]);
913   if (StartShape.IsNull()) return 1;
914
915   TopoDS_Shape EndShape = DBRep::Get(a[4]);
916   if (EndShape.IsNull()) return 1;
917
918   BRepOffsetAPI_MiddlePath Builder(aShape, StartShape, EndShape);
919   Builder.Build();
920
921   TopoDS_Shape Result = Builder.Shape();
922   DBRep::Set(a[1], Result);
923
924   return 0;
925 }
926
927 //=======================================================================
928 //function : SweepCommands
929 //purpose  : 
930 //=======================================================================
931
932 void  BRepTest::SweepCommands(Draw_Interpretor& theCommands)
933 {
934   static Standard_Boolean done = Standard_False;
935   if (done) return;
936   done = Standard_True;
937
938   DBRep::BasicCommands(theCommands);
939
940   const char* g = "Sweep commands";
941
942   theCommands.Add("prism",
943     "prism result base dx dy dz [Copy | Inf | Seminf]",
944     __FILE__, prism, g);
945
946   theCommands.Add("revol",
947     "revol result base px py pz dx dy dz angle [Copy]",
948     __FILE__, revol, g);
949
950   theCommands.Add("pipe",
951     "pipe result Wire_spine Profile [Mode [Approx]], no args to get help",
952     __FILE__, pipe, g);
953
954   theCommands.Add("evolved",
955     "evolved , no args to get help",
956     __FILE__, evolved, g);
957
958   theCommands.Add("pruled",
959     "pruled result Edge1/Wire1 Edge2/Wire2",
960     __FILE__, pruled, g);
961
962   theCommands.Add("gener", "gener result wire1 wire2 [..wire..]",
963     __FILE__, gener, g);
964
965   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)",
966     __FILE__, thrusections, g);
967
968   theCommands.Add("mksweep", "mksweep wire",
969     __FILE__, mksweep, g);
970
971   theCommands.Add("setsweep", "setsweep  no args to get help",
972     __FILE__, setsweep, g);
973
974   theCommands.Add("addsweep",
975     "addsweep wire [vertex] [-M ] [-C] [auxiilaryshape]:no args to get help",
976     __FILE__, addsweep, g);
977
978   theCommands.Add("deletesweep",
979     "deletesweep wire, To delete a section",
980     __FILE__, deletesweep, g);
981
982   theCommands.Add("buildsweep", "builsweep [r] [option] [Tol] , no args to get help",
983     __FILE__, buildsweep, g);
984
985   theCommands.Add("errorsweep", "errorsweep: returns the summary error on resulting surfaces reached by Sweep",
986     __FILE__, errorsweep, g);
987
988   theCommands.Add("simulsweep", "simulsweep r [n] [option]"
989     __FILE__, simulsweep, g);
990   theCommands.Add("geompipe", "geompipe r spineedge profileedge radius [byACR [byrotate]]"
991     __FILE__, geompipe, g);
992
993   theCommands.Add("middlepath", "middlepath res shape startshape endshape",
994     __FILE__, middlepath, g);
995 }
996