Curtain Panel Orientation - false normals


I’m doing a definition to analyse world orientations of Windows and Curtain Panels. It’s quite easy for Windows, but as node FamilyInstance.FacingOrientation cannot be used for Curtain Panels and CurtainPanel.PanelPlane doesn’t work for panels on a curved Curtain Wall, I’m running into trouble.

I’ve got everything working except panels on curved walls. I’m just starting to wrap my head around vectors and normals, but I understand what is going on and why it fails - I just don’t know how to solve it. It seems like the direction / orientation of the panels is the missing link.

Can anybody help me out?


Window Orientation 2.dyn (55.1 KB)
version 2.rvt (2.6 MB)

Don’t you find it funny it’s exactly 90 degrees off :smiley:

From 0-180 deg the values are correct - also the two panels you’ve dimensioned, as their faces have angles of 12 and 29 deg related to true north. So the values are actually not 90 degrees off :slight_smile:

The problem occurs on panels oriented from 180 to 360 deg related to true north, as it’s the wrong side of the panels that are being “calculated”.

I guess it could be something concerning the direction of the normals:

Probably depending on the direction of the normal it’s calculating the bigger angle.

It’s calculating like shown below;

All red are false. All angles should be calculated like the green ones, pointing away from the exterior side of the panels.

I have had to solve this problem a few months ago. I have posted it on our company blog, with the Dynamo files available for download. Maybe it will help you:


Here’s another method that may also work assuming the normals of the CurtainPanel.Boundaries is consistent:

Assuming it is, and assuming the surfaces created from the CurtainPanel.Boundaries results in inconsistent normals; calculate their dot product. Any scalar of -1 is an inverted Surface.NormalAtPoint. Use Vector.Reverese guided by an if statement and you should now be able to output the correct angles for all panels from this ‘corrected’ set of vectors.

Before conditional reverse:

After conditional reverse:


EDIT: ps, if the result of the dot is anything to go by, it seems the normals of the CurtainPanel.Boundaries indicate these elements are treated as planar, meaning you can bypass everything and simply use Curve.Normal, I haven’t tested this so I’ll leave that for you to uncover.


That is brilliant! Thank you for your thorough walkthrough.

As you assumed, Curve.Normal does the job.

Here’s the final definition if somebody’s interested;

Window Orientation.dyn (53.1 KB)


I have tried many things on my own and what you and @Thomas_Mahon have posted with no luck. The screen shot below is using the script you posted (without any changes). The two show, one was copied and then flipped but it is still showing the normal in the same direction. The two curtain walls in the first image are the same ones in the following ones after.

The panel normal, curve normal, and the patch normal are all equal for both walls.

The code in the python script is

import clr


from Autodesk.Revit.DB import *


import Revit



wallinstances = UnwrapElement(IN[0])

vectorlist = list()

for item in wallinstances:


        lcurve = item.Location.Curve

        if str(lcurve.GetType()) == "Autodesk.Revit.DB.Line":



            direction = (lcurve.GetEndPoint(1) - lcurve.GetEndPoint(0)).Normalize()




OUT = vectorlist

any help would be great,

1 Like

I just found Wall.ExteriorDirection in Archi-lab and it works. Sorry for the post.


1 Like

Hi - I have a similar problem but need a different solution. I’m creating generic adaptive family members which are defined with 4 points (a rectangle) and a thickness. This works, but the thickness side dynamo/revit chooses is not consistent. I would like to do the above approach (vector dot product of the resultant shape and the curve.normal, to properly fix the thickness side (- or + value to my thickness parameter). My problem is that I don’t know how to find the normal vector of my adaptive component. It’s not a surface, not a curtain wall, not a wall… so how can I find the direction that dynamo/revit has chosen, to analyze and adjust which way it really should go? I am 100% certain that all my points are being fed in a consistent order to match my generic adaptive component family, but being new to both Revit and Dynamo, it is possible that my family is lacking a control/constraint somehow, which would help me out. Thanks so much!

Hi - any possible solutions out there? @Thomas_Mahon - can you suggest anything for adaptive components to find the normal vector of what gets created? Thanks!