Table of Contents
Calculating the Volume Centroid of Solid Objects
C++, .NET
Version: Rhino 4
Summary: Demonstrates how to calculating the volume centroid of closed surface and polysurface objects using Rhino 4 SDK.
The following sample code demonstrates how to calculating the volume centroid of closed surface and polysurface.
C++
CRhinoCommand::result CCommandTest::RunCommand( const CRhinoCommandContext& context ) { CRhinoGetObject go; go.SetCommandPrompt( L"Select solids for volume centroid calculation" ); go.SetGeometryFilter( CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object ); go.SetGeometryAttributeFilter( CRhinoGetObject::closed_surface | CRhinoGetObject::closed_polysrf ); go.EnableSubObjectSelect( false ); go.EnableGroupSelect( true ); go.GetObjects( 1, 0 ); if( go.CommandResult() != success ) return go.CommandResult(); ON_SimpleArray<const ON_Geometry*> geom( go.ObjectCount() ); int i; for( i = 0; i < go.ObjectCount(); i++ ) { const ON_Geometry* geo = go.Object(i).Geometry(); if( 0 == geo ) return failure; geom.Append( geo ); } // Get bounding box of all objects ON_BoundingBox bbox; for( i = 0; i < geom.Count(); i++ ) geom[i]->GetBoundingBox( bbox, bbox.IsValid() ); ON_3dPoint base_point = bbox.Center(); ON_SimpleArray<ON_MassProperties> MassProp; MassProp.Reserve( geom.Count() ); for( i = 0; i < geom.Count(); i++ ) { ON_MassProperties* mp = &MassProp.AppendNew(); if( const ON_Surface* srf = ON_Surface::Cast(geom[i]) ) srf->VolumeMassProperties( *mp, true, true, false, false, base_point ); else if( const ON_Brep* brep = ON_Brep::Cast(geom[i]) ) brep->VolumeMassProperties( *mp, true, true, false, false, base_point ); } ON_MassProperties results; results.Sum( MassProp.Count(), MassProp.Array() ); ON_3dPoint pt( results.m_x0, results.m_y0, results.m_z0 ); context.m_doc.AddPointObject( pt ); context.m_doc.Redraw(); RhinoApp().Print( L"Volume centroid = %g,%g,%g\n", pt.x, pt.y, pt.z ); return success; }
C#
public override IRhinoCommand.result RunCommand(IRhinoCommandContext context) { MRhinoGetObject go = new MRhinoGetObject(); go.SetCommandPrompt( "Select solids for volume centroid calculation" ); go.SetGeometryFilter( IRhinoGetObject.GEOMETRY_TYPE_FILTER.surface_object | IRhinoGetObject.GEOMETRY_TYPE_FILTER.polysrf_object ); go.SetGeometryAttributeFilter( IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.closed_surface | IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.closed_polysrf ); go.EnableSubObjectSelect( false ); go.EnableGroupSelect( true ); go.GetObjects( 1, 0 ); if( go.CommandResult() != IRhinoCommand.result.success ) return go.CommandResult(); System.Collections.Generic.List<IOnGeometry> geom = new System.Collections.Generic.List<IOnGeometry>(); for( int i = 0; i < go.ObjectCount(); i++ ) { IOnGeometry geo = go.Object(i).Geometry(); if( geo == null ) return IRhinoCommand.result.failure; geom.Add( geo ); } // Get bounding box of all objects OnBoundingBox bbox = new OnBoundingBox(); for( int i = 0; i < geom.Count; i++ ) geom[i].GetBoundingBox( ref bbox, 1); On3dPoint base_point = bbox.Center(); System.Collections.Generic.List<OnMassProperties> MassProp = new System.Collections.Generic.List<OnMassProperties>(); for(int i = 0; i < geom.Count; i++ ) { OnMassProperties mp = new OnMassProperties(); IOnSurface srf = OnSurface.ConstCast(geom[i]); IOnBrep brep = OnBrep.ConstCast(geom[i]); if( srf != null ) srf.VolumeMassProperties( ref mp, true, true, false, false, base_point ); else if( brep != null ) brep.VolumeMassProperties( ref mp, true, true, false, false, base_point ); else mp = null; if( mp != null ) MassProp.Add(mp); } OnMassProperties results = new OnMassProperties(); results.Sum( MassProp.ToArray() ); On3dPoint pt = new On3dPoint(results.m_x0, results.m_y0, results.m_z0 ); context.m_doc.AddPointObject( pt ); context.m_doc.Redraw(); string msg = string.Format("Volume centroid = {0}\n",pt); RhUtil.RhinoApp().Print( msg ); return IRhinoCommand.result.success; }
VB.NET
Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) _ As RMA.Rhino.IRhinoCommand.result Dim go As New MRhinoGetObject() go.SetCommandPrompt("Select solids for volume centroid calculation") go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.surface_object Or _ IRhinoGetObject.GEOMETRY_TYPE_FILTER.polysrf_object) go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.closed_surface Or _ IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.closed_polysrf) go.EnableSubObjectSelect(False) go.EnableGroupSelect(True) go.GetObjects(1, 0) If (go.CommandResult() <> IRhinoCommand.result.success) Then Return go.CommandResult() End If Dim geom As New System.Collections.Generic.List(Of IOnGeometry)() For i As Integer = 0 To go.ObjectCount() - 1 Dim geo As IOnGeometry = go.Object(i).Geometry() If (geo Is Nothing) Then Return IRhinoCommand.result.failure End If geom.Add(geo) Next ' Get bounding box of all objects Dim bbox As New OnBoundingBox() For i As Integer = 0 To geom.Count - 1 geom(i).GetBoundingBox(bbox, 1) Next Dim base_point As On3dPoint = bbox.Center() Dim MassProp As New System.Collections.Generic.List(Of OnMassProperties)() For i As Integer = 0 To geom.Count - 1 Dim mp As New OnMassProperties() Dim srf As IOnSurface = OnSurface.ConstCast(geom(i)) Dim brep As IOnBrep = OnBrep.ConstCast(geom(i)) If (srf IsNot Nothing) Then srf.VolumeMassProperties(mp, True, True, False, False, base_point) ElseIf (brep IsNot Nothing) Then brep.VolumeMassProperties(mp, True, True, False, False, base_point) Else mp = Nothing End If If (mp IsNot Nothing) Then MassProp.Add(mp) Next Dim results As New OnMassProperties() results.Sum(MassProp.ToArray()) Dim pt As New On3dPoint(results.m_x0, results.m_y0, results.m_z0) context.m_doc.AddPointObject(pt) context.m_doc.Redraw() Dim msg As String = String.Format("Volume centroid = {0}", pt) RhUtil.RhinoApp().Print(msg + vbCrLf) Return IRhinoCommand.result.success End Function