0022804: Sewing increases tolerance of vertices for redundant value.
[occt.git] / src / BRepTest / BRepTest_SurfaceCommands.cxx
1 // File:        DBRep_4.cxx
2 // Created:     Thu Jul 22 16:39:43 1993
3 // Author:      Remi LEQUETTE
4 //              <rle@nonox>
5
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9 #include <stdio.h>
10 #include <BRepTest.hxx>
11 #include <GeometryTest.hxx>
12
13 #include <DrawTrSurf.hxx>
14 #include <DBRep.hxx>
15 #include <Draw_Interpretor.hxx>
16 #include <Draw_Appli.hxx>
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepLib.hxx>
21 #include <BRepTools_Quilt.hxx>
22 #include <BRepAdaptor_Curve.hxx>
23 #include <BRepBuilderAPI_MakeFace.hxx>
24 #include <BRepBuilderAPI_MakeShell.hxx>
25 #include <BRepBuilderAPI.hxx>
26 #include <BRepBuilderAPI_Sewing.hxx>
27 #include <BRepOffsetAPI_FindContigousEdges.hxx>
28 #include <TopExp_Explorer.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <Geom_Surface.hxx>
32 #include <Geom2d_TrimmedCurve.hxx>
33 #include <TopTools_ListOfShape.hxx>
34 #include <Precision.hxx>
35 #include <Draw_ProgressIndicator.hxx>
36
37 #ifdef WNT
38 //#define strcasecmp strcmp Already defined
39 #include <stdio.h>
40 #endif
41 #ifdef HAVE_STRINGS_H
42 # include <strings.h>
43 #endif
44
45 //-----------------------------------------------------------------------
46 // suppressarg : suppress a[d],modifie na--
47 //-----------------------------------------------------------------------
48 static void suppressarg(Standard_Integer& na,const char** a,const Standard_Integer d) 
49 {
50   for(Standard_Integer i=d;i<na;i++) {
51     a[i]=a[i+1];
52     a[i+1]=NULL;
53   }
54   na--;
55 }
56
57
58 //=======================================================================
59 // mkface
60 //=======================================================================
61
62 static Standard_Integer mkface(Draw_Interpretor& , Standard_Integer n, const char** a)
63 {
64   if (n < 3) return 1;
65   
66   Handle(Geom_Surface) S = DrawTrSurf::GetSurface(a[2]);
67   if (S.IsNull()) {
68     cout << a[2] << " is not a surface" << endl;
69     return 1;
70   }
71   
72   Standard_Boolean mkface = a[0][2] == 'f';
73   TopoDS_Shape res;
74
75   Standard_Boolean Segment = Standard_False;
76   if ( !mkface && (n == 4 || n == 8)) {
77     Segment = !strcmp(a[n-1],"1");
78     n--;
79   }
80
81   if (n == 3) {
82     if (mkface)
83       res = BRepBuilderAPI_MakeFace(S, Precision::Confusion());
84     else
85       res = BRepBuilderAPI_MakeShell(S,Segment);
86   }
87   else if (n <= 5) {
88     if (!mkface) return 1;
89     Standard_Boolean orient = (n  == 4);
90     TopoDS_Shape W = DBRep::Get(a[3],TopAbs_WIRE);
91     if (W.IsNull()) return 1;
92     res = BRepBuilderAPI_MakeFace(S,TopoDS::Wire(W),orient);
93   }
94   else {
95     if (mkface)
96       res = BRepBuilderAPI_MakeFace(S,atof(a[3]),atof(a[4]),atof(a[5]),atof(a[6]),Precision::Confusion());
97     else
98       res = BRepBuilderAPI_MakeShell(S,atof(a[3]),atof(a[4]),atof(a[5]),atof(a[6]),
99                               Segment);
100   }
101   
102   DBRep::Set(a[1],res);
103   return 0;
104 }
105
106 //=======================================================================
107 // quilt
108 //=======================================================================
109
110 static Standard_Integer quilt(Draw_Interpretor& , Standard_Integer n, const char** a)
111 {
112   if (n < 4) return 1;
113   BRepTools_Quilt Q;
114
115   Standard_Integer i = 2;
116   while (i < n) {
117     TopoDS_Shape S = DBRep::Get(a[i]);
118     if (!S.IsNull()) {
119       if (S.ShapeType() == TopAbs_EDGE) {
120         if (i+1 < n) {
121           TopoDS_Shape E = DBRep::Get(a[i+1]);
122           if (!E.IsNull()) {
123             if (E.ShapeType() == TopAbs_EDGE) {
124               i++;
125               Q.Bind(TopoDS::Edge(S),TopoDS::Edge(E));
126             }
127           }
128         }
129       }
130       if (S.ShapeType() == TopAbs_VERTEX) {
131         if (i+1 < n) {
132           TopoDS_Shape E = DBRep::Get(a[i+1]);
133           if (!E.IsNull()) {
134             if (E.ShapeType() == TopAbs_VERTEX) {
135               i++;
136               Q.Bind(TopoDS::Vertex(S),TopoDS::Vertex(E));
137             }
138           }
139         }
140       }
141       else {
142         Q.Add(S);
143       }
144     }
145     i++;
146   }
147
148   DBRep::Set(a[1],Q.Shells());
149   return 0;
150 }
151
152
153 //=======================================================================
154 // mksurface
155 //=======================================================================
156
157 static Standard_Integer mksurface(Draw_Interpretor& , Standard_Integer n, const char** a)
158 {
159   if (n < 3) return 1;
160
161   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_FACE);
162   if (S.IsNull()) return 1;
163   TopLoc_Location L;
164   Handle(Geom_Surface) C = BRep_Tool::Surface(TopoDS::Face(S),L);
165
166
167   DrawTrSurf::Set(a[1],C->Transformed(L.Transformation()));
168   return 0;
169 }
170
171 //=======================================================================
172 // mkplane
173 //=======================================================================
174
175 static Standard_Integer mkplane(Draw_Interpretor& , Standard_Integer n, const char** a)
176 {
177   if (n < 3) return 1;
178
179   TopoDS_Shape S = DBRep::Get(a[2],TopAbs_WIRE);
180   if (S.IsNull()) return 1;
181
182   Standard_Boolean OnlyPlane = Standard_False;
183   if ( n == 4) {
184     OnlyPlane =  !strcmp(a[3],"1");
185   }
186
187   TopoDS_Face F = BRepBuilderAPI_MakeFace(TopoDS::Wire(S), OnlyPlane);
188
189   DBRep::Set(a[1],F);
190   return 0;
191 }
192
193 //=======================================================================
194 // pcurve
195 //=======================================================================
196 Standard_IMPORT Draw_Color DrawTrSurf_CurveColor(const Draw_Color col);
197 Standard_IMPORT void DBRep_WriteColorOrientation ();
198 Standard_IMPORT Draw_Color DBRep_ColorOrientation (const TopAbs_Orientation Or);
199
200 static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const char** a)
201 {
202   Standard_Boolean mute = Standard_False;
203   for(Standard_Integer ia=1;ia<n;ia++) {
204     if (!strcasecmp(a[ia],"-mute")) {
205       suppressarg(n,a,ia);
206       mute = Standard_True;
207     }
208   }
209
210   if (n == 2) {
211     // pcurves of a face
212     TopoDS_Shape S = DBRep::Get(a[1],TopAbs_FACE);
213     if (S.IsNull()) return 1;
214
215     if (!mute) DBRep_WriteColorOrientation();
216     Draw_Color col, savecol = DrawTrSurf_CurveColor(Draw_rouge);
217
218     char* name = new char[100];
219     Standard_Real f,l;
220     S.Orientation(TopAbs_FORWARD);
221     TopExp_Explorer ex(S,TopAbs_EDGE);
222     for (Standard_Integer i=1; ex.More(); ex.Next(), i++) {
223       const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface
224         (TopoDS::Edge(ex.Current()),TopoDS::Face(S),f,l);
225       if ( c.IsNull() ) {
226         cout << "Error: Edge " << i << " does not have pcurve" << endl;
227         continue;
228       }
229       col = DBRep_ColorOrientation(ex.Current().Orientation());
230       DrawTrSurf_CurveColor(col);
231
232       sprintf(name,"%s_%d",a[1],i);
233       DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l));
234     }
235     DrawTrSurf_CurveColor(savecol);
236
237   }
238   else if (n >= 4) {
239     TopoDS_Shape SE = DBRep::Get(a[2],TopAbs_EDGE);
240     if (SE.IsNull()) return 1;
241     TopoDS_Shape SF = DBRep::Get(a[3],TopAbs_FACE);
242     if (SF.IsNull()) return 1;
243
244     Draw_Color col, savecol = DrawTrSurf_CurveColor(Draw_rouge);
245     Standard_Real f,l;
246     const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface
247       (TopoDS::Edge(SE),TopoDS::Face(SF),f,l);
248
249     col = DBRep_ColorOrientation(SE.Orientation());
250     DrawTrSurf_CurveColor(col);
251     DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l));
252     DrawTrSurf_CurveColor(savecol);
253   }
254   else { 
255     return 1;
256   }
257     
258   return 0;
259 }
260
261 //=======================================================================
262 // sewing
263 //=======================================================================
264
265 static Standard_Integer sewing (Draw_Interpretor& theDi, 
266                                 Standard_Integer n, const char** a)
267 {
268   if (n < 3) return (1);
269
270   BRepBuilderAPI_Sewing aSewing;
271   Standard_Integer ntmp = n;
272
273   TopoDS_Shape sh = DBRep::Get(a[2]);
274   Standard_Integer i=2;
275   Standard_Real tol = 1.0e-06;
276   if (sh.IsNull()) {
277     if (n < 4) return (1);
278     tol = atof(a[2]);
279     //Standard_Real tol = atof(a[2]);
280     //aSewing.Init(tol, Standard_True,Standard_True,Standard_True,Standard_False);
281     i = 3;
282   }
283
284   Standard_Boolean NonManifoldMode = Standard_False;
285   sh = DBRep::Get(a[n-1]);
286   if (sh.IsNull()) {
287     // read non manifold mode
288     Standard_Integer nmm = atoi(a[n-1]);
289     if(nmm==1)
290       NonManifoldMode = Standard_True;
291     ntmp--;
292   }
293   aSewing.Init(tol, Standard_True,Standard_True,Standard_True,NonManifoldMode);
294   
295   while (i < ntmp) {
296     sh = DBRep::Get(a[i]);
297     aSewing.Add(sh);
298     i++;
299   }
300   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDi, 1);
301   aSewing.Perform (aProgress);
302   aSewing.Dump();
303   const TopoDS_Shape& sh2 = aSewing.SewedShape();
304   if (!sh2.IsNull()) {
305     DBRep::Set(a[1], sh2);
306   }
307   return 0;
308 }
309
310 //=======================================================================
311 // continuity
312 //=======================================================================
313
314 static Standard_Integer continuity (Draw_Interpretor& , 
315                                     Standard_Integer n, const char** a)
316 {
317   if (n < 2) return (1);
318
319   BRepOffsetAPI_FindContigousEdges aFind;
320
321   TopoDS_Shape sh = DBRep::Get(a[1]);
322   Standard_Integer i=1;
323   if (sh.IsNull()) {
324     if (n < 3) return (1);
325     Standard_Real tol = atof(a[1]);
326     aFind.Init(tol, Standard_False);
327     i = 2;
328   }
329   
330   while (i < n) {
331     sh = DBRep::Get(a[i]);
332     aFind.Add(sh);
333     i++;
334   }
335
336   aFind.Perform();
337   aFind.Dump();
338
339   for (i=1; i<=aFind.NbContigousEdges(); i++) {
340 #ifdef DEB
341     const TopoDS_Edge& edge =
342 #endif
343                               aFind.ContigousEdge(i);
344     const TopTools_ListOfShape& list = aFind.ContigousEdgeCouple(i);
345     const TopoDS_Edge& sec1 = TopoDS::Edge(list.First());
346     const TopoDS_Edge& sec2 = TopoDS::Edge(list.Last());
347 #ifdef DEB
348     const TopoDS_Edge& bound1 =
349 #endif
350                                 aFind.SectionToBoundary(sec1);
351 #ifdef DEB
352     const TopoDS_Edge& bound2 =
353 #endif
354                                 aFind.SectionToBoundary(sec2);
355   }
356
357   return 0;
358 }
359
360 //=======================================================================
361 // encoderegularity
362 //=======================================================================
363 static Standard_Integer encoderegularity (Draw_Interpretor& , 
364                                           Standard_Integer n, const char** a)
365
366 {
367   if (n < 2) return 1;
368   TopoDS_Shape sh = DBRep::Get(a[1]);
369   if (sh.IsNull()) return 1;
370   if (n==2) 
371     BRepLib::EncodeRegularity(sh);
372   else {
373     Standard_Real Tol = atof(a[2]);
374     Tol *= PI/180.;
375     BRepLib::EncodeRegularity(sh, Tol);
376   }
377   return 0;
378 }
379
380
381 //=======================================================================
382 //function : SurfaceCommands
383 //purpose  : 
384 //=======================================================================
385
386 void  BRepTest::SurfaceCommands(Draw_Interpretor& theCommands)
387 {
388   static Standard_Boolean done = Standard_False;
389   if (done) return;
390   done = Standard_True;
391
392   DBRep::BasicCommands(theCommands);
393   GeometryTest::SurfaceCommands(theCommands);
394
395   const char* g = "Surface topology commands";
396
397   theCommands.Add("mkface",
398                   "mkface facename surfacename [ufirst ulast vfirst vlast] [wire [norient]]",
399                   __FILE__,mkface,g);
400
401   theCommands.Add("mkshell",
402                   "mkshell shellname surfacename [ufirst ulast vfirst vlast] [segment 0/1]",
403                   __FILE__,mkface,g);
404
405   theCommands.Add("quilt",
406                   "quilt compoundname shape1 edgeshape2  edgeshape1... shape2  edgeshape3 edgeshape1or2 ... shape3 ...",
407                   __FILE__,quilt,g);
408   
409   theCommands.Add("mksurface",
410                   "mksurface surfacename facename",
411                   __FILE__,mksurface,g);
412
413   theCommands.Add("mkplane",
414                   "mkplane facename wirename [OnlyPlane 0/1]",
415                   __FILE__,mkplane,g);
416
417   theCommands.Add("pcurve",
418                   "pcurve [name edgename] facename",
419                   __FILE__,pcurve,g);
420
421   theCommands.Add("sewing",
422                   "sewing result [tolerance] shape1 shape2 ...",
423                   __FILE__,sewing, g);
424
425   theCommands.Add("continuity", 
426                   "continuity [tolerance] shape1 shape2 ...",
427                   __FILE__,continuity, g);
428
429   theCommands.Add("encoderegularity", 
430                   "encoderegularity shape [tolerance (in degree)]",
431                   __FILE__,encoderegularity, g);
432 }
433