Grid extents alignment based on crop region

grid extents need to placed at crop region…

Version:0.9 StartHTML:00000097 EndHTML:00005232 StartFragment:00000199 EndFragment:00005194

import clr
# ProtoGeometry (Dynamo)
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# API
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# RevtiServices
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# RevitNodes, ToDSType method, Geometry conversion
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# defs
def Convert(num):
return UnitUtils.ConvertToInternalUnits(num, DisplayUnitType.DUT_MILLIMETERS)

# start
doc = DocumentManager.Instance.CurrentDBDocument

view = UnwrapElement(IN[0])

av = doc.ActiveView

#Top Grid
deltatop = IN[1]
#vatopx = Convert(deltatop[0].X)
#vatopy = Convert(deltatop[0].Y)
#vatopz = Convert(deltatop[0].Z)
grids = [UnwrapElement(item) for item in IN[2]]

#Bottom Grid
deltabottom = IN[3]
#vabottomx = Convert(deltabottom[0].X)
#vabottomy = Convert(deltabottom[0].Y)
#vabottomz = Convert(deltabottom[0].Z)

TransactionManager.Instance.EnsureInTransaction(doc)
for g in range(len(grids)):
    newStart = XYZ(deltatop[g].X, deltatop[g].Y, deltatop[g].Z)
    newEnd = XYZ(deltabottom[g].X, deltabottom[g].Y, deltabottom[g].Z)
    newCurve = Line.CreateBound(newStart, newEnd)
    grids[g].SetCurveInView(DatumExtentType.ViewSpecific, view , newCurve)

TransactionManager.Instance.TransactionTaskDone()

# end
OUT = grids

Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 54, in
Exception: The curve is unbound or not coincident with the original one of the datum plane.
Parameter name: curve

please help on this error.

Why not just Element.SetParameterByName?

no its not possible. I need to move the grid extent beyond the crop boundry

Hello @dhilipseshan
you need to get the “cut elevation” CutPlane of the view to set elevation of bounds curve (CropBox)

an example with the active view

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

def createDatumLine(boundLines, grid):
	gridLine = None
	curveG = grid.Curve
	vectGrid = curveG.Direction 
	ptmid = curveG.Evaluate(0.5, True)
	lstPtToLine = []
	for lineBound in boundLines:
		interResult = lineBound.Project(ptmid)
		vectInterResult = Autodesk.Revit.DB.Line.CreateBound( ptmid , interResult.XYZPoint).Direction
		if vectInterResult.IsAlmostEqualTo(vectGrid, 0.1) or vectInterResult.IsAlmostEqualTo(vectGrid.Negate(), 0.1):
			lstPtToLine.append(interResult.XYZPoint)

	if len(lstPtToLine) == 2:
		gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
	return gridLine
					
def getBoundLines(bbx, Zvalue ):
	lstPt = []
	lstLine = []
	lstPt.append(XYZ(bbx.Min.X, bbx.Min.Y, Zvalue))
	lstPt.append(XYZ(bbx.Max.X, bbx.Min.Y, Zvalue))
	lstPt.append(XYZ(bbx.Max.X, bbx.Max.Y, Zvalue))
	lstPt.append(XYZ(bbx.Min.X, bbx.Max.Y, Zvalue))
	for idx, pt in enumerate(lstPt):
		if idx == 0:
			lstLine.append(Line.CreateBound(lstPt[- 1], pt))
		else:	
			lstLine.append(Line.CreateBound(lstPt[idx - 1], pt))			
	return lstLine		

activView = doc.ActiveView
cropBox = activView.CropBox 
viewRange = activView.GetViewRange()
cutOffset = viewRange.GetOffset(PlanViewPlane.CutPlane)

fecGrids = FilteredElementCollector(doc, activView.Id).OfClass(DatumPlane).ToElements()
outLst = []
boundLines = getBoundLines(cropBox, cutOffset)

TransactionManager.Instance.EnsureInTransaction(doc)
for grid in fecGrids:
	newGLine = createDatumLine(boundLines, grid)
	if newGLine:
		grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
		outLst.append(newGLine)
TransactionManager.Instance.TransactionTaskDone()

OUT = outLst
6 Likes

@c.poupin. Thank you so much.
your work is amazing.
I am looking into this many times to understand.
but i think i missed to specify diagonal grids as shown in image.
is that possible for diagonal grids also?

Hello @dhilipseshan
I had not considered this scenario :grinning:
try this version

  • Edit 03/02/2022
    fix bug
import clr
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 
	ptmid = curveG.PointAtParameter(0.5)
	lstPtToLine = []
	for lineBound in boundLines:
		lineBoundDs = lineBound.ToProtoType()
		ptmid = DSGeo.Point.ByCoordinates(ptmid.X, ptmid.Y, lineBoundDs.StartPoint.Z)
		interResultA = ptmid.Project(lineBoundDs, vectGrid)
		interResultB = ptmid.Project(lineBoundDs, vectGrid.Reverse())

		if len(interResultA) > 0:
			lstPtToLine.append(interResultA[0].ToXyz())
		if len(interResultB) > 0:
			lstPtToLine.append(interResultB[0].ToXyz())			

	if len(lstPtToLine) == 2:
		gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
	return gridLine

					
def getBoundLines(bbx, Zvalue = 0):
	lstPt = []
	lstLine = []
	lstPt.append(XYZ(bbx.Min.X, bbx.Min.Y, Zvalue))
	lstPt.append(XYZ(bbx.Max.X, bbx.Min.Y, Zvalue))
	lstPt.append(XYZ(bbx.Max.X, bbx.Max.Y, Zvalue))
	lstPt.append(XYZ(bbx.Min.X, bbx.Max.Y, Zvalue))
	for idx, pt in enumerate(lstPt):
		if idx == 0:
			lstLine.append(Line.CreateBound(lstPt[- 1], pt))
		else:	
			lstLine.append(Line.CreateBound(lstPt[idx - 1], pt))			
	return lstLine		

activView = doc.ActiveView
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 = []
boundLines = getBoundLines(cropBox, cutOffset)


TransactionManager.Instance.EnsureInTransaction(doc)
for grid in fecGrids:
	newGLine = createDatumLine(boundLines, grid)
	if newGLine and True:
		grid.SetCurveInView(DatumExtentType.ViewSpecific, activView, newGLine)
		outLst.append(newGLine)

TransactionManager.Instance.TransactionTaskDone()

OUT = outLst

another version here

6 Likes

@c.poupin.
Thank you so much.
This is working perfect even for diagonal grids also.

1 Like

Its not work for Elevation plan, can you fix it, thank you so much!

Start new topic original post is already solved.

3 Likes