Hi @SirLegend7,
Writing interoperability code can be very complicated. I highly suggest Googling “P/Invoke” and reading up on the topic, as there is a lot to learn.
Since you are starting with the Moose solution, I can help with this.
On the C++ side, start with a robust function like this:
MOOSECORELIB_C_FUNCTION
bool ON_MeshTree_IntersectLine(
const ON_Mesh* pMesh,
const ON_Line* pLine,
ON_3dPointArray* pPoints
)
{
bool rc = false;
if (pMesh && pLine && pPoints)
{
const int points_count = pPoints->Count();
const ON_MeshTree* pMeshTree = pMesh->MeshTree(true);
if (pMeshTree)
{
ON_SimpleArray<ON_CMX_EVENT> cmx_events;
const int cmx_count = pMeshTree->IntersectLine(*pLine, cmx_events);
for (int i = 0; i < cmx_count; i++)
{
const ON_CMX_EVENT& cmx = cmx_events[i];
if (cmx.m_type == ON_CMX_EVENT::cmx_point)
pPoints->Append(cmx.m_M[0].m_P);
}
}
rc = pPoints->Count() > points_count;
}
return rc;
}
Note, it’s not possible to pass custom classes between C++ and C#. But it is possible to pass class pointers. Many of the RhinoCommon classes just hold onto a pointer to the native Rhino or openNURBS class. So the above example just accepts points are arguments.
On the C# side, you will want to declare the unsafe native method like this:
[DllImport("MooseCoreLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool ON_MeshTree_IntersectLine(IntPtr pMesh, ref Line line, IntPtr pPoints);
An IntPtr
is an integer which is the same size as a pointer. RhinoCommon uses IntPtr
to store a pointer to native Rhino and openNURBS classes.
You can now wrap this unsafe native method for use like this:
public static Point3d[] MeshLineIntersection(Mesh mesh, Line line)
{
if (null == mesh)
throw new ArgumentNullException(nameof(mesh));
if (null == line)
throw new ArgumentNullException(nameof(mesh));
using (var points_array = new Rhino.Runtime.InteropWrappers.SimpleArrayPoint3d())
{
var ptr_points = points_array.NonConstPointer();
var ptr_const_mesh = Rhino.Runtime.Interop.NativeGeometryConstPointer(mesh);
var rc = UnsafeNativeMethods.ON_MeshTree_IntersectLine(ptr_const_mesh, ref line, ptr_points);
if (rc)
return points_array.ToArray();
}
return new Point3d[0];
}
RhinoCommon contains some interop helper classes and methods that are helpful when trying to call into the Rhino C++ SDK.
Finally, you can call the new method like this:
var sphere = new Sphere(Plane.WorldXY, 5.0);
var mesh = Mesh.CreateQuadSphere(sphere, 4);
var line = new Line(new Point3d(-10, 0, 0), new Point3d(10, 0, 0));
var points = MooseCommon.Utility.MeshLineIntersection(mesh, line);
foreach (var pt in points)
doc.Objects.AddPoint(pt);
Hope this gets you started.
– Dale