0030346: Modeling Algorithms - BRepPrimAPI_MakeRevol throws "BRepSweep_Translation...
[occt.git] / src / BRepTest / BRepTest_SurfaceCommands.cxx
index b82ff08..3c55eaa 100644 (file)
@@ -5,8 +5,8 @@
 //
 // 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 version 2.1 as published
+// 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.
@@ -14,9 +14,6 @@
 // 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 <TopTools_SequenceOfShape.hxx>
 #include <Precision.hxx>
 #include <Draw_ProgressIndicator.hxx>
+#include <NCollection_Vector.hxx>
+#include <BRepBuilderAPI_FastSewing.hxx>
+
+#include <GeomAPI_ProjectPointOnSurf.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--
@@ -184,7 +182,7 @@ static Standard_Integer mksurface(Draw_Interpretor& , Standard_Integer n, const
 // mkplane
 //=======================================================================
 
-static Standard_Integer mkplane(Draw_Interpretor& , Standard_Integer n, const char** a)
+static Standard_Integer mkplane(Draw_Interpretor& theDI, Standard_Integer n, const char** a)
 {
   if (n < 3) return 1;
 
@@ -196,9 +194,30 @@ static Standard_Integer mkplane(Draw_Interpretor& , Standard_Integer n, const ch
     OnlyPlane =  !strcmp(a[3],"1");
   }
 
-  TopoDS_Face F = BRepBuilderAPI_MakeFace(TopoDS::Wire(S), OnlyPlane);
+  BRepBuilderAPI_MakeFace aMF(TopoDS::Wire(S), OnlyPlane);
+
+  switch(aMF.Error())
+  {
+  case BRepBuilderAPI_FaceDone:
+    DBRep::Set(a[1],aMF.Face());
+    break;
+  case BRepBuilderAPI_NoFace:
+    theDI << "Error. mkplane has been finished with \"No Face\" status.\n";
+    break;
+  case BRepBuilderAPI_NotPlanar:
+    theDI << "Error. mkplane has been finished with \"Not Planar\" status.\n";
+    break;
+  case BRepBuilderAPI_CurveProjectionFailed:
+    theDI << "Error. mkplane has been finished with \"Fail in projection curve\" status.\n";
+    break;
+  case BRepBuilderAPI_ParametersOutOfRange:
+    theDI << "Error. mkplane has been finished with \"Parameters are out of range\" status.\n";
+    break;
+  default:
+    theDI << "Error. Undefined status. Please check the code.\n";
+    break;
+  }
 
-  DBRep::Set(a[1],F);
   return 0;
 }
 
@@ -242,7 +261,24 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha
       DrawTrSurf_CurveColor(col);
 
       Sprintf(name,"%s_%d",a[1],i);
-      DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l));
+      Standard_Real fr = c->FirstParameter(), lr = c->LastParameter();
+      Standard_Boolean IsPeriodic = c->IsPeriodic();
+      if (c->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
+      {
+        const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (c)->BasisCurve(); 
+        IsPeriodic = aC->IsPeriodic();
+        fr = aC->FirstParameter();
+        lr = aC->LastParameter();
+      }
+      if(!IsPeriodic && 
+        ((fr - f > Precision::PConfusion()) || (l - lr > Precision::PConfusion())))
+      {
+        DrawTrSurf::Set(name, c);
+      }
+      else
+      {
+        DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l));
+      }
     }
     DrawTrSurf_CurveColor(savecol);
 
@@ -257,10 +293,27 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha
     Standard_Real f,l;
     const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface
       (TopoDS::Edge(SE),TopoDS::Face(SF),f,l);
+    Standard_Real fr = c->FirstParameter(), lr = c->LastParameter();
+    Standard_Boolean IsPeriodic = c->IsPeriodic();
+    if (c->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
+    {
+      const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (c)->BasisCurve(); 
+      IsPeriodic = aC->IsPeriodic();
+      fr = aC->FirstParameter();
+      lr = aC->LastParameter();
+    }
 
     col = DBRep_ColorOrientation(SE.Orientation());
     DrawTrSurf_CurveColor(col);
-    DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l));
+    if(!IsPeriodic && 
+      ((fr - f > Precision::PConfusion()) || (l - lr > Precision::PConfusion())))
+    {
+      DrawTrSurf::Set(a[1], c);
+    }
+    else
+    {
+      DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l));
+    }
     DrawTrSurf_CurveColor(savecol);
   }
   else { 
@@ -311,7 +364,7 @@ static Standard_Integer sewing (Draw_Interpretor& theDi,
             }
             else
             {
-              theDi << "Error! min tolerance can't possess the null value" << "\n";
+              theDi << "Error! min tolerance can't possess the null value\n";
               return (1);
             }
           }
@@ -321,7 +374,7 @@ static Standard_Integer sewing (Draw_Interpretor& theDi,
               aMaxTol = Draw::Atof (theArgv[++i]);
             else
             {
-              theDi << "Error! max tolerance can't possess the null value" << "\n";
+              theDi << "Error! max tolerance can't possess the null value\n";
               return (1);
             }
           }
@@ -354,22 +407,22 @@ static Standard_Integer sewing (Draw_Interpretor& theDi,
    
   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";
+    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);
   }
     
@@ -381,12 +434,12 @@ static Standard_Integer sewing (Draw_Interpretor& theDi,
     aMinTol = Precision::Confusion();
   if (aMinTol > aTol)
   {
-    theDi << "Error! min tolerance can't exceed working tolerance" << "\n";
+    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";
+    theDi << "Error! max tolerance can't be less than working tolerance\n";
     return (1);
   }
 
@@ -410,6 +463,66 @@ static Standard_Integer sewing (Draw_Interpretor& theDi,
   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;
+  }
+
+  BRepBuilderAPI_FastSewing aFS;
+
+  Standard_Integer aStartIndex = 2;
+
+  if(!strcmp(theArgVal[aStartIndex], "-tol"))
+  {
+    aFS.SetTolerance(Draw::Atof (theArgVal[aStartIndex+1]));
+    aStartIndex = 4;
+  }
+
+  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";
+    }
+  }
+
+  BRepBuilderAPI_FastSewing::FS_VARStatuses aStatus = aFS.GetStatuses();
+
+  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;
+}
+
 //=======================================================================
 // continuity
 //=======================================================================
@@ -462,6 +575,139 @@ static Standard_Integer encoderegularity (Draw_Interpretor& ,
   return 0;
 }
 
+static Standard_Integer getedgeregul
+  (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
+{
+  if( argc < 3)
+  {
+    cout<<"Invalid number of arguments. Should be: checkedgeregularity edge face1 [face2]"<<endl;
+    return 1;
+  }
+  
+  TopoDS_Shape anEdge =  DBRep::Get(argv[1],TopAbs_EDGE);
+  TopoDS_Shape aFace1 = DBRep::Get(argv[2],TopAbs_FACE);
+  TopoDS_Shape aFace2 = (argc > 3  ? DBRep::Get(argv[3],TopAbs_FACE) : aFace1);
+  if( anEdge.IsNull() || aFace1.IsNull() || aFace2.IsNull())
+  {
+    cout<<"Invalid number of arguments. Should be: getedgeregularity edge face1 [face2]"<<endl;
+    return 1;
+  }
+  GeomAbs_Shape aRegularity = BRep_Tool::Continuity(TopoDS::Edge(anEdge), TopoDS::Face(aFace1),  TopoDS::Face(aFace2));
+  TCollection_AsciiString aStrReg("Regularity of edge : ");
+  switch( aRegularity)
+  {
+    default:
+    case GeomAbs_C0 : aStrReg += "C0"; break;
+    case GeomAbs_G1 : aStrReg += "G1"; break;
+    case GeomAbs_C1 : aStrReg += "C1"; break;
+    case GeomAbs_G2 : aStrReg += "G2"; break;
+    case GeomAbs_C2 : aStrReg += "C2"; break;
+    case GeomAbs_C3 : aStrReg += "C3"; break;
+    case GeomAbs_CN : aStrReg += "CN"; break;
+  };
+
+  di<<aStrReg.ToCString()<<"\n";
+  return 0; // Done
+}
+
+//=======================================================================
+//function : projponf
+//purpose  : 
+//=======================================================================
+static Standard_Integer projponf(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+  if (n < 3 || n > 5) {
+    di << "Project point on the face.\n";
+    di << "Usage: projponf face pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]\n";
+    return 1;
+  }
+  // get face
+  TopoDS_Shape aS = DBRep::Get(a[1]);
+  if (aS.IsNull()) {
+    di << "the face is a null shape\n";
+    return 0;
+  }
+  //
+  if (aS.ShapeType() != TopAbs_FACE) {
+    di << "not a face\n";
+    return 0;
+  }
+  //
+  const TopoDS_Face& aFace = *(TopoDS_Face*)&aS;
+  //
+  // get point
+  gp_Pnt aP;
+  DrawTrSurf::GetPoint(a[2], aP);
+  //
+  // get projection options
+  // default values;
+  Extrema_ExtAlgo anExtAlgo = Extrema_ExtAlgo_Grad;
+  Extrema_ExtFlag anExtFlag = Extrema_ExtFlag_MINMAX;
+  //
+  for (Standard_Integer i = 3; i < n; ++i) {
+    if (!strcasecmp(a[i], "-min")) {
+      anExtFlag = Extrema_ExtFlag_MIN;
+    }
+    else if (!strcasecmp(a[i], "-max")) {
+      anExtFlag = Extrema_ExtFlag_MAX;
+    }
+    else if (!strcasecmp(a[i], "-minmax")) {
+      anExtFlag = Extrema_ExtFlag_MINMAX;
+    }
+    else if (!strcasecmp(a[i], "-t")) {
+      anExtAlgo = Extrema_ExtAlgo_Tree;
+    }
+    else if (!strcasecmp(a[i], "-g")) {
+      anExtAlgo = Extrema_ExtAlgo_Grad;
+    }
+  }
+  //
+  // get surface
+  TopLoc_Location aLoc;
+  const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc);
+  // move point to surface location
+  aP.Transform(aLoc.Transformation().Inverted());
+  //
+  // get bounds of the surface
+  Standard_Real aUMin, aUMax, aVMin, aVMax;
+  aSurf->Bounds(aUMin, aUMax, aVMin, aVMax);
+  //
+  // initialize projector
+  GeomAPI_ProjectPointOnSurf aProjPS;
+  aProjPS.Init(aSurf, aUMin, aUMax, aVMin, aVMax);
+  // set the options
+  aProjPS.SetExtremaAlgo(anExtAlgo);
+  aProjPS.SetExtremaFlag(anExtFlag);
+  // perform projection
+  aProjPS.Perform(aP);
+  //
+  if (aProjPS.NbPoints()) {
+    // lower distance
+    Standard_Real aDist = aProjPS.LowerDistance();
+    // lower distance parameters
+    Standard_Real U, V;
+    aProjPS.LowerDistanceParameters(U, V);
+    // nearest point
+    gp_Pnt aPProj = aProjPS.NearestPoint();
+    // translate projection point to face location
+    aPProj.Transform(aLoc.Transformation());
+    //
+    // print the projection values
+    di << "proj dist = " << aDist << "\n";
+    di << "uvproj = " << U << " " << V << "\n";
+    di << "pproj = " << aPProj.X() << " " << aPProj.Y() << " " << aPProj.Z() << "\n";
+  }
+  else {
+    if (!aProjPS.IsDone()) {
+      di << "projection failed\n";
+    }
+    else {
+      di << "no projection found\n";
+    }
+  }
+  return 0;
+}
 
 //=======================================================================
 //function : SurfaceCommands
@@ -514,5 +760,14 @@ 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);
+  theCommands.Add ("getedgeregularity", "getedgeregularity edge face1 [face2]",  __FILE__,getedgeregul,g);
+
+  theCommands.Add ("projponf",
+                   "projponf face pnt [extrema flag: -min/-max/-minmax] [extrema algo: -g(grad)/-t(tree)]\n"
+                   "\t\tProject point on the face.",
+                   __FILE__, projponf, g);
 }