pyRevit: CPython (Python 3) equivalent of the IronPython (Python 2) "import clr"

Good day.

In IronPython, the clr module points to the following:

SCRIPT:

import clr
print(dir(clr)

OUTPUT:

[‘AddReference’, ‘AddReferenceByName’, ‘AddReferenceByPartialName’, ‘AddReferenceToFile’, ‘AddReferenceToFileAndPath’, ‘AddReferenceToTypeLibrary’, ‘ArgChecker’, ‘ClearProfilerData’, ‘CompileModules’, ‘CompileSubclassTypes’, ‘Convert’, ‘Deserialize’, ‘Dir’, ‘DirClr’, ‘EnableProfiler’, ‘GetBytes’, ‘GetClrType’, ‘GetCurrentRuntime’, ‘GetDynamicType’, ‘GetProfilerData’, ‘GetPythonType’, ‘GetString’, ‘GetSubclassedTypes’, ‘ImportExtensions’, ‘IsNetStandard’, ‘LoadAssemblyByName’, ‘LoadAssemblyByPartialName’, ‘LoadAssemblyFromFile’, ‘LoadAssemblyFromFileWithPath’, ‘LoadTypeLibrary’, ‘Reference’, ‘References’, ‘ReferencesList’, ‘ReturnChecker’, ‘RuntimeArgChecker’, ‘RuntimeReturnChecker’, ‘Self’, ‘Serialize’, ‘SetCommandDispatcher’, ‘StrongBox’, ‘Use’, ’ name ', ’ package ', ‘accepts’, ‘returns’]

When running this with CPython, it seems to point to a completely different module (I believe pythonnet).

SCRIPT:

#! python3
import clr
print(dir(clr)

OUTPUT:

– too long to post here, but not the same as the first output.

My question is what is the equivalent module or method to obtain the correct clr module?

Sample code that works in IronPython (Python 2) is:

SCRIPT:
from Autodesk.Revit import DB
import clr

start_point = DB.XYZ(float(50),float(0),float(0))
end_point = DB.XYZ(float(50),float(80),float(0))
start_point2 = DB.XYZ(float(0),float(50),float(0))
end_point2 = DB.XYZ(float(80),float(50),float(0))

line = DB.Line.CreateBound(start_point, end_point)
line2 = DB.Line.CreateBound(start_point2, end_point2)

resultArray = clr.ReferenceDB.IntersectionResultArray

result = line.Intersect(line2, resultArray)
print(result)
print(resultArray.IsEmpty)
print(resultArray.Item[0].XYZPoint)

OUT:
Overlap
False
(50.000000000, 50.000000000, 0.000000000)

The same code in CPython (Python 3) (#! python3 first line) returns an error, so if I change the script a bit ( resultArray = DB.IntersectionResultArray() ), I can find that they overlap, but the IsEmpty returns a TRUE and then cannot find the intersection:

SCRIPT:
#! python3

test2

from Autodesk.Revit import DB
import clr

start_point = DB.XYZ(float(50),float(0),float(0))
end_point = DB.XYZ(float(50),float(80),float(0))
start_point2 = DB.XYZ(float(0),float(50),float(0))
end_point2 = DB.XYZ(float(80),float(50),float(0))

line = DB.Line.CreateBound(start_point, end_point)
line2 = DB.Line.CreateBound(start_point2, end_point2)

resultArray = DB.IntersectionResultArray()

result = line.Intersect(line2, resultArray)
print(result)
print(resultArray.IsEmpty)
print(resultArray.Item[0].XYZPoint)

OUT:
(8, <Autodesk.Revit.DB.IntersectionResultArray object at 0x0000024A157A3730>)
True
CPython Traceback:
AttributeError : ‘IntersectionResultArray’ object has no attribute ‘Item’

The 8 in the output above is the Python 3 equivalent of Overlap.

Thank you in advance for any help.

3 Likes

Even if it might be a late response, I found a solution for your specific problem, to obtain the intersection from two curves. However, I unfortunately dont have a solution why clr.Reference[SOMETHING] does not work under CPython in general.

#! python3

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

doc   = __revit__.ActiveUIDocument.Document

# Example Code to retrieve all grid lines in the current project
allGridElems = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Grids).WhereElementIsNotElementType().ToElements()

curve1 = allGridElems[0].Curve
curve2 = allGridElems[30].Curve

results = IntersectionResultArray()
cmt_or_result_tuple = curve1.Intersect(curve2, results)
print(cmt_or_result_tuple) # when both curves overlap the result will be a tuple of (SetComparisonResult.Overlap, IntersectionResultArray), otherwise it will be just the 'SetComparisonResult.Overlap'
if(cmt_or_result_tuple[0] == 8):
    r = cmt_or_result_tuple[1] # when overlap access the result in the tuple (SetComparisonResult.Overlap, IntersectionResultArray)
    intersection_point = r.get_Item(0) # there's an undocumented method named 'get_Item'. I used print(dir(r)) to inspect the element
    print(intersection_point) # in internal revit units 'feet' convert if necessary