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) 
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 ,
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 
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