Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

developer:sdksamples:createblock [2015/09/14] (current)
Line 1: Line 1:
 +====== Creating Blocks ======
 +====== C++, .NET ======
 +> **Version:​** //Rhino 4//
 +> **Summary:​** //​Demonstrates how to create an instance definition using the Rhino 4 SDK.//
 +> **Notice:** //For Rhino 5, this example is adapted for the new RhinoCommon SDK [[developer:​rhinocommonsamples:​createblock|here]].//​
 +
 +=====Also see=====
 +[[developer:​sdksamples:​insertblock|How to Insert a Block]]
 +
 +[[developer:​sdksamples:​insertblock|Dynamically Inserting Blocks]]
 +
 +=====Overview=====
 +Rhino blocks, known in the SDK as **instances**,​ are single objects that combine one or more objects. Using blocks lets you:
 +
 +  * Create parts libraries.
 +  * Update all instances by modifying the block definition.
 +  * Keep a smaller model size by using block instances instead of copying identical geometry.
 +  * Use the **BlockManager** command to view information about the blocks defined in the model.
 +  * Use the **Insert** command to place block instances into your model, which scales and rotates the instance.
 +
 +=====More information=====
 +Creating instance definitions using the Rhino SDK requires two steps:
 +
 +  - Define the instance definition objects. Instance definition objects are similar to regular Rhino objects - the ones that you see on the screen. The difference is that instance definition objects reside in a different location in the document. To add instance definition objects to the document, use **CRhinoDoc::​AddObject** and make sure you set the **bInstanceDefinition** parameter to **true**.
 +  - Add a new instance definition object to Rhino'​s instance definition table, which is located on the Rhino document. An instance definition defines the name of the instance and the instance definition objects used by it.
 +
 +**Note:** An instance definition'​s base point is always the world origin (0,​0,​0). ​ Knowing this, you need to orient your instance definition geometry around the world origin. The **Block** command does this by prompting the user for a base point and then transforming the selected objects from the user's picked point to the world origin. If you are adding your own geometry on the fly, and not picking it, just create your objects knowing that the base point for your instance definition will be the world origin.
 +
 +
 +=====Example=====
 +The following example code demonstrates how to select one or more objects and create a block definition with them. 
 +
 +**Note:** Unlike Rhino'​s Block command, this example code does not delete the selected objects, nor does it automatically insert a block instance at the location defined by the user.
 +
 +==== C++ ====
 +<code c++>
 +CRhinoCommand::​result CCommandTest::​RunCommand( const CRhinoCommandContext&​ context )
 +{
 +  // Select objects to define block
 +  CRhinoGetObject go;
 +  go.SetCommandPrompt( L"​Select objects to define block" );
 +  go.EnableReferenceObjectSelect( false );
 +  go.EnableSubObjectSelect( false );
 +  go.EnableGroupSelect( true );
 +
 +  // Phantoms, grips, lights, etc., cannot be in blocks.
 +  const unsigned int forbidden_geometry_filter ​
 +                = CRhinoGetObject::​light_object
 +                | CRhinoGetObject::​grip_object
 +                | CRhinoGetObject::​phantom_object;​
 +  const unsigned int geometry_filter = forbidden_geometry_filter ​
 +                               ^ CRhinoGetObject::​any_object;​
 +  go.SetGeometryFilter( geometry_filter );
 +  go.GetObjects( 1, 0 );
 +  if( go.CommandResult() != success )
 +    return go.CommandResult();​
 +
 +  // Block base point
 +  CRhinoGetPoint gp;
 +  gp.SetCommandPrompt( L"​Block base point" );
 +  gp.GetPoint();​
 +  if( gp.CommandResult() != success )
 +    return gp.CommandResult();​
 +
 +  ON_3dPoint base_point = gp.Point();
 +
 +  // Block definition name
 +  CRhinoGetString gs;
 +  gs.SetCommandPrompt( L"​Block definition name" );
 +  gs.GetString();​
 +  if( gs.CommandResult() != success )
 +    return gs.CommandResult();​
 +
 +  // Validate block name
 +  ON_wString idef_name = gs.String();​
 +  idef_name.TrimLeftAndRight();​
 +  if( idef_name.IsEmpty() )
 +    return nothing;
 +
 +  // See if block name already exists
 +  CRhinoInstanceDefinitionTable&​ idef_table = context.m_doc.m_instance_definition_table;​
 +  int idef_index = idef_table.FindInstanceDefinition( idef_name );
 +  if( idef_index >= 0 )
 +  {
 +    RhinoApp().Print( L"​Block definition \"​%s\"​ already exists.\n",​ idef_name );
 +    return nothing;
 +  }
 +
 +  // Create new block definition
 +  ON_InstanceDefinition idef;
 +  idef.SetName( idef_name );
 +
 +  // Gather all of the selected objects
 +  ON_SimpleArray<​const CRhinoObject*>​ objects( go.ObjectCount() );
 +  int i;
 +  for( i = 0; i < go.ObjectCount();​ i++ )
 +  {
 +    const CRhinoObject* obj = go.Object(i).Object();​
 +    if( obj )
 +      objects.Append( obj);
 +  }
 +
 +  ON_Xform xform;
 +  xform.Translation( ON_origin - base_point );
 +
 +  // Duplicate all of the selected objects and add them
 +  // to the document as instance definition objects
 +  ON_SimpleArray<​const CRhinoObject*>​ idef_objects( objects.Count() );
 +  for( i = 0; i < objects.Count();​ i++ )
 +  {
 +    const CRhinoObject* obj = objects[i];
 +    if( obj )
 +    {
 +      CRhinoObject* dupe = context.m_doc.TransformObject( obj, xform, false, false, false );
 +      if( dupe)
 +      {
 +        context.m_doc.AddObject( dupe, false, true );
 +        idef_objects.Append( dupe );
 +      }
 +    }
 +  }
 +
 +  if( idef_objects.Count() < 1 )
 +  {
 +    RhinoApp().Print( L"​Unable to duplicate block definition geometry.\n"​ );
 +    return failure;
 +  }
 +
 +  idef_index = idef_table.AddInstanceDefinition( idef, idef_objects );
 +  if( idef_index < 0 )
 +  {
 +    RhinoApp().Print( L"​Unable to create block definition \"​%s\"​.\n",​ idef_name );
 +    return failure;
 +  }
 +
 +  return success;
 +}
 +
 +</​code>​
 +==== C# ====
 +<code c#>
 +public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
 +{
 +  // Select objects to define block
 +  MRhinoGetObject go = new MRhinoGetObject();​
 +  go.SetCommandPrompt( "​Select objects to define block" );
 +  go.EnableReferenceObjectSelect( false );
 +  go.EnableSubObjectSelect( false );
 +  go.EnableGroupSelect( true );
 +
 +  // Phantoms, grips, lights, etc., cannot be in blocks.
 +  uint forbidden_geometry_filter = (uint)(IRhinoGetObject.GEOMETRY_TYPE_FILTER.light_object |
 +                                          IRhinoGetObject.GEOMETRY_TYPE_FILTER.grip_object |
 +                                          IRhinoGetObject.GEOMETRY_TYPE_FILTER.phantom_object );
 +  uint geometry_filter = forbidden_geometry_filter ^ (uint)IRhinoGetObject.GEOMETRY_TYPE_FILTER.any_object;​
 +  go.SetGeometryFilter( geometry_filter );
 +  go.GetObjects( 1, 0 );
 +  if( go.CommandResult() != IRhinoCommand.result.success )
 +    return go.CommandResult();​
 +
 +  // Block base point
 +  MRhinoGetPoint gp = new MRhinoGetPoint();​
 +  gp.SetCommandPrompt( "Block base point" );
 +  gp.GetPoint();​
 +  if( gp.CommandResult() != IRhinoCommand.result.success )
 +    return gp.CommandResult();​
 +
 +  On3dPoint base_point = gp.Point();
 +
 +  // Block definition name
 +  MRhinoGetString gs = new MRhinoGetString();​
 +  gs.SetCommandPrompt( "Block definition name" );
 +  gs.GetString();​
 +  if( gs.CommandResult() != IRhinoCommand.result.success )
 +    return gs.CommandResult();​
 +
 +  // Validate block name
 +  string idef_name = gs.String().Trim();​
 +  if( string.IsNullOrEmpty(idef_name))
 +    return IRhinoCommand.result.nothing;​
 +
 +  // See if block name already exists
 +  MRhinoInstanceDefinitionTable idef_table = context.m_doc.m_instance_definition_table;​
 +  int idef_index = idef_table.FindInstanceDefinition( idef_name );
 +  if( idef_index >= 0 )
 +  {
 +    string msg = "Block definition \ + idef_name + "​\"​ already exists.\n";​
 +    RhUtil.RhinoApp().Print( msg );
 +    return IRhinoCommand.result.nothing;​
 +  }
 +
 +  // Create new block definition
 +  OnInstanceDefinition idef = new OnInstanceDefinition();​
 +  idef.SetName( idef_name );
 +
 +  // Gather all of the selected objects
 +  List<​IRhinoObject>​ objects = new List<​IRhinoObject>​();​
 +  for( int i = 0; i < go.ObjectCount();​ i++ )
 +  {
 +    IRhinoObject obj = go.Object(i).Object();​
 +    if( obj != null )
 +      objects.Add( obj );
 +  }
 +
 +  OnXform xform = new OnXform();
 +  xform.Translation( new On3dPoint(OnUtil.On_origin) - base_point );
 +
 +  // Duplicate all of the selected objects and add them
 +  // to the document as instance definition objects
 +  List<​IRhinoObject>​ idef_objects = new List<​IRhinoObject>​();​
 +  for( int i = 0; i < objects.Count;​ i++ )
 +  {
 +    IRhinoObject obj = objects[i];
 +    if( obj != null )
 +    {
 +      MRhinoObject dupe = context.m_doc.TransformObject(obj,​ xform, false, false, false);
 +      if( dupe != null )
 +      {
 +        // Transform the geometry to the world origin so
 +        // they insert in the location the user expects.
 +        context.m_doc.AddObject( dupe, false, true);
 +        idef_objects.Add( dupe );
 +      }
 +    }
 +  }
 +
 +  if( idef_objects.Count < 1 )
 +  {
 +    RhUtil.RhinoApp().Print( "​Unable to duplicate block definition geometry.\n"​ );
 +    return IRhinoCommand.result.failure;​
 +  }
 +
 +  idef_index = idef_table.AddInstanceDefinition( idef, idef_objects.ToArray() );
 +  if( idef_index < 0 )
 +  {
 +    RhUtil.RhinoApp().Print( "​Unable to create block definition \+idef_name+"​\"​\n"​ );
 +    return IRhinoCommand.result.failure;​
 +  }
 +  return IRhinoCommand.result.success;​
 +}
 +
 +</​code>​
 +====VB.NET (Rhino 4)====
 +
 +<code c++>
 +Public Overrides Function RunCommand(ByVal context _
 +  As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
 +  ' Select objects to define block
 +  Dim go As New MRhinoGetObject()
 +  go.SetCommandPrompt("​Select objects to define block"​)
 +  go.EnableReferenceObjectSelect(False)
 +  go.EnableSubObjectSelect(False)
 +  go.EnableGroupSelect(True)
 +
 +  ' Phantoms, grips, lights, etc., cannot be in blocks.
 +  Dim forbidden_geometry_filter As UInteger = _
 +      CType(IRhinoGetObject.GEOMETRY_TYPE_FILTER.light_object Or _
 +            IRhinoGetObject.GEOMETRY_TYPE_FILTER.grip_object Or _
 +            IRhinoGetObject.GEOMETRY_TYPE_FILTER.phantom_object,​ UInteger)
 +
 +  Dim geometry_filter As UInteger = _
 +     ​(forbidden_geometry_filter Xor CType(IRhinoGetObject.GEOMETRY_TYPE_FILTER.any_object,​ UInteger))
 +  go.SetGeometryFilter(geometry_filter)
 +  go.GetObjects(1,​ 0)
 +  If (go.CommandResult() <> IRhinoCommand.result.success) Then
 +    Return go.CommandResult()
 +  End If
 +
 +  ' Block base point
 +  Dim gp As New MRhinoGetPoint()
 +  gp.SetCommandPrompt("​Block base point"​)
 +  gp.GetPoint()
 +  If (gp.CommandResult() <> IRhinoCommand.result.success) Then
 +    Return gp.CommandResult()
 +  End If
 +
 +  Dim base_point As On3dPoint = gp.Point()
 +
 +  ' Block definition name
 +  Dim gs As New MRhinoGetString()
 +  gs.SetCommandPrompt("​Block definition name")
 +  gs.GetString()
 +  If (gs.CommandResult() <> IRhinoCommand.result.success) Then
 +    Return gs.CommandResult()
 +  End If
 +
 +  ' Validate block name
 +  Dim idef_name As String = gs.String().Trim()
 +  If (String.IsNullOrEmpty(idef_name)) Then
 +    Return IRhinoCommand.result.nothing
 +  End If
 +
 +  ' See if block name already exists
 +  Dim idef_table As MRhinoInstanceDefinitionTable = context.m_doc.m_instance_definition_table
 +  Dim idef_index As Integer = idef_table.FindInstanceDefinition(idef_name)
 +  If (idef_index >= 0) Then
 +    Dim msg As String = "Block definition " + idef_name + " already exists."​
 +    RhUtil.RhinoApp().Print(msg + vbCrLf)
 +    Return IRhinoCommand.result.nothing
 +  End If
 +
 +  ' Create new block definition
 +  Dim idef As New OnInstanceDefinition()
 +  idef.SetName(idef_name)
 +
 +  ' Gather all of the selected objects
 +  Dim objects As New List(Of IRhinoObject)()
 +  For i As Integer = 0 To go.ObjectCount() - 1
 +    Dim obj As IRhinoObject = go.Object(i).Object()
 +    If (obj IsNot Nothing) Then objects.Add(obj)
 +  Next
 +
 +  Dim xform As New OnXform()
 +  xform.Translation(New On3dPoint(OnUtil.On_origin) - base_point)
 +
 +  ' Duplicate all of the selected objects and add them
 +  ' to the document as instance definition objects
 +  Dim idef_objects As New List(Of IRhinoObject)()
 +  For i As Integer = 0 To objects.Count - 1
 +    Dim obj As IRhinoObject = objects(i)
 +    If (obj IsNot Nothing) Then
 +      Dim dupe As MRhinoObject = context.m_doc.TransformObject(obj,​ xform, False, False, False)
 +      If (dupe IsNot Nothing) Then
 +        ' Transform the geometry to the world origin so
 +        ' they insert in the location the user expects.
 +        context.m_doc.AddObject(dupe,​ False, True)
 +        idef_objects.Add(dupe)
 +      End If
 +    End If
 +  Next
 +
 +  If (idef_objects.Count < 1) Then
 +    RhUtil.RhinoApp().Print("​Unable to duplicate block definition geometry."​ + vbCrLf)
 +    Return IRhinoCommand.result.failure
 +  End If
 +
 +  idef_index = idef_table.AddInstanceDefinition(idef,​ idef_objects.ToArray())
 +  If (idef_index < 0) Then
 +    RhUtil.RhinoApp().Print("​Unable to create block definition " + idef_name +  + vbCrLf)
 +    Return IRhinoCommand.result.failure
 +  End If
 +  Return IRhinoCommand.result.success
 +End Function
 +
 +</​code>​
 +
 +
 +{{tag>​Developer cplusplus dotnet}}
  
developer/sdksamples/createblock.txt ยท Last modified: 2015/09/14 (external edit)