Is there a way to open the block editor in a rhino plugin C#?


#1

Has anyone succeeded in doing this?


(Menno Deij - van Rijswijk) #2

Do you want to edit blocks from code, or do you want to show the user the block editor, just as if they would open it themselves?


#3

Thx for the response. I want the code to insert some text and a closed polyline and then close the editing session.

Does that answer your question?


(Menno Deij - van Rijswijk) #4

In the RhinoCommon SDK, blocks are known as InstanceDefinition. If you search for this term in the online SDK documentation http://4.rhino3d.com/5/rhinocommon/, you will find many hits.

For example to add a new block definition:
http://4.rhino3d.com/5/rhinocommon/html/M_Rhino_DocObjects_Tables_InstanceDefinitionTable_Add_2.htm


#5

But I want to be able to open an existing instance, add the oval and text, and save the addition


(Dale Fugier) #6

You can modify an instance definition without using the BlockEditor. Just call doc.InstanceDefinitions.ModifyGeometry passing it new list of geometry.


#7

Thanks, Dale. How does one get a selection of an instanceDefinition.

here it is step by step:

  1. User creates a block of lines, arcs, and text.
  2. User issues my command.
  3. Dialog comes up in which user supplies various user data.
  4. My command adds an oval and adds the user data to that oval.
  5. My command adds text, the value of which is the value of the first item of user data.(PartNo)
  6. User is given the opportunity to scale the oval and text.
  7. User is given the opportunity to rotate the oval and text.
  8. User is given the opportunity to move the oval and text.
  9. User presses enter to signify satisfaction with 7, 8. and 9.

Where I have issues at the moment is that the Rhino.Input.RhinoGet.GetOneObject method won’t accept a Rhino.DocObjects.InstanceDefinition object as the final parameter.

Here’s the code:

PartInfo pi = new PartInfo(); <-- my new class
pi.PartNo = “xxx-yyy-1234”;
pi.Matl = “Alum”;
pi.Area = 100;
pi.Thickness = 0.25;
pi.X = 1234.5;
pi.Y = 555.64;
pi.Z = 456.78;

Rhino.DocObjects.ObjRef objref;

var rc = Rhino.Input.RhinoGet.GetOneObject(“Select Object”, false,
Rhino.DocObjects.ObjectType.InstanceReference, out objref);
if (rc != Rhino.Commands.Result.Success)
return rc;
var rg = objref.Geometry();
rg.SetUserString(“partno”, pi.PartNo.ToString());
rg.SetUserString(“matl”, pi.Matl.ToString());
rg.SetUserString(“area”, pi.Area.ToString());
rg.SetUserString(“thickness”, pi.Thickness.ToString());
rg.SetUserString(“x”, pi.X.ToString());
rg.SetUserString(“y”, pi.Y.ToString());
rg.SetUserString(“z”, pi.Z.ToString());
rg.SetUserString(“descr”, pi.Descr.ToString());


(Menno Deij - van Rijswijk) #8

The code below works for me. You select by objecttype InstanceReference. The object class is then InstanceObject and the attached geometry is InstanceReferenceGeometry. On this you can set a user string.

I think that in your code the statement objref.Geometry() gets you a copy of the geometry, rather than a reference to it. But I may be mistaken.

ObjRef iRef;
Result res = RhinoGet.GetOneObject("Select block", false, ObjectType.InstanceReference, out iRef);
if (res != Result.Success || null == iRef)
    return res;

RhinoObject obj = iRef.Object();
if (null == obj)
    return Result.Failure;

InstanceObject instanceObject = obj as InstanceObject;
if (null == instanceObject)
    return Result.Failure;

InstanceReferenceGeometry g = obj.Geometry as InstanceReferenceGeometry;

g.SetUserString("MY_KEY", "MY_VALUE");

RhinoObject obj2 = doc.Objects.Find(obj.Id);
String obtained = obj2.Geometry.GetUserString("MY_KEY");
RhinoApp.WriteLine("obtained user string: {0}", obtained);

return Result.Success;

#9

Bingo!!! That did the trick. Thank you both so much for your help.


#10

How can the display text of a textObject inside a block be modified?

I got the textObj, modified the text in the text geometry of the object and committed the changes.
the display text still remains the same.


(Menno Deij - van Rijswijk) #11

Just a quick check: does it remain the same if you redraw the views using doc.Views.Redraw()?

Can you share your code?


#12

Assuming there is only one instanceObject…

            RhinoObject[] pieces = doc.InstanceDefinitions.ElementAt(0).GetObjects();
            TextObject titleText = pieces.Where(o => o.Name == "Title").First() as TextObject;
            if (titleText != null)
            {
                titleText.TextGeometry.Text = "Test";   //has display text as 'Sample', need to change it to Test.
                titleText.CommitChanges();
            }