Elevation Marker facing the wrong way

I found this topic once placing Elevation Marker and have the face a certain direction
(i’ll try to find the original topic.

It uses this Python, but sometimes one Elevation Marker faces the wrong direction. Any idea why? @c.poupin maybe?

import clr
import System
from System.Collections.Generic import List

# Add Revit API References
clr.AddReference('RevitAPI')
clr.AddReference("RevitServices")
clr.AddReference("RevitNodes")

import RevitServices
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

import Autodesk
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

from math import atan2

# Document reference
doc = DocumentManager.Instance.CurrentDBDocument

# ------------------------------
# Inputs
# ------------------------------
toggle = IN[0]                                  # Boolean toggle to run
points = [UnwrapElement(pt) for pt in IN[1]]    # Elevation marker positions
modelPoints = [UnwrapElement(mp) for mp in IN[2]] # Model reference points
viewType = UnwrapElement(IN[3])                 # ViewFamilyType for elevation

# Normalize input format for multi-point runs
if not isinstance(points[0], list):
    points = [points]
    modelPoints = [modelPoints]

# ------------------------------
# Execution
# ------------------------------
created_views = [[] for _ in range(len(points))]  # One list per group/scope box

if toggle:
    TransactionManager.Instance.EnsureInTransaction(doc)

    for i in range(len(points)):

        pts = points[i]
        mps = modelPoints[i]

        for ind, point in enumerate(pts):
            try:
                # Get XYZ positions
                modelMP = mps[ind].ToXyz()
                elevationPT = point.ToXyz()
                
                # Vector direction for rotation
                elptRotate = XYZ(elevationPT.X, elevationPT.Y, elevationPT.Z + 100)
                axis = Line.CreateBound(elevationPT, elptRotate)
                angle = atan2(elevationPT.Y - modelMP.Y, elevationPT.X - modelMP.X)

                # Create elevation marker and view
                eleMarker = ElevationMarker.CreateElevationMarker(doc, viewType.Id, elevationPT, 100)
                eleView = eleMarker.CreateElevation(doc, doc.ActiveView.Id, 0)

                # Rotate the marker to face the model point
                ElementTransformUtils.RotateElement(doc, eleMarker.Id, axis, angle)

                # Add the view to the correct group
                created_views[i].append(eleView)

            except Exception:
                continue

    TransactionManager.Instance.TransactionTaskDone()

# ------------------------------
# Outputs
# ------------------------------
OUT = created_views if toggle else []

EDIT
I think this was the original topic :backhand_index_pointing_down:.

OR

To add.

After i moved my Scope Boxes it does face the right direction :exploding_head:.
This isn’t a solution though.

EDIT
Revit 2025.

Here is a solution that uses the newly created elevation’s view direction by comparing it to the (midLine → center) vector.

import clr
import System
from System.Collections.Generic import List

clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)

# Add Revit API References
clr.AddReference('RevitAPI')
clr.AddReference("RevitServices")
clr.AddReference("RevitNodes")

import RevitServices
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

import Autodesk
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Document reference
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

scope_box = UnwrapElement(IN[0])
viewType = UnwrapElement(IN[1])
out_views = []

currentView = doc.ActiveView
opt = Options()

lines = []
for geo in scope_box.get_Geometry(opt):
    if isinstance(geo, DB.Line):
        if abs(geo.Direction.Z) > 0.5:
            continue
        lines.append(geo)
        
# get bottom lines
lines.sort(key = lambda x : x.GetEndPoint(0).Z)
lines = lines[0:4]

# get center
ptmid = lines[0].Evaluate(0.5, True)
for l in lines[1:]:
    ptmid += l.Evaluate(0.5, True)
ptmid /= 4

TransactionManager.Instance.EnsureInTransaction(doc)
for l in lines:
    # create vectors from midcurve to center
    pt = l.Evaluate(0.5, True)
    vect = DB.Line.CreateBound(pt, ptmid).Direction 
    # create maker
    eleMarker = ElevationMarker.CreateElevationMarker(doc, viewType.Id, XYZ(pt.X, pt.Y, currentView.GenLevel.ProjectElevation), 100)
    eleView = eleMarker.CreateElevation(doc, currentView.Id, 0)
    doc.Regenerate()
    elev_direction = eleView.ViewDirection.Negate()
    #
    angle = vect.AngleTo(elev_direction)
    factor = -1 if vect.CrossProduct(elev_direction).Z > 0.01 else 1
    angle *= factor
    axis = DB.Line.CreateUnbound(pt, XYZ.BasisZ)
    ElementTransformUtils.RotateElement(doc, eleMarker.Id, axis, angle)
    out_views.append(eleView)
    
TransactionManager.Instance.TransactionTaskDone()

OUT = out_views
3 Likes

Thanks for your time and effort @c.poupin, but unfortunately it didn’t work.

I used this approach for now.

So i set the right tick box for each marker.
That seemed to be more reliable.

nice, for info this method will do not work with a rotated scopbox

demo with my code above

create_markers_on_scopbox

When i post a RVT with just my scope boxes and position can you have a look then?

Maybe you can tell why i am having that issue.

yes you can post an sample file

It works in the example file i wanted to post but not in my actual project?!?


So let me strip the project file first.

EDIT
When i stripped the project it also worked?!? I am confused.

It may be that there is invalid data, or file setup, which is causing the blocker. Without a dataset to test line and view by view it’s really tough to know why things are reacting the way they are. Cropbox rotation, view rotation, view orientation, and more will all play a role in ‘why’.

In these cases debugging is painful, but if you go about it systematically you can often identify the issue.

  1. Make a new view of the same class as one of the failing views and see if the brand new view behaves incorrectly. Make sure no template, extents, or other info is set - we want this as close to a ‘raw’ view from Revit as possible.
  2. If so, check for project wide settings which impact orientation such as true north angle.
  3. If not start to look at configuration differences between the new ‘raw’ view and the project specific one which impact orientation. Scope box, crop region, north orientation, etc. Turn things on 1x1 and re-run the tool until you find the ‘problematic setting’.
  4. Once you have the setting identified, look to append an additional transform in the code to deal with whatever alterations the property of the view is applying.
1 Like

I am aware, but…

It does not work and works in the same Project on the same View,
using the same Scope Box etc.
Only difference is i stripped the project from the Geometry (Families) so i was left with just the
Scope Boxes, Levels, Grids, Views etc.

So for now people can let this rest till i found the culprit.

2 Likes