Site Tools


Get Surface Curvature Statistics

Developer: .NET
Summary: Demonstrates how to get surface curvature statistics.

Question

How can I get surface curvature statistics, such as Gaussian, Min, Max, and Mean curvature using the Rhino SDK?

Answer

Surface curvature analysis is based off of a surface's analysis mesh. Once you have an analysis mesh, then you can then calculate curvature statistics using OnMeshCurvatureStats.

Example

The following example function demonstrates a generic way to calculate curvature statistics.

C#

static bool RhinoSurfaceCurvatureStatistics(
  IOnBrep brep, 
  IOn.curvature_style kappa_style, 
  ref OnMeshCurvatureStats stats
  )
{
  if (null == brep || !brep.IsValid())
   return false;
 
  MRhinoDoc doc = RhUtil.RhinoApp().ActiveDoc();
  if (null == doc)
    return false;
 
  OnMeshParameters mp = new OnMeshParameters(doc.Properties().AnalysisMeshSettings());
  mp.m_bComputeCurvature = true;
 
  stats.Destroy();
 
  // Get curvature statistics from each analysis mesh
 
  int face_count = brep.m_F.Count();
  List<OnMeshCurvatureStats> mesh_stats = new List<OnMeshCurvatureStats>(face_count);
  for (int fi = 0; fi < face_count; fi++)
  {
    IOnBrepFace face = brep.m_F[fi];
    if (null == face || face.m_face_index != fi)
     continue;
 
    OnMesh mesh = face.CreateMesh(mp);
    if (null == mesh)
     continue;
 
    OnMeshCurvatureStats mesh_cs = new OnMeshCurvatureStats();
    if (mesh.GetCurvatureStats(IOn.curvature_style.gaussian_curvature, ref mesh_cs))
      mesh_stats.Add(mesh_cs);
  }
 
  // Calculate total stats
 
  int mesh_count = mesh_stats.Count;
  if (0 == mesh_count)
    return false;
 
  stats = mesh_stats[0];
 
  if (mesh_count > 1)
  {
    OnMeshCurvatureStats mesh_cs = null;
    double d = 0.0;
 
    stats.m_average = stats.m_average * stats.m_count;
    stats.m_mode = stats.m_mode * stats.m_count;
    for (int i = 1; i < mesh_count; i++)
    {
      mesh_cs = mesh_stats[i];
      if (mesh_cs.m_infinity < stats.m_infinity)
        stats.m_infinity = mesh_cs.m_infinity;
      stats.m_count_infinite += mesh_cs.m_count_infinite;
      stats.m_count += mesh_cs.m_count;
      stats.m_average += mesh_cs.m_count * mesh_cs.m_average;
      stats.m_mode += mesh_cs.m_count * mesh_cs.m_mode;
      if (stats.m_count > 0 && mesh_cs.m_count > 0)
      {
        if (stats.m_range[0] > mesh_cs.m_range[0])
          stats.m_range[0] = mesh_cs.m_range[0];
        if (stats.m_range[1] < mesh_cs.m_range[1])
          stats.m_range[1] = mesh_cs.m_range[1];
      }
      else if (mesh_cs.m_count > 0)
      {
        stats.m_range = mesh_cs.m_range;
      }
    }
 
    if (stats.m_count > 0)
    {
      d = 1.0 / stats.m_count;
      stats.m_average *= d;
      stats.m_mode *= d;
      stats.m_adev = 0.0;
    }
 
    // (Over) estimate total average deviation from
    // actual deviations on each mesh.
 
    for (int i = 0; i < mesh_count; i++)
    {
      mesh_cs = mesh_stats[i];
      d = mesh_cs.m_adev + Math.Abs(stats.m_average - mesh_cs.m_average);
      d = d * mesh_cs.m_count;
      stats.m_adev += d;
    }
 
    if (stats.m_count > 0)
      stats.m_adev = stats.m_adev / stats.m_count;
  }
 
  return true;
}


developer/getcurvaturestats.txt ยท Last modified: 2015/09/14 (external edit)