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