0020716: Eliminate usage of "config.h" header file
[occt.git] / src / BRepTest / BRepTest_SurfaceCommands.cxx
1 // Created on: 1993-07-22
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-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 #include <stdio.h>
18 #include <BRepTest.hxx>
19 #include <GeometryTest.hxx>
20
21 #include <DrawTrSurf.hxx>
22 #include <DBRep.hxx>
23 #include <Draw_Interpretor.hxx>
24 #include <Draw_Appli.hxx>
25
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepLib.hxx>
29 #include <BRepTools_Quilt.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepBuilderAPI_MakeFace.hxx>
32 #include <BRepBuilderAPI_MakeShell.hxx>
33 #include <BRepBuilderAPI.hxx>
34 #include <BRepBuilderAPI_Sewing.hxx>
35 #include <BRepOffsetAPI_FindContigousEdges.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom2d_TrimmedCurve.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_SequenceOfShape.hxx>
43 #include <Precision.hxx>
44 #include <Draw_ProgressIndicator.hxx>
45
46 #ifdef _WIN32
47 //#define strcasecmp strcmp Already defined
48 #include <stdio.h>
49 #endif
50
51 //-----------------------------------------------------------------------
52 // suppressarg : suppress a[d],modifie na--
53 //-----------------------------------------------------------------------
54 static void suppressarg(Standard_Integer& na,const char** a,const Standard_Integer d) 
55 {
56   for(Standard_Integer i=d;i<na;i++) {
57     a[i]=a[i+1];
58     a[i+1]=NULL;
59   }
60   na--;
61 }
62
63
64 //=======================================================================
65 // mkface
66 //=======================================================================
67
68 static Standard_Integer mkface(Draw_Interpretor& , Standard_Integer n, const char** a)
69 {
70   if (n < 3) return 1;
71   
72   Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[2]);
73   if (S.IsNull()) {
74     cout << a[2] << " is not a surface" << endl;
75     return 1;
76   }
77   
78   Standard_Boolean mkface = a[0][2] == 'f';
79   TopoDS_Shape res;
80
81   Standard_Boolean Segment = Standard_False;
82   if ( !mkface && (n == 4 || n == 8)) {
83     Segment = !strcmp(a[n-1],"1");
84     n--;
85   }
86
87   if (n == 3) {
88     if (mkface)
89       res = BRepBuilderAPI_MakeFace(S, Precision::Confusion());
90     else
91       res = BRepBuilderAPI_MakeShell(S,Segment);
92   }
93   else if (n <= 5) {
94     if (!mkface) return 1;
95     Standard_Boolean orient = (n  == 4);
96     TopoDS_Shape W = DBRep::Get(a[3],TopAbs_WIRE);
97     if (W.IsNull()) return 1;
98     res = BRepBuilderAPI_MakeFace(S,TopoDS::Wire(W),orient);
99   }
100   else {
101     if (mkface)
102       res = BRepBuilderAPI_MakeFace(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),Precision::Confusion());
103     else
104       res = BRepBuilderAPI_MakeShell(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),
105                               Segment);
106   }
107   
108   DBRep::Set(a[1],res);
109   return 0;
110 }
111
112 //=======================================================================
113 // quilt
114 //=======================================================================
115
116 static Standard_Integer quilt(Draw_Interpretor& , Standard_Integer n, const char** a)
117 {
118   if (n < 4) return 1;
119   BRepTools_Quilt Q;
120
121   Standard_Integer i = 2;
122   while (i < n) {
123     TopoDS_Shape S = DBRep::Get(a[i]);
124     if (!S.IsNull()) {
125       if (S.ShapeType() == TopAbs_EDGE) {
126         if (i+1 < n) {
127           TopoDS_Shape E = DBRep::Get(a[i+1]);
128           if (!E.IsNull()) {
129             if (E.ShapeType() == TopAbs_EDGE) {
130               i++;
131               Q.Bind(TopoDS::Edge(S),TopoDS::Edge(E));
132             }
133           }
134         }
135       }
136       if (S.ShapeType() == TopAbs_VERTEX) {
137         if (i+1 < n) {
138           TopoDS_Shape E = DBRep::Get(a[i+1]);
139           if (!E.IsNull()) {
140             if (E.ShapeType() == TopAbs_VERTEX) {
141               i++;
142               Q.Bind(TopoDS::Vertex(S),TopoDS::Vertex(E));
143             }
144           }
145         }
146       }
147       else {
148         Q.Add(S);
149       }
150     }
151     i++;
152   }
153
154   DBRep::Set(a[1],Q.Shells());
155   return 0;
156 }
157
158
159 //=======================================================================
160 // mksurface
161 //=======================================================================
162
163 static Standard_Integer mksurface(Draw_Interpretor& , Standard_Integer n, const char** a)
164 {
165   if (n < 3) return 1;
166
167   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_FACE);
168   if (S.IsNull()) return 1;
169   TopLoc_Location L;
170   Handle(Geom_Surface) C = BRep_Tool::Surface(TopoDS::Face(S),L);
171
172
173   DrawTrSurf::Set(a[1],C->Transformed(L.Transformation()));
174   return 0;
175 }
176
177 //=======================================================================
178 // mkplane
179 //=======================================================================
180
181 static Standard_Integer mkplane(Draw_Interpretor& , Standard_Integer n, const char** a)
182 {
183   if (n < 3) return 1;
184
185   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_WIRE);
186   if (S.IsNull()) return 1;
187
188   Standard_Boolean OnlyPlane = Standard_False;
189   if ( n == 4) {
190     OnlyPlane =  !strcmp(a[3],"1");
191   }
192
193   TopoDS_Face F = BRepBuilderAPI_MakeFace(TopoDS::Wire(S), OnlyPlane);
194
195   DBRep::Set(a[1],F);
196   return 0;
197 }
198
199 //=======================================================================
200 // pcurve
201 //=======================================================================
202 Standard_IMPORT Draw_Color DrawTrSurf_CurveColor(const Draw_Color col);
203 Standard_IMPORT void DBRep_WriteColorOrientation ();
204 Standard_IMPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or);
205
206 static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
207 {
208   Standard_Boolean mute = Standard_False;
209   for(Standard_Integer ia=1;ia<n;ia++) {
210     if (!strcasecmp(a[ia],"-mute")) {
211       suppressarg(n,a,ia);
212       mute = Standard_True;
213     }
214   }
215
216   if (n == 2) {
217     // pcurves of a face
218     TopoDS_Shape S = DBRep::Get(a[1],TopAbs_FACE);
219     if (S.IsNull()) return 1;
220
221     if (!mute) DBRep_WriteColorOrientation();
222     Draw_Color col, savecol = DrawTrSurf_CurveColor(Draw_rouge);
223
224     char* name = new char[100];
225     Standard_Real f,l;
226     S.Orientation(TopAbs_FORWARD);
227     TopExp_Explorer ex(S,TopAbs_EDGE);
228     for (Standard_Integer i=1; ex.More(); ex.Next(), i++) {
229       const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface
230         (TopoDS::Edge(ex.Current()),TopoDS::Face(S),f,l);
231       if ( c.IsNull() ) {
232         cout << "Error: Edge " << i << " does not have pcurve" << endl;
233         continue;
234       }
235       col = DBRep_ColorOrientation(ex.Current().Orientation());
236       DrawTrSurf_CurveColor(col);
237
238       Sprintf(name,"%s_%d",a[1],i);
239       DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l));
240     }
241     DrawTrSurf_CurveColor(savecol);
242
243   }
244   else if (n >= 4) {
245     TopoDS_Shape SE = DBRep::Get(a[2],TopAbs_EDGE);
246     if (SE.IsNull()) return 1;
247     TopoDS_Shape SF = DBRep::Get(a[3],TopAbs_FACE);
248     if (SF.IsNull()) return 1;
249
250     Draw_Color col, savecol = DrawTrSurf_CurveColor(Draw_rouge);
251     Standard_Real f,l;
252     const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface
253       (TopoDS::Edge(SE),TopoDS::Face(SF),f,l);
254
255     col = DBRep_ColorOrientation(SE.Orientation());
256     DrawTrSurf_CurveColor(col);
257     DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l));
258     DrawTrSurf_CurveColor(savecol);
259   }
260   else { 
261     return 1;
262   }
263     
264   return 0;
265 }
266
267 //=======================================================================
268 // sewing
269 //=======================================================================
270
271 static Standard_Integer sewing (Draw_Interpretor& theDi, 
272                                 Standard_Integer theArgc, const char** theArgv)
273 {
274   BRepBuilderAPI_Sewing aSewing;
275   Standard_Integer aPar = 1;
276   TopTools_SequenceOfShape aSeq;
277
278   Standard_Real aTol = 1.0e-06;
279   Standard_Boolean aSewingMode = Standard_True;
280   Standard_Boolean anAnalysisMode = Standard_True;
281   Standard_Boolean aCuttingMode = Standard_True;
282   Standard_Boolean aNonManifoldMode = Standard_False;
283   Standard_Boolean aSameParameterMode = Standard_True;
284   Standard_Boolean aFloatingEdgesMode = Standard_False;
285   Standard_Boolean aFaceMode = Standard_True;
286   Standard_Boolean aSetMinTol = Standard_False;
287   Standard_Real aMinTol = 0.;
288   Standard_Real aMaxTol = Precision::Infinite();
289
290   for (Standard_Integer i = 2; i < theArgc; i++)
291   {
292     if (theArgv[i][0] == '-' || theArgv[i][0] == '+')
293     {
294       Standard_Boolean aVal = (theArgv[i][0] == '+' ? Standard_True : Standard_False);
295       switch (tolower(theArgv[i][1]))
296       {
297       case 'm':
298         {
299           if (tolower(theArgv[i][2]) == 'i' && i+1 < theArgc)
300           {
301             if (Draw::Atof (theArgv[i+1]))
302             {
303               aMinTol = Draw::Atof (theArgv[++i]);
304               aSetMinTol = Standard_True;
305             }
306             else
307             {
308               theDi << "Error! min tolerance can't possess the null value" << "\n";
309               return (1);
310             }
311           }
312           if (tolower(theArgv[i][2]) == 'a' && i+1 < theArgc)
313           {
314             if (Draw::Atof (theArgv[i+1]))
315               aMaxTol = Draw::Atof (theArgv[++i]);
316             else
317             {
318               theDi << "Error! max tolerance can't possess the null value" << "\n";
319               return (1);
320             }
321           }
322         }
323         break;
324       case 's': aSewingMode = aVal; break;
325       case 'a': anAnalysisMode = aVal; break;
326       case 'c': aCuttingMode = aVal; break;
327       case 'n': aNonManifoldMode = aVal; break;
328       case 'p': aSameParameterMode = aVal; break;
329       case 'e': aFloatingEdgesMode = aVal; break;
330       case 'f': aFaceMode = aVal; break;
331       }
332     }
333     else
334     {
335       TopoDS_Shape aShape = DBRep::Get (theArgv[i]);
336       if (!aShape.IsNull())
337       {
338         aSeq.Append (aShape);
339         aPar++;
340       }
341       else
342       {
343         if (Draw::Atof (theArgv[i]))
344           aTol = Draw::Atof (theArgv[i]);
345       }
346     }
347   }
348    
349   if (aPar < 2)
350   {
351     theDi << "Use: " << theArgv[0] << " result [tolerance] shape1 shape2 ... [min tolerance] [max tolerance] [switches]" << "\n";
352     theDi << "To set user's value of min/max tolerances the following syntax is used: +<parameter> <value>" << "\n";
353     theDi << "- parameters are identified by letters:" << "\n";
354     theDi << "  mint - min tolerance" << "\n";
355     theDi << "  maxt - max tolerance" << "\n";
356     theDi << "Switches allow to tune other parameters of Sewing" << "\n";
357     theDi << "The following syntax is used: <symbol><parameter>" << "\n";
358     theDi << "- symbol may be - to set parameter off, + to set on" << "\n";
359     theDi << "- parameters are identified by letters:" << "\n";
360     theDi << "  s - mode for creating sewed shape" << "\n";
361     theDi << "  a - mode for analysis of input shapes" << "\n";
362     theDi << "  c - mode for cutting of free edges" << "\n";
363     theDi << "  n - mode for non manifold processing" << "\n";
364     theDi << "  p - mode for same parameter processing for edges" << "\n";
365     theDi << "  e - mode for sewing floating edges" << "\n";
366     theDi << "  f - mode for sewing faces" << "\n";
367     return (1);
368   }
369     
370   if (!aSetMinTol)
371     aMinTol = aTol*1e-4;
372   if (aTol < Precision::Confusion())
373     aTol = Precision::Confusion();
374   if (aMinTol < Precision::Confusion())
375     aMinTol = Precision::Confusion();
376   if (aMinTol > aTol)
377   {
378     theDi << "Error! min tolerance can't exceed working tolerance" << "\n";
379     return (1);
380   }
381   if (aMaxTol < aTol)
382   {
383     theDi << "Error! max tolerance can't be less than working tolerance" << "\n";
384     return (1);
385   }
386
387   aSewing.Init (aTol, aSewingMode, anAnalysisMode, aCuttingMode, aNonManifoldMode);
388   aSewing.SetSameParameterMode (aSameParameterMode);
389   aSewing.SetFloatingEdgesMode (aFloatingEdgesMode);
390   aSewing.SetFaceMode (aFaceMode);
391   aSewing.SetMinTolerance (aMinTol);
392   aSewing.SetMaxTolerance (aMaxTol);
393
394   for (Standard_Integer i = 1; i <= aSeq.Length(); i++)
395     aSewing.Add(aSeq.Value(i));
396   
397   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDi, 1);
398   aSewing.Perform (aProgress);
399   aSewing.Dump();
400
401   const TopoDS_Shape& aRes = aSewing.SewedShape();
402   if (!aRes.IsNull())
403     DBRep::Set(theArgv[1], aRes);
404   return 0;
405 }
406
407 //=======================================================================
408 // continuity
409 //=======================================================================
410
411 static Standard_Integer continuity (Draw_Interpretor& , 
412                                     Standard_Integer n, const char** a)
413 {
414   if (n < 2) return (1);
415
416   BRepOffsetAPI_FindContigousEdges aFind;
417
418   TopoDS_Shape sh = DBRep::Get(a[1]);
419   Standard_Integer i=1;
420   if (sh.IsNull()) {
421     if (n < 3) return (1);
422     Standard_Real tol = Draw::Atof(a[1]);
423     aFind.Init(tol, Standard_False);
424     i = 2;
425   }
426   
427   while (i < n) {
428     sh = DBRep::Get(a[i]);
429     aFind.Add(sh);
430     i++;
431   }
432
433   aFind.Perform();
434   aFind.Dump();
435
436   return 0;
437 }
438
439 //=======================================================================
440 // encoderegularity
441 //=======================================================================
442 static Standard_Integer encoderegularity (Draw_Interpretor& , 
443                                           Standard_Integer n, const char** a)
444
445 {
446   if (n < 2) return 1;
447   TopoDS_Shape sh = DBRep::Get(a[1]);
448   if (sh.IsNull()) return 1;
449   if (n==2) 
450     BRepLib::EncodeRegularity(sh);
451   else {
452     Standard_Real Tol = Draw::Atof(a[2]);
453     Tol *= M_PI/180.;
454     BRepLib::EncodeRegularity(sh, Tol);
455   }
456   return 0;
457 }
458
459
460 //=======================================================================
461 //function : SurfaceCommands
462 //purpose  : 
463 //=======================================================================
464
465 void  BRepTest::SurfaceCommands(Draw_Interpretor& theCommands)
466 {
467   static Standard_Boolean done = Standard_False;
468   if (done) return;
469   done = Standard_True;
470
471   DBRep::BasicCommands(theCommands);
472   GeometryTest::SurfaceCommands(theCommands);
473
474   const char* g = "Surface topology commands";
475
476   theCommands.Add("mkface",
477                   "mkface facename surfacename [ufirst ulast vfirst vlast] [wire [norient]]",
478                   __FILE__,mkface,g);
479
480   theCommands.Add("mkshell",
481                   "mkshell shellname surfacename [ufirst ulast vfirst vlast] [segment 0/1]",
482                   __FILE__,mkface,g);
483
484   theCommands.Add("quilt",
485                   "quilt compoundname shape1 edgeshape2  edgeshape1... shape2  edgeshape3 edgeshape1or2 ... shape3 ...",
486                   __FILE__,quilt,g);
487   
488   theCommands.Add("mksurface",
489                   "mksurface surfacename facename",
490                   __FILE__,mksurface,g);
491
492   theCommands.Add("mkplane",
493                   "mkplane facename wirename [OnlyPlane 0/1]",
494                   __FILE__,mkplane,g);
495
496   theCommands.Add("pcurve",
497                   "pcurve [name edgename] facename",
498                   __FILE__,pcurve,g);
499
500   theCommands.Add("sewing",
501                   "sewing result [tolerance] shape1 shape2 ... [min tolerance] [max tolerance] [switches]",
502                   __FILE__,sewing, g);
503
504   theCommands.Add("continuity", 
505                   "continuity [tolerance] shape1 shape2 ...",
506                   __FILE__,continuity, g);
507
508   theCommands.Add("encoderegularity", 
509                   "encoderegularity shape [tolerance (in degree)]",
510                   __FILE__,encoderegularity, g);
511 }
512