Hi!
Is there a way te create rectangle borders around multipe text’s?
Hi!
Is there a way te create rectangle borders around multipe text’s?
BoundingBox will do that, but it will create a box that is tight around the text. For small numbers of objects, you can then offset the rectangle(s). For an automatic function on larger numbers of texts, I think a script will be necessary.
–Mitch
Thanks!
If all text is selected, only one big BoundingBox is created.
So indeed a script is necessary, I am not very good at scripting… this is wat I got so far:
Option Explicit
Call TextBorder()
Sub TextBorder()
Dim aObj, sObj, i, BBox
Rhino.ClearCommandHistory
aObj = Rhino.GetObjects("Select Text..", , True)
If Not isarray(aObj) Then Exit Sub
BBox = Rhino.BoundingBox(aObj(i))
If IsArray(aObj) Then
Rhino.EnableRedraw False
For Each sObj In aObj
rhino.BoundingBox sObj
Next
Rhino.ClearCommandHistory
Rhino.EnableRedraw True
End If
End Sub
Doesnt work jet, any suggestions?
Hi Thomas
the below script in Pyhon is ok
the equivalent in vbscript is buggy
import rhinoscriptsyntax as rs
def rt():
testi=rs.GetObjects("seleziona testi")
for testo in testi:
rs.SelectObject(testo)
rs.Command("_BoundingBox enter")
rs.UnselectAllObjects()
rt()
Ciao Vittorio
I prefer to write this in Python, it just works nicer… Creates an offset rectangle around text objects in any plane, offset is user-settable and sticky within session.
"""Creates an offset rectangle around each selected text object
Text can be in any plane, rectangle is created in same plane as text object.
Script by Mitch Heynick 19 December 2014"""
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def text_filt(rhino_object, geometry, component_index):
return rs.IsText(geometry)
def TextOffsetBoundingBox():
msg="Select texts for bounding box"
objs=rs.GetObjects(msg,512,preselect=True, custom_filter=text_filt)
if not objs: return
if "TO_BB_PrevValue" in sc.sticky: prev_offset = sc.sticky["TO_BB_PrevValue"]
else: prev_offset = 1.0
offset=rs.GetReal("Offset value?",prev_offset,0)
if offset==None: return
for objID in objs:
plane=rs.TextObjectPlane(objID)
xform=rs.XformRotation1(plane,rs.WorldXYPlane())
obj=sc.doc.Objects.Find(objID).Geometry
obj.Transform(xform)
bb=obj.GetBoundingBox(plane)
bb.Inflate(offset)
pts=bb.GetCorners()
cp=rs.PointArrayTransform(pts,rs.XformPlanarProjection(rs.WorldXYPlane()))
xform=rs.XformRotation1(rs.WorldXYPlane(),plane)
cp=rs.PointArrayTransform(cp,xform)
rect=Rhino.Geometry.Polyline([cp[0],cp[1],cp[2],cp[3],cp[0]])
sc.doc.Objects.AddPolyline(rect)
sc.doc.Views.Redraw()
sc.sticky["TO_BB_PrevValue"] = offset
TextOffsetBoundingBox()
–Mitch
Edit: odd, I see the formatting in the preview box, but it disappears when I submit.
TextOffsetBoundingBox.py (1.4 KB)
Super thanks!!
Works perfect!!
I am going to learn some scripting…
what also be super usefull for us, is to create blocks of each text and border. Is that an easy addition to this script? The block name can be the same as the text or just a specific text.
Thanks in advance!
Should be possible… Since you can have the same text multiple times, the block name couldn’t necessarily be the text - as block names need to be unique. You could just let Rhino add the block name as it sees fit (Block 01, Block 02, etc.) or there would have to be a mechanism for checking and creating unique block names. Where would you want the insertion point? The text object point, or world 0 or…?
–Mitch
Cool!
Little explanation of the end goal:
The purpose of this script is to add a posnr (object identification) derived from an attribute and place it to the middel of the bbbox of an object.
The posnr itself should have a offset border and combined to a block.
The name of the block should be the same name as the text (posnr).
The basepoint is the middle of the block (border).
The script below is a script to derive the attribute info from an object.
Is this can be combined in one script is would be awesome!!
Option Explicit
'Script written by David Rutten
Sub AutoAnnotateNamedObjects()
Dim selObjects, i
Dim midPoint, strName, strFont
strFont = "ISOCPEUR"
selObjects = Rhino.GetObjects("Select objects to annotate...", 4 + 8 + 16, vbFalse, vbTrue, vbTrue)
If IsNull(selObjects) Then Exit Sub
Rhino.EnableRedraw vbFalse
For i = 0 To Ubound(selObjects)
strName = Rhino.GetUserText(selObjects(i), "Posnummer")
If Not IsNull(strName) Then
midPoint = GetMidPoint(selObjects(i))
If Not IsNull(midPoint) Then
Rhino.AddText strName, midPoint, 20, "ISOCPEUR"
End If
End If
Next
Rhino.EnableRedraw vbTrue
Rhino.Print "Posnummers added as anotation text objects"
End Sub
AutoAnnotateNamedObjects
Function GetMidPoint(strID)
GetMidPoint = Null
Dim BBox, mPoint(2)
If Rhino.IsCurve(strID) Then
BBox = Rhino.DivideCurve(strID, 3, vbFalse)
If IsNull(BBox) Then Exit Function
mPoint(0) = BBox(1)(0)
mPoint(1) = BBox(1)(1)
mPoint(2) = BBox(1)(2)
Else
BBox = Rhino.BoundingBox(strID)
If IsNull(BBox) Then Exit Function
mPoint(0) = (BBox(0)(0) + BBox(6)(0)) / 2
mPoint(1) = (BBox(0)(1) + BBox(6)(1)) / 2
mPoint(2) = (BBox(0)(2) + BBox(6)(2)) / 2
End If
GetMidPoint = mPoint
End Function
OK, I guess that’s possible if the posnr is unique, otherwise the script might fail if it tries to make 2 blocks with the same name. Does the object itself need to be included in the block, or just the text and rectangle? Do you have a small sample file with a couple of objects to do some testing?
–Mitch
Ok super!
Just the text and rectangle combined in a block. A sample file is attached. The objects contain attributes (usertext).
Is it also possible to add the objectname as shown in the sample file?
posnr.3dm (286.8 KB)
OK, sorry I haven’t had time to work on it so far… Maybe tomorrow. As concerns your last post and the sample file, my questions are now:
Your object is a 3D object (an extrusion). You would like to extract the usertext of the object plus its name and then place those in a text label for the object at its BB center with the rectangle border.
Since the text does not yet exist, I don’t know what plane to place it in. If the object was a planar curve or surface, I could get its plane, but an arbitrary 3D object does not have a “plane” associated with it. If they are all guaranteed to be extrusions, I could get the extrusion plane, but if they are polysurfaces, there is no real way. I could place it in the current view plane, but again, you would have to make sure that the correct view is active before running the script.
My second comment is simply the BB center placement - for certain geometries, that will not actually be on the object. For example with your inverted “C” shaped top profile S07b, the BB center will be very near its lower edge.
–Mitch
Does using a text mask simplify the rectangle/bounding box part of this?
-Pascal
That was one of the first things I looked at, but I kinda thought the rectangle would be nicer, given that it’s “transparent”… And maybe be able to have the rectangle as “snappable” geometry. These could be added as “wishes” for Text btw…
–Mitch
Mitch!
First of all, thanks for your help and effort so far! I really appreciate this.
Ok, the 3d extrusion object was just a quick export of a bigger model.
We use a custom made plugin and sectiontools to create the production information. This info is divided in 2d production drawings and C-NC output.
The custom made plugin creates C-NC production info, in-place for each part. (see image)
Sectiontools is used to create all 2d section views. So the plane is just top view on the sections.
But sectiontools doesn´t add info to the sections.
You already created a way to add to posnr, so thats awesome. But to check all posnr in acad, we have to perform a block count. Therefore we need the posnr with rectangle to be combined in a block.
The placing is not very important, because we will move and rotate the info in the right position. (unless it’s possible to move and rotate it within the object edges )
So the step were are missing is the info (posnr and partname) on the 2d sections. If we can select all 2d surfaces and add all info it would be great.
I hoop the above clarifies the process a little bit!
Thanks!!
The 3d construction:
The custom C-NC tool:
The custom C-NC tool:
The 2d sections:
And, Happy birthday Mitch!
all manual here
Send me a pm if you want to exchange some method’s specific for the shipbuilding industry.
OK, here is a version to test… It uses the active view’s CPlane to determine which direction the text faces, so make sure the correct view is active before running the script. Should work OK if all objects are aligned parallel to the View CPlane. You have options for rectangle offset and text height (sticky within session).
Let me know if it works for you and what needs adjusting…
Cheers, --Mitch
AddTextBoxNotationView.py (2.3 KB)
Mitch!
That’s a nice Christmas present!!
First day at the office since Christmas, so i’m going to test it right away!
I’ll get back to you.
Regards,
Thomas