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

Here an updated code compatible with all python engines

import clr
import sys
pyEngineName = sys.implementation.name 
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)
		if pyEngineName == "ironpython":
			outInterR = clr.Reference[IntersectionResultArray]()
			result = rayc.Intersect(lineBound, outInterR)
			print(result)
			if result == SetComparisonResult.Overlap:
				interResult = outInterR.Value
				lstPtToLine.append(interResult[0].XYZPoint)
		else:
			dummy_out = IntersectionResultArray()
			result, interResult = rayc.Intersect(lineBound, dummy_out)
			print((result, interResult))
			if result == SetComparisonResult.Overlap:
				lstPtToLine.append(interResult[0].XYZPoint)
		#
	print(lstPtToLine)
	if len(lstPtToLine) == 2:
		gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
	return gridLine
	
def toList(x):
	if isinstance(x, list):
		return x
	elif hasattr(x, "GetType") and x.GetType().GetInterface("IEnumerable") is not None:
		return x
	else :
		return [x]

lstView = toList(UnwrapElement(IN[0]))
offset_number = IN[1]

TransactionManager.Instance.EnsureInTransaction(doc)
#
for activView in lstView:
	activView.CropBoxVisible = True
	doc.Regenerate()
	cropBox = activView.CropBox 
	
	fecMultiGrids_Ids = [id for m in FilteredElementCollector(doc).OfClass(MultiSegmentGrid).WhereElementIsNotElementType() for id in m.GetGridIds()]
	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) and x.Id not in fecMultiGrids_Ids]
	
	outLst = []
	shpManager = activView.GetCropRegionShapeManager()
	boundLines = shpManager.GetCropShape()[0]
	boundLines = CurveLoop.CreateViaOffset(boundLines, offset_number, activView.ViewDirection.Negate())
	
	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 =  lstView

Revit API, PythonNet, IronPython, .Net Framework, .Net Core, etc… all of this is evolving

it is an illusion to think that a code will never need to be corrected/fixed

3 Likes