Salome HOME
NPAL15298: KindOfShape(). For all cases.
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IMeasureOperations.cxx
index 1dc078d530ebd24f0ba8edeecfa969d6cebfc8a8..f047467160e107866a003bf267f199f54cc151fa 100644 (file)
 #include <GEOMImpl_MeasureDriver.hxx>
 #include <GEOMImpl_IMeasure.hxx>
 
+#include <GEOMAlgo_ShapeInfo.hxx>
+#include <GEOMAlgo_ShapeInfoFiller.hxx>
+
 #include <GEOM_Function.hxx>
 #include <GEOM_PythonDump.hxx>
 
-#include "utilities.h"
+#include <utilities.h>
 #include <OpUtil.hxx>
 #include <Utils_ExceptHandlers.hxx>
 
@@ -132,318 +135,587 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
   TopoDS_Shape aShape = aRefShape->GetValue();
   if (aShape.IsNull()) return aKind;
 
-  TopAbs_ShapeEnum aType = aShape.ShapeType();
+  // Call algorithm
+  GEOMAlgo_ShapeInfoFiller aSF;
+  aSF.SetShape(aShape);
+  aSF.Perform();
+  Standard_Integer iErr = aSF.ErrorStatus();
+  if (iErr) {
+    SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
+    return SK_NO_SHAPE;
+  }
+  const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
+
+  // Interprete results
+  TopAbs_ShapeEnum aType = anInfo.Type();
   switch (aType)
   {
-    //??? geompy.kind.compound     nb_solids nb_faces nb_edges nb_vertices
-    //??? geompy.kind.compsolid    nb_solids nb_faces nb_edges nb_vertices
-    //? "nb_faces" - all faces or only 'standalone' faces?
-    case TopAbs_COMPOUND:
-      aKind = SK_COMPOUND;
-      //
-      break;
-    case TopAbs_COMPSOLID:
-      aKind = SK_COMPSOLID;
-      //
-      break;
-    case TopAbs_SHELL:
-      //geompy.kind.shell        geompy.info.closed   nb_faces nb_edges nb_vertices
-      //geompy.kind.shell        geompy.info.unclosed nb_faces nb_edges nb_vertices
+  case TopAbs_COMPOUND:
+  case TopAbs_COMPSOLID:
+    {
+      // (+) geompy.kind.COMPOUND     nb_solids nb_faces nb_edges nb_vertices
+      // (+) geompy.kind.COMPSOLID    nb_solids nb_faces nb_edges nb_vertices
+      // ??? "nb_faces" - all faces or only 'standalone' faces?
+      if (aType == TopAbs_COMPOUND)
+        aKind = SK_COMPOUND;
+      else
+        aKind = SK_COMPSOLID;
+
+      //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
+      //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+    }
+    break;
+
+  case TopAbs_SHELL:
+    {
+      // (+) geompy.kind.SHELL  geompy.info.closed   nb_faces nb_edges nb_vertices
+      // (+) geompy.kind.SHELL  geompy.info.unclosed nb_faces nb_edges nb_vertices
       aKind = SK_SHELL;
-      //
-      break;
-    case TopAbs_WIRE:
-      //geompy.kind.wire         geompy.info.closed   nb_edges nb_vertices
-      //geompy.kind.wire         geompy.info.unclosed nb_edges nb_vertices
+
+      theIntegers->Append((int)anInfo.KindOfClosed());
+
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+    }
+    break;
+
+  case TopAbs_WIRE:
+    {
+      // (+) geompy.kind.WIRE  geompy.info.closed   nb_edges nb_vertices
+      // (+) geompy.kind.WIRE  geompy.info.unclosed nb_edges nb_vertices
       aKind = SK_WIRE;
-      //
-      break;
-    case TopAbs_SOLID:
-      //geompy.kind.sphere       xc yc zc  R
-      //geompy.kind.cylinder     xb yb zb  dx dy dz  R  H
-      //geompy.kind.box          xc yc zc  dx dy dz
-      //geompy.kind.rotated_box  xo yo zo  zx zy zz  xx xy xz  dx dy dz
-      //geompy.kind.torus        xc yc zc  dx dy dz  R_1 R_2
-      //geompy.kind.cone         xb yb zb  dx dy dz  H  R_1  R_2
-      //geompy.kind.polyhedron   nb_faces nb_edges nb_vertices
-      //geompy.kind.solid        nb_faces nb_edges nb_vertices
+
+      theIntegers->Append((int)anInfo.KindOfClosed());
+
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+      theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+    }
+    break;
+
+  case TopAbs_SOLID:
+    {
       aKind = SK_SOLID;
-      //if () {
-      //  aKind = SK_SPHERE;
-      //  aKind = SK_CYLINDER;
-      //  aKind = SK_BOX;
-      //  aKind = SK_ROTATED_BOX;
-      //  aKind = SK_TORUS;
-      //  aKind = SK_CONE;
-      //  aKind = SK_POLYHEDRON;
-      //}
-      break;
-    case TopAbs_FACE:
-      // geompy.kind.sphere2d     xc yc zc  R
-      // + geompy.kind.cylinder2d   xb yb zb  dx dy dz  R  H
-      // geompy.kind.torus2d      xc yc zc  dx dy dz  R_1 R_2
-      // geompy.kind.cone2d       xc yc zc  dx dy dz  R_1 R_2
-      // geompy.kind.disk         xc yc zc  dx dy dz  R
-      // geompy.kind.ellipse2d    xc yc zc  dx dy dz  R_1 R_2
-      // geompy.kind.polygon      xo yo zo  dx dy dz  nb_edges nb_vertices
-      // + geompy.kind.planar       xo yo zo  dx dy dz  nb_edges nb_vertices
-      // + geompy.kind.face         nb_edges nb_vertices _surface_type_id_
-      aKind = SK_FACE;
-      {
-        TopoDS_Face aF = TopoDS::Face(aShape);
 
-        int nbWires = 0, nbEdges = 0, nbVertices = 0;
+      GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
+      switch (aKN)
+      {
+      case GEOMAlgo_KN_SPHERE:
+        // (+) geompy.kind.SPHERE  xc yc zc  R
+        {
+          aKind = SK_SPHERE;
 
-        TopTools_MapOfShape mapShape;
-        TopExp_Explorer expw (aF, TopAbs_WIRE);
-        for (; expw.More(); expw.Next()) {
-          if (mapShape.Add(expw.Current())) {
-            //listShape.Append(expw.Current());
-            nbWires++;
-          }
-        }
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
 
-        mapShape.Clear();
-        TopExp_Explorer expe (aF, TopAbs_EDGE);
-        for (; expe.More(); expe.Next()) {
-          if (mapShape.Add(expe.Current())) {
-            //listShape.Append(expe.Current());
-            nbEdges++;
-          }
+          theDoubles->Append(anInfo.Radius1());
         }
-
-        mapShape.Clear();
-        TopExp_Explorer expf (aF, TopAbs_VERTEX);
-        for (; expf.More(); expf.Next()) {
-          if (mapShape.Add(expf.Current())) {
-            //listShape.Append(expf.Current());
-            nbVertices++;
-          }
+        break;
+      case GEOMAlgo_KN_CYLINDER:
+        // (+) geompy.kind.CYLINDER  xb yb zb  dx dy dz  R  H
+        {
+          aKind = SK_CYLINDER;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Height());
         }
-
-        // Geometry
-        Handle(Geom_Surface) aGS = BRep_Tool::Surface(aF);
-        if (!aGS.IsNull()) {
-          BRepAdaptor_Surface aBAS (aF);
-
-          if (aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
-            // planar
-            aKind = SK_PLANAR;
-
-            Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
-            gp_Pln aPln = aGPlane->Pln();
-            gp_Ax3 aPos = aPln.Position();
-            gp_Pnt anOri = aPos.Location();
-            gp_Dir aDirZ = aPos.Direction();
-            //gp_Dir aDirX = aPos.XDirection();
-
-            // xo yo zo
-            theDoubles->Append(anOri.X());
-            theDoubles->Append(anOri.Y());
-            theDoubles->Append(anOri.Z());
-
-            // dx dy dz
-            theDoubles->Append(aDirZ.X());
-            theDoubles->Append(aDirZ.Y());
-            theDoubles->Append(aDirZ.Z());
-
-            // nb_edges nb_vertices (for planar only)
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
-
-            //if () {
-            //  aKind = SK_DISK;
-            //  aKind = SK_ELLIPSE2D;
-            //  aKind = SK_POLYGON;
-            //}
+        break;
+      case GEOMAlgo_KN_BOX:
+        // (+) geompy.kind.BOX  xc yc zc  ax ay az
+        {
+          aKind = SK_BOX;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          gp_Dir aX = anAx3.XDirection();
+
+          // ax ay az
+          if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
+              aX.IsParallel(gp::DX(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Length()); // ax'
+            theDoubles->Append(anInfo.Width());  // ay'
+            theDoubles->Append(anInfo.Height()); // az'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
-            //if (/*isSphere*/false) {
-            if (aBAS.IsUClosed() && aBAS.IsVClosed()) { // does not work
-              Handle(Geom_SphericalSurface) aGSph = Handle(Geom_SphericalSurface)::DownCast(aGS);
-
-              // parameters
-              gp_Pnt aLoc = aGSph->Location();
-              Standard_Real rr = aGSph->Radius();
-
-              // xc yc zc
-              theDoubles->Append(aLoc.X());
-              theDoubles->Append(aLoc.Y());
-              theDoubles->Append(aLoc.Z());
-
-              // R
-              theDoubles->Append(rr);
-
-              aKind = SK_SPHERE2D;
-            }
-            else {
-              // nb_edges nb_vertices (for spherical only)
-              theIntegers->Append(nbEdges);
-              theIntegers->Append(nbVertices);
-
-              theIntegers->Append((Standard_Integer)GeomAbs_Sphere);
-            }
+          else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
+                   aX.IsParallel(gp::DY(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Width());  // ay'
+            theDoubles->Append(anInfo.Length()); // ax'
+            theDoubles->Append(anInfo.Height()); // az'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
-            // Pure cylinder or just a piece of cylindric surface
-            TopLoc_Location aL;
-            Handle(Geom_Surface) aGSLoc = BRep_Tool::Surface(aF, aL);
-
-            //aF.Orientation(TopAbs_FORWARD);
-            TopExp_Explorer ex (aF, TopAbs_EDGE);
-            Standard_Real uMin, uMax, vMin, vMax;
-            bool isCylinder = true;
-            for (; ex.More(); ex.Next()) {
-              // check all edges: pure cylinder has only one seam edge
-              //                  and two edges with const v parameter
-              TopoDS_Edge E = TopoDS::Edge(ex.Current());
-
-              if (BRep_Tool::IsClosed(E, aGSLoc, aL)) {
-                // seam edge
-                //TopoDS_Edge ERevr = E;
-                //ERevr.Reverse();
-                //Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface(E    , aF, f,l);
-                //Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface(ERevr, aF, f,l);
-              }
-              else {
-                BRepTools::UVBounds(aF, E, uMin, uMax, vMin, vMax);
-                if (Abs(vMin - vMax) > Precision::Confusion())
-                  // neither seam, nor v-constant
-                  isCylinder = false;
-              }
-            }
-
-            if (isCylinder) {
-              aKind = SK_CYLINDER2D;
-
-              Handle(Geom_CylindricalSurface) aGCyl = Handle(Geom_CylindricalSurface)::DownCast(aGS);
-
-              // parameters
-              gp_Pnt aLoc = aGCyl->Location();
-              gp_Ax1 anAx = aGCyl->Axis();
-              gp_Dir aDir = anAx.Direction();
-              Standard_Real rr = aGCyl->Radius();
-
-              // xb yb zb
-              theDoubles->Append(aLoc.X());
-              theDoubles->Append(aLoc.Y());
-              theDoubles->Append(aLoc.Z());
-
-              // dx dy dz
-              theDoubles->Append(aDir.X());
-              theDoubles->Append(aDir.Y());
-              theDoubles->Append(aDir.Z());
-
-              // R
-              theDoubles->Append(rr);
-
-              // H
-              Standard_Real hh = Abs(aBAS.FirstVParameter() - aBAS.LastVParameter());
-              theDoubles->Append(hh);
-            }
-            else {
-              // nb_edges nb_vertices (for cylinrical only)
-              theIntegers->Append(nbEdges);
-              theIntegers->Append(nbVertices);
-
-              theIntegers->Append((Standard_Integer)GeomAbs_Cylinder);
-            }
+          else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
+                   aX.IsParallel(gp::DZ(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Height()); // az'
+            theDoubles->Append(anInfo.Width());  // ay'
+            theDoubles->Append(anInfo.Length()); // ax'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
-            //  aKind = SK_TORUS2D;
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
-
-            theIntegers->Append((Standard_Integer)GeomAbs_Torus);
+          else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
+                   aX.IsParallel(gp::DY(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Height()); // az'
+            theDoubles->Append(anInfo.Length()); // ax'
+            theDoubles->Append(anInfo.Width());  // ay'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
-            //  aKind = SK_CONE2D;
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
-
-            theIntegers->Append((Standard_Integer)GeomAbs_Cone);
+          else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
+                   aX.IsParallel(gp::DZ(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Width());  // ay'
+            theDoubles->Append(anInfo.Height()); // az'
+            theDoubles->Append(anInfo.Length()); // ax'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
-
-            theIntegers->Append((Standard_Integer)GeomAbs_SurfaceOfExtrusion);
+          else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
+                   aX.IsParallel(gp::DX(), Precision::Angular())) {
+            theDoubles->Append(anInfo.Length()); // ax'
+            theDoubles->Append(anInfo.Height()); // az'
+            theDoubles->Append(anInfo.Width());  // ay'
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
-
-            theIntegers->Append((Standard_Integer)GeomAbs_SurfaceOfRevolution);
+          else {
+            // (+) geompy.kind.ROTATED_BOX  xo yo zo  zx zy zz  xx xy xz  ax ay az
+            aKind = SK_ROTATED_BOX;
+
+            // Direction and XDirection
+            theDoubles->Append(aD.X());
+            theDoubles->Append(aD.Y());
+            theDoubles->Append(aD.Z());
+
+            theDoubles->Append(aX.X());
+            theDoubles->Append(aX.Y());
+            theDoubles->Append(aX.Z());
+
+            // ax ay az
+            theDoubles->Append(anInfo.Length());
+            theDoubles->Append(anInfo.Width());
+            theDoubles->Append(anInfo.Height());
           }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
+        }
+        break;
+      case GEOMAlgo_KN_TORUS:
+        // (+) geompy.kind.TORUS  xc yc zc  dx dy dz  R_1 R_2
+        {
+          aKind = SK_TORUS;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+        }
+        break;
+      case GEOMAlgo_KN_CONE:
+        // (+) geompy.kind.CONE  xb yb zb  dx dy dz  R_1 R_2  H
+        {
+          aKind = SK_CONE;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+          theDoubles->Append(anInfo.Height());
+        }
+        break;
+      case GEOMAlgo_KN_POLYHEDRON:
+        // (+) geompy.kind.POLYHEDRON  nb_faces nb_edges nb_vertices
+        {
+          aKind = SK_POLYHEDRON;
+
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+        }
+        break;
+      default:
+        // (+) geompy.kind.SOLID  nb_faces nb_edges nb_vertices
+        {
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+        }
+      }
+    }
+    break;
 
-            theIntegers->Append((Standard_Integer)GeomAbs_BezierSurface);
-          }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
+  case TopAbs_FACE:
+    {
+      aKind = SK_FACE;
 
-            theIntegers->Append((Standard_Integer)GeomAbs_BSplineSurface);
-          }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
+      GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
+      switch (aKN) {
+      case GEOMAlgo_KN_SPHERE:
+        // (+) geompy.kind.SPHERE2D  xc yc zc  R
+        {
+          aKind = SK_SPHERE2D;
 
-            theIntegers->Append((Standard_Integer)GeomAbs_OffsetSurface);
-          }
-          else if (aGS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
-            //
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
 
-            theIntegers->Append((Standard_Integer)GeomAbs_OtherSurface);
-          }
-          else {
-            // ???
-            theIntegers->Append(nbEdges);
-            theIntegers->Append(nbVertices);
+          theDoubles->Append(anInfo.Radius1());
+        }
+        break;
+      case GEOMAlgo_KN_CYLINDER:
+        // (+) geompy.kind.CYLINDER2D  xb yb zb  dx dy dz  R  H
+        {
+          aKind = SK_CYLINDER2D;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Height());
+        }
+        break;
+      case GEOMAlgo_KN_TORUS:
+        // (+) geompy.kind.TORUS2D  xc yc zc  dx dy dz  R_1 R_2
+        {
+          aKind = SK_TORUS2D;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+        }
+        break;
+      case GEOMAlgo_KN_CONE:
+        // (+) geompy.kind.CONE2D  xc yc zc  dx dy dz  R_1 R_2  H
+        {
+          aKind = SK_CONE2D;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+          theDoubles->Append(anInfo.Height());
+        }
+        break;
+      case GEOMAlgo_KN_DISKCIRCLE:
+        // (+) geompy.kind.DISK_CIRCLE  xc yc zc  dx dy dz  R
+        {
+          aKind = SK_DISK_CIRCLE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+        }
+        break;
+      case GEOMAlgo_KN_DISKELLIPSE:
+        // (+) geompy.kind.DISK_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
+        {
+          aKind = SK_DISK_ELLIPSE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+        }
+        break;
+      case GEOMAlgo_KN_RECTANGLE:
+      case GEOMAlgo_KN_TRIANGLE:
+      case GEOMAlgo_KN_QUADRANGLE:
+      case GEOMAlgo_KN_POLYGON:
+        // (+) geompy.kind.POLYGON  xo yo zo  dx dy dz  nb_edges nb_vertices
+        {
+          aKind = SK_POLYGON;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+        }
+        break;
+      case GEOMAlgo_KN_PLANE: // infinite
+        // (+) geompy.kind.PLANE  xo yo zo  dx dy dz
+        {
+          aKind = SK_PLANE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+        }
+        break;
+      default:
+        if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
+          // (+) geompy.kind.PLANAR  xo yo zo  dx dy dz  nb_edges nb_vertices
+
+          aKind = SK_PLANAR;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+        }
+        else {
+          // ??? geompy.kind.FACE  nb_edges nb_vertices _surface_type_id_
+          // (+) geompy.kind.FACE  nb_edges nb_vertices
 
-            theIntegers->Append((Standard_Integer)GeomAbs_OtherSurface);
-          }
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
         }
       }
-      break;
-    case TopAbs_EDGE:
-      //geompy.kind.circle       xc yc zc  dx dy dz  R
-      //geompy.kind.arc          xc yc zc  dx dy dz  R  x1 y1 z1  x2 y2 z2
-      //geompy.kind.ellipse      xc yc zc  dx dy dz  R_1 R_2
-      //geompy.kind.arcEllipse   xc yc zc  dx dy dz  R_1 R_2  x1 y1 z1  x2 y2 z2
-      //geompy.kind.line         x1 y1 z1  x2 y2 z2
-      //geompy.kind.segment      x1 y1 z1  x2 y2 z2
-      //geompy.kind.edge         nb_vertices _curve_type_id_
+    }
+    break;
+
+  case TopAbs_EDGE:
+    {
       aKind = SK_EDGE;
-      //if () {
-      //  aKind = SK_CIRCLE;
-      //  aKind = SK_ARC;
-      //  aKind = SK_ELLIPSE;
-      //  aKind = SK_ARC_ELLIPSE;
-      //  aKind = SK_LINE;
-      //  aKind = SK_SEGMENT;
-      //}
-      break;
-    case TopAbs_VERTEX:
-      //geompy.kind.VERTEX  x y z
-      aKind = SK_VERTEX;
-      {
-        TopoDS_Vertex aV = TopoDS::Vertex(aShape);
-        gp_Pnt aP = BRep_Tool::Pnt(aV);
-        theDoubles->Append(aP.X());
-        theDoubles->Append(aP.Y());
-        theDoubles->Append(aP.Z());
+
+      GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
+      switch (aKN) {
+      case GEOMAlgo_KN_CIRCLE:
+        {
+          // (+) geompy.kind.CIRCLE  xc yc zc  dx dy dz  R
+          aKind = SK_CIRCLE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+        }
+        break;
+      case GEOMAlgo_KN_ARCCIRCLE:
+        {
+          // (+) geompy.kind.ARC_CIRCLE  xc yc zc  dx dy dz  R  x1 y1 z1  x2 y2 z2
+          aKind = SK_ARC_CIRCLE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+
+          gp_Pnt aP1 = anInfo.Pnt1();
+          theDoubles->Append(aP1.X());
+          theDoubles->Append(aP1.Y());
+          theDoubles->Append(aP1.Z());
+
+          gp_Pnt aP2 = anInfo.Pnt2();
+          theDoubles->Append(aP2.X());
+          theDoubles->Append(aP2.Y());
+          theDoubles->Append(aP2.Z());
+        }
+        break;
+      case GEOMAlgo_KN_ELLIPSE:
+        {
+          // (+) geompy.kind.ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
+          aKind = SK_ELLIPSE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+        }
+        break;
+      case GEOMAlgo_KN_ARCELLIPSE:
+        {
+          // (+) geompy.kind.ARC_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2  x1 y1 z1  x2 y2 z2
+          aKind = SK_ARC_ELLIPSE;
+
+          gp_Pnt aC = anInfo.Location();
+          theDoubles->Append(aC.X());
+          theDoubles->Append(aC.Y());
+          theDoubles->Append(aC.Z());
+
+          gp_Ax3 anAx3 = anInfo.Position();
+          gp_Dir aD = anAx3.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+
+          theDoubles->Append(anInfo.Radius1());
+          theDoubles->Append(anInfo.Radius2());
+
+          gp_Pnt aP1 = anInfo.Pnt1();
+          theDoubles->Append(aP1.X());
+          theDoubles->Append(aP1.Y());
+          theDoubles->Append(aP1.Z());
+
+          gp_Pnt aP2 = anInfo.Pnt2();
+          theDoubles->Append(aP2.X());
+          theDoubles->Append(aP2.Y());
+          theDoubles->Append(aP2.Z());
+        }
+        break;
+      case GEOMAlgo_KN_LINE:
+        {
+          // ??? geompy.kind.LINE  x1 y1 z1  x2 y2 z2
+          // (+) geompy.kind.LINE  x1 y1 z1  dx dy dz
+          aKind = SK_LINE;
+
+          gp_Pnt aO = anInfo.Location();
+          theDoubles->Append(aO.X());
+          theDoubles->Append(aO.Y());
+          theDoubles->Append(aO.Z());
+
+          gp_Dir aD = anInfo.Direction();
+          theDoubles->Append(aD.X());
+          theDoubles->Append(aD.Y());
+          theDoubles->Append(aD.Z());
+        }
+        break;
+      case GEOMAlgo_KN_SEGMENT:
+        {
+          // (+) geompy.kind.SEGMENT  x1 y1 z1  x2 y2 z2
+          aKind = SK_SEGMENT;
+
+          gp_Pnt aP1 = anInfo.Pnt1();
+          theDoubles->Append(aP1.X());
+          theDoubles->Append(aP1.Y());
+          theDoubles->Append(aP1.Z());
+
+          gp_Pnt aP2 = anInfo.Pnt2();
+          theDoubles->Append(aP2.X());
+          theDoubles->Append(aP2.Y());
+          theDoubles->Append(aP2.Z());
+        }
+        break;
+      default:
+        // ??? geompy.kind.EDGE  nb_vertices _curve_type_id_
+        // (+) geompy.kind.EDGE  nb_vertices
+        theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
       }
-      break;
+    }
+    break;
+
+  case TopAbs_VERTEX:
+    {
+      // (+) geompy.kind.VERTEX  x y z
+      aKind = SK_VERTEX;
+
+      gp_Pnt aP = anInfo.Location();
+      theDoubles->Append(aP.X());
+      theDoubles->Append(aP.Y());
+      theDoubles->Append(aP.Z());
+    }
+    break;
   }
 
   SetErrorCode(OK);