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