Creating text objects and outputting them as normal Rhino geometry

Hi Bianchi,

I am trying to use the textCurve_edit component. Did you ever manage to orient the text to a different (or a given) plane other than rhino XY?

Thanks!

Hi @René_Corella, to change the plane orientation, I think you’d have to go into the TextGoo object code (pasted below, I’ll indicate where I think you can play around with it) and change it manually:

class TextGoo(gh.Types.GH_GeometricGoo[r.Display.Text3d], gh.IGH_BakeAwareData, gh.IGH_PreviewData):
    #region construction
    def __init__(self, text):
        self.m_value = text
    
    @staticmethod
    def DuplicateText3d(original):
        if original is None: return None

        text = r.Display.Text3d(original.Text, original.TextPlane, original.Height) #try editing original.TextPlane here
        #text.Bold = original.Bold,
        #text.Italic = original.Italic,
        text.FontFace = original.FontFace
        return text
    
    def DuplicateGeometry(self):
        return TextGoo(TextGoo.DuplicateText3d(self.m_value))
    
    #region properties
    def get_TypeName(self):
        return "3D Text"
        
    def get_TypeDescription(self):
        return "3D Text"
    
    def ToString(self):
        if self.m_value is None: return "<null>"
        return self.m_value.Text
        
    def get_Boundingbox(self):
        if self.m_value is None:
            return r.Geometry.BoundingBox.Empty;
        return self.m_value.BoundingBox;
        
    def GetBoundingBox(self, xform):
        if self.m_value is None:
            return r.Geometry.BoundingBox.Empty
        box = self.m_value.BoundingBox
        corners = xform.TransformList(box.GetCorners())
        return r.Geometry.BoundingBox(corners)
    
    #region methods
    def Transform(self, xform):
        text = TextGoo.DuplicateText3d(self.m_value)
        if text is None: return TextGoo(None)
        
        plane = text.TextPlane
        point = plane.PointAt(1, 1)

        plane.Transform(xform)
        point.Transform(xform)
        dd = point.DistanceTo(plane.Origin)
        
        text.TextPlane = plane;
        text.Height *= dd / sqrt(2)
        return TextGoo(text)
        
    def Morph(self, xmorph):
        return self.DuplicateGeometry()

    #region preview
    def get_ClippingBox(self):
        return self.get_Boundingbox()
        
    def DrawViewportWires(self, args):
        if self.m_value is None: return
        args.Pipeline.Draw3dText(self.m_value, args.Color)
      
    def DrawViewportMeshes(self, args):
        # Do not draw in meshing layer.
        pass

    #region baking
    def BakeGeometry(self, doc, att, id):
        try:
            id = sy.Guid.Empty
            
            if self.m_value is None:
                return false, id
            
            if att is None:
                att = doc.CreateDefaultAttributes()
            
            id = doc.Objects.AddText(self.m_value, att)
            
            return True, id
        except Exception, ex:
            sy.Windows.Forms.MessageBox.Show(str(ex))
            return False, sy.Guid.Empty

Just throwing this out there. Wombat has a good bakeable text component.


Capture

2 Likes

Thanks Michael!

Thanks a lot Bianchi. This is very helpful. Thanks for taking the time!

TLTR, what is the recommended procedure in January, 2020 (R6) for using and baking text in Grasshopper? I see that the issue is at least ten years old and many have struggled with coding their own solutions over the years:

Is it still necessary to write my own code to do this?

I use the components that come with the Squid plugin and they work okay for text outlines. For baking actual text tags I would recommend Elefront.

I have a quick question for @piac that’s about his component and GHPython in general. I noticed that, when I plug the custom text object into a GHPython component with the Type Hint set to str, I don’t get the output of the .NET ToString() nor the Python __repr__(). Instead I getRhino.Display.Text3d like so:

So my question is what is the name of the method that GHPython is calling in order to cast the input to a string if it’s not ToString() so that I can overwrite it on your custom text object class?

Also, thank you immensely for this sample. These transformable/bakeable text objects are revolutionizing the next version of Ladybug Tools.

Hi @chris12
don’t remember much about this topic, it’s been a long time. Can you upload a sample with what you see and what you’d like to get?

Thank you for the lightning-quick response @piac . Here is a sample file and screenshot of what I’m trying to achieve:

BakeableTextGhPy_CastToString.gh (9.1 KB)

Essentially, I am wondering why the casting done by the str Type Hint on the GHPython component isn’t behaving like the same way as the casting done by the native Grasshopper Text component. I had assumed that both were calling the ToString() method under the hood but that doesn’t seem to be the case.

The “casting” of this object in Grasshopper – which is really just the transformation done by a Param – uses the “Value” property (in C#) and is specialized for this type. We write the ToString() function in the first component.
You don’t see this type later because GH_Goo objects, before being used in scripting components, get replaced by their “ScriptVariable()” counterpart, which is usually just the “Value” property. Users of scripting components do not usually want to deal with the complexity of GH_Goo. There’s no way to access GH_Goo in scripting components right now.

You can, however, override the ScriptVariable function in the first component and tell it that the variable for this Goo is just the Goo itself:

    def ScriptVariable(self):
        return self

This means that you can later access this in the components…

Giulio


giulio@mcneel.com

BakeableTextGhPy_CastToString2.gh (14.9 KB)

2 Likes

Beautiful! That ScriptVariable method exactly what I needed, @piac . Thank you!

1 Like

The type of goo text works fine,but how can I control the insert point of the text from lower left point to center point?