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