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