Align Surface Patterns to Wall Edge

Hi All,

I have a lot of brick hatch which I need to align to the wall edges, so I’m trying to rewrite this in Python & make it work for walls…

https://forums.autodesk.com/t5/revit-api-forum/use-of-align-function-programatically-to-change-the-alignment-of/m-p/7350967/highlight/true#M24949

I’m getting a problem where the reference is not aligned to the reference plane… Any assistance gratefully received!

On a side note… If anyone had some tips on making the C# into an addin, that would also be really helpful, I’m sure it would be easy for someone more capable than me! I’m not sure how to connect the variables from the helper method to the variables in the main class.

Thanks,

Mark

Dimension Align Pattern-6.dyn (17.0 KB) align.rvt (1.5 MB)

#thanks to Genius Loci and Fair59
import clr
import sys

pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

import string

# Import Element wrapper extension methods
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
# toProtoType etc.
clr.ImportExtensions(Revit.GeometryConversion)

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

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

wall = UnwrapElement(IN[0])
references = UnwrapElement(IN[1])
line = Line.CreateBound(XYZ.Zero, XYZ(10, 0, 0))

elementsRef = ReferenceArray()

for reference in references:
	elementsRef.Append(reference)
	
TransactionManager.Instance.EnsureInTransaction(doc)

dimension = doc.Create.NewDimension(doc.ActiveView, line, elementsRef)

TransactionManager.Instance.TransactionTaskDone()

for w in wall:
	try:
		extSide = HostObjectUtils.GetSideFaces(w,ShellLayerType.Exterior)	
		for eS in extSide:
			wallFace = w.GetGeometryObjectFromReference(eS)
	except:
		wallFace = 'no external face found'
#corner = start point of the 'first or default' edge loop of the face we're interested in
cvList = []
for cv in wallFace.GetEdgesAsCurveLoops()[0]:
	cvList.append(cv.GetEndPoint(0))
	cvList.append(cv.GetEndPoint(1))
corner = cvList[0]


#not sure exactly what this is doing...
dimDirection = dimension.Curve.Direction

dimOrigin = dimension.Origin.Subtract(dimDirection.Multiply(dimension.Value/2))

hatchDirection = dimDirection.CrossProduct(wallFace.FaceNormal).Normalize()

r1 = dimension.References.get_Item(0)

translation = dimOrigin.Subtract(corner)


#we need to move the reference or it's 'element'

#start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)

#we need a reference plane
#the reference plane is made of the origin vector moved the hatch direction added, the origin, the wall face normal (out vector)

pl = doc.Create.NewReferencePlane(dimOrigin.Add(hatchDirection),dimOrigin,wallFace.FaceNormal,doc.ActiveView)

format = "{0}:{0}:{1}"
uid = pl.UniqueId
arg = "SURFACE"
stableRef = str.Format(format,uid,arg)
#
#stableRef = string.Formatter("{0}:0:{1}",pl.UniqueId,"SURFACE")
ref2Plane = Reference.ParseFromStableRepresentation(doc,stableRef)
#we need a reference plane & the first reference item... 
doc.Create.NewAlignment(doc.ActiveView,ref2Plane,r1)
#finish transaction
TransactionManager.Instance.TransactionTaskDone()

#start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)
#we are moving the the reference plane to the origin
ElementTransformUtils.MoveElement(doc,pl.Id,translation)
#finish transaction
TransactionManager.Instance.TransactionTaskDone()

Update… Needs some more refinement…

Dimension Align Pattern-8.dyn (29.5 KB)

Hi Mark,

I was on the rigth track yesterday evening.
I had just made a mistake in the direction of translation. Now it works.

Before:


After:

Dimension Align Pattern-9.dyn (12.4 KB)

2 Likes

Thanks so much for your help!

1 Like

I’ve done a bit more work to get it running with patterns that have more than 1 reference… It now works for lists of walls & aligns both vertically and horizontally…

Wall Pattern Align Bricks Ele View.dyn (28.1 KB)

4 Likes

Thank you for the solution. When running in Revit 2020.3 and the “align.rvt” test file, rule 35 of “Create Ref Plane” runs into an error;

"IronPythonEvaluator.EvaluateIronPythonScript operation failed.
Traceback (most recent call last):
File “”, line 35, in
AttributeError: ‘Material’ object has no attribute ‘SurfacePatternId’

Might this be API dependent and how to solve this issue?

Hi,

Try with the Align Pattern To Edges node in Genius Loci package.
I have made some improvements since those first attempts;

2 Likes

Thank you. This node is not working well, I made some changes in the Python code to cope with the Revit 2020 API. For me this works well with the earlier example file.
Though, when run on stacked walls it will not work well, do you have a suggestion for this?

Adaptation:
Line 43: patternType = doc.GetElement(mat.SurfacePatternId)
Changed to: patternType = doc.GetElement(mat.SurfaceForegroundPatternId)

Thanks for telling me about this necessary node update.

You may be able to use the Align Pattern node in conjonction with the Get Wall Member node.

No problem. Thank you for the suggestion! Will try it monday and get back to you about this workaround