Hi all,
I am trying to follow the ModelCreation.gh
provided in the scripting guide examples to build a Karamba model and solve in a CPython environment.
So far, I’ve succeeded in converting the provided C# example to IronPython as below:
Since IronPython does not support python3.X
and I want to use Karamba in an external CPython environment, I am trying to use the clr
provided by pythonnet and reproduce what we can do with IronPython. To reproduce the error below, you can use any python3.x
distribution from CPython (not in Rhino/GH) and install pythonnet
by running pip install pythonnet
.
A minimal example is attached at the end of this post. All the module importing works, and the construction of Karamba.Geometry.Point3
and Line3
works. However, when it comes to LineToBeam
, which has the following C# function definition:
List<BuilderBeam> LineToBeam(
List<Line3> curves,
List<string> identifiers,
List<CroSec> crosecs,
MessageLogger info,
out List<Point3> outNodes,
// optional params...
)
In IronPython, we can use clr.Reference[Type]()
to construct the variables for out
and it works well (read more about this in IronPython’s doc). But for pythonet
, we do not have such a mechanism. Instead, the pythonnet
documentation and test code here suggests placing a None
or a placeholder dumb object in the out
parameter. However, I get the following error when passing a dumb placeholder object for outNodes
when using pythonnet
:
nodes = List[Point3]()
# this doesnt' work either
# nodes = List[Point3]().GetType().MakeByRefType ()
elems, ns = k3d.Part.LineToBeam(List[Line3]([L0]), List[str](["B1"]), List[CroSec](),
logger, nodes)
Error messages:
System.EntryPointNotFoundException: Unable to find an entry point named 'SWIGRegisterExceptionCallbacks_karamba' in DLL 'karamba'.
at feb.karambaPINVOKE.SWIGExceptionHelper.SWIGRegisterExceptionCallbacks_karamba(ExceptionDelegate applicationDelegate, ExceptionDelegate arithmeticDelegate, ExceptionDelegate divideByZeroDelegate, ExceptionDelegate indexOutOfRangeDelegate, ExceptionDelegate invalidCastDelegate, ExceptionDelegate invalidOperationDelegate, ExceptionDelegate ioDelegate, ExceptionDelegate nullReferenceDelegate, ExceptionDelegate outOfMemoryDelegate, ExceptionDelegate overflowDelegate, ExceptionDelegate systemExceptionDelegate)
at feb.karambaPINVOKE.SWIGExceptionHelper..cctor()
The above exception was the direct cause of the following exception:
System.TypeInitializationException: The type initializer for 'SWIGExceptionHelper' threw an exception.
at feb.karambaPINVOKE.SWIGExceptionHelper..ctor()
at feb.karambaPINVOKE..cctor()
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File ".\model_creation.py", line 59, in <module>
logger, nodes)
System.TypeInitializationException: The type initializer for 'feb.karambaPINVOKE' threw an exception.
at feb.karambaPINVOKE.new_NKDTreeDupli__SWIG_0(Int32 jarg1)
at feb.NKDTreeDupli..ctor(Int32 number_of_points)
at Karamba.Elements.LineToBeam.solve(List`1 in_nodes, List`1 in_curves, Boolean new_nodes, Boolean remove_dup, Double limit_dist, List`1 in_z_oris, List`1 in_ids, List`1 in_colours, List`1 in_crosecs, Boolean in_bending, List`1& out_points, List`1& out_beams, String& info)
at KarambaCommon.Factories.FactoryPart.LineToBeam(List`1 curves, List`1 identifiers, List`1 crosecs, MessageLogger info, List`1& outNodes, Boolean bending, Double limitDist, List`1 zOris, List`1 colors, List`1 points, Boolean newNodes, Boolean removeDup)
Before diving into pythonnet and debug there, is there useful diagnosis information we can deduce from the messages above?
A code snippet of a minimal testing example is attached below. The full python code and GH script can be found here: pythonnet_examples.zip (725.9 KB)
Thank you so much in advance for helping!
Best,
Yijiang
##############################
import clr
import sys
import os
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
BIN_DIR = os.path.join(ROOT_DIR, 'bin')
sys.path.append(BIN_DIR)
clr.AddReference("Karamba")
clr.AddReference("KarambaCommon")
clr.AddReference("System.Collections")
clr.AddReference("System.Runtime")
import Karamba
import feb
from Karamba.Models import Model
from Karamba.Geometry import Point3, Line3, Vector3
from Karamba.CrossSections import CroSec
from Karamba.Supports import Support
from Karamba.Loads import Load
from Karamba.Utilities import MessageLogger, UnitsConversionFactories
import KarambaCommon
import System
from System.Collections.Generic import List
###############################
logger = MessageLogger();
k3d = KarambaCommon.Toolkit();
p0 = Point3(0.0, 0.0, 0.0);
p1 = Point3(0.0, 0.0, 5.0);
L0 = Line3(p0, p1);
# IronPython clr trick to handle C# out parameter
# https://ironpython.net/documentation/dotnet/dotnet.html#id52
# nodes = clr.Reference[List[Point3]]()
# pythonnet
# https://mail.python.org/pipermail/pythondotnet/2010-November/001011.html
nodes = List[Point3]()
# nodes = List[Point3]().GetType().MakeByRefType ()
elems, ns = k3d.Part.LineToBeam(List[Line3]([L0]), List[str](["B1"]), List[CroSec](),
logger, nodes)