0026118: Implement FastSewing algorithm
[occt.git] / src / BRepTest / BRepTest_SurfaceCommands.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 04868d3..72ec470
@@ -1,11 +1,19 @@
-// File:       DBRep_4.cxx
-// Created:    Thu Jul 22 16:39:43 1993
-// Author:     Remi LEQUETTE
-//             <rle@nonox>
+// Created on: 1993-07-22
+// Created by: Remi LEQUETTE
+// Copyright (c) 1993-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
 #include <stdio.h>
 #include <BRepTest.hxx>
 #include <GeometryTest.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 #include <Precision.hxx>
+#include <Draw_ProgressIndicator.hxx>
+#include <NCollection_Vector.hxx>
+#include <BRepBuilderAPI_FastSewing.hxx>
 
-#ifdef WNT
+#ifdef _WIN32
 //#define strcasecmp strcmp Already defined
 #include <stdio.h>
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 
 //-----------------------------------------------------------------------
 // suppressarg : suppress a[d],modifie na--
@@ -92,9 +101,9 @@ static Standard_Integer mkface(Draw_Interpretor& , Standard_Integer n, const cha
   }
   else {
     if (mkface)
-      res = BRepBuilderAPI_MakeFace(S,atof(a[3]),atof(a[4]),atof(a[5]),atof(a[6]),Precision::Confusion());
+      res = BRepBuilderAPI_MakeFace(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),Precision::Confusion());
     else
-      res = BRepBuilderAPI_MakeShell(S,atof(a[3]),atof(a[4]),atof(a[5]),atof(a[6]),
+      res = BRepBuilderAPI_MakeShell(S,Draw::Atof(a[3]),Draw::Atof(a[4]),Draw::Atof(a[5]),Draw::Atof(a[6]),
                              Segment);
   }
   
@@ -228,7 +237,7 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha
       col = DBRep_ColorOrientation(ex.Current().Orientation());
       DrawTrSurf_CurveColor(col);
 
-      sprintf(name,"%s_%d",a[1],i);
+      Sprintf(name,"%s_%d",a[1],i);
       DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l));
     }
     DrawTrSurf_CurveColor(savecol);
@@ -261,50 +270,199 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha
 // sewing
 //=======================================================================
 
-static Standard_Integer sewing (Draw_Interpretor& , 
-                               Standard_Integer n, const char** a)
+static Standard_Integer sewing (Draw_Interpretor& theDi
+                               Standard_Integer theArgc, const char** theArgv)
 {
-  if (n < 3) return (1);
-
   BRepBuilderAPI_Sewing aSewing;
-  Standard_Integer ntmp = n;
+  Standard_Integer aPar = 1;
+  TopTools_SequenceOfShape aSeq;
+
+  Standard_Real aTol = 1.0e-06;
+  Standard_Boolean aSewingMode = Standard_True;
+  Standard_Boolean anAnalysisMode = Standard_True;
+  Standard_Boolean aCuttingMode = Standard_True;
+  Standard_Boolean aNonManifoldMode = Standard_False;
+  Standard_Boolean aSameParameterMode = Standard_True;
+  Standard_Boolean aFloatingEdgesMode = Standard_False;
+  Standard_Boolean aFaceMode = Standard_True;
+  Standard_Boolean aSetMinTol = Standard_False;
+  Standard_Real aMinTol = 0.;
+  Standard_Real aMaxTol = Precision::Infinite();
+
+  for (Standard_Integer i = 2; i < theArgc; i++)
+  {
+    if (theArgv[i][0] == '-' || theArgv[i][0] == '+')
+    {
+      Standard_Boolean aVal = (theArgv[i][0] == '+' ? Standard_True : Standard_False);
+      switch (tolower(theArgv[i][1]))
+      {
+      case 'm':
+        {
+          if (tolower(theArgv[i][2]) == 'i' && i+1 < theArgc)
+          {
+            if (Draw::Atof (theArgv[i+1]))
+            {
+              aMinTol = Draw::Atof (theArgv[++i]);
+              aSetMinTol = Standard_True;
+            }
+            else
+            {
+              theDi << "Error! min tolerance can't possess the null value" << "\n";
+              return (1);
+            }
+          }
+          if (tolower(theArgv[i][2]) == 'a' && i+1 < theArgc)
+          {
+            if (Draw::Atof (theArgv[i+1]))
+              aMaxTol = Draw::Atof (theArgv[++i]);
+            else
+            {
+              theDi << "Error! max tolerance can't possess the null value" << "\n";
+              return (1);
+            }
+          }
+        }
+        break;
+      case 's': aSewingMode = aVal; break;
+      case 'a': anAnalysisMode = aVal; break;
+      case 'c': aCuttingMode = aVal; break;
+      case 'n': aNonManifoldMode = aVal; break;
+      case 'p': aSameParameterMode = aVal; break;
+      case 'e': aFloatingEdgesMode = aVal; break;
+      case 'f': aFaceMode = aVal; break;
+      }
+    }
+    else
+    {
+      TopoDS_Shape aShape = DBRep::Get (theArgv[i]);
+      if (!aShape.IsNull())
+      {
+        aSeq.Append (aShape);
+        aPar++;
+      }
+      else
+      {
+        if (Draw::Atof (theArgv[i]))
+          aTol = Draw::Atof (theArgv[i]);
+      }
+    }
+  }
+   
+  if (aPar < 2)
+  {
+    theDi << "Use: " << theArgv[0] << " result [tolerance] shape1 shape2 ... [min tolerance] [max tolerance] [switches]" << "\n";
+    theDi << "To set user's value of min/max tolerances the following syntax is used: +<parameter> <value>" << "\n";
+    theDi << "- parameters are identified by letters:" << "\n";
+    theDi << "  mint - min tolerance" << "\n";
+    theDi << "  maxt - max tolerance" << "\n";
+    theDi << "Switches allow to tune other parameters of Sewing" << "\n";
+    theDi << "The following syntax is used: <symbol><parameter>" << "\n";
+    theDi << "- symbol may be - to set parameter off, + to set on" << "\n";
+    theDi << "- parameters are identified by letters:" << "\n";
+    theDi << "  s - mode for creating sewed shape" << "\n";
+    theDi << "  a - mode for analysis of input shapes" << "\n";
+    theDi << "  c - mode for cutting of free edges" << "\n";
+    theDi << "  n - mode for non manifold processing" << "\n";
+    theDi << "  p - mode for same parameter processing for edges" << "\n";
+    theDi << "  e - mode for sewing floating edges" << "\n";
+    theDi << "  f - mode for sewing faces" << "\n";
+    return (1);
+  }
+    
+  if (!aSetMinTol)
+    aMinTol = aTol*1e-4;
+  if (aTol < Precision::Confusion())
+    aTol = Precision::Confusion();
+  if (aMinTol < Precision::Confusion())
+    aMinTol = Precision::Confusion();
+  if (aMinTol > aTol)
+  {
+    theDi << "Error! min tolerance can't exceed working tolerance" << "\n";
+    return (1);
+  }
+  if (aMaxTol < aTol)
+  {
+    theDi << "Error! max tolerance can't be less than working tolerance" << "\n";
+    return (1);
+  }
 
-  TopoDS_Shape sh = DBRep::Get(a[2]);
-  Standard_Integer i=2;
-  Standard_Real tol = 1.0e-06;
-  if (sh.IsNull()) {
-    if (n < 4) return (1);
-    tol = atof(a[2]);
-    //Standard_Real tol = atof(a[2]);
-    //aSewing.Init(tol, Standard_True,Standard_True,Standard_True,Standard_False);
-    i = 3;
+  aSewing.Init (aTol, aSewingMode, anAnalysisMode, aCuttingMode, aNonManifoldMode);
+  aSewing.SetSameParameterMode (aSameParameterMode);
+  aSewing.SetFloatingEdgesMode (aFloatingEdgesMode);
+  aSewing.SetFaceMode (aFaceMode);
+  aSewing.SetMinTolerance (aMinTol);
+  aSewing.SetMaxTolerance (aMaxTol);
+
+  for (Standard_Integer i = 1; i <= aSeq.Length(); i++)
+    aSewing.Add(aSeq.Value(i));
+  
+  Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDi, 1);
+  aSewing.Perform (aProgress);
+  aSewing.Dump();
+
+  const TopoDS_Shape& aRes = aSewing.SewedShape();
+  if (!aRes.IsNull())
+    DBRep::Set(theArgv[1], aRes);
+  return 0;
+}
+
+//=======================================================================
+//function : fastsewing
+//purpose  : 
+//=======================================================================
+Standard_Integer fastsewing (Draw_Interpretor& theDI, 
+                            Standard_Integer theNArg, 
+                            const char** theArgVal)
+{
+  if(theNArg < 3)
+  {
+    //                0         1       2     3         4
+    theDI << "Use: fastsewing result [-tol <value>] <list_of_faces>\n";
+    return 1;
   }
 
-  Standard_Boolean NonManifoldMode = Standard_False;
-  sh = DBRep::Get(a[n-1]);
-  if (sh.IsNull()) {
-    // read non manifold mode
-    Standard_Integer nmm = atoi(a[n-1]);
-    if(nmm==1)
-      NonManifoldMode = Standard_True;
-    ntmp--;
+  BRepBuilderAPI_FastSewing aFS;
+
+  Standard_Integer aStartIndex = 2;
+
+  if(!strcmp(theArgVal[aStartIndex], "-tol"))
+  {
+    aFS.SetTolerance(Draw::Atof (theArgVal[aStartIndex+1]));
+    aStartIndex = 4;
   }
 
-  aSewing.Init(tol, Standard_True,Standard_True,Standard_True,NonManifoldMode);
-  
-  while (i < ntmp) {
-    sh = DBRep::Get(a[i]);
-    aSewing.Add(sh);
-    i++;
+  for(Standard_Integer i = aStartIndex; i < theNArg; i++)
+  {
+    TopoDS_Shape aS = DBRep::Get(theArgVal[i]);
+    
+    if(!aFS.Add(aS))
+    {
+      theDI << "Face is not added. See statuses.\n";
+    }
   }
 
-  aSewing.Perform();
-  aSewing.Dump();
+  BRepBuilderAPI_FastSewing::FS_VARStatuses aStatus = aFS.GetStatuses();
 
-  const TopoDS_Shape& sh2 = aSewing.SewedShape();
-  if (!sh2.IsNull()) {
-    DBRep::Set(a[1], sh2);
+  if(aStatus)
+  {
+    theDI << "Error: There are some problems while adding (" <<
+                        (static_cast<Standard_Integer>(aStatus)) << ")\n";
+    aFS.GetStatuses(&cout);
   }
+
+  aFS.Perform();
+
+  aStatus = aFS.GetStatuses();
+
+  if(aStatus)
+  {
+    theDI << "Error: There are some problems while performing (" <<
+                        (static_cast<Standard_Integer>(aStatus)) << ")\n";
+    aFS.GetStatuses(&cout);
+  }
+
+  DBRep::Set(theArgVal[1], aFS.GetResult());
+
   return 0;
 }
 
@@ -323,7 +481,7 @@ static Standard_Integer continuity (Draw_Interpretor& ,
   Standard_Integer i=1;
   if (sh.IsNull()) {
     if (n < 3) return (1);
-    Standard_Real tol = atof(a[1]);
+    Standard_Real tol = Draw::Atof(a[1]);
     aFind.Init(tol, Standard_False);
     i = 2;
   }
@@ -337,24 +495,6 @@ static Standard_Integer continuity (Draw_Interpretor& ,
   aFind.Perform();
   aFind.Dump();
 
-  for (i=1; i<=aFind.NbContigousEdges(); i++) {
-#ifdef DEB
-    const TopoDS_Edge& edge =
-#endif
-                              aFind.ContigousEdge(i);
-    const TopTools_ListOfShape& list = aFind.ContigousEdgeCouple(i);
-    const TopoDS_Edge& sec1 = TopoDS::Edge(list.First());
-    const TopoDS_Edge& sec2 = TopoDS::Edge(list.Last());
-#ifdef DEB
-    const TopoDS_Edge& bound1 =
-#endif
-                                aFind.SectionToBoundary(sec1);
-#ifdef DEB
-    const TopoDS_Edge& bound2 =
-#endif
-                                aFind.SectionToBoundary(sec2);
-  }
-
   return 0;
 }
 
@@ -371,8 +511,8 @@ static Standard_Integer encoderegularity (Draw_Interpretor& ,
   if (n==2) 
     BRepLib::EncodeRegularity(sh);
   else {
-    Standard_Real Tol = atof(a[2]);
-    Tol *= PI/180.;
+    Standard_Real Tol = Draw::Atof(a[2]);
+    Tol *= M_PI/180.;
     BRepLib::EncodeRegularity(sh, Tol);
   }
   return 0;
@@ -420,7 +560,7 @@ void  BRepTest::SurfaceCommands(Draw_Interpretor& theCommands)
                  __FILE__,pcurve,g);
 
   theCommands.Add("sewing",
-                 "sewing result [tolerance] shape1 shape2 ...",
+                 "sewing result [tolerance] shape1 shape2 ... [min tolerance] [max tolerance] [switches]",
                  __FILE__,sewing, g);
 
   theCommands.Add("continuity", 
@@ -430,5 +570,8 @@ void  BRepTest::SurfaceCommands(Draw_Interpretor& theCommands)
   theCommands.Add("encoderegularity", 
                  "encoderegularity shape [tolerance (in degree)]",
                  __FILE__,encoderegularity, g);
+
+  theCommands.Add ("fastsewing", "fastsewing result [-tol <value>] <list_of_faces>", 
+                                                __FILE__, fastsewing, g);
 }