Change the Curve that determines the 2D extents of Grids in Each View

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

2 Likes

Hello @c.poupin
Thank you for the fix :smiley:

This are the results:

Works with simple cropregion:

grid1

Makes a Mess with complex crop regions, and grids that have a kink get split up into two seperate grids.

grid2

And does still nothing in section views:

grid3

1 Like

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

test extend grid2

5 Likes

:open_mouth: This is amazing @c.poupin :smiley:

Thank you so much, i will try to add an input to set an offset and to adjust the grid bubbles.
:slight_smile:

Hello @c.poupin :slight_smile:

After a few tests i now added some nodes and code because i want to only show the upper bubbles in sectionviews:

ezgbubble

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 :slight_smile:

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])
1 Like

I´m getting the Error, that I´m having a type-object.

image
image

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 :slight_smile:

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

1 Like

Woohoo it´s working :smiley:

abc

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:

image

1 Like

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()
3 Likes

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 :slight_smile:

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? :thinking:

1 Like
1 Like

@c.poupin

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:

image

Kind regards :slight_smile:

1 Like

declare your variable outLst = [] outside the floor loop
(for activView in lstInputViews)

2 Likes

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 :slight_smile:

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
2 Likes

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 ?

1 Like