I’m assuming there must be a way to do this that I don’t know about… Right now I end up making a centerpoint using areacentroid and rotating or using the gumball, but it would be nice if I could just a FromCenterpoint option nested within the Rotate command.
You could make a macro…
Sure! Do you have an idea of what would the macro be that would do this?
Select the object
Get the area centroid or volume centroid
rotate
Not sure how the script detects the centroid
enter the angle
delete the centroid
Right, the getting the centroid part is where I’m stuck too. I’m not sure how to do this with a macro
A python script might be more flexible.
@pdfaze - BoxEdit can do this.
– Dale
Hi @pdfaze
Here is a script that does what you are asking. Copy and place the text below on an icon or run from the macro editor.
The second line in the script is very useful as it auto creates a point at the gumball center so can be used with other scripts. One caveat is that object must be preselected but I took care of that by adding the selection option so you can either preselect or mouse select after running the command, though the script works with preselection and for I think all object types.
Below is the macro copy to an icon…
_select _Pause
_SetRedrawOff _CPlane _Gumball _Point 0 _CPlane _Undo _SetRedrawOn
rotate
RM
This the command but will only work when the object is preselected.
RM
Hi RM,
Thanks for this script and for your help! Is there are a way using the script to auto-input the centerpoint for the rotate command? Ideally i’d like the workflow to be:
- Select the object (or have it pre-selected)
- Run the script
- Rotate command begins using the centerpoint as the first input point
Right now for me the script marks the centerpoint but I’m not seeing the benefit over a command like AreaCentroid.
And maybe for clarification, the reason for wanting to streamline this so much is that when I’m doing this I’m often rotating and adjusting a lot of objects and want it the drawing experience to be very fluid.
What I would imagine the script would be is something like
Rotate
(some command that automatically-enters the centerpoint of the object)
Hi @pdfaze
Yes I can understand your request.
Try this new script it also deletes the centroid point and auto snaps to centroid, I had to script in VB and there is no one rotation call for all object types and I’m terribly rusty with vbscript. This script only works for polysurfaces/extrusions and surfaces no curves or meshes sorry about that. When I have more time I might look into adding the other types.
Let me know if you encounter any errors
RM
Copy and place on an icon, don’t miss the last parenthesis at the bottom
-_RunScript (
Option Explicit
'Script written by RM
'Script version Thursday, August 15, 2024 11:50:32 PM
Sub RotateAroundCenter
Dim strObject, arrMP, ptx
strObject = Rhino.GetObject("Select a surface",,, True)
If Not IsNull(strObject) Then
arrMP = Rhino.SurfaceAreaCentroid(strObject)
If IsArray(arrMP) Then
ptx = Rhino.AddPoint(arrMP(0))
Rhino.Command "rotate " & Rhino.Pt2Str(arrMP(0))
Rhino.Command "SelNone"
Rhino.ObjectName ptx, "ptx"
rhino.Command "-_selname ptx"
rhino.Command "delete"
End If
End If
End Sub
RotateAroundCenter
)
Hi @dale
Sorry to bother you. If I create a box and use the above script Rhino correctly finds the area center in perspective and top view but does not in front and right views. Is this a bug or am I doing something wrong? I would expect if perspective view finds the correct center why is right and front view location’s center so different. One would think Rhino.SurfaceAreaCentroid would not vary no matter in which viewport it is used or?
RM
Does the following do anything for you?
def RotateAboutCtrInteractive():
objs=rs.GetObjects("Select objects to rotate",preselect=True,select=True)
if not objs: return
cplane=rs.ViewCPlane()
bb=rs.BoundingBox(objs,cplane)
if bb:
ctr=(bb[0]+bb[6])/2
ctr=rs.XformWorldToCPlane(ctr,cplane)
rs.Command("_Rotate {}".format(ctr))
RotateAboutCtrInteractive()
It uses the current CPlane-aligned bounding box of selected objects as the center for executing the normal interactive rotate command…
@Helvetosaur
Very nice that works wonderfully.
Definitely the solution, this should be made into a Rhino command.
Plus this can be tuned to work with other commands like move just by substituting the rotate command and altering the prompt wording.
Thanks for sharing.
RM
Whats wrong with using the Gumball?
Hi @pdfaze,
I’ve logged this as a wish for the Rotate
command.
https://mcneel.myjetbrains.com/youtrack/issue/RH-83372
– Dale
Works great! Thanks Mitch!
Hi @dale @Helvetosaur
Thanks Dale that’s nice of you.
However both mine and Mitches scripts loose proper center when you rotate them in front and right views something seems wrong with the way Rhino is calculating center in those viewports. I’m using centroid area and he’s using a transform matrix and both loose where center actually is if you use the scripts in front or right viewport.
I can easily see this visually and you can see that in the attached images…
Select the object in front or right views and notice it’s bounding box center is correct now run either mine or Mitches script and notice the CenterPoint location is off.
RM
TestRotate.3dm (23.4 KB)
Hmm, I used the bounding box in the view CPlane… maybe I got it wrong. Don’t have time to fix today…
Edit: Forgot to transform the world coordinates to CPlane. Fixed above, please try it now.
This also works:
(forgot about the option in the BoundingBox method)
def RotateAboutCtrInteractive():
objs=rs.GetObjects("Select objects to rotate",preselect=True,select=True)
if not objs: return
cplane=rs.ViewCPlane()
bb=rs.BoundingBox(objs,cplane,False)
if bb:
ctr=(bb[0]+bb[6])/2
rs.Command("_Rotate {}".format(ctr))
RotateAboutCtrInteractive()