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