4.6 Geometry Conversion Methods

Dynamo geometry and Revit geometry might seem similar but are different!

Introduction

If you haven't read the excellent Dynamo Primer section on Geometry, it helps to brush up on it beforehand. Also, if your scripts include geometry make sure to include the geometry libraries in your boilerplate code!

Revit Geometry and Dynamo Geometry

As explained in the section on unwrapping Revit elements, Dynamo has a parallel class library to Revit. This means special conversion methods need to be used to smoothly interoperate between the two.

Dynamo's Github wiki has a page which goes into detail on this topic, which can be found here. In short, it is worth being conscious of which geometry classes you're working with.

A good hint for understanding which geometry types you're working with are whether they're visible in the 3D background preview after being outputted from the node. Revit types won't be visible unless you use special conversion methods.

Conversion Methods

You can easily go between Dynamo and Revit geometry types using the conversion methods in Dynamo's API, but it's not always intuitive to know which ones to use. There is ToProtoType(),ToDSType(), ToLine(), ToPoint(), ToVector(), and ToXyz()!

The next sections will attempt to tackle the main kinds of geometry you're likely to encounter one-by-one.

Points

Let's start with something simple - points! Points are defined in 3D space by their X, Y and Z coordinates and have no measurable dimensions.

To create a Dynamo point, we need to use the Designscript Library, which is a part of Dynamo. Dynamo Points are of type Autodesk.DesignScript.Geometry.Point. If you output the below dynamo_point from a Python node it will immediately show up in Dynamo's 3D background preview.

#Boilerplate code
​
dynamo_point = Autodesk.DesignScript.Geometry.Point.ByCoordinates(0,0,0)
OUT = dynamo_point

That's the Dynamo point done. Now let's look at creating a Revit point. The thing is, Revit actually has two kinds of 'points':

Even though we're creating Revit objects here, in this case we don't need to wrap them in a transaction.

#Boilerplate code
revit_xyz = XYZ(0,0,0) #A Revit XYZ
#The Point class is created using an XYZ object
revit_point = Point.Create(revit_xyz)
OUT = revit_xyz, revit_point

We can output our XYZ and our Point from the Python Script node, but they won't be visible in the Dynamo geometry preview unless we convert them to Dynamo types like so:

#Boilerplate code
revit_xyz = XYZ(0,0,0)
revit_point = Point.Create(revit_xyz)
OUT = revit_xyz.ToPoint(), revit_point.ToProtoType()

Lines / Curves

As before, let's look at the Dynamo classes first: Dynamo has two 'line-like' geometry classes. It's worth disambiguating the two to see how they differ.

  • Autodesk.DesignScript.Geometry.Line this is more like a 'classic' straight line, which has a start point and an end point.

  • Autodesk.DesignScript.Geometry.Curve Dynamo's curve class can be a bit more ambitious than a simple straight line. It can handle complex surfaces or UV coordinates.

To keep this example simple, we'll show how to create a straightforward Dynamo line below. First we'll create to Dynamo points, then use these as the start and end points defining our line.

#Boilerplate Code
dynamo_point_1 = Autodesk.DesignScript.Geometry.Point.ByCoordinates(0,0,0)
dynamo_point_2 = Autodesk.DesignScript.Geometry.Point.ByCoordinates(10,10,0)
dynamo_line = Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint(dynamo_point_1, dynamo_point_2)
OUT = dynamo_line

Again, once output from the Python Script node this dynamo_line is immediately visible in the 3D background preview.

Now let's look at creating a Revit line:

#Boilerplate Code
revit_xyz_1 = XYZ(0,0,0)
revit_xyz_2 = XYZ(10,10,0)
revit_line = Line.CreateBound(revit_xyz_1, revit_xyz_2)
OUT = revit_line

Again, this won't be visible in the Dynamo geometry preview unless we convert it to a Dynamo geometry type, using .ToProtoType(), like so:

#Boilerplate Code
revit_xyz_1 = XYZ(0,0,0)
revit_xyz_2 = XYZ(10,10,0)
revit_line = Line.CreateBound(revit_xyz_1, revit_xyz_2)
OUT = revit_line.ToProtoType()