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