Rotate grid

I created a script to turn on grid datum on one side or on the other. Problem is that for some grids the end0 and end1 are opposite to the others which renders it useless.

I created another script that takes a list of grids and rotates them putting out a message in case of success, and when running the script it runs successfully (after many attempts and corrections), but for some reason the grids aren’t being rotated…

The following is the script I used.

Anyone detect a something wrong?

import clr
import sys


import System
from System import Array,Math
from System.Collections.Generic import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument

pi = Math.PI

#List of grids
elems = UnwrapElement(IN[0]) if isinstance(UnwrapElement(IN[0]),list) else [UnwrapElement(IN[0])]

lines = []
successMessage = []

#Begin transaction
try:
    TransactionManager.Instance.EnsureInTransaction(doc)
    
    for el in elems:
        line = el.Curve   #get grid line 
    
        start = line.GetEndPoint(0)
        end = line.GetEndPoint(1)
        
        #get mid point as point of axis rotation line
        mid = start.Add(end).Divide(2)
        
        #Get grid direction and line out of plane to find the perpendicular rotation axis
        gridDirection = end.Subtract(start)
        z_axis = XYZ(0,0,1)
        
        perpDir = gridDirection.CrossProduct(z_axis)
        
        #if perpDir Vector equals zero, then the Vector is parallel to the grid Vector
        if (perpDir.IsZeroLength()):
            x_axis = XYZ(1,0,0)
            perpDir = gridDirection.CrossProduct(x_axis)
        
        #create line for rotation axis position at mid point
        midEnd = start.Add(perpDir)
        midLine = Line.CreateBound(midEnd, mid)
        
        #rotate element
        ElementTransformUtils.RotateElement(doc,el.Id,midLine,pi)
        
        successMessage.append(f"The direction of grid '{el.Name}' has been flipped successfully!")

except Exception as e:
    successMessage = f"An error has occured: {str(e)}"
    
finally:
    TransactionManager.Instance.TransactionTaskDone()


OUT = successMessage

Just have your first script calculate which end needs the grid head and which doesn’t. If you have a standard “side” (ex: top and left get grid heads, bottom and right don’t) then you can just calculate which endpoints need to be toggled.

1 Like

Code is a bit old, but this was my grid flipping.
My level flip is pretty much the same.

def FlipGrids(myGrids):
    try:
        t = Transaction(doc, "Flip Grids")
        t.Start()
        for g in myGrids:
            c = g.GetCurvesInView(DatumExtentType.Model, view)
            l = c.Item[0]
            pt0 = l.GetEndPoint(0)
            pt1 = l.GetEndPoint(1)
            line = Line.CreateBound(pt1, pt0)
            g.SetCurveInView(DatumExtentType.Model, view, line )
        t.Commit()
    except:
        with forms.WarningBar(title='I\'m Afraid I Can\'t Do That, Dave.'):
                forms.alert('Wrong sort of view to do this. \n Canceling...', exitscript = False)
        t.RollBack()
3 Likes

Thanks Nick!
How would you suggest to test if the datum bubble is on the same side if the end0 for each are on opposite sides?

Hey Aaron, thanks for the response and I’ll check it out!

I modified the code to use the SetCurveInView but I am getting an error that the curve is unbounds still…

import clr
import sys


import System
from System import Array,Math
from System.Collections.Generic import *
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager 
from RevitServices.Transactions import TransactionManager 

clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')

import Autodesk 
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication 
app = uiapp.Application 
uidoc = uiapp.ActiveUIDocument

pi = Math.PI

elems = UnwrapElement(IN[0]) if isinstance(UnwrapElement(IN[0]),list) else [UnwrapElement(IN[0])]

lines = []
successMessage = []
try:
    TransactionManager.Instance.EnsureInTransaction(doc)
    
    for el in elems:
        line = el.Curve
    
        start = line.GetEndPoint(0)
        end = line.GetEndPoint(1)
        
        newCurve = Line.CreateBound(end,start)
        
        
        el.SetCurveInView(DatumExtentType.Model,uidoc.ActiveView,newCurve)
        
        successMessage.append(f"The direction of grid '{el.Name}' has been flipped successfully!")
        
finally:
    TransactionManager.Instance.TransactionTaskDone()


OUT = successMessage

I modified the code again to get the curve using the following and it worked. Is there a reason why getting the curve through the grid.Curve property wouldn’t be the same?

1 Like

another way with nodes …could probably work as well

aEeXoxQgYD

2 Likes

Seems like a great option which I will keep in mind for further use. Thanks for sharing!

1 Like

The idea is that if you want the bubble on the left then you just have to get the coordinates of both ends and see which one has the lesser X value. That end is to the left and gets the bubble, doesn’t matter which end it is.

2 Likes

The SetCurve… is view specific. It could be clipped to 2d or could be 3d. The GetCurve allows you to specify that you want the model extents. And Grid.Curve doesn’t have a method to set - only get. So, you have to use the DatumPlane and its methods to replace the line with a new one.

Your method would work but you perform the translation on the grid - not the line.
ElementTransformUtils.RotateElement(doc, grid.Id, rotation_axis, angle_radians)
…helpful to know in case you want to rotate a grid.

But switchiong end point for start point is more of a flip than a rotate. (Abstract sematics.) And the code is short. But could be a little shorter.

selection = uidoc.Selection.GetElementIds()
view = doc.ActiveView
t = Transaction(doc, "Flip Grids")
t.Start()
for e in selection:
    g = doc.GetElement(e)
    c = g.GetCurvesInView(DatumExtentType.Model, view)
    l = c.Item[0]
    line = l.CreateReversed()
    g.SetCurveInView(DatumExtentType.Model, view, line )
t.Commit()
1 Like

The reason for flipping the grid isn’t bubbles in this view necessarily. But for new views that are created. When you get users that create some grids left to right and then others right to left, well - new views always have the bubbles at the wrong ends as the bubbles are view specific. I find this happens with levels more than grids, but users are users and fixing that is always tedious.

That’s a fair point. I was assuming that this was being run for the whole project so it’s just the same to modify all views, but you’re right, it’s a better solution to flip grids to the correct orientation. Bubble ends is just a common quick fix that has been discussed many times on the forum so I figured it would be an easier place to start.

1 Like

Hi,
I tried with the Outline class approach
finding the end
rep25_01_15
this code can definitely be improved

import sys
import clr
clr.AddReference("RevitAPI")
import Autodesk 
from Autodesk.Revit.DB import Grid,DatumEnds,Transaction
def rminpoint(i,v):
    outline=i.GetExtents()
    pointmini=outline.MinimumPoint
    curve=i.Curve
    pointbegin=curve.GetEndPoint(0)
    i.HasBubbleInView(DatumEnds.End1,v)
    if (round(pointmini.X,3) == round(pointbegin.X,3)) and (round(pointmini.Y,3) == round(pointbegin.Y,3)):
        return [i.ShowBubbleInView(DatumEnds.End1,v),i.HideBubbleInView(DatumEnds.End0,v)]
    else:
        return [i.ShowBubbleInView(DatumEnds.End0,v),i.HideBubbleInView(DatumEnds.End1,v)]


grids=UnwrapElement(IN[0])
doc=grids[0].Document
view=doc.ActiveView
t=Transaction(doc,"Bubbles Left")
t.Start()
out=[rminpoint(g,view) for g in grids]
t.Commit()
OUT = "do"

cordially
christian.stan

2 Likes