Site Tools


Create or Modify an Instance Definition

Developer: .NET
Summary: Demonstrates how to create a new or modify an existing instance definition
Notice: The Rhino.NET SDK is deprecated in Rhino 5. This example adapted for the new RhinoCommon SDK is here.

Example

C#

public override IRhinoCommand.result RunCommand(IRhinoCommandContext context)
{
  // Step 1, select objects to include in the instance definition
  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();
 
  // Step 2, select 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();
 
  // Step 3, get instance definition name
  MRhinoGetString gs = new MRhinoGetString();
  gs.SetCommandPrompt("Block definition name");
  gs.SetDefaultString(GetUnusedInstanceDefinitionName(context.m_doc));
  gs.GetString();
  if (gs.CommandResult() != IRhinoCommand.result.success)
    return gs.CommandResult();
 
  string idef_name = gs.String().Trim();
  if (string.IsNullOrEmpty(idef_name))
    return IRhinoCommand.result.nothing;
 
  // Step 4, verify objects
  int found_index = context.m_doc.m_instance_definition_table.FindInstanceDefinition(idef_name);
  List<IRhinoObject> objects = new List<IRhinoObject>();
 
  bool bQuietly = context.IsInteractive() ? false : true;
 
  for (int i = 0; i < go.ObjectCount(); i++)
  {
    IRhinoObject obj = go.Object(i).Object();
    if (obj == null)
      continue;
 
    // Probably don't need to do this...
    if (0 != (forbidden_geometry_filter & (uint)obj.ObjectType()))
      continue;
 
    if( obj.ObjectType() == IOn.object_type.instance_reference)
    {
      IRhinoInstanceObject iref_obj = MRhinoInstanceObject.ConstCast(obj);
      if (iref_obj != null)
      {
        if (found_index >= 0 && iref_obj.UsesDefinition(found_index) > 0)
        {
          if (!bQuietly)
            RhUtil.RhinoApp().Print("Unable to create block.\n");
          return IRhinoCommand.result.failure;
        }
      }
    }
    objects.Add(obj);
  }
 
  // Step 5, create instance definition
  OnInstanceDefinition idef = new OnInstanceDefinition();
  idef.SetName(idef_name);
 
  int idef_index = CreateInstanceDefinition(context.m_doc, idef, base_point, objects, bQuietly);
  if (idef_index < 0)
    return IRhinoCommand.result.failure;
 
  // Step 6, create the instance reference
  OnXform xform = new OnXform();
  xform.Translation(base_point - new On3dPoint(OnUtil.On_origin));
  IRhinoInstanceObject inst_obj = context.m_doc.m_instance_definition_table.CreateInstanceObject(idef_index, xform);
  if (inst_obj != null)
  {
    inst_obj.Select(true);
  }
  else
  {
    if (!bQuietly)
      RhUtil.RhinoApp().Print("Error creating block.\n");
    return IRhinoCommand.result.failure;
  }
 
  // Step 7, delete existing geometry
  for (int i = 0; i < objects.Count; i++)
    context.m_doc.DeleteObject(new MRhinoObjRef(objects[i]));
 
  context.m_doc.Redraw();
 
  return IRhinoCommand.result.success;
}
 
string GetUnusedInstanceDefinitionName(MRhinoDoc doc)
{
  string idef_name = string.Empty;
  doc.m_instance_definition_table.GetUnusedInstanceDefinitionName(ref idef_name);
  return idef_name;
}
 
// Identify subsets of the instance definition fields.
// These bits are used to determine which fields to set
// when an OnInstanceDefinition class is used to modify
// an existing instance definition.
enum IDEF_SETTINGS : int
{
  no_idef_settings            =  0x0,
  idef_name_setting           =  0x1,  // m_name
  idef_description_setting    =  0x2,  // m_description
  idef_url_setting            =  0x4,  // all m_url_* fields
  idef_units_setting          =  0x8,  // m_us and m_unit_scale
  idef_source_archive_setting = 0x10,  // all m_source_* fields
  idef_userdata_setting       = 0x20,  // all m_source_* fields
  all_idef_settings           = 0xFFFF
}
 
int CreateInstanceDefinition(MRhinoDoc doc, IOnInstanceDefinition idef, IOn3dPoint point, List<IRhinoObject> objects, bool bQuietly)
{
  int found_index = doc.m_instance_definition_table.FindInstanceDefinition(idef.Name(), true);
  List<IRhinoObject> idef_objects = new List<IRhinoObject>();
 
  OnXform xform = new OnXform();
  xform.Translation(new On3dPoint(OnUtil.On_origin) - point);
 
  for (int i = 0; i < objects.Count; i++)
  {
    IRhinoObject obj = objects[i];
    if (obj == null)
      continue;
 
    if (obj.ObjectType() == IOn.object_type.light_object   ||
        obj.ObjectType() == IOn.object_type.grip_object    ||
        obj.ObjectType() == IOn.object_type.phantom_object
      )
      continue;
 
    // Transform geometry and attributes, but do not add to the document
    MRhinoObject dupe = doc.TransformObject(obj, xform, false, false, false);
    if (dupe != null)
    {
      if (doc.AddObject(dupe, false, true))
        idef_objects.Add(dupe);
    }
  }
 
  if (idef_objects.Count < 1)
    return -1;
 
  int idef_index = -1;
 
  if( found_index < 0)
    idef_index = doc.m_instance_definition_table.AddInstanceDefinition(idef, idef_objects.ToArray(), false, bQuietly);
  else if( doc.m_instance_definition_table.ModifyInstanceDefinitionGeometry(found_index, idef_objects.ToArray(), bQuietly))
  {
    idef_index = found_index;
    doc.m_instance_definition_table.ModifyInstanceDefinition(idef, idef_index, (uint)IDEF_SETTINGS.all_idef_settings, bQuietly);
 
    if (!bQuietly)
    {
      IRhinoInstanceObject[] iref_object_list = null;
      int iref_count = doc.m_instance_definition_table[found_index].GetReferences(out iref_object_list);
      if( iref_count > 0)
        RhUtil.RhinoApp().Print(string.Format("{0} Instances of block \"{1}\" have been updated.\n", iref_count, idef.Name()));
    }
  }
 
  if (idef_index < 0 && !bQuietly )
  {
    string message = (found_index < 0) ? "Error creating block.\n" : "Error modifying block.\n";
    RhUtil.RhinoApp().Print(message);
  }
 
  return idef_index;
}


developer/sdksamples/createmodifyidef.txt ยท Last modified: 2016/03/22 by sandy