Text Fields Self-Referencing User Attribute Text?

I’m trying to make a kind of fake “dynamic block” (actually a group) in which I can update several text fields by changing the values of the associated attribute user texts.

image

image

This works for a single group of course, but if I make copies of my group the text fields are still, as expected, referencing the original group. Changing the new groups Attribute Texts will have no effect.

Is there a way I can make a text field “self-reference” a key mapped to it without having to add a GUID? I’m thinking of something that behaves like “objectname”, but for key/value pairs.

I realize I could script this but was hoping that a user could work solely in the Properties->Attribute User Text Tab. Any options here?

The problem is that the Text object and its textfield function have no relationship to any other object you’ve made other than the one specified by a guid id.

I made an example for another person some time ago that was slightly different but similar. You could modify it to do what you’re looking for.

1 Like

Great job @Trav,

Could you please add this to _TestPackageManager?
I see this being very handy.

Thanks in advance

@tomh,

Here’s something I just did.
I don’t know how useful it is yet but it could be extended:

import rhinoscriptsyntax as rs
import Rhino
import scriptcontext as sc

obj_id = rs.GetObject("select: ")

key_string = "key"
value_string = "da value"
rs.SetUserText(obj_id,key_string,value_string)

pt = rs.SurfaceAreaCentroid(obj_id)[0]

txt_string = '%<UserText({0},{1})>%'.format(obj_id,key_string)

rs.AddText(txt_string, pt, 100.0, 'Arial', 0, 2|131072)#

Thanks gents! I should be able to tweak these snippets to suit my needs.

2 Likes

Hello Together,
is there a Syntax for the Textobject in the Textfield like %<UserText(“currentObject”,“Tür-Nummer”)>% in stead of the objectID hardcoded ?

@cma01 Have a look at Rhino 7.0 WIP’s Block Attributes abilities. They are designed to do this.

1 Like

Thank you!

Maybe an other Question, because my boss don’t want to drive on the WIP-version:
is it possible to write in Visual Studio (prefer C#) a command that copies a Textobject and excess its Textfield?
something like:
string id = currentGUID
string textField = string.Format( “%<UserText(”{0}",“Tür-Nummer”)>%",id)

sorry for this wannabe code, i’m a total Beginner.

Maybe an other Question, because my boss don’t want to drive on the WIP-version:
is it possible to write in Visual Studio (prefer C#) a command that copies a Textobject and excess its Textfield?
something like:
string id = currentGUID
string textField = string.Format( “%<UserText(”{0}",“Tür-Nummer”)>%",id)

sorry for this wannabe code, i’m a total Beginner.

in v6 UserText requires a guid. This is what Block Attribute Text was designed to do.

1 Like

@Trav we don’t have a “self” or “this” key though for non-block cases (at least I don’t remember adding it). Seems like something to get on the wishlist

2 Likes

I started to add it yesterday after reading this and realized we had the block attributes for this scenario so I took pause. If you guys think its worth adding to UserText I can pop it in there.
https://mcneel.myjetbrains.com/youtrack/issue/RH-57956

3 Likes

I think it’s worth adding to every DocObject type.
Name of object that is able to display object’s attributes - very useful. Or usertext making calculations on the fly

1 Like

Nice!
I still hope to get help with my issue, before devolope it in common.

my target:

select an TextObject > Copy the TextObject > get the GUID of the Copied TextObject and store it in a variable > access the Content (TextField) of the Copied TextObject > paste the stored GUID in a string.Format() and fill it in the contet of the Copied TextObject
=> own command in c# code

i will be very thankfull if somebody can help me out with this.

it sounds like everything you’d need to do what you’re saying via C# is listed in the sample source i posted in the thread further up.

There’s a video as well as sample source here.

i have found a solution for my issue.
there is still some area to develop. For example the Attribute Keys are in this example hard written an not dynamic. may be it is an idea to write it in the commadbar, one by one.

but i still wait happiefull of the release of Rhino7.
there is an release year in view?

here my code in beginner syntax, may be it helps someone, to work on:

 protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        //Beschreibung des Befehls.
        RhinoApp.WriteLine("The {0} command will display the AttributeText in the Texfield of the choosen Textobject.", EnglishName);

        //Mehrere TextObjects auswählen.
        ObjRef[] objrefs;
        Result rc = RhinoGet.GetMultipleObjects("Select any text objects", false, ObjectType.Annotation, out objrefs);
        if (rc != Result.Success || objrefs == null)
            return rc;

        //TextObjects in einer Liste speichern.
        RhinoList<TextObject> textObjects = new RhinoList<TextObject>();
        for (int i = 0; i < objrefs.Length; i++)
        {
            TextObject textObj_i = objrefs[i].Object() as TextObject;
            if (textObj_i != null)
                textObjects.Add(textObj_i);
            else
                return Result.Failure;
        }

        //speichert den Inhalt jedes einzelnen TextObjects aus der Liste <textObjects> in eine neue Liste <textEntities> ab.
        RhinoList<TextEntity> textEntities = new RhinoList<TextEntity>();
        for (int i = 0; i < objrefs.Length; i++)
        {
            TextEntity textEntity_i = textObjects[i].Geometry as TextEntity;
            if (textEntity_i != null)
                textEntities.Add(textEntity_i);
            else
                return Result.Failure;
        }

        //speichert die GUID jedes einzelnen TextObjects aus der Liste <textObjects> in eine neue Liste <new_IDs> ab.
        RhinoList<string> new_IDs = new RhinoList<string>();
        for (int i = 0; i < objrefs.Length; i++)
        {
            string new_ID_i = textObjects[i].Id.ToString();
            if (new_ID_i != null)
                new_IDs.Add(new_ID_i);
            else
                return Result.Failure;
        }

        //erstellt eine Liste mit einem string pro Eintrag, welches die ID des jeweiligesn textObjectes beinhaltet, an der jeweiligen Listenposition.
        RhinoList<string> str_textEntities = new RhinoList<string>();
        for (int i = 0; i < objrefs.Length; i++)
        {
            string current_ID =new_IDs[i];
            string str_textEntity_i = string.Format("{{\\rtf1\\deff0{{\\fonttbl{{\\f0 Arial Narrow; }} }}\\fs40{{\\f0\\b %<UserText(\"{0}\",\"T\\u252?r-Nummer\")>%}} {{\\par}} {{\\f0 %<UserText(\"{0}\",\"Brandschutz\")>%}} {{\\par}} {{\\f0 %<UserText(\"{0}\",\"Funktion\")>%}}\\par}}", current_ID);
            if (str_textEntity_i != null)
                str_textEntities.Add(str_textEntity_i);

        }
        //{\rtf1\deff0{\fonttbl{\f0 Arial Narrow; } }\fs40{\f0\b %< UserText("d93d4b28-e504-450c-8833-96bda9df9586", "T\u252?r-Nummer") >%} {\par} {\f0 %< UserText("d93d4b28-e504-450c-8833-96bda9df9586", "Brandschutz") >%} {\par} {\f0 %< UserText("d93d4b28-e504-450c-8833-96bda9df9586", "Funktion") >%}\par}


        for (int i = 0; i < objrefs.Length; i++)
        {
            //weist den neuen string samt aktueller GUID der TextEntity des TextObject zu.
            textEntities[i].RichText = str_textEntities[i];
            if (textEntities[i] == null)
                return Result.Failure;

            //schickt die Änderungen an das TextObject an das RhinoDoc zurück.
            textObjects[i].CommitChanges();
        }

        //Berechnet die Bildschirmdarstellung neu.
        doc.Views.Redraw();

        return Result.Success;
    }

peace

@cma01 I added self references for Text annotations to last weeks Rhino 7.0 WIP. You can now leave the guid empty and it will reference the text annotations attributes text for User Text matches.

%<UserText("",“MyKey”)>%

Also in Rhino 6 when you copy and paste objects that have self referenced text fields. The guids will be updated on the new pasted objects on their own. You can also use the user text context menu to copy and paste user text containing text field functions and those too will automatically update self referenced guids. In this example I have a text annotation with attribute text on it that contains the text field ObjectName for the text annotation. If you copy and paste the text annotation itself and paste it, the new text object will be automatically updated. The same is true if you copy/paste just the key values to another text object. This doesn’t update the text annotation objects rich text function obviously but is good food for thought.

Pasted to object 2.

1 Like

Great add-on
Small question since the text does not intstantly updates.
What command can be used to update all text objects?

What i did is refer a value to th object name. And the object only uptates as I set focus to the value field of that object.

Is this self referenced text annotations feature coming to Rhino 6?