Calculation of Steel Design, CPython3

Hi all,

We are currently upgrading our scripts from IronPhyton 2 to CPhyton 3.
Currently I am trying to do the steel calculation design in Robot through dynamo. The first picture shows that the code works, getting results of the Ratio, and Case name.
But, we would like to get also the Eurocode3 results, for example, the BuckStrenNbyrd.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

from System import Environment
user = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

clr.AddReference(user+r"\Dynamo\Dynamo Core\2.11\packages\Structural Analysis for Dynamo\bin\RSA\Interop.RobotOM.dll")

from RobotOM import *
from System import Object

objects = IN[0]

application = RobotApplicationClass()
project = application.Project
structure = project.Structure
labels = structure.Labels
application.Project.ViewMngr.Refresh()
project.CalcEngine.AnalysisParams.IgnoreWarnings = True
calcEngine = project.CalcEngine
calcEngine.AutoGenerateModel = True
calcEngine.UseStatusWindow = True
calcEngine.Calculate()

RDMServer = IRDimServer(application.Kernel.GetExtension("RDimServer"))
RDMServer.Mode = 1
RDmEngine = IRDimCalcEngine(RDMServer.CalculEngine)
RDMCalpar = IRDimCalcParam(RDmEngine.GetCalcParam())
RDMCalCnf = IRDimCalcConf(RDmEngine.GetCalcConf())
RDmStream = IRDimStream(RDMServer.Connection.GetStream())

RDmStream.Clear()
RDmStream.WriteText("all")
RDMCalpar.SetObjsList(IRDimCalcParamVerifType.I_DCPVT_MEMBERS_VERIF, RDmStream)
RDMCalpar.SetLimitState(IRDimCalcParamLimitStateType.I_DCPLST_ULTIMATE,1)
RDmStream.Clear()
RDmStream.WriteText("1to4")

RDMCalpar.SetLoadsList(RDmStream)
RDmEngine.Solve(RDmStream)
RDmAllResObjType = IRDimAllResObjectType
RDmAllRes = IRDimAllRes(RDmEngine.Results())
IRDimAllResObjectType = 1

ObjCnt = RDmAllRes.ObjectsCount
RDmRetValue = IRDimMembCalcRetValue
RDmDetRes = IRDimDetailedRes(RDmAllRes.Get("1"))

Case = RDmDetRes.GovernCaseName
Ratio = RDmDetRes.Ratio
RDmCodeRes = Object
RDmCodeRes = RDmDetRes.CodeResults
Nbyrd = RDmCodeRes.BuckStrenNbyrd
#RDmCodeRes = IRDimCodeResEC3(structure(RDmCodeRes(IRDimDetailedRes.CodeResults.BuckStrenNbyrd("1"))))

OUT = Case, Ratio 





The second figure shows, in the red box, the value that we want to get; Ny, b, Rd, but the following error appears:
“AttributeError : ‘__ComObject’ object has no attribute ‘BuckStrenNbyrd’ [’ File “”, line 54, in \n’]”.

Line 55 shows how I am trying to call the attribute BuckStrenNbyrd, but I get the following error:
“TypeError : instance property must be accessed through a class instance [’ File “”, line 55, in \n’]”

Line 55: RDmCodeRes = IRDimCodeResEC3(structure(RDmCodeRes(IRDimDetailedRes.CodeResults.BuckStrenNbyrd("1"))))

Could someone help me to check what is missing in the code? To get through the comObject and Class instance.

Thank you in advance.

@gwizdzm @Jonathan.Olesen I have seen your names in similar topics.

Best regards,
Stefany
Calc steel design 0_06_RSA_forum.dyn (17.9 KB)

Hi all,

I’m stil curious about the solution for this one. maybe @solamour @ina @sanzoghenzo or other know how to get this one?

Thanks in advance
Gr Edward

For starters, I discorage you to switch to cpython in RSA dynamo, as I stated on my quickstart guide and other posts in here.
But if you insist on switching, here are my impressions:

For the comObject error, you can use the ComObj class I reported here;

Your second attempt, as well as most of your code, smells like c# code poorly translated into python.

Usually words that starts with I are interfaces (think of them as an API documentation), not conctete classes; we don’t do that here (in python) :wink:
The error you see is because you’re trying to get the CodeResults from the IRDimDetailedRes interface instead of RdmCodeRes.

I suppose that lines like

RDmAllRes = IRDimAllRes(RDmEngine.Results())

work because they perform a cast of the object, but I think it’s unnecessary and can be rewritten as
(Also I would use camelCase, with lowercase first letter, or better yet snake_case for variables names as opposed to PascalCase for classes names)

all_results = RDmEngine.Results()

You also don’t need to “declare” the variables with their type/interface, lines like

RDmCodeRes = Object

Are totally useless.

This is my completely untested take at fixing and cleaning the code:

import clr
clr.AddReference(
    r"C:\Program Files\Autodesk\Robot Structural Analysis Professional 2023\Exe\Interop.RobotOM.dll"
)
from RobotOM import RobotApplicationClass, IRDimCalcParamVerifType, IRDimCalcParamLimitStateType
clr.AddReference("System.Reflection")
from System.Reflection import BindingFlags


class ComObj:
    def __init__(self, obj):
        self.obj = obj
        self.typ = obj.GetType()

    def __getattr__(self, name):       
        def newm(*args):
            args = args or (None,)
            return self.typ.InvokeMember(
                name, 
                BindingFlags.InvokeMethod | BindingFlags.GetProperty, 
                None,
                self.obj,
                *args,
            )
        return newm


objects = IN[0]

application = RobotApplicationClass()
project = application.Project
project.ViewMngr.Refresh()
calc_engine = project.CalcEngine
calc_engine.AnalysisParams.IgnoreWarnings = True
calc_engine.AutoGenerateModel = True
calc_engine.UseStatusWindow = True
calc_engine.Calculate()

rdm_server = application.Kernel.GetExtension("RDimServer")
rdm_server.Mode = 1
rdm_calc_engine = rdm_server.CalculEngine
calc_param = rdm_calc_engine.GetCalcParam()
calc_conf = rdm_calc_engine.GetCalcConf()
stream = rdm_server.Connection.GetStream()

stream.Clear()
stream.WriteText("all")
calc_param.SetObjsList(IRDimCalcParamVerifType.I_DCPVT_MEMBERS_VERIF, stream)
calc_param.SetLimitState(IRDimCalcParamLimitStateType.I_DCPLST_ULTIMATE,1)
stream.Clear()
stream.WriteText("1to4")

calc_param.SetLoadsList(stream)
rdm_calc_engine.Solve(stream)
all_results = rdm_calc_engine.Results()

detailed_results = all_results.Get("1")
case = detailed_results.GovernCaseName
ratio = detailed_results.Ratio
code_results = ComObj(detailed_results.CodeResults)
Nbyrd = code_results.BuckStrenNbyrd

OUT = case, ratio 

Hi @sanzoghenzo,
Thank you for your updated script.
I did apply it and I get now the answers of the functions, instead of values, see picture below.

This is the code now:

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

from System import Environment
user = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

clr.AddReference(user+r"\Dynamo\Dynamo Core\2.11\packages\Structural Analysis for Dynamo\bin\RSA\Interop.RobotOM.dll")

from RobotOM import *
from System import Object

class ComObj:
    def __init__(self, obj):
        self.obj = obj
        self.typ = obj.GetType()

    def __getattr__(self, name):       
        def newm(*args):
            args = args or (None,)
            return self.typ.InvokeMember(
                name, 
                BindingFlags.InvokeMethod | BindingFlags.GetProperty, 
                None,
                self.obj,
                *args,
            )
        return newm


objects = IN[0]

application = RobotApplicationClass()
project = application.Project
project.ViewMngr.Refresh()
calc_engine = project.CalcEngine
calc_engine.AnalysisParams.IgnoreWarnings = True
calc_engine.AutoGenerateModel = True
calc_engine.UseStatusWindow = True
calc_engine.Calculate()

rdm_server = IRDimServer(application.Kernel.GetExtension("RDimServer"))
rdm_server.Mode = 1
rdm_calc_engine = IRDimCalcEngine(rdm_server.CalculEngine)
calc_param = IRDimCalcParam(rdm_calc_engine.GetCalcParam())
calc_conf = IRDimCalcConf(rdm_calc_engine.GetCalcConf())
stream = IRDimStream(rdm_server.Connection.GetStream())

stream.Clear()
stream.WriteText("all")
calc_param.SetObjsList(IRDimCalcParamVerifType.I_DCPVT_MEMBERS_VERIF, stream)
calc_param.SetLimitState(IRDimCalcParamLimitStateType.I_DCPLST_ULTIMATE,1)
stream.Clear()
stream.WriteText("1to4")

calc_param.SetLoadsList(stream)
rdm_calc_engine.Solve(stream)
all_results = IRDimAllRes(rdm_calc_engine.Results())

detailed_results = IRDimDetailedRes(all_results.Get("1"))
case = detailed_results.GovernCaseName
ratio = detailed_results.Ratio

code_results = ComObj(detailed_results.CodeResults)
Nbyrd = code_results.BuckStrenNbyrd

OUT = case, ratio, code_results, Nbyrd

Could you help me to review the code? Because I want to get the values.

Thank you in advance.

Best regards,
Stefany Salguero

Hi @stefanyC6JZ7 ,

  • code_results is correctly returning the ComObj class that wraps the actual class with the results, not sure what you want to get from it;
  • I forgot that the ComObj class turns all the members of the wrapped class as methods, so to get the value of a field/property you have to call it with parenthesis:
    Nbyrd = code_results.BuckStrenNbyrd()
    

This is why I still discourage people (especially python beginners) from migrating to CPython3: handling all these subtleties is a PITA.

Hi @sanzoghenzo,
Thank you for your reply.
I changed the code, but it has an error: " name ‘BindingFlags’ is not defined [’ File “”, line 65, in \n’, ’ File “”, line 23, in newm\n’]", see figure below.

Could you help me to check what is wrong with the code? Because I would like to get the value of Nbyrd, the same way I get the value of the ratio.

Thank you in advance.

Best regards,
Stefany

Hi Stefany,
the error occurs because you didn’t imported BindingFlags from System.Reflection as illustrated in my example.
I don’t know why, but you copied everything except the import part :wink:

In my version I also got rid of the useless ProtoGeometry import and switched to the Interop.RobotOM.dll that you can find in RSA installation directory, instead of fiddling with users directories.

Hi @sanzoghenzo,
Thank you very much for your help. I am sorry that I did not copy correctly, and miss the important part. Now the script is working perfectly!

Best regards,
Stefany Salguero

Hi @sanzoghenzo,
To finish the discussion I wanted to share the last script, that is working perfectly.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

from System import Environment
user = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

clr.AddReference(user+r"\Dynamo\Dynamo Core\2.11\packages\Structural Analysis for Dynamo\bin\RSA\Interop.RobotOM.dll")


from RobotOM import RobotApplicationClass, IRDimCalcParamVerifType, IRDimCalcParamLimitStateType
clr.AddReference("System.Reflection")
from System.Reflection import BindingFlags
from RobotOM import *
from System import Object

class ComObj:
    def __init__(self, obj):
        self.obj = obj
        self.typ = obj.GetType()

    def __getattr__(self, name):       
        def newm(*args):
            args = args or (None,)
            return self.typ.InvokeMember(
                name, 
                BindingFlags.InvokeMethod | BindingFlags.GetProperty, 
                None,
                self.obj,
                *args,
            )
        return newm


objects = IN[0]

application = RobotApplicationClass()
project = application.Project
project.ViewMngr.Refresh()
calc_engine = project.CalcEngine
calc_engine.AnalysisParams.IgnoreWarnings = True
calc_engine.AutoGenerateModel = True
calc_engine.UseStatusWindow = True
calc_engine.Calculate()

rdm_server = IRDimServer(application.Kernel.GetExtension("RDimServer"))
rdm_server.Mode = 1
rdm_calc_engine = IRDimCalcEngine(rdm_server.CalculEngine)
calc_param = IRDimCalcParam(rdm_calc_engine.GetCalcParam())
calc_conf = rdm_calc_engine.GetCalcConf()
stream = IRDimStream(rdm_server.Connection.GetStream())

stream.Clear()
stream.WriteText("all")
calc_param.SetObjsList(IRDimCalcParamVerifType.I_DCPVT_MEMBERS_VERIF, stream)
calc_param.SetLimitState(IRDimCalcParamLimitStateType.I_DCPLST_ULTIMATE,1)
stream.Clear()
stream.WriteText("1to4")

calc_param.SetLoadsList(stream)
rdm_calc_engine.Solve(stream)
all_results = IRDimAllRes(rdm_calc_engine.Results())

detailed_results = IRDimDetailedRes(all_results.Get("1"))
case = detailed_results.GovernCaseName
ratio = detailed_results.Ratio
code_results = ComObj(detailed_results.CodeResults)
Nbyrd = code_results.BuckStrenNbyrd()
Myelrd = code_results.ElastMomStrenMelyrd()
OUT = case, ratio, Nbyrd, Myelrd```
Best regards, 
Stefany
1 Like