Python: Plane.ByOriginNormal

I’m trying to create a Plane.ByOriginNormal inside a python script.

Somehow it keeps saying “expected point, got XYZ”.

Even though I tried numerous things to convert XYZ to point.

Can you give an example of how it can be done?


import clr
from Autodesk.DesignScript.Geometry import *

# Import RevitAPI
import Autodesk

import Revit

# Import DocumentManager and TransactionManager
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Import geometry conversion extension methods

# Import Element wrapper extension methods

doc = IN[0]

if IN[0] != None:

origin = doc.ActiveView.Origin
xyz = Autodesk.Revit.DB.XYZ(origin[0], origin[1], origin[2])
xyz_point = xyz.ToPoint()
normal = doc.ActiveView.ViewDirection

plane = Plane.ByOriginNormal(normal, xyz_point)

OUT = [xyz_point,normal]

You are mixing and matching RevitAPI objects and methods with ProtoGeometry objects and methods - the warning is letting you know that too.

Stick to one or the other and check your data types before calling a method.

You might also experience a namespace clash once you do fix your code (most likely between Point class objects from the aforementioned libraries) in which case you should either use aliases or stick to just one library if you can, and perform conversion when you output.

Thanks for your reply.

You are mixing and matching RevitAPI objects and methods with ProtoGeometry objects and methods - the warning is letting you know that too.

How can I see that from the warning?

check your data types before calling a method.

Can you tell me what’s a good way to check if an objects datatype is of the Revit API type or of ProtoGeometry type? I sometimes try this: OUT = type(someElement). But then I get something like IronPython.RunTime.Types.PythonType, which is not very clear to me…

Stick to one or the other

I will. I intuitively prefer working with the RevitAPI above ProtoGeometry. I feel like it gives me more freedom. Doesnt come without its challenges though.

thanks again. Hope you can help me further.

Allright I got it.

if IN[0] != None:

	origin = doc.ActiveView.Origin
	#xyz = Autodesk.Revit.DB.XYZ(origin[0], origin[1], origin[2])
	#xyz_point = xyz.ToPoint()
	normal = doc.ActiveView.ViewDirection
	#point = Autodesk.Revit.DB.Point.Create(origin).ToProtoType()
	#plane = Plane.ByOriginNormal(normal, point)
	plane = Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(normal,origin)

	OUT = plane

Seems like I have to be more careful in regards to which method I’m browsing to. It may help me to define the path specifically through Autodesk.Revit.DB… so that I am sure that the method comes from Revit API and not from Dynamo or something.

Still interested though in the answers to the stated questions:

-How can i see that i am mixing Revit API and ProtoGeometry from the warning that I got?

-Whats a good way to check between Revit API / ProtoGeometry datatypes?


1 Like

Diligence ultimately - know which class and which method you are calling, from which library, and look it up in the API documentation to ensure your inputs are valid. When you’re on top of that, exceptions like the one shown become a lot clearer. Plane.ByOriginNormal() (from the ProtoGeometry library) for example, takes a ProtoGeometry Point and Vector. Therefore, passing a Revit API point (XYZ) as an input will throw an exception since its the wrong data type from the wrong library, which should inform you that you need to either convert it to a Proto Point, or instantiate a Proto Point to satisfy the input type.

The runtime issue is typically caused by a syntax error, where you call a method without including the parenthesis; essentially calling a method like a property, which prevents the Python compiler from locating the member of the type.


Thanks for your explanation, Thomas.