Site Tools


솔리드 개체의 체적 중심 계산

C++, .NET

Version: Rhino 4
Summary: Rhino 4 SDK 를 사용하여 닫힌 서페이스와 폴리서페이스 개체의 체적 중심을 계산하는 법을 소개합니다.

다음의 샘플 코드에서는 닫힌 서페이스/폴리서페이스의 체적 중심 계산법을 소개합니다.

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


ko/developer/sdksamples/volumecentroid.txt · Last modified: 2020/08/14 (external edit)