Please log in to write a message.
-
9. mmpolites (Jul 30, 2010 03.01):
Does anyone know a way to do this with nurbs and not meshes?
-
8. Hanno (Apr 13, 2009 21.44):
Thanks for uploading!
Hanno
-
7. dingle (Apr 07, 2009 23.19):
hey, never had a chance to wrap this one up successfully, but it works, just sometimes need to refreshed a few times. here's the flawed but functional version:
www.rhinoscript.org/scripts/65
and here's the "refresh" version that just updates the group with a click
www.rhinoscript.org/scripts/66
-
6. Hanno (Mar 18, 2009 11.26):
Hi,
you either want to rotate by 90-angle or by 90+angle degree (because thats "the other way round"), then it should work.
Hanno
-
5. dingle (Mar 17, 2009 01.58):
hanno,
great tip with the cross product. that's a lot simpler than how i was thinking about it. but i'm still missing a step, and i can't figure it out. the script works, but it takes 4 runs to make it work properly for all selected objects. baffling to me.
here's what i have so far. (going to incoporate some group functions later to make it easier to make a toolbar button - hence the first sub)
Option Explicit
'Script written by AM
'Script version Sunday, March 15, 2009 7:17:30 PM
Call AddObjects()
Sub AddObjects()
Dim strObjects
strObjects = Rhino.GetObjects("Select meshes to rotate", 32, True)
If IsNull(strObjects) Then
Rhino.Print "No valid objects selected."
Exit Sub
End If
RotateObjectsToCamera(strObjects)
End Sub
Function RotateObjectsToCamera(strObjects)
Dim arrCam, arrVertices, arrVertex, strBottomLine, arrMid
Dim arrLine1, arrLine2, arrAngle, dblRotateAngle
Dim arrNormals, arrPlane, arrVecCamToMid, arrNormalAngle
Dim i
arrCam = Rhino.ViewCamera
Rhino.EnableRedraw(False)
For i=0 To UBound(strObjects)
'OBJECT TYPE
Select Case Rhino.ObjectType(strObjects(i))
Case 8
arrNormals = Rhino.SurfaceNormal(strObjects(i))
arrVertices = Rhino.SurfacePoints(strObjects(i))
Case 32
arrNormals = Rhino.MeshVertexNormals(strObjects(i))
arrVertices = Rhino.MeshVertices(strObjects(i))
End Select
If IsNull(arrNormals) Then Exit For
If IsNull(arrVertices) Then Exit For
'CONSTRUCTION LINES
arrVertex = arrVertices(2)
strBottomLine = Rhino.AddLine(arrVertices(0), arrVertex)
arrMid = Rhino.CurveMidPoint(strBottomLine)
arrLine1 = Array(Array(arrCam(0),arrCam(1)), Array(arrMid(0),arrMid(1)))
arrLine2 = Array(Array(arrVertices(0)(0),arrVertices(0)(1)), Array(arrVertex(0),arrVertex(1)))
arrAngle = Rhino.Angle2(arrLine1, arrLine2)
If Not IsArray(arrAngle) Then Exit For
'NORMAL ANALYSIS. FRONT VS BACK, CW VS CCW
arrPlane = Rhino.PlaneFromNormal(arrVertices(0), arrNormals(0))
arrVecCamToMid = Rhino.VectorCreate(Array(arrCam(0),arrCam(1)), Array(arrMid(0),arrMid(1)))
Dim u0 : u0 = Rhino.VectorUnitize(arrVecCamToMid)
Dim u1 : u1 = Rhino.VectorUnitize(arrPlane(0))
Dim cross : cross = Rhino.VectorCrossProduct(u0, u1)
'Rhino.Print Rhino.Pt2Str(cross)
'ALREADY PERPENDICULAR
If cross(2) = 0 Then Exit For
'FRONT
If cross(2) < 0 Then
'Rhino.Print "Angle: " & CStr(arrAngle(0))
dblRotateAngle = (CDbl(arrAngle(0)))-90
Rhino.RotateObject strObjects(i), arrMid, dblRotateAngle
End If
'BACK
If cross(2) > 0 Then
'Rhino.Print "Angle: " & CStr(arrAngle(0))
dblRotateAngle = 90-(CDbl(arrAngle(0)))
Rhino.RotateObject strObjects(i), arrMid, dblRotateAngle
End If
Rhino.DeleteObjects Array(strBottomLine)
Next
Rhino.EnableRedraw(True)
End Function
-
4. Hanno (Mar 16, 2009 13.08):
Hi,
that seems to me to be the typical 180 degree problem - you will never get an angle between two vectors that is > 180, so from the angle alone you cannot know if you should rotate clockwise or counterclockwise.
To solve this, you can check if the cross product of your vectors points in positive or negative z direction, and use this to control your rotation direction.
Hope that helps!
Hanno
PS: Would be great if you added the finished script to our script library!
-
3. dingle (Mar 16, 2009 12.49):
also, i've found that if i run the script 3 times, it corrects all the ones that rotate the wrong direction.
perhaps there's a much simpler way to do this than comparing the mesh's normal angle to the camera vector.
-
2. dingle (Mar 16, 2009 01.19):
wow, sorry about that getobjects string message on line 9... my bad for not double checking!
please feel free to edit that out of my post.
-
1. dingle (Mar 16, 2009 01.18):
hey all,
i wonder if anyone has already done this? we have a library of 2D people mapped onto 4-vertex meshes, and it would be super good to have an instantaneous way to re-orient the people to face the camera. would actually save hours in rendering and photoshop times. kinda like the 3ds max lookat function, but not as insanely dumb and tedious. just want all the people to face the camera with the click of a button.
so. i've almost got it. (even swiped some dot product code from the rhinoscript wiki.) but there's a hiccup somewhere. i think it has something to do with declaring variables inside the loop? when i run the script, sometimes the "normal angle" is calculated wrong, causing the meshes to rotate the wrong direction. i should be able to select any face, no matter which direction it's rotated, and have it orient itself to the camera.
actually, i think it might have something to do with choosing the Y direction of the planefromnormal instead of the X. sometimes it wants to be X, sometimes Y?
anyway, let me know if i should post a rhino file... if you'd like to recreate my situation, just copy around a flat 4-vertex mesh a bunch of times.
as always, thanks a million for looking.
Call OrientMeshToCamera()
Sub OrientMeshToCamera()
Dim strObjects, arrCam, arrVertices, arrVertex, strBottomLine, arrMid
Dim arrLine1, arrLine2, Line1, Line2, arrAngle, dblRotateAngle
Dim arrNormals, arrPlane, arrVecCamToMid, arrNormalAngle
Dim i
strObjects = Rhino.GetObjects("Select motherfuckers", 32, True, True)
If IsNull(strObjects) Then Exit Sub
Rhino.EnableRedraw(False)
For i=0 To UBound(strObjects)
arrCam = Rhino.ViewCamera
arrVertices = Rhino.MeshVertices(strObjects(i))
If IsNull(arrVertices) Then Exit For
'daniel case
arrVertex = arrVertices(2)
strBottomLine = Rhino.AddLine(arrVertices(0), arrVertex)
arrMid = Rhino.CurveMidPoint(strBottomLine)
arrLine1 = Array(Array(arrCam(0),arrCam(1)), Array(arrMid(0),arrMid(1)))
arrLine2 = Array(Array(arrVertices(0)(0),arrVertices(0)(1)), Array(arrVertex(0),arrVertex(1)))
arrAngle = Rhino.Angle2(arrLine1, arrLine2)
If Not IsArray(arrAngle) Then Exit For
'NORMAL ANALYSIS. FRONT VS BACK.
arrNormals = Rhino.MeshVertexNormals(strObjects(i))
arrPlane = Rhino.PlaneFromNormal(arrVertices(0), arrNormals(0))
arrVecCamToMid = Rhino.VectorCreate(Array(arrCam(0),arrCam(1)), Array(arrMid(0),arrMid(1)))
Dim u0 : u0 = Rhino.VectorUnitize(arrVecCamToMid)
Dim u1 : u1 = Rhino.VectorUnitize(arrPlane(1))
Dim dot : dot = Rhino.VectorDotProduct(u0, u1)
If (dot < -1.0) Then
dot = -1.0
ElseIf (dot > 1.0) Then
dot = 1.0
End If
arrNormalAngle = Rhino.ToDegrees(Rhino.ACos(dot))
'Rhino.Print "Normal Angle: " & CStr(arrNormalAngle)
'FRONT
If arrNormalAngle <= 90 Then
Rhino.Print "Angle: " & CStr(arrAngle(0))
dblRotateAngle = (CDbl(arrAngle(0)))-90
Rhino.RotateObject strObjects(i), arrMid, dblRotateAngle
End If
'BACK
If arrNormalAngle > 90 Then
Rhino.Print "Angle: " & CStr(arrAngle(0))
dblRotateAngle = 90-(CDbl(arrAngle(0)))
Rhino.RotateObject strObjects(i), arrMid, dblRotateAngle
End If
Rhino.DeleteObjects Array(strBottomLine)
Next
Rhino.EnableRedraw(True)
End Sub