0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / SWDRAW / SWDRAW_ShapeUpgrade.cxx
1 // Created on: 1999-03-09
2 // Created by: data exchange team
3 // Copyright (c) 1999-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 //gka,rln 30.04.99 S4137: new commands for testing ShapeDivide added, some removed
18 //abv,pdn 05.05.99 S4174: new commands for testing ShapeDivide added, some removed
19 //pdn,gka 10.06.99 S4189: command DT_ShapeConvertRev added
20
21 #include <BRep_Tool.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRepBuilderAPI.hxx>
24 #include <BRepBuilderAPI_Transform.hxx>
25 #include <BRepTest_Objects.hxx>
26 #include <BRepTools.hxx>
27 #include <BRepTools_ReShape.hxx>
28 #include <DBRep.hxx>
29 #include <Draw.hxx>
30 #include <Draw_Interpretor.hxx>
31 #include <DrawTrSurf.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_OffsetCurve.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_OffsetCurve.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_RectangularTrimmedSurface.hxx>
38 #include <Geom_Surface.hxx>
39 #include <Precision.hxx>
40 #include <ShapeBuild_ReShape.hxx>
41 #include <ShapeCustom.hxx>
42 #include <ShapeExtend_CompositeSurface.hxx>
43 #include <ShapeFix.hxx>
44 #include <ShapeFix_ComposeShell.hxx>
45 #include <ShapeUpgrade.hxx>
46 #include <ShapeUpgrade_RemoveInternalWires.hxx>
47 #include <ShapeUpgrade_RemoveLocations.hxx>
48 #include <ShapeUpgrade_ShapeConvertToBezier.hxx>
49 #include <ShapeUpgrade_ShapeDivideAngle.hxx>
50 #include <ShapeUpgrade_ShapeDivideArea.hxx>
51 #include <ShapeUpgrade_ShapeDivideClosed.hxx>
52 #include <ShapeUpgrade_ShapeDivideContinuity.hxx>
53 #include <ShapeUpgrade_SplitCurve2dContinuity.hxx>
54 #include <ShapeUpgrade_SplitCurve3dContinuity.hxx>
55 #include <ShapeUpgrade_SplitSurfaceContinuity.hxx>
56 #include <ShapeUpgrade_UnifySameDomain.hxx>
57 #include <SWDRAW.hxx>
58 #include <SWDRAW_ShapeUpgrade.hxx>
59 #include <TColGeom2d_HArray1OfCurve.hxx>
60 #include <TColGeom_HArray1OfCurve.hxx>
61 #include <TColGeom_HArray2OfSurface.hxx>
62 #include <TColStd_Array1OfReal.hxx>
63 #include <TColStd_HArray1OfReal.hxx>
64 #include <TColStd_HSequenceOfReal.hxx>
65 #include <TopExp_Explorer.hxx>
66 #include <TopoDS.hxx>
67 #include <TopoDS_Compound.hxx>
68 #include <TopoDS_Edge.hxx>
69 #include <TopoDS_Face.hxx>
70 #include <TopoDS_Iterator.hxx>
71 #include <TopoDS_Shape.hxx>
72 #include <TopoDS_Shell.hxx>
73 #include <TopoDS_Wire.hxx>
74
75 #include <stdio.h> 
76 //#include <SWDRAW_ShapeUpgrade.hxx>
77 //#include <ShapeUpgrade_SupportModification.hxx>
78 //#include <ShapeExtend_WireData.hxx>
79 //#include <ShapeAnalysis_Shell.hxx>
80 //#include <ShapeAnalysis_WireOrder.hxx>
81 //#include <ShapeAnalysis_Wire.hxx>
82 //#include <ShapeUpgrade_ShellSewing.hxx>
83 // the plane (equation z=0) shared by PlaneDividedFaceContinuity and PlaneGridShell
84 //static Handle(Geom_Plane) ThePlane= new Geom_Plane(0,0,1,0);
85 //=======================================================================
86 //function : DT_ShapeDivide 
87 //purpose  : 
88 //=======================================================================
89 static Standard_Integer DT_ShapeDivide (Draw_Interpretor& di,
90                                         Standard_Integer n, const char** a)
91 {
92   // DT_ShapeDivide result Shape Tol
93   // a[1]= result
94   // a[2]= input Face/Surface
95   // a[3] si n>3= Wire/Face
96   // a[n-1]= Tolerance
97    
98   if (n<3) {
99     di << "bad number of arguments\n";
100     return 1;
101   } 
102   
103   // try to read a shape:
104   TopoDS_Shape inputShape=DBRep::Get(a[2]);
105   if (inputShape.IsNull()) {
106     di << "Unknown shape\n";
107     return 1;
108   }
109   // a[2] is a shape. managing:
110   // DT_ShapeDivide result Face Tol
111   
112   // giving a face is available only in the constructor:
113   // we make the whole and quit.
114   ShapeUpgrade_ShapeDivideContinuity tool(inputShape);
115     
116   // tolerance is optional
117   if (n==4) {
118     Standard_Real Tol=Draw::Atof(a[3]);
119     tool.SetTolerance(Tol);
120   }
121   
122   //  theTool.SetGlobalCriterion(GeomAbs_C1);
123   tool.Perform();
124   TopoDS_Shape res = tool.Result();
125
126   if ( tool.Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
127   if ( tool.Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
128   if ( tool.Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
129   if ( tool.Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
130   if ( tool.Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
131   if ( tool.Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
132   if ( tool.Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
133   if ( tool.Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
134   if ( tool.Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
135   if ( tool.Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
136   if ( tool.Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
137   if ( tool.Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
138   if ( tool.Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
139   if ( tool.Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
140   if ( tool.Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
141   if ( tool.Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
142   if ( tool.Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
143
144   // fixes
145   
146   ShapeFix::SameParameter ( res, Standard_False );
147
148   DBRep::Set(a[1],res);
149   return 0;
150 }
151
152 static Standard_Integer DT_ShapeConvertRev (Draw_Interpretor& di,
153                                          Standard_Integer n, const char** a)
154 {
155   if (n<5) {
156     di << "bad number of arguments\n";
157     return 1;
158   } 
159   
160   // try to read a shape:
161   TopoDS_Shape inputShape=DBRep::Get(a[2]);
162   if (inputShape.IsNull()) {
163     di << "Unknown shape\n";
164     return 1;
165   }
166   
167   Standard_Integer c2d = Draw::Atoi(a[3]);
168   Standard_Integer c3d = Draw::Atoi(a[4]);
169   TopoDS_Shape revsh = ShapeCustom::ConvertToRevolution (inputShape);
170   if (revsh.IsNull()) { di<<"NO RESULT\n"; return 1; }
171   else if (revsh == inputShape) { di<<"No modif\n";}
172   else di<<"ConvertToRevolution -> Result : \n";
173   
174   ShapeUpgrade_ShapeConvertToBezier tool(revsh);
175   tool.SetSurfaceConversion(Standard_True);
176   if(c2d)
177     tool.Set2dConversion(Standard_True);
178   if(c3d) {
179     tool.Set3dConversion(Standard_True);
180     if(n > 5)
181       tool.Set3dLineConversion(Standard_False);
182     if(n > 6)
183       tool.Set3dCircleConversion(Standard_False);
184     if(n > 7)
185       tool.Set3dConicConversion(Standard_False);
186   }
187   tool.Perform();
188   TopoDS_Shape res = tool.Result();
189   
190   if ( tool.Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
191   if ( tool.Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
192   if ( tool.Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
193   if ( tool.Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
194   if ( tool.Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
195   if ( tool.Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
196   if ( tool.Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
197   if ( tool.Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
198   if ( tool.Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
199   if ( tool.Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
200   if ( tool.Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
201   if ( tool.Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
202   if ( tool.Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
203   if ( tool.Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
204   if ( tool.Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
205   if ( tool.Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
206   if ( tool.Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
207
208   // fixes
209   
210   ShapeFix::SameParameter ( res, Standard_False );
211
212   DBRep::Set(a[1],res);
213   return 0;
214 }
215
216
217 /*
218   if (!inputShape.IsNull()) {
219     // a[2] is a shape. managing:
220     // DT_ShapeDivide result Face Tol
221
222     TopoDS_Face  inputFace = TopoDS::Face(inputShape);
223     if (inputFace.IsNull()) {
224       di << a[2] << " is not a face\n";
225       return 1;
226     }
227
228     // giving a face is available only in the constructor:
229     // we make the whole and quit.
230     ShapeUpgrade_ShapeDivideContinuity theTool(inputFace);
231     
232     // tolerance is optional
233     if (n==4) {
234       Standard_Real Tol=Draw::Atof(a[n-1]);
235       theTool.SetTolerance(Tol);
236     }
237
238     theTool.SetGlobalCriterion(GeomAbs_C1);
239     theTool.Build();
240     if (!theTool.IsDone()) {
241       ShapeUpgrade_Error theError=theTool.Error();
242       di << "Not done: error=";
243       if (theError==ShapeUpgrade_Done) 
244         di << "Done\n";
245       else if (theError==ShapeUpgrade_NotDone) 
246         di << "NotDone\n";
247       else if (theError==ShapeUpgrade_EmptyShell) 
248         di << "EmptyShell\n";
249       else if (theError==ShapeUpgrade_InvalidCriterion) 
250         di << "InvalidCriterion\n";
251       else if (theError==ShapeUpgrade_InvalidGridSurface) 
252         di << "InvalidGridSurface\n";
253       else if (theError==ShapeUpgrade_DegeneratedEdge) 
254         di << "DegeneratedEdge\n";
255       else if (theError==ShapeUpgrade_NoSurface) 
256         di << "NoSurface\n";
257       else if (theError==ShapeUpgrade_NoTolerance) 
258         di << "NoTolerance\n";
259       return 1;
260     }   
261     TopoDS_Shell res = theTool.Shell();
262     DBRep::Set(a[1],res);
263     
264     return 0;
265   }
266   else {
267     // not a face: we can use the empty consturctor.
268     ShapeUpgrade_ShapeDivideContinuity theTool;
269     Standard_Real Tol=Draw::Atof(a[n-1]);
270     theTool.SetTolerance(Tol);
271     theTool.SetGlobalCriterion(GeomAbs_C1);
272
273     // try to read a surface:
274     Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[2]);
275     if (! GS.IsNull()) {
276       // a[2] is a surface. managing the configurations:
277       // DT_ShapeDivide result Surface Tol
278       // DT_ShapeDivide result Surface Face Tol
279       // DT_ShapeDivide result Surface Wire Surf Tol
280       
281       theTool.SetSupport(GS);
282
283       // try to read a Wire or a Face:
284       if (n>=5) {
285         TopoDS_Shape inputBoundary=DBRep::Get(a[3]);
286         if (inputBoundary.IsNull()) {
287           di << "Invalid Boundary\n";
288           return 1;
289         }
290         TopoDS_Wire WireBoundary = TopoDS::Wire(inputBoundary);
291         if (!WireBoundary.IsNull()) {
292           // DT_ShapeDivide result Surface Wire Surf Tol
293           Handle(Geom_Surface) WireSupport = DrawTrSurf::GetSurface(a[4]);
294           if (WireSupport.IsNull()) {
295             di << "Invalid Surface supporting the Wire\n";
296             return 1;
297           }
298           theTool.SetBoundary(WireBoundary, WireSupport);
299         }
300         else {
301           TopoDS_Face  FaceBoundary = TopoDS::Face(inputBoundary);
302           // DT_ShapeDivide result Surface Face Tol
303           theTool.SetBoundary(FaceBoundary);
304         }
305       }
306     }
307     else {
308       // it must be a grid: managing the configurations:
309       // DT_ShapeDivide result NbU NbV {Surf_u_v...} Tol
310       // DT_ShapeDivide result NbU NbV {Surf_u_v...} Face Tol
311       // DT_ShapeDivide result NbU NbV {Surf_u_v...} Wire Surf Tol
312       if (n<6) {
313         di << "bad number of arguments for grid input\n";
314         return 1;
315       }
316       // number of surf:
317       Standard_Integer NbU=Draw::Atoi(a[2]);
318       Standard_Integer NbV=Draw::Atoi(a[3]);
319       if (n < 4+NbU*NbV+1) {
320         di << "bad number of arguments\n";
321         return 1;
322       }
323       
324       Handle(TColGeom_HArray2OfSurface) 
325         TheGridSurf= new TColGeom_HArray2OfSurface(1,NbU,1,NbV);
326       
327       for (Standard_Integer iu=1; iu<=NbU; iu++) {
328         for (Standard_Integer jv=1; jv<=NbV; jv++) {
329           Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[4+(iu-1)*NbV+jv-1]);
330           TheGridSurf->SetValue(iu,jv,GS);
331         }
332       }
333       theTool.SetSupport(TheGridSurf,Tol);   
334
335       // try to read a Wire or a Face:
336       if (n>=6+NbU*NbV) {
337         TopoDS_Shape inputBoundary=DBRep::Get(a[4+NbU*NbV]);
338         if (inputBoundary.IsNull()) {
339           di << "Invalid Boundary\n";
340           return 1;
341         }
342         TopoDS_Wire  WireBoundary = TopoDS::Wire(inputBoundary);
343         if (!WireBoundary.IsNull()) {
344           // DT_ShapeDivide result Surface Wire Surf Tol
345           Handle(Geom_Surface) WireSupport = DrawTrSurf::GetSurface(a[4+NbU*NbV+1]);
346           if (WireSupport.IsNull()) {
347             di << "Invalid Surface supporting the Wire\n";
348             return 1;
349           }
350           theTool.SetBoundary(WireBoundary, WireSupport);
351         }
352         else {
353           TopoDS_Face  FaceBoundary = TopoDS::Face(inputBoundary);
354           // DT_ShapeDivide result Surface Face Tol
355           theTool.SetBoundary(FaceBoundary);
356         }
357       }     
358     } 
359
360     theTool.Build();
361     if (!theTool.IsDone()) {
362       ShapeUpgrade_Error theError=theTool.Error();
363       di << "Not done: error=";
364       if (theError==ShapeUpgrade_Done) 
365         di << "Done\n";
366       else if (theError==ShapeUpgrade_NotDone) 
367         di << "NotDone\n";
368       else if (theError==ShapeUpgrade_EmptyShell) 
369         di << "EmptyShell\n";
370       else if (theError==ShapeUpgrade_InvalidCriterion) 
371         di << "InvalidCriterion\n";
372       else if (theError==ShapeUpgrade_InvalidGridSurface) 
373         di << "InvalidGridSurface\n";
374       else if (theError==ShapeUpgrade_DegeneratedEdge) 
375         di << "DegeneratedEdge\n";
376       else if (theError==ShapeUpgrade_NoSurface) 
377         di << "NoSurface\n";
378       else if (theError==ShapeUpgrade_NoTolerance) 
379         di << "NoTolerance\n";
380       return 1;
381     }   
382     
383     TopoDS_Shell res = theTool.Shell();
384     DBRep::Set(a[1],res);
385     
386     return 0;
387   }
388 }
389 */
390 static Standard_Integer DT_ShapeConvert (Draw_Interpretor& di,
391                                          Standard_Integer n, const char** a)
392 {
393   if (n<5) {
394     di << "bad number of arguments\n";
395     return 1;
396   } 
397   
398   // try to read a shape:
399   TopoDS_Shape inputShape=DBRep::Get(a[2]);
400   if (inputShape.IsNull()) {
401     di << "Unknown shape\n";
402     return 1;
403   }
404   
405   Standard_Integer c2d = Draw::Atoi(a[3]);
406   Standard_Integer c3d = Draw::Atoi(a[4]);
407   
408   ShapeUpgrade_ShapeConvertToBezier tool(inputShape);
409   tool.SetSurfaceConversion(Standard_True);
410   if(c2d)
411     tool.Set2dConversion(Standard_True);
412   if(c3d)
413     tool.Set3dConversion(Standard_True);
414   tool.Perform();
415   TopoDS_Shape res = tool.Result();
416   
417   if ( tool.Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
418   if ( tool.Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
419   if ( tool.Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
420   if ( tool.Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
421   if ( tool.Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
422   if ( tool.Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
423   if ( tool.Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
424   if ( tool.Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
425   if ( tool.Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
426   if ( tool.Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
427   if ( tool.Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
428   if ( tool.Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
429   if ( tool.Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
430   if ( tool.Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
431   if ( tool.Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
432   if ( tool.Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
433   if ( tool.Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
434
435   // fixes
436   
437   ShapeFix::SameParameter ( res, Standard_False );
438
439   DBRep::Set(a[1],res);
440   return 0;
441 }
442 static Standard_Integer DT_SplitAngle(Draw_Interpretor& di,
443                                       Standard_Integer n, const char** a)
444 {
445   if (n<3) {
446     di << "bad number of arguments\n";
447     return 1;
448   }
449   
450   TopoDS_Shape inputShape=DBRep::Get(a[2]);
451   if (inputShape.IsNull()) {
452     di << "Unknown shape\n";
453     return 1;
454   }
455   
456   Standard_Real maxangle = 95;
457   if ( n >3 ) {
458     maxangle = Draw::Atof ( a[3] );
459     if ( maxangle <1 ) maxangle = 1;
460   }
461   
462   ShapeUpgrade_ShapeDivideAngle tool(maxangle * M_PI/180,inputShape);
463   tool.Perform();
464   TopoDS_Shape res = tool.Result();
465
466   if ( tool.Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
467   if ( tool.Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
468   if ( tool.Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
469   if ( tool.Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
470   if ( tool.Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
471   if ( tool.Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
472   if ( tool.Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
473   if ( tool.Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
474   if ( tool.Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
475   if ( tool.Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
476   if ( tool.Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
477   if ( tool.Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
478   if ( tool.Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
479   if ( tool.Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
480   if ( tool.Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
481   if ( tool.Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
482   if ( tool.Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
483
484   // fixes
485   
486   ShapeFix::SameParameter ( res, Standard_False );
487
488   DBRep::Set(a[1],res);
489   return 0;
490 }
491   
492 /*  
493 //=======================================================================
494 //function : DT_PlaneDividedFace 
495 //purpose  : Transfer into a plane with boundary divided
496 //           
497 //
498 //=======================================================================
499 static Standard_Integer DT_PlaneDividedFace (Draw_Interpretor& di,
500                                    Standard_Integer n, const char** a)
501
502 {
503   // a[1]= result
504   // a[2]= input Face
505   // a[3]= Tolerance
506
507   if (n !=4) {
508     di << "bad number of arguments\n";
509     return 1;
510   }
511
512   Standard_Real      Tol=Draw::Atof(a[3]);
513   TopoDS_Shape inputShape=DBRep::Get(a[2]);
514   TopoDS_Face  inputFace = TopoDS::Face(inputShape);
515   if (inputFace.IsNull()) {
516     di << a[2] << " is not a face\n";
517     return 1;
518   }
519
520   ShapeUpgrade_PlaneDividedFace theTool(ThePlane);
521   theTool.Init(inputFace);
522   //theTool.SetBoundaryCriterion(GeomAbs_C1);
523   //theTool.SetTolerance(Tol);
524   theTool.Build();
525   if (!theTool.IsDone()) {
526     di << "Not done\n";
527     return 1;
528   }    
529
530   TopoDS_Face res = theTool.Face();
531   DBRep::Set(a[1],res);
532
533   Standard_Real the2d3dFactor=theTool.Get2d3dFactor();
534   di << "2d3dFactor="<<the2d3dFactor<< "\n";
535   return 0;
536 }
537
538 //=======================================================================
539 //function : DT_PlaneGridShell 
540 //purpose  : Create a Plane Grid Shell from U and V knots
541 //           
542 //
543 //=======================================================================
544 static Standard_Integer DT_PlaneGridShell (Draw_Interpretor& di,
545                                    Standard_Integer n, const char** a)
546
547 {
548
549   if (n < 4) return 1;
550   // a[1]= result
551   // a[2]= NbU >=2
552   // a[3]= NbV >=2
553   // a[4..]= {UKnots}
554   // a[4+NbU...] = {VKnots}
555   // a[4+NbU+NbV+1] = Tol
556
557   // number of knots:
558   Standard_Integer NbU=Draw::Atoi(a[2]);
559   Standard_Integer NbV=Draw::Atoi(a[3]);
560   if (n != 4+NbU+NbV+1) {
561     di << "bad number of arguments\n";
562     return 1;
563   }
564
565   TColStd_Array1OfReal TheUKnots(1,NbU);
566   TColStd_Array1OfReal TheVKnots(1,NbV);
567
568   for (Standard_Integer ii=1; ii<=NbU; ii++) {
569     TheUKnots(ii)=Draw::Atof(a[4+ii-1]);
570   }
571   for (ii=1; ii<=NbV; ii++) {
572     TheVKnots(ii)=Draw::Atof(a[4+NbU+ii-1]);
573   }
574
575   Standard_Real Tol=Draw::Atof(a[4+NbU+NbV]);
576
577   ShapeUpgrade_PlaneGridShell TheGrid(ThePlane,TheUKnots,TheVKnots,Tol);
578
579   TopoDS_Shell res = TheGrid.Shell();
580   DBRep::Set(a[1],res);
581
582   return 0;
583 }
584
585 //=======================================================================
586 //function : DT_PlaneFaceCommon 
587 //purpose  : Common between a plane Face and a Shell whose all Faces are 
588 //           laying in the same plane
589 //           
590 //
591 //=======================================================================
592 static Standard_Integer DT_PlaneFaceCommon (Draw_Interpretor& di,
593                                    Standard_Integer n, const char** a)
594
595 {
596   // a[1]= result
597   // a[2]= input Face
598   // a[3]= input Shell
599
600   if (n !=4) {
601     di << "bad number of arguments\n";
602     return 1;
603   }
604
605   TopoDS_Shape inputShape= DBRep::Get(a[2]);
606   TopoDS_Face  inputFace = TopoDS::Face(inputShape);
607   if (inputFace.IsNull()) {
608     di << a[2] << " is not a face\n";
609     return 1;
610   }
611
612   inputShape = DBRep::Get(a[3]);
613   TopoDS_Shell inputShell = TopoDS::Shell(inputShape);
614   if (inputShell.IsNull()) {
615     di << a[3] << " is not a shell\n";
616     return 1;
617   }
618
619   ShapeUpgrade_PlaneFaceCommon theTool;
620   theTool.Init(inputFace,inputShell);
621
622   TopoDS_Shell res = theTool.Shell();
623   DBRep::Set(a[1],res);
624
625   return 0;
626 }*/
627
628 //=======================================================================
629 //function : DT_SplitCurve 
630 //purpose  :  Splits the curve with C1 criterion
631 //           
632 //
633 //=======================================================================
634 static Standard_Integer DT_SplitCurve (Draw_Interpretor& di,
635                                    Standard_Integer n, const char** a)
636
637 {
638   // a[1]= input curve. This name is used with a suffix to name the output curves
639   // a[2]= Tolerance
640
641   if (n < 3) {
642     di << "bad number of arguments\n";
643     return 1;
644   }
645
646   Standard_Real      Tol=Draw::Atof(a[2]);
647   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]);
648   if ( GC.IsNull()) return 1;
649   Standard_Integer Split = Draw::Atoi(a[3]);
650   Handle(ShapeUpgrade_SplitCurve3dContinuity) theTool = new ShapeUpgrade_SplitCurve3dContinuity;
651   theTool->Init(GC);
652   theTool->SetTolerance (Tol);
653   theTool->SetCriterion (GeomAbs_C1);
654   if(Split == 1) {
655     Handle(TColStd_HSequenceOfReal) spval = new TColStd_HSequenceOfReal;
656     for(Standard_Integer i = 1; i<=5; i++) spval->Append(i);
657     theTool->SetSplitValues(spval);
658   }
659   theTool->Perform (Standard_True);
660   Handle(TColGeom_HArray1OfCurve) theCurves= theTool->GetCurves();
661   Standard_Integer NbC=theCurves->Length();
662   for (Standard_Integer icurv=1; icurv<=NbC; icurv++) {
663     char name[100];
664     Sprintf(name,"%s%s%d",a[1],"_",icurv);
665     char* newname = name;
666     DrawTrSurf::Set(newname, theCurves->Value(icurv));
667     di.AppendElement(newname);
668   }
669   return 0;
670 }
671
672
673 //=======================================================================
674 //function : DT_SplitCurve2d 
675 //purpose  :  Splits the curve with C1 criterion
676 //           
677 //
678 //=======================================================================
679 static Standard_Integer DT_SplitCurve2d (Draw_Interpretor& di,
680                                    Standard_Integer n, const char** a)
681
682 {
683   // a[1]= input 2d curve. This name is used with a suffix to name the output curves
684   // a[2]= Tolerance
685
686   if (n < 3) {
687     di << "bad number of arguments\n";
688     return 1;
689   }
690
691   Standard_Real      Tol=Draw::Atof(a[2]);
692   Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(a[1]);
693   if ( GC.IsNull()) return 1;
694   Standard_Integer Split = Draw::Atoi(a[3]);
695   Handle(ShapeUpgrade_SplitCurve2dContinuity) theTool = new ShapeUpgrade_SplitCurve2dContinuity;
696   theTool->Init(GC);
697   theTool->SetTolerance (Tol);
698   theTool->SetCriterion (GeomAbs_C1);
699   if(Split == 1) {
700     Handle(TColStd_HSequenceOfReal) spval = new TColStd_HSequenceOfReal;
701     for(Standard_Integer i = 1; i<=5; i++) spval->Append(i);
702     theTool->SetSplitValues(spval);
703   }
704   theTool->Perform (Standard_True);
705   Handle(TColGeom2d_HArray1OfCurve) theCurves= theTool->GetCurves();
706   Standard_Integer NbC=theCurves->Length();
707   for (Standard_Integer icurv=1; icurv<=NbC; icurv++) {
708     char name[100];
709         Sprintf(name,"%s%s%d",a[1],"_",icurv);
710     char* newname = name;
711     DrawTrSurf::Set(newname, theCurves->Value(icurv));
712     di.AppendElement(newname);
713   }
714   return 0;
715 }
716
717
718 //=======================================================================
719 //function : DT_SplitSurface 
720 //purpose  :  Splits the surface with C1 criterion
721 //           
722 //
723 //=======================================================================
724 /*
725 static Standard_Integer DT_SplitWire (Draw_Interpretor& di,
726                                       Standard_Integer n, const char** a)
727 {
728
729   if (n <3) {
730     di << "bad number of arguments\n";
731     return 1;
732   }
733
734   TopoDS_Face source = TopoDS::Face(DBRep::Get(a[2]));
735   if(source.IsNull()) {
736     di <<"Shape is not face\n";
737     return 1;
738   }
739   TopoDS_Iterator wi(source);
740   if(!wi.More()) {
741     di <<"Shape is face without wire\n";
742     return 1;
743   }
744   
745   TopoDS_Wire wire = TopoDS::Wire(wi.Value());
746   Handle(ShapeUpgrade_WireDivideContinuity) tool = new ShapeUpgrade_WireDivideContinuity;
747   tool->Init(wire,source);
748   if(n >=4 ) {
749     Standard_Real      Tol=Draw::Atof(a[3]);
750   }
751   Handle(ShapeBuild_ReShape) context = new ShapeBuild_ReShape;
752   tool->Perform(context);
753   TopoDS_Wire result = tool->Wire();
754   DBRep::Set(a[1],result);
755   return 0;
756 }
757 */
758 /*
759 static Standard_Integer DT_SplitFace (Draw_Interpretor& di,
760                                       Standard_Integer n, const char** a)
761 {
762
763   if (n <3) {
764     di << "bad number of arguments\n";
765     return 1;
766   }
767
768   TopoDS_Face source = TopoDS::Face(DBRep::Get(a[2]));
769   if(source.IsNull()) {
770     di <<"Shape is not face\n";
771     return 1;
772   } 
773   Handle(ShapeUpgrade_ShapeDivideContinuity) tool = new ShapeUpgrade_FaceDivideContinuity;
774   tool->Init(source);
775   if(n >=4 ) {
776     Standard_Real      Tol=Draw::Atof(a[3]);
777     tool->SetPrecision(Tol);
778   }
779   
780   Handle(ShapeBuild_ReShape) context = new ShapeBuild_ReShape;
781   tool->Perform(context);
782   TopoDS_Shape result = tool->Result();
783   
784   
785   if ( tool->Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
786   if ( tool->Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
787   if ( tool->Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
788   if ( tool->Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
789   if ( tool->Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
790   if ( tool->Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
791   if ( tool->Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
792   if ( tool->Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
793   if ( tool->Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
794   if ( tool->Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
795   if ( tool->Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
796   if ( tool->Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
797   if ( tool->Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
798   if ( tool->Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
799   if ( tool->Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
800   if ( tool->Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
801   if ( tool->Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
802
803   // fixes
804   
805   ShapeFix::SameParameter ( result, Standard_False );
806   
807   DBRep::Set(a[1],result);
808   return 0;
809 }
810 */
811
812 static Standard_Integer DT_SplitSurface (Draw_Interpretor& di,
813                                    Standard_Integer n, const char** a)
814
815 {
816   // a[1]= result (used with a suffix to name the output surfaces)
817   // a[2]= input surface. 
818   // a[3]= Tolerance
819
820   // a[1]= result
821   // a[2]= nbU
822   // a[3]= nbV
823   // a[3+1]..a[3+nbU*nbV] = Input Surfaces
824   // a[4+nbU*nbV]= Tolerance
825
826   if (n <4) {
827     di << "bad number of arguments\n";
828     return 1;
829   }
830
831   Handle(ShapeUpgrade_SplitSurfaceContinuity) theTool = new ShapeUpgrade_SplitSurfaceContinuity;//S4137
832   
833   Standard_Real      Tol=Draw::Atof(a[3]);
834   Standard_Integer Split = Draw::Atoi(a[4]);
835   theTool->SetTolerance(Tol);
836   theTool->SetCriterion(GeomAbs_C1);
837   Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[2]);
838 /* 
839   if ( GS.IsNull()) {
840     // Case of composite grid surface
841     di << "composite surf\n";
842     Standard_Integer      nbU=Draw::Atoi(a[2]);
843     Standard_Integer      nbV=Draw::Atoi(a[3]);
844     if (nbU==0 || nbV==0) return 1;
845     Handle(TColGeom_HArray2OfSurface) 
846       theGrid= new TColGeom_HArray2OfSurface(1,nbU,1,nbV);
847     for (Standard_Integer iu=1; iu<=nbU; iu++) {
848       for (Standard_Integer iv=1; iv<=nbV; iv++) {
849         Handle(Geom_Surface) GS = DrawTrSurf::GetSurface(a[3+(iu-1)*nbV+iv]);
850         theGrid->SetValue(iu,iv,GS);
851       }
852     }
853     di << "appel a SplitSurface::Init\n";
854     theTool->Init(theGrid);
855   }
856   else {*/
857     // Case of single surface
858   di << "single surf\n";
859   
860   di << "appel a SplitSurface::Init\n";
861   theTool->Init(GS);
862   if(Split ==1) {
863     Handle(TColStd_HSequenceOfReal) spval = new TColStd_HSequenceOfReal;
864     for(Standard_Integer i = 1; i<=5; i++) spval->Append(i);
865     theTool->SetUSplitValues(spval);
866     theTool->SetVSplitValues(spval);
867   }
868
869   di << "appel a SplitSurface::Build\n";
870   theTool->Build(Standard_True);
871
872   di << "appel a SplitSurface::GlobalU/VKnots\n";
873   Handle(ShapeExtend_CompositeSurface) Grid = theTool->ResSurfaces();
874   Handle(TColStd_HArray1OfReal) GlobalU=Grid->UJointValues();
875   Handle(TColStd_HArray1OfReal) GlobalV=Grid->VJointValues();
876   Standard_Integer nbGlU=GlobalU->Length();
877   Standard_Integer nbGlV=GlobalV->Length();
878   di << "nb GlobalU ; nb GlobalV="<<nbGlU<<" "<<nbGlV;
879   for (Standard_Integer iu=1; iu<=nbGlU; iu++)
880     di  <<" "<< GlobalU->Value(iu);
881 //  di <<"\n";
882 //  di << "nb GlobalV="<<nbGlV;
883   for (Standard_Integer iv=1; iv<=nbGlV; iv++)
884     di  <<" "<< GlobalV->Value(iv);
885   di <<"\n";
886
887 di << "appel a Surfaces\n";
888   Handle(TColGeom_HArray2OfSurface) theSurfaces= Grid->Patches();
889
890 di << "transfert resultat\n";
891   Standard_Integer NbRow=theSurfaces->ColLength();
892   Standard_Integer NbCol=theSurfaces->RowLength();
893   for (Standard_Integer irow=1; irow<=NbRow; irow++) {
894     for (Standard_Integer icol=1; icol<=NbCol; icol++) {
895       char name[100];
896       Sprintf(name,"%s%s%d%s%d",a[1],"_",irow,"_",icol);
897       char* newname = name;
898       DrawTrSurf::Set(newname, theSurfaces->Value(irow, icol));
899       di.AppendElement(newname);
900     }
901   }
902   return 0;
903 }
904
905 //---------------gka
906 //=======================================================================
907 //function : offset2dcurve
908 //purpose  : 
909 //
910 //=======================================================================
911 static Standard_Integer offset2dcurve
912   (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
913 {
914   if (argc < 4) {
915     di<<"result + curve + offset\n";
916     
917     return 1 /* Error */;    
918   }
919 //  Standard_CString arg1 = argv[1];
920 //  Standard_CString arg2 = argv[2];
921   Standard_Real Offset = Draw::Atof(argv[3]);
922   Handle(Geom2d_Curve) GC = DrawTrSurf::GetCurve2d(argv[2]);
923   if ( GC.IsNull()) return 1;
924   Handle(Geom2d_OffsetCurve) offcrv = new Geom2d_OffsetCurve(GC,Offset);
925   DrawTrSurf::Set(argv[1], offcrv);
926   return 0;
927 }
928
929 //=======================================================================
930 //function : offsetcurve
931 //purpose  : 
932 //
933 //=======================================================================
934 static Standard_Integer offsetcurve
935   (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
936 {
937   if (argc < 5) {
938     di<<"result + curve + offset + Dir\n";
939     
940     return 1 /* Error */;    
941   }
942 //  Standard_CString arg1 = argv[1];  
943 //  Standard_CString arg2 = argv[2];
944   Standard_Real Offset = Draw::Atof(argv[3]);
945   Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(argv[2]);
946   if ( GC.IsNull()) return 1;
947   gp_Pnt point;
948   DrawTrSurf::GetPoint(argv[4],point);
949   gp_Dir dir(point.XYZ()); 
950   Handle(Geom_OffsetCurve) offcrv = new Geom_OffsetCurve(GC,Offset,dir);
951   DrawTrSurf::Set(argv[1], offcrv);
952   return 0;
953 }
954
955 //=======================================================================
956 //function : compose shell
957 //purpose  : 
958 //=======================================================================
959 static Standard_Integer splitface
960   (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
961 {
962   if (argc < 5) {
963     di << "Split face: splitface result face [u usplit1 usplit2...] [v vsplit1 vsplit2 ...]\n";
964     return 1;    
965   }
966   
967   TopoDS_Shape aLocalShape = DBRep::Get(argv[2]) ;
968   TopoDS_Face face = TopoDS::Face ( aLocalShape );
969   if ( face.IsNull() ) {
970     di << argv[2] << " is not Face\n";
971     return 1;
972   }
973   
974   Handle(Geom_Surface) S = BRep_Tool::Surface ( face );
975   Standard_Real Uf, Ul, Vf, Vl;
976   BRepTools::UVBounds ( face, Uf, Ul, Vf, Vl );
977   Standard_Real Umin, Umax, Vmin, Vmax;
978   S->Bounds ( Umin, Umax, Vmin, Vmax );
979   if ( Uf < Umin && ! S->IsUPeriodic() ) Uf = Umin;
980   else if ( Uf > Umin ) {
981     if ( Precision::IsInfinite(Umin) ) Uf -= 100;
982     else Uf = Umin;
983   }
984   if ( Vf < Vmin && ! S->IsVPeriodic() ) Vf = Vmin;
985   else if ( Vf > Vmin ) {
986     if ( Precision::IsInfinite(Vmin) ) Vf -= 100;
987     else Vf = Vmin;
988   }
989   if ( Ul > Umax && ! S->IsUPeriodic() ) Ul = Umax;
990   else if ( Ul < Umax ) {
991     if ( Precision::IsInfinite(Umax) ) Ul += 100;
992     else Ul = Umax;
993   }
994   if ( Vl > Vmax && ! S->IsVPeriodic() ) Vl = Vmax;
995   else if ( Vl < Vmax ) {
996     if ( Precision::IsInfinite(Vmax) ) Vl += 100;
997     else Vl = Vmax;
998   }
999   
1000   TColStd_SequenceOfReal uval;
1001   TColStd_SequenceOfReal vval;
1002
1003   Standard_Boolean byV = Standard_False;
1004   Standard_Integer i; // svv Jan11 2000 : porting on DEC
1005   for ( i=3; i < argc; i++ ) {
1006     if ( argv[i][0] == 'u' ) byV = Standard_False;
1007     else if ( argv[i][0] == 'v' ) byV = Standard_True;
1008     else {
1009       Standard_Real val = Draw::Atof ( argv[i] );
1010       TColStd_SequenceOfReal &vals = ( byV ? vval : uval );
1011       if ( vals.Length() >0 && val - vals.Last() < Precision::PConfusion() ) {
1012         di << "Values should be sorted in increasing order; skipped\n";
1013         continue;
1014       }
1015       if ( ( byV && ( val < Vf+Precision::PConfusion() || 
1016                       val > Vl-Precision::PConfusion() ) ) ||
1017            (!byV && ( val < Uf+Precision::PConfusion() || 
1018                       val > Ul-Precision::PConfusion() ) ) ) {
1019         di << "Values should be inside range of surface; skipped\n";
1020         continue; 
1021       }
1022       vals.Append ( val );
1023     }
1024   }
1025   if ( uval.Length() <1 && vval.Length() <1 ) {
1026     di << "No splitting defined\n";
1027     return 1;
1028   }
1029   if ( uval.Length() >0 ) {
1030     di << "Splitting by U: ";
1031     for ( Standard_Integer j=1; j <= uval.Length(); j++ ) {
1032       //std::cout << ( i >j ? ", " : "" ) << uval(j);
1033       if (i >j) {
1034         di << ", ";
1035       } else {
1036         di << "";
1037       }
1038       di << uval(j);
1039     }
1040     di << "\n";
1041   }
1042   if ( vval.Length() >0 ) {
1043     di << "Splitting by V: ";
1044     for ( Standard_Integer j=1; j <= vval.Length(); j++ ) {
1045       //std::cout << ( j >1 ? ", " : "" ) << vval(j);
1046       if (j >1) {
1047         di << ", ";
1048       } else {
1049         di << "";
1050       }
1051       di << vval(j);
1052     }
1053     di << "\n";
1054   }
1055   
1056   Handle(TColGeom_HArray2OfSurface) AS = new TColGeom_HArray2OfSurface ( 1, uval.Length()+1, 
1057                                                                          1, vval.Length()+1 );
1058   for ( i=0; i <= uval.Length(); i++ ) {
1059     Standard_Real umin = ( i ? uval(i) : Uf );
1060     Standard_Real umax = ( i < uval.Length() ? uval(i+1) : Ul );
1061     for ( Standard_Integer j=0; j <= vval.Length(); j++ ) {
1062       Standard_Real vmin = ( j ? vval(j) : Vf );
1063       Standard_Real vmax = ( j < vval.Length() ? vval(j+1) : Vl );
1064       Handle(Geom_RectangularTrimmedSurface) rect = 
1065         new Geom_RectangularTrimmedSurface ( S, umin, umax, vmin, vmax );
1066       AS->SetValue ( i+1, j+1, rect );
1067     }
1068   }
1069
1070   Handle(ShapeExtend_CompositeSurface) Grid = new ShapeExtend_CompositeSurface;
1071   if ( ! Grid->Init ( AS ) ) di << "Grid badly connected!\n";
1072
1073   ShapeFix_ComposeShell SUCS;
1074   TopLoc_Location l;
1075   SUCS.Init ( Grid, l, face, Precision::Confusion() );
1076   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
1077   SUCS.SetContext( RS );
1078   SUCS.Perform ();
1079   
1080   if ( SUCS.Status ( ShapeExtend_OK ) ) di << "Status: OK\n";
1081   if ( SUCS.Status ( ShapeExtend_DONE1 ) ) di << "Status: DONE1\n";
1082   if ( SUCS.Status ( ShapeExtend_DONE2 ) ) di << "Status: DONE2\n";
1083   if ( SUCS.Status ( ShapeExtend_DONE3 ) ) di << "Status: DONE3\n";
1084   if ( SUCS.Status ( ShapeExtend_DONE4 ) ) di << "Status: DONE4\n";
1085   if ( SUCS.Status ( ShapeExtend_DONE5 ) ) di << "Status: DONE5\n";
1086   if ( SUCS.Status ( ShapeExtend_DONE6 ) ) di << "Status: DONE6\n";
1087   if ( SUCS.Status ( ShapeExtend_DONE7 ) ) di << "Status: DONE7\n";
1088   if ( SUCS.Status ( ShapeExtend_DONE8 ) ) di << "Status: DONE8\n";
1089   if ( SUCS.Status ( ShapeExtend_FAIL1 ) ) di << "Status: FAIL1\n";
1090   if ( SUCS.Status ( ShapeExtend_FAIL2 ) ) di << "Status: FAIL2\n";
1091   if ( SUCS.Status ( ShapeExtend_FAIL3 ) ) di << "Status: FAIL3\n";
1092   if ( SUCS.Status ( ShapeExtend_FAIL4 ) ) di << "Status: FAIL4\n";
1093   if ( SUCS.Status ( ShapeExtend_FAIL5 ) ) di << "Status: FAIL5\n";
1094   if ( SUCS.Status ( ShapeExtend_FAIL6 ) ) di << "Status: FAIL6\n";
1095   if ( SUCS.Status ( ShapeExtend_FAIL7 ) ) di << "Status: FAIL7\n";
1096   if ( SUCS.Status ( ShapeExtend_FAIL8 ) ) di << "Status: FAIL8\n";
1097
1098   TopoDS_Shape sh = SUCS.Result();
1099   ShapeFix::SameParameter ( sh, Standard_False );
1100   DBRep::Set ( argv[1], sh );
1101   return 0;
1102 }
1103
1104 static Standard_Integer converttobspline
1105   (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1106 {
1107   if (argc<3) {
1108     di << "Use: " << argv[0] << " result shape [options=ero]\n";
1109     di << "where options is combination of letters indicating kinds of\n";
1110     di << "surfaces to be converted:\n";
1111     di << "e - extrusion\n";
1112     di << "r - revolution\n";
1113     di << "o - offset\n";
1114     di << "p - plane";
1115     return 1;
1116   }
1117   const char *options = ( argc > 3 ? argv[3] : "ero" );
1118   
1119   TopoDS_Shape inputShape=DBRep::Get(argv[2]);
1120   if (inputShape.IsNull()) {
1121     di << "Unknown shape\n";
1122     return 1;
1123   }
1124   TopoDS_Shape revsh = ShapeCustom::ConvertToRevolution (inputShape);
1125   TopoDS_Shape res = 
1126     ShapeCustom::ConvertToBSpline (revsh, strchr (options, 'e') != 0,
1127                                           strchr (options, 'r') != 0,
1128                                           strchr (options, 'o') != 0,
1129                                           strchr (options, 'p') != 0);
1130   ShapeFix::SameParameter ( res, Standard_False );
1131   DBRep::Set ( argv[1], res );
1132   return 0;
1133 }
1134
1135
1136 static Standard_Integer splitclosed (Draw_Interpretor& di, 
1137                                      Standard_Integer argc, 
1138                                      const char** argv)
1139 {
1140   if (argc<3) {
1141     di << "bad number of arguments\n";
1142     return 1;
1143   }
1144   
1145   TopoDS_Shape inputShape=DBRep::Get(argv[2]);
1146   if (inputShape.IsNull()) {
1147     di << "Unknown shape\n";
1148     return 1;
1149   }
1150   
1151   ShapeUpgrade_ShapeDivideClosed tool (inputShape);
1152   tool.Perform();
1153   TopoDS_Shape res = tool.Result();
1154   
1155   ShapeFix::SameParameter ( res, Standard_False );
1156   DBRep::Set ( argv[1], res );
1157   return 0;
1158 }
1159
1160 static Standard_Integer splitarea (Draw_Interpretor& di, 
1161                                      Standard_Integer argc, 
1162                                      const char** argv)
1163 {
1164   if (argc<4) {
1165     di << "bad number of arguments\n";
1166     return 1;
1167   }
1168   
1169   TopoDS_Shape inputShape=DBRep::Get(argv[2]);
1170   if (inputShape.IsNull()) {
1171     di << "Unknown shape\n";
1172     return 1;
1173   }
1174   Standard_Real aMaxArea = Draw::Atof(argv[3]);
1175   
1176     
1177   ShapeUpgrade_ShapeDivideArea tool (inputShape);
1178   if(argc >4) {
1179     Standard_Real prec = Draw::Atof(argv[4]);
1180     tool.SetPrecision(prec);
1181   }
1182   tool.MaxArea() = aMaxArea;
1183   tool.Perform();
1184   TopoDS_Shape res = tool.Result();
1185   
1186   ShapeFix::SameParameter ( res, Standard_False );
1187   DBRep::Set ( argv[1], res );
1188   return 0;
1189 }
1190
1191 static Standard_Integer removeinternalwires (Draw_Interpretor& di, 
1192                                              Standard_Integer argc, 
1193                                              const char** argv)
1194 {
1195   if (argc<4) {
1196     di << "bad number of arguments\n";
1197     return 1;
1198   }
1199   Standard_Real aMinArea = Draw::Atof(argv[2]);
1200   TopoDS_Shape inputShape=DBRep::Get(argv[3]);
1201   if (inputShape.IsNull()) {
1202     di << "Unknown shape\n";
1203     return 1;
1204   }
1205   Handle(ShapeUpgrade_RemoveInternalWires) aTool;
1206   TopTools_SequenceOfShape aSeqShapes;
1207   if(inputShape.ShapeType() < TopAbs_WIRE)
1208      aTool = new ShapeUpgrade_RemoveInternalWires(inputShape);
1209   else {
1210    di<<"Invalid type of first shape: should be FACE,SHELL,SOLID or COMPOUND\n";
1211    return 1;
1212   }
1213   
1214   Standard_Integer k = 4;
1215   Standard_Boolean isShape = Standard_True;
1216   Standard_Boolean aModeRemoveFaces =Standard_True;
1217   
1218  
1219   for( ; k < argc; k++) {
1220     if(isShape) {
1221       TopoDS_Shape aShape=DBRep::Get(argv[k]);
1222       isShape = !aShape.IsNull();
1223       if(isShape) {
1224         if(aShape.ShapeType() == TopAbs_FACE || aShape.ShapeType() == TopAbs_WIRE)
1225           aSeqShapes.Append(aShape);
1226       }
1227     }
1228     if(!isShape) 
1229       aModeRemoveFaces = (Draw::Atoi(argv[k]) == 1);
1230   }
1231   
1232   aTool->MinArea() = aMinArea;
1233   aTool->RemoveFaceMode() = aModeRemoveFaces;
1234   if(aSeqShapes.Length())
1235     aTool->Perform(aSeqShapes);
1236   else
1237     aTool->Perform();
1238   if(aTool->Status(ShapeExtend_FAIL1))
1239      di<<"Initial shape has invalid type\n";
1240   else if(aTool->Status(ShapeExtend_FAIL2))
1241      di<<"Specified sub-shape is not belonged to whole shape\n";   
1242   if(aTool->Status(ShapeExtend_DONE1)) {
1243     const TopTools_SequenceOfShape& aRemovedWires =aTool->RemovedWires(); 
1244      di<<aRemovedWires.Length()<<" internal wires were removed\n";
1245     
1246   }
1247   if(aTool->Status(ShapeExtend_DONE2)) {
1248     const TopTools_SequenceOfShape& aRemovedFaces =aTool->RemovedFaces(); 
1249      di<<aRemovedFaces.Length()<<" small faces were removed\n";
1250     
1251   }   
1252   TopoDS_Shape res = aTool->GetResult();
1253   
1254   
1255   DBRep::Set ( argv[1], res );
1256   return 0;
1257 }
1258
1259 static Standard_Integer removeloc (Draw_Interpretor& di, 
1260                                    Standard_Integer argc, 
1261                                    const char** argv)
1262 {
1263   if (argc<3) {
1264     di << "bad number of arguments. Should be:  removeloc res shape [remove_level(see ShapeEnum)]\n";
1265     return 1;
1266   }
1267   
1268   TopoDS_Shape aShape = DBRep::Get(argv[2]);
1269   if(aShape.IsNull())
1270     return 1;
1271   ShapeUpgrade_RemoveLocations aRemLoc;
1272   if (argc > 3)
1273     aRemLoc.SetRemoveLevel((TopAbs_ShapeEnum)Draw::Atoi(argv[3]));
1274   aRemLoc.Remove(aShape);
1275   TopoDS_Shape aNewShape = aRemLoc.GetResult();
1276   
1277   DBRep::Set(argv[1],aNewShape);
1278   return 0;
1279 }
1280
1281 static ShapeUpgrade_UnifySameDomain& Unifier() {
1282   static ShapeUpgrade_UnifySameDomain sUnifier;
1283   return sUnifier;
1284 }
1285
1286 //=======================================================================
1287 // unifysamedom
1288 //=======================================================================
1289 static Standard_Integer unifysamedom(Draw_Interpretor& di, Standard_Integer n, const char** a)
1290 {
1291   if (n < 3)
1292   {
1293     di << "Use unifysamedom result shape [s1 s2 ...] [-f] [-e] [-nosafe] [+b] [+i] [-t val] [-a val]\n";
1294     di << "options:\n";
1295     di << "s1 s2 ... to keep the given edges during unification of faces\n";
1296     di << "-f to switch off 'unify-faces' mode \n";
1297     di << "-e to switch off 'unify-edges' mode\n";
1298     di << "-nosafe to switch off 'safe input shape' mode\n";
1299     di << "+b to switch on 'concat bspline' mode\n";
1300     di << "+i to switch on 'allow internal edges' mode\n";
1301     di << "-t val to set linear tolerance\n";
1302     di << "-a val to set angular tolerance (in degrees)\n";
1303     di << "'unify-faces' and 'unify-edges' modes are switched on by default";
1304     return 1;
1305   }
1306
1307   TopoDS_Shape aShape = DBRep::Get(a[2]);
1308   if (aShape.IsNull())
1309     return 1;
1310
1311   // default values
1312   Standard_Boolean anUFaces = Standard_True;
1313   Standard_Boolean anUEdges = Standard_True;
1314   Standard_Boolean anConBS = Standard_False;
1315   Standard_Boolean isAllowInternal = Standard_False;
1316   Standard_Boolean isSafeInputMode = Standard_True;
1317   Standard_Real aLinTol = Precision::Confusion();
1318   Standard_Real aAngTol = Precision::Angular();
1319   TopoDS_Shape aKeepShape;
1320   TopTools_MapOfShape aMapOfShapes;
1321
1322   if (n > 3)
1323     for ( int i = 3; i < n; i++ ) 
1324     {
1325       aKeepShape = DBRep::Get(a[i]);
1326       if (!aKeepShape.IsNull()) {
1327         aMapOfShapes.Add(aKeepShape);
1328       }
1329       else {
1330         if ( !strcmp(a[i], "-f")) 
1331           anUFaces = Standard_False;
1332         else if (!strcmp(a[i], "-e"))
1333           anUEdges = Standard_False;
1334         else if (!strcmp(a[i], "-nosafe"))
1335           isSafeInputMode = Standard_False;
1336         else if (!strcmp(a[i], "+b"))
1337           anConBS = Standard_True;
1338         else if (!strcmp(a[i], "+i"))
1339           isAllowInternal = Standard_True;
1340         else if (!strcmp(a[i], "-t") || !strcmp(a[i], "-a"))
1341         {
1342           if (++i < n)
1343           {
1344             if (a[i-1][1] == 't')
1345               aLinTol = Draw::Atof(a[i]);
1346             else
1347               aAngTol = Draw::Atof(a[i]) * (M_PI / 180.0);
1348           }
1349           else
1350           {
1351             di << "value expected after " << a[i-1];
1352             return 1;
1353           }
1354         }
1355       }
1356     }
1357
1358   Unifier().Initialize(aShape, anUEdges, anUFaces, anConBS);
1359   Unifier().KeepShapes(aMapOfShapes);
1360   Unifier().SetSafeInputMode(isSafeInputMode);
1361   Unifier().AllowInternalEdges(isAllowInternal);
1362   Unifier().SetLinearTolerance(aLinTol);
1363   Unifier().SetAngularTolerance(aAngTol);
1364   Unifier().Build();
1365   TopoDS_Shape Result = Unifier().Shape();
1366
1367   if (BRepTest_Objects::IsHistoryNeeded())
1368     BRepTest_Objects::SetHistory(Unifier().History());
1369
1370   DBRep::Set(a[1], Result);
1371   return 0;
1372 }
1373
1374 static Standard_Integer copytranslate(Draw_Interpretor& di, 
1375                                    Standard_Integer argc, 
1376                                    const char** argv)
1377 {
1378   if (argc<6) {
1379     di << "bad number of arguments. Should be:  copytranslate res shape dx dy dz\n";
1380     return 1;
1381   }
1382   TopoDS_Shape aShape = DBRep::Get(argv[2]);
1383   if(aShape.IsNull())
1384     return 1;
1385   Standard_Real aDx = Draw::Atof(argv[3]);
1386   Standard_Real aDy = Draw::Atof(argv[4]);
1387   Standard_Real aDz = Draw::Atof(argv[5]);
1388   gp_Trsf aTrsf;
1389   aTrsf.SetTranslation(gp_Vec(aDx, aDy, aDz));
1390   BRepBuilderAPI_Transform builderTransform(aTrsf);
1391   builderTransform.Perform (aShape, true); 
1392   TopoDS_Shape aNewShape = builderTransform.Shape();
1393   DBRep::Set(argv[1],aNewShape);
1394   return 0;
1395   
1396 }
1397
1398 static Standard_Integer reshape(Draw_Interpretor& /*theDI*/,
1399                                 Standard_Integer  theArgc,
1400                                 const char**      theArgv)
1401 {
1402   if ( theArgc < 4 )
1403   {
1404     std::cout << "Error: wrong number of arguments. Type 'help " << theArgv[0] << "'\n";
1405     return 1;
1406   }
1407
1408   TopoDS_Shape aSource = DBRep::Get(theArgv[2]);
1409   if ( aSource.IsNull() )
1410   {
1411     std::cout << "Error: source shape ('" << theArgv[2] << "') is null\n";
1412     return 1;
1413   }
1414
1415   Handle(BRepTools_ReShape) aReShaper = new BRepTools_ReShape;
1416
1417   // Record the requested modifications
1418   for ( Standard_Integer i = 3; i < theArgc; ++i )
1419   {
1420     Standard_CString        anArg = theArgv[i];
1421     TCollection_AsciiString anOpt(anArg);
1422     anOpt.LowerCase();
1423
1424     if ( anOpt == "-replace" )
1425     {
1426       if ( theArgc - i < 3 )
1427       {
1428         std::cout << "Error: not enough arguments for replacement\n";
1429         return 1;
1430       }
1431
1432       TopoDS_Shape aWhat = DBRep::Get(theArgv[++i]);
1433       if ( aWhat.IsNull() )
1434       {
1435         std::cout << "Error: argument shape ('" << theArgv[i] << "') is null\n";
1436         return 1;
1437       }
1438
1439       TopoDS_Shape aWith = DBRep::Get(theArgv[++i]);
1440       if ( aWith.IsNull() )
1441       {
1442         std::cout << "Error: replacement shape ('" << theArgv[i] << "') is null\n";
1443         return 1;
1444       }
1445
1446       aReShaper->Replace(aWhat, aWith);
1447     }
1448     else if ( anOpt == "-remove" )
1449     {
1450       if ( theArgc - i < 2 )
1451       {
1452         std::cout << "Error: not enough arguments for removal\n";
1453         return 1;
1454       }
1455
1456       TopoDS_Shape aWhat = DBRep::Get(theArgv[++i]);
1457       if ( aWhat.IsNull() )
1458       {
1459         std::cout << "Error: shape to remove ('" << theArgv[i] << "') is null\n";
1460         return 1;
1461       }
1462
1463       aReShaper->Remove(aWhat);
1464     }
1465     else
1466     {
1467       std::cout << "Error: invalid syntax at " << anOpt << "\n" ;
1468       return 1;
1469     }
1470   }
1471
1472   // Apply all the recorded modifications
1473   TopoDS_Shape aResult = aReShaper->Apply(aSource);
1474   if ( aResult.IsNull() )
1475   {
1476     std::cout << "Error: result shape is null\n";
1477     return 1;
1478   }
1479
1480   DBRep::Set(theArgv[1], aResult);
1481   return 0;
1482 }
1483
1484 //=======================================================================
1485 //function : InitCommands
1486 //purpose  : 
1487 //=======================================================================
1488
1489  void SWDRAW_ShapeUpgrade::InitCommands(Draw_Interpretor& theCommands) 
1490 {
1491   static Standard_Integer initactor = 0;
1492   if (initactor)
1493   {
1494     return;
1495   }
1496   initactor = 1;
1497   
1498   Standard_CString g = SWDRAW::GroupName(); // "Tests of DivideTool";
1499  
1500   theCommands.Add("DT_ShapeDivide",
1501                   "DT_ShapeDivide Result Shape Tol: Divides shape with C1 Criterion",
1502                   __FILE__,
1503                   DT_ShapeDivide,g);
1504   
1505   theCommands.Add("DT_SplitAngle",
1506                   "DT_SplitAngle Result Shape [MaxAngle=95]: Divides revolved surfaces on segments less MaxAngle deg",
1507                   __FILE__,
1508                   DT_SplitAngle,g);
1509
1510   theCommands.Add("DT_ShapeConvert",
1511                   "DT_ShapeConvert Result Shape convert2d convert3d: Converts curves to beziers",
1512                   __FILE__,
1513                   DT_ShapeConvert,g);
1514   
1515   theCommands.Add("DT_ShapeConvertRev",
1516                   "DT_ShapeConvert Result Shape convert2d convert3d: Converts curves to beziers",
1517                   __FILE__,
1518                   DT_ShapeConvertRev,g);
1519 /*  theCommands.Add("DT_PlaneDividedFace",
1520                   "DT_PlaneDividedFace Result Face Tol: Transfer into a plane with boundary divided",
1521                   __FILE__,
1522                   DT_PlaneDividedFace,g);
1523
1524   theCommands.Add("DT_PlaneGridShell",
1525                   "DT_PlaneGridShell Result NbU NbV {UKnots} {VKnots} Tol : Create a plane grid Shell",
1526                   __FILE__,
1527                   DT_PlaneGridShell,g);
1528
1529   theCommands.Add("DT_PlaneFaceCommon",
1530                   "DT_PlaneFaceCommon Result Face Shell: Common between a plane Face and a Shell",
1531                   __FILE__,
1532                   DT_PlaneFaceCommon,g);*/
1533
1534   theCommands.Add("DT_SplitCurve2d",
1535                   "DT_SplitCurve2d Curve Tol: Splits the curve with C1 criterion",
1536                   __FILE__,
1537                   DT_SplitCurve2d,g);
1538
1539   theCommands.Add("DT_SplitCurve",
1540                   "DT_SplitCurve Curve Tol: Splits the curve with C1 criterion",
1541                   __FILE__,
1542                   DT_SplitCurve,g);
1543
1544   theCommands.Add("DT_SplitSurface",
1545                   "DT_SplitSurface Result Surface/GridSurf Tol: Splits the surface with C1 criterion",
1546                   __FILE__,
1547                   DT_SplitSurface,g);
1548
1549   /*theCommands.Add("DT_SupportModification",
1550                   "DT_SupportModification Result Shell Surface 2d3dFactor: Surface will support all the faces",
1551                   __FILE__,
1552                   DT_SupportModification,g);*/
1553
1554 //  theCommands.Add("DT_SpltWire","DT_SpltWire Result Wire Tol",
1555 //                __FILE__,DT_SplitWire,g);
1556   
1557 //  theCommands.Add("DT_SplitFace", "DT_SplitFace Result Face Tol",
1558 //                __FILE__, DT_SplitFace,g);
1559   
1560 //  theCommands.Add("DT_Debug", "DT_Debug 0/1 : activation/desactivation of the debug messages",
1561 //                __FILE__, DT_Debug,g);
1562 //  theCommands.Add ("shellsolid","option[a-b-c-f] shape result",
1563 //                 __FILE__,shellsolid,g);
1564   theCommands.Add ("offset2dcurve","result curve offset",
1565                    __FILE__,offset2dcurve,g);
1566   
1567   theCommands.Add ("offsetcurve","result curve offset dir",
1568                    __FILE__,offsetcurve,g);
1569
1570   theCommands.Add ("splitface","result face [u usplit1 usplit2...] [v vsplit1 vsplit2 ...]",
1571                    __FILE__,splitface,g);
1572   
1573   theCommands.Add ("DT_ToBspl","result shape [options=erop]",
1574                    __FILE__,converttobspline,g);
1575   theCommands.Add ("DT_ClosedSplit","result shape",
1576                    __FILE__,splitclosed,g);
1577   theCommands.Add ("DT_SplitByArea","result shape maxarea [preci]",
1578                    __FILE__,splitarea,g);
1579   
1580   theCommands.Add ("RemoveIntWires","result minarea wholeshape [faces or wires] [moderemoveface ]",
1581                    __FILE__,removeinternalwires,g);
1582   
1583   theCommands.Add ("removeloc","result shape [remove_level(see ShapeEnum)]",__FILE__,removeloc,g);
1584   
1585   theCommands.Add ("unifysamedom",
1586                    "unifysamedom result shape [s1 s2 ...] [-f] [-e] [-nosafe] [+b] [+i] [-t val] [-a val]",
1587                     __FILE__,unifysamedom,g);
1588
1589   theCommands.Add ("copytranslate","result shape dx dy dz",__FILE__,copytranslate,g);
1590
1591   theCommands.Add ("reshape",
1592     "\n    reshape : result shape [-replace what with] [-remove what]"
1593     "\n    Basic utility for topological modification: "
1594     "\n      '-replace what with'   Replaces 'what' sub-shape with 'with' sub-shape"
1595     "\n      '-remove what'         Removes 'what' sub-shape"
1596     "\n    Requests '-replace' and '-remove' can be repeated many times.",
1597     __FILE__, reshape, g);
1598 }