Python3 - no method matches given arguments

Dear Revit experts,

Is it possible to call Panel.GetRefGridLines method in Dynamo on Python3?

u_v_gridLineId = curtainPanel.GetRefGridLines()

This method worked without issues on Ironpython2, but now on Python3, it raises an error:

No method matches given arguments for GetRefGridLines()

@c.poupin provided a solution for the same error message (but different method):

returned = curtainPanel.GetType().GetMethod('GetRefGridLines')
u_v_gridLineId = returned.Invoke(curtainPanel, None)

But on my Revit 2024, the last line raises an error:

‘Parameter count mismatch’

Does anyone know how to call the curtainPanel.GetRefGridLines() method on Python3?

I would be very grateful for any kind of help.

@george we have put effort into upgrading the CPython3 project to a new engine: PythonNET3 which is currently on the package manager, and will become the base implementation in the future. It seeks to bring much closer parity between IronPython and CPython.

However, it’s gated to versions of Dynamo 3.3 and above.

There is an experimental (Read: Not being actively worked upon or updated) IronPython3 we also put on the Package Manager - if in a version earlier than Dynamo 3.3 you could try it?

1 Like

It is working on Revit 2024.2
However I noted this was not exposed initially for CPython3 or IronPython2 using the dir function of python - then I installed latest version of Revit Lookup here and it appeared after relaunch :person_shrugging:
EDIT I don’t think it requires Revit Lookup, I also changed my filtered element collector - just check is the method is available like this "GetRefGridLines" in dir(panel)

import clr

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager

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

doc = DocumentManager.Instance.CurrentDBDocument

def get_refgrids(panel):
    # Get grids using GetRefGridLine method
    grids = panel.GetRefGridLines(ElementId.InvalidElementId, ElementId.InvalidElementId)
    
    return [doc.GetElement(id) for id in grids if id and id != ElementId.InvalidElementId]

bic = BuiltInCategory.OST_CurtainWallPanels

panels = FilteredElementCollector(doc).OfClass(FamilyInstance).OfCategory(bic).ToElements()

OUT = map(get_refgrids, panels)

3 Likes

Hi @Mike.Buttery
Thank you very much for the solution!

Do you know if it is possible to separate vertical and horizontal grids (U and V grids)?

I need them separated, in order to get the CurtainCell of each curtainPanel:

curtainGrid = curtainPanel.Host.CurtainGrid
curtainCell = curtainGrid.GetCell(u_GridLineId, v_GridLineId)  # how to get u and v grids?

Hi @solamour

Thank you for the help as well!
I will try for now to stick with the default CPython3 engine, used on Revit 2024.
If I can’t solve this issue with it, then I will try the engines you suggested. Nevertheless, thank you the help.

1 Like

Hi,

To use out & ref parameters with PythonNet, there is a special syntax.

See here

Note : for methods that return nothing (void) the syntax differs slightly between PythonNet2.5(Cpython3) and PythonNet3

2 Likes

Hi @c.poupin ,
Thank you very much for the solution!

If I understood the link, in this case, we have PythonNet2.5 second case?

Then I am strugguling to understand, why we have both void and uGridLineId, vGridLineId returned:

void, uGridLineId, vGridLineId = panel.GetRefGridLines(dummy_uGridLineId, dummy_vGridLineId)

this is one of the bugs from PythonNet2.5 that has been fixed in PythonNet3

if you use the CPython3 engine, yes it’s PythonNet2.5 that is used

2 Likes

Thank you very much for the patience @c.poupin and help.

So it is the second case from the link you provided.
Just there is a bug in PythonNET2.5, and it requires void output as well?
Or did I misunderstand you?

just for method that return nothing

If the method returns an object, it is necessary to add it with out/ref parameters.

Another Example with Face.Intersect()

dummy_out = IntersectionResultArray()
result, interResultArr = rvtFace.Intersect(curve, dummy_out)
if result == SetComparisonResult.Overlap:
    clashPoint = interResultArr[0].XYZPoint 

3 Likes

Look at Wall.CurtainGrid property which provides access to the ‘CurtainGrid’ class

Once you have the CurtainGrid object you have access to the GetUGridLineIds() and GetVGridLineIds() methods

If you have individual grid ids check for their membership in the U or V collections with the Contains() method

1 Like

Thank you very much for the help. All of you: @Mike.Buttery @c.poupin , @solamour !

@solamour , so at this point, it is not clear if PythonNET3 will be the default Python engine for Revit 2026?
Or is it too late for Revit 2026, and PythonNET3 may be default engine from 2027 onwards?

Because we are not yet complete, we will retain PythonNET3 as a package for the 2026 versions of host applications like Revit, and for 2027 series it will become the base. This allows flexibility during the change, but also allows us to update it out-of-band with Dynamo updates to ensure we get it right :slight_smile:

3 Likes

Hi @solamour ,
Great. Thank you very much for this useful information!

1 Like