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?

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))
}

// 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;
}

// (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;