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