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.
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()
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?
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.
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()
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.