Grid to crop line using python

I use python code from Forum… but it always make grid head to top and right.
How can I fix this code to make grid head top and “LEFT”?

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

Ah, I have been using the same code recently for a different purpose.

You need to incorporate a set of additional conditions in the boundline definition.

  1. Assess if the boundline is vertically oriented to the view, as to filter out only the horizontal boundlines.

  2. Checking the start and end point of the horizontal boundlines, and reversing it’s direction if the X value of start point is greater than the X value of the end point.

The above depends on the view being orthogonal with the X and Y axis where they are expected to be, which might not be entirely accurate if the view is using a rotated scope box.

What view orientation do you have?

Do you have python programming experience?

This is not the easiest place to start working with Python/Revit via Dynamo, but if you give it a go and post your attempts, we are here to guide you towards a solution.

Thank you reply.
First of all, I need check word.

  • boundline → crop line
  • horizontal boundlines → crop view parallel with plan view

Is it right?

What view orientation do you have?

  • It is plan view and never rotated

Do you have python programming experience?

  • I learned about python programming several month, Can’t make code, but read code in elementary level.
	if len(lstPtToLine) == 2:
		gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
	return gridLine

I thought in this line, (lstPtToLine[0], lstPtToLine[1]) change these value to (lstPtToLine[1], lstPtToLine[0]), but It’s wrong. because right grid head turned into left head grid and top head grid turned into down head grid.

Fianlly I thought, if I get hor-grid startpoint-endpoint reversely, this problem will be fixed.
but It’s difficult to change code

You are thinking along the correct lines.
Have a look at the logic here, then give it a go :wink:

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:
		
		# Enforce Line Orientation
		if lstPtToLine[0].Y > lstPtToLine[1].Y:
			# The grid is vertial and starts from the top
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
		elif lstPtToLine[0].X < lstPtToLine[1].X and lstPtToLine[0].Y == lstPtToLine[1].Y:
			# The grid is horizontal and starts from the left
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])
		else:
			# The grid orientation is incorrect, swap the direction
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[1], lstPtToLine[0])


	return gridLine
1 Like

Good morning! It’s 8 o’clock here

lstPtToLine[0].Y means y coordinates of point !

I understand what you want to do in IF function, but also can’t understand this

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

I already tried swiching lstPtToLine[0] <-> lstPtToLine[1] in previous code but it failed.
There is no differences defining IstPtToLine but swiching in “else” function is successful

What’s difference in two? (just swich “IstPtToLine[0], lstPtToLine[1]” in previous code, and if …

oh, I understand.
That “IF” code means
Not make grid in same time like previous one, but make grid step by step.
vertical? ok~ horizontal? no → swap . oh I see

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:
		
		# Enforce Line Orientation
		if lstPtToLine[0].Y > lstPtToLine[1].Y:
			# The grid is vertial and starts from the top
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[1], lstPtToLine[0])
		elif lstPtToLine[0].X < lstPtToLine[1].X and lstPtToLine[0].Y == lstPtToLine[1].Y:
			# The grid is horizontal and starts from the left
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[1], lstPtToLine[0])
		else:
			# The grid orientation is incorrect, swap the direction
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])


	return gridLine

Result is good, grid head appear right and bottom. but I change all point( 0->1 , 1->0) in your code
It’s solved. very very thank you for your help!

1 Like

Glad to hear it works for you. :+1:
Please mark the solution for anyone else who visits this topic in future.

1 Like
	if len(lstPtToLine) == 2:
		
		# Enforce Line Orientation
		if lstPtToLine[0].Y > lstPtToLine[1].Y:
			# The grid is vertial and starts from the top
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[1], lstPtToLine[0])
		elif lstPtToLine[0].X < lstPtToLine[1].X and lstPtToLine[0].Y == lstPtToLine[1].Y:
			# The grid is horizontal and starts from the left
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[1], lstPtToLine[0])
		else:
			# The grid orientation is incorrect, swap the direction
			gridLine = Autodesk.Revit.DB.Line.CreateBound(lstPtToLine[0], lstPtToLine[1])


	return gridLine

ah… one more thing plz?
I think It should be work on elevation, because of “else” phrase
but It isn’t.
why this problem happened?

This is likely because the Grid ‘Curves’ are now vertical specific to the view and so need to be extracted slightly differently. I’ll have a look when I get a chance.

thanks !!