Ordinate dimension text position

I know people have been looking for a dim style without all the lines, for sales brochures for example, at least here in Holland. Almost all revert to detail items with a line and a label reading the line length. Looks good, but a pain in the a$$ to manage.

With Ordinate dims you can turn off the lines, but the text also jumps to one of the sides of the dim line, so those have to be moved manually, which is also a pain in the a$$.

So, thought I’d give it a go with Dynamo. With normal dims, pretty simple add < and > as prefix and suffix, get the curve of the dim, find the middle, move text (all with help from the rhythm package of course (thanx @john_pierson).

But those Ordinate dims are a weird and special breed. The < and > work great but moving text isn’t. If you look at the attached project and dynamo script, you’ll see that it already goes BOOM when trying to get the curve of the dimension and I have no other idea how to get them for the Ordinate dims.

Any help would be appreciated.

AND of course typing this gives me an idea to try. Maybe start with normal dims, get the middle of those, replace the dim style to the Ordinate one and move text. Not tried that yet. If it works a workable workaround, but not having to switch style would of course be much better.

Dimension test.dyn (35.4 KB) Dimension test.rvt (504 KB)

Hey Robin,

You can find the middle point by extracting the Origins from the DimStyle, and using their X and Y to find the middle.

Only the Ordinate Style does not seem to support a moved Text location.

1 Like

Seems there is a Methods to check if it can be done:
https://www.revitapidocs.com/2020/e3d0717c-713d-64b0-64a9-336cbb95519a.htm

1 Like

Yeah thats what I figured :frowning:
I was hoping there was a possibility in the API for example.

I thought about this topic and there is a workaround I think.

You have your ordinate dimensions (labels all the way to the Right side)

  1. with Dynamo you change the dimension type to something which is Continuous or you change the property of you Ordinate dimension to Continuous.
  2. You move the label with dynamo all the way to the Left side
  3. Change the Type back to ordinate, this will place the labels in the middle.

You could do this in a Python script

2 Likes

That is a very cool trick. Works like a charm when doing that manual, so need to adjust my script to make that happen.

2 Likes

And the script works as well. Need to make a few adjustments to make it work as I want it too. It is a 2 step process right now as for some reason when doing it all at once not all the dimensions change. So, run script to move all dims to the side, unfreeze a node, run again and all is well.

Will post it here when I’m happy with it.

1 Like

I was toying around with it in python, but those dang multi segments are still acting funny in one script.

if anyone was interested in trying to improve my script:

import clr

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

#Preparing input from dynamo to revit
dimensions = UnwrapElement(IN[0])

TransactionManager.Instance.EnsureInTransaction(doc)
for i in dimensions:
	
	#obtain ordinate type to use
	ordinateTypeId = filter(lambda d : doc.GetElement(d).get_Parameter(BuiltInParameter.LINEAR_DIM_TYPE).AsInteger() == 3,i.GetValidTypes())[0]
	ordinateType = doc.GetElement(ordinateTypeId)
	
	#obtain a continuous type to use
	continuousTypeId = filter(lambda d : doc.GetElement(d).get_Parameter(BuiltInParameter.LINEAR_DIM_TYPE).AsInteger() == 1,i.GetValidTypes())[0]
	continuousType = doc.GetElement(continuousTypeId)
	
	#obtain the dimension type to change
	dimType = doc.GetElement(i.GetTypeId())
		
	#set the dim type to continuous
	i.DimensionType = continuousType
	
	#for single segment dimensions
	if i.NumberOfSegments == 0:
		i.TextPosition = XYZ(i.Origin.X - i.Value/2,i.Origin.Y,i.Origin.Z)
	#for multi segment dimensions
	else:
		for s in i.Segments:
			s.TextPosition = XYZ(s.Origin.X - s.Value/2,s.Origin.Y,s.Origin.Z)
			
	i.DimensionType = ordinateType
	
TransactionManager.Instance.TransactionTaskDone()	
	
OUT = dimensions
2 Likes

Anything I do with ‘normal’ Dynamo has the same issue :(.
But if that means I can’t use multi segment dims for this I’m more then happy too in this case.

I changed the python script a little bit, it now translates the test positions in the direction of the dimension, not just in the Y direction. Now it also works for vertical/diagonal dimensions

import clr

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

#Import the Revit Nodes
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

def tolist(obj1):
	if hasattr(obj1,"__iter__"):
		return obj1
	else:
		return [obj1]

#Preparing input from dynamo to revit
dimensions = UnwrapElement(tolist(IN[0]))

TransactionManager.Instance.EnsureInTransaction(doc)
for i in dimensions:
	temp = []
	
	#obtain ordinate type to use
	ordinateTypeId = filter(lambda d : doc.GetElement(d).get_Parameter(BuiltInParameter.LINEAR_DIM_TYPE).AsInteger() == 3,i.GetValidTypes())[0]
	ordinateType = doc.GetElement(ordinateTypeId)
	
	#obtain a continuous type to use
	continuousTypeId = filter(lambda d : doc.GetElement(d).get_Parameter(BuiltInParameter.LINEAR_DIM_TYPE).AsInteger() == 1,i.GetValidTypes())[0]
	continuousType = doc.GetElement(continuousTypeId)
	
	#obtain the dimension type to change
	dimType = doc.GetElement(i.GetTypeId())
		
	#set the dim type to continuous
	i.DimensionType = continuousType
	
	#for single segment dimensions
	if i.NumberOfSegments == 0:
	
		#Translate the Point to the Start of the Dimension
		position = i.Origin.ToPoint()
		length = i.Value/2;
		vector = i.Curve.Direction.ToVector()
		position = position.Translate(vector.Reverse(), length*304.8)
		
		i.TextPosition = position.ToXyz()
	#for multi segment dimensions
	else:
		for s in i.Segments:
		
			#Translate the Point to the Start of the Dimension
			position = s.Origin.ToPoint()
			length = s.Value/2;
			vector = i.Curve.Direction.ToVector()
			position = position.Translate(vector.Reverse(), length*304.8)
			
			#Set the position
			s.LeaderEndPosition = position.ToXyz()
			s.TextPosition = position.ToXyz()
			
	i.DimensionType = ordinateType
	
TransactionManager.Instance.TransactionTaskDone()	
	
OUT = dimensions
2 Likes

OK, after a lot of changes and adjustments both in how the script works and to make is work well with Dynamo Player I think it is ready to share.

In the end I didn’t use the Python scripts you guys posted and also got the 2 step methode back too just 1, so I’m happy with it. Uploaded a tiny revit project as well, that has all the names that are default in the script, so you can run it on that straight away.

Lemme know what you think

Dynamo-verkoop-maatvoering.rvt (496 KB)
Dynamo-verkoop-maatvoering.dyn (83.2 KB)

1 Like

Hey Robin, I tried your script thanks for sharing
Does it only work in drafting view, I tried it on a plan view put the dimension text was pushed very far away from the actual dimension I have to do a zoom extent and keep zooming so I can find it

Not a 100% sure what happened to that little project, but it seems the verkoop dim style I use in the script was is not in there. Attached you’ll find another little project that has the right ordinate dim style with all the settings right as seen below in the image.

ordinate

Dynamo-verkoop-maatvoering v2.rvt (500 KB)