Not working but hopefully light at end of tunnel for tomorrow
ModifyGridTwoDimensionExtents.dyn (127.0 KB)
Hi,
I fix here the code for Revit 2022
I didn’t test for now on sections View
Hello @c.poupin
Thank you for the fix
This are the results:
Works with simple cropregion:
Makes a Mess with complex crop regions, and grids that have a kink get split up into two seperate grids.
And does still nothing in section views:
Something going on with my script where it takes the crop box draws it, take the grid curve and draws it but they never intersect. Its like the grid and the crop region are at different scales or something. I can get the grid curve to extend but they just never meet. Any ideas? Even the original script has the same problem…maybe something changed in 2022 vs 2020 revit in which the script was made for
grids.dyn (111.8 KB)
I bet its something to do with the fact that sections have a thickness ie an extent. My crop region and my grids are probably not on the same plane per se. Idk going to break and think some more lol
Here an update code
there will surely be cases where it will not work
import clr
import System
clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DSGeo
from Autodesk.DesignScript.Geometry import *
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
def createDatumLine(boundLines, grid):
gridLine = None
curveG = grid.Curve#.ToProtoType()
vectGrid = curveG.Direction
lstPtToLine = []
for lineBound in boundLines:
rayc = DB.Line.CreateUnbound(XYZ(curveG.Origin.X, curveG.Origin.Y, lineBound.GetEndPoint(0).Z) , vectGrid)
outInterR = clr.Reference[IntersectionResultArray]()
result = rayc.Intersect(lineBound, outInterR)
print(result)
if result == SetComparisonResult.Overlap:
interResult = outInterR.Value
lstPtToLine.append(interResult[0].XYZPoint)
print(lstPtToLine)
if len(lstPtToLine) == 2:
gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
return gridLine
activView = doc.ActiveView
TransactionManager.Instance.EnsureInTransaction(doc)
#
activView.CropBoxVisible = True
doc.Regenerate()
cropBox = activView.CropBox
fecGrids = FilteredElementCollector(doc, activView.Id).OfClass(DatumPlane).ToElements()
cutOffset = fecGrids[0].GetCurvesInView(DatumExtentType.ViewSpecific, activView)[0].GetEndPoint(0).Z
fecGrids = [x for x in fecGrids if isinstance(x, DB.Grid)]
outLst = []
shpManager = activView.GetCropRegionShapeManager()
boundLines = shpManager.GetCropShape()[0]
if activView.ViewDirection.IsAlmostEqualTo(XYZ(0,0,1)):
# get Current Elevation of boundLines
currentZ = list(boundLines)[0].GetEndPoint(0).Z
# transform boundLines CurveLoop
tf = Transform.CreateTranslation( XYZ(0,0, cutOffset - currentZ))
boundLines = CurveLoop.CreateViaTransform(boundLines, tf)
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
else:
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
TransactionManager.Instance.TransactionTaskDone()
OUT = outLst, [x.ToProtoType() for x in boundLines], cutOffset,
some tests in Video with a slightly different process
This is amazing @c.poupin
Thank you so much, i will try to add an input to set an offset and to adjust the grid bubbles.
Hello @c.poupin
After a few tests i now added some nodes and code because i want to only show the upper bubbles in sectionviews:
Can you please tell me why your code only shows the bottom bubble in section views, so i can try to change this in your code?
But my most important request would be to add an additional input to your python code for an offset, so that the grids will not be directly on the cropbox. May you give me some information on how to achieve that?
Many Thanks
Hi,
You can try to re-draw the gridLine
with an offset (with the vector of this line)
gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
I´m getting the Error, that I´m having a type-object.
Fail 1: CreateViaTransform only works for curveloops, not for curves:
gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
tfm = Transform.CreateTranslation( XYZ(0,0,1))
gridLineOff = Curve.CreateViaTransform(gridLine, tfm)
return gridLineOff
Fail 2: Curve.Offset
gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
offset = []
gridLineOff = offset.append(Curve.Offset(gridLine,1))
return gridLineOff
So are these Boundlines even curves, or just lines, and whats this “type-object” error about?
Kind Regards
try to transform the start point lstPtToLine[0]
and the end point lstPtToLine[1]
with your offset and the gridLine Direction, then re-make an BoundLine
Woohoo it´s working
But I´m sure there would be a better way than converting ToPoints and back To Xyz?
if len(lstPtToLine) == 2:
P1 = lstPtToLine[0].ToPoint()
P2 = lstPtToLine[1].ToPoint()
TransXYZ1 = Geometry.Translate(P1 ,0,0,1)
TransXYZ2 = Geometry.Translate(P2 ,0,0,-0.5)
TransPoint1 = TransXYZ1.ToXyz()
TransPoint2 = TransXYZ2.ToXyz()
gridLine = Autodesk.Revit.DB.Line.CreateBound(TransPoint1, TransPoint2)
return gridLine
Next step will be to make this work for a list of views, currently its just working with 1 view:
try to add a for loop
# Some Code
lstInputViews = UnwrapElement(IN[0])
TransactionManager.Instance.EnsureInTransaction(doc)
for activView in lstInputViews:
#
activView.CropBoxVisible = True
doc.Regenerate()
#
# Rest of Code
TransactionManager.Instance.TransactionTaskDone()
This is an awesome thread, back on the project where I have time to work this out. Can someone point me to like a python for dummies or basic learning website? so I can try to follow along with the information in this thread.
I get this error when I try to use the script Cyril wrote:
Warning: AttributeError : module ‘clr’ has no attribute ‘Reference’ [’ File “”, line 80, in \n’, ’ File “”, line 37, in createDatumLine\n’]
This works
activView = UnwrapElement(IN[0])
lstInputViews = UnwrapElement(IN[0])
TransactionManager.Instance.EnsureInTransaction(doc)
for activView in lstInputViews:
#
activView.CropBoxVisible = True
doc.Regenerate()
#
cropBox = activView.CropBox
fecGrids = FilteredElementCollector(doc, activView.Id).OfClass(DatumPlane).ToElements()
cutOffset = fecGrids[0].GetCurvesInView(DatumExtentType.ViewSpecific, activView)[0].GetEndPoint(0).Z
fecGrids = [x for x in fecGrids if isinstance(x, DB.Grid)]
outLst = []
shpManager = activView.GetCropRegionShapeManager()
boundLines = shpManager.GetCropShape()[0]
if activView.ViewDirection.IsAlmostEqualTo(XYZ(0,0,1)):
# get Current Elevation of boundLines
currentZ = list(boundLines)[0].GetEndPoint(0).Z
# transform boundLines CurveLoop
tf = Transform.CreateTranslation( XYZ(0,0, cutOffset - currentZ))
boundLines = CurveLoop.CreateViaTransform(boundLines, tf)
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
else:
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
TransactionManager.Instance.TransactionTaskDone()
But i don`t understand it. Why do we have to give the input views two different names? lstInputViews and activView? And now we are looping the list of views with…itselfe?
I would like the python script not to throw an error if the input is an empty list.
Can you tell me how to do this?
This is the error:
Kind regards
declare your variable outLst = []
outside the floor loop
(for activView in lstInputViews)
Hello @c.poupin, thanks for your reply!
I also had to declare “shpManager” and “boundLines” outside of the loop because they also gave an error. Now the code is not working anymore: " line 58, in
AttributeError: ‘List[object]’ object has no attribute ‘GetCropRegionShapeManager’"
activView = UnwrapElement(IN[0])
lstInputViews = UnwrapElement(IN[0])
TransactionManager.Instance.EnsureInTransaction(doc)
outLst = []
shpManager = activView.GetCropRegionShapeManager()
boundLines = shpManager.GetCropShape()[0]
for activView in lstInputViews:
#
activView.CropBoxVisible = True
doc.Regenerate()
#
cropBox = activView.CropBox
fecGrids = FilteredElementCollector(doc, activView.Id).OfClass(DatumPlane).ToElements()
cutOffset = fecGrids[0].GetCurvesInView(DatumExtentType.ViewSpecific, activView)[0].GetEndPoint(0).Z
fecGrids = [x for x in fecGrids if isinstance(x, DB.Grid)]
if activView.ViewDirection.IsAlmostEqualTo(XYZ(0,0,1)):
# get Current Elevation of boundLines
currentZ = list(boundLines)[0].GetEndPoint(0).Z
# transform boundLines CurveLoop
tf = Transform.CreateTranslation( XYZ(0,0, cutOffset - currentZ))
boundLines = CurveLoop.CreateViaTransform(boundLines, tf)
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
else:
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
TransactionManager.Instance.TransactionTaskDone()
OUT = lstInputViews, outLst, [x.ToProtoType() for x in boundLines], cutOffset,
So i just removed all the output because i don`t need them, and now it works fine
import clr
import System
clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DSGeo
from Autodesk.DesignScript.Geometry import *
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
def createDatumLine(boundLines, grid):
gridLine = None
curveG = grid.Curve#.ToProtoType()
vectGrid = curveG.Direction
lstPtToLine = []
for lineBound in boundLines:
rayc = DB.Line.CreateUnbound(XYZ(curveG.Origin.X, curveG.Origin.Y, lineBound.GetEndPoint(0).Z) , vectGrid)
outInterR = clr.Reference[IntersectionResultArray]()
result = rayc.Intersect(lineBound, outInterR)
print(result)
if result == SetComparisonResult.Overlap:
interResult = outInterR.Value
lstPtToLine.append(interResult[0].XYZPoint)
print(lstPtToLine)
if len(lstPtToLine) == 2:
P1 = lstPtToLine[0].ToPoint()
P2 = lstPtToLine[1].ToPoint()
TransXYZ1 = Geometry.Translate(P1 ,0,0,1)
TransXYZ2 = Geometry.Translate(P2 ,0,0,-0.5)
TransPoint1 = TransXYZ1.ToXyz()
TransPoint2 = TransXYZ2.ToXyz()
gridLine = Autodesk.Revit.DB.Line.CreateBound(TransPoint1, TransPoint2)
return gridLine
activView = UnwrapElement(IN[0])
lstInputViews = UnwrapElement(IN[0])
TransactionManager.Instance.EnsureInTransaction(doc)
for activView in lstInputViews:
#
activView.CropBoxVisible = True
doc.Regenerate()
#
cropBox = activView.CropBox
fecGrids = FilteredElementCollector(doc, activView.Id).OfClass(DatumPlane).ToElements()
cutOffset = fecGrids[0].GetCurvesInView(DatumExtentType.ViewSpecific, activView)[0].GetEndPoint(0).Z
fecGrids = [x for x in fecGrids if isinstance(x, DB.Grid)]
outLst = []
shpManager = activView.GetCropRegionShapeManager()
boundLines = shpManager.GetCropShape()[0]
if activView.ViewDirection.IsAlmostEqualTo(XYZ(0,0,1)):
# get Current Elevation of boundLines
currentZ = list(boundLines)[0].GetEndPoint(0).Z
# transform boundLines CurveLoop
tf = Transform.CreateTranslation( XYZ(0,0, cutOffset - currentZ))
boundLines = CurveLoop.CreateViaTransform(boundLines, tf)
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
else:
for grid in fecGrids:
outLst.append(grid.Curve.ToProtoType())
newGLine = createDatumLine(boundLines, grid)
if newGLine is not None:
grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
TransactionManager.Instance.TransactionTaskDone()
OUT = lstInputViews
So now as it works for sectionviews to give an offset by calculating the points i would like to add an offset to planviews also.
The offset should be the same on all sides, but calculating the points would be too complex for planviews because the grids won`t be just horizontal and vertikal.
So for planviews i would need a method to give the grid curve an offset, right ?