Align text with line


#1

Hi,

David Rutten wrote the script below. For each object the name is used to create a text.
The text is aligned in world x,y,z plane. I would like to add the functionality to align the text with the corresponding curves. How should I do that?

Option Explicit
'Script written by David Rutten
Sub AutoAnnotateNamedObjects()
	Dim selObjects, i
	Dim midPoint, strName
	
	selObjects = Rhino.GetObjects("Select objects to annotate...", 2 + 4 + 8 + 16 + 32 + 4096, vbFalse, vbTrue, vbTrue)
	If IsNull(selObjects) Then Exit Sub
	
	Rhino.EnableRedraw vbFalse
	For i = 0 To Ubound(selObjects)
		strName = Rhino.ObjectName(selObjects(i))
		If Not IsNull(strName) Then
			midPoint = GetMidPoint(selObjects(i))
			If Not IsNull(midPoint) Then
				Rhino.AddText strName, midPoint, 30, "Simplex",, 1
				
			End If
		End If
	Next
	Rhino.EnableRedraw vbTrue
	Rhino.Print "Object names 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

(Dale Fugier) #2

Here is one way:

Option Explicit

Call AutoAnnotateNamedCurves

Sub AutoAnnotateNamedCurves
	
	Dim arrCurves, strCurve, strName
	Dim arrPt3d, arrPt2d, arrPlane, arrX, arrY, arrZ
	
	arrCurves = Rhino.GetObjects("Select named curves", 4, True, True)
	If IsNull(arrCurves) Then Exit Sub
	
	Call Rhino.EnableRedraw(False)
	
	arrPlane = Rhino.ViewCPlane
	arrZ = arrPlane(3)
	
	For Each strCurve In arrCurves
		strName = Rhino.ObjectName(strCurve)
		If Not IsNull(strName) Then
			arrPt3d = Rhino.CurveMidPoint(strCurve)
			arrPt2d = Rhino.CurveClosestPoint(strCurve, arrPt3d)
			arrX = Rhino.CurveTangent(strCurve, arrPt2d)
			arrY = Rhino.VectorCrossProduct(arrZ, arrX)
			arrPlane = Rhino.PlaneFromFrame(arrPt3d, arrX, arrY)
			Call Rhino.AddText(strName, arrPlane)
		End If
	Next
	
	Call Rhino.EnableRedraw(True)

End Sub


#3

Thanks! Works great!


#4

Hi,

I tried to rewrite the script in python, but I get a message I don’t understand: Message: expected float, got tuple

Any idea?

import os
import scriptcontext
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def Markers():
    msg2= "Select all markers..."
    markers = rs.GetObjects(msg2,4,preselect=True)
    for marker in markers:
        crvstart=rs.CurveStartPoint(marker)
        crvend=rs.CurveEndPoint(marker)
        crvmid=rs.CurveMidPoint(marker)
        angle=rs.Angle(crvstart,crvend, True)
        rs.ObjectColor(marker,color=[0,255,0])
        text=rs.ObjectName(marker)
        
        new_text=rs.AddText(text,crvmid,50,font="Simplex",justification=2)
        rs.RotateObject(new_text,crvmid,angle, None, False)

Markers()

#5

Hi Thomas,

The rs.Angle function returns a tuple. What you need is its first element (angle in degrees):

import os
import scriptcontext
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino

def Markers():
    msg2= "Select all markers..."
    markers = rs.GetObjects(msg2,4,preselect=True)
    for marker in markers:
        crvstart=rs.CurveStartPoint(marker)
        crvend=rs.CurveEndPoint(marker)
        crvmid=rs.CurveMidPoint(marker)
        angle=rs.Angle(crvstart,crvend, True)[0]
        rs.ObjectColor(marker,color=[0,255,0])
        text=rs.ObjectName(marker)
        if not text:
            text = "someObjectName"
        new_text=rs.AddText(text,crvmid,50,font="Simplex",justification=2)
        rs.RotateObject(new_text,crvmid,angle, None, False)

Markers()

#6

aah thanks!