Hello @indexofrefraction,

as a disclaimer upfront, this is a private posting of mine, your case is still being handled by @m_adam.

When I see your case correctly, you are interested in the point *p* and its normal *n* on a polygonal mesh *M* that is closest to a given point *q* on a spline *S*. Or in short, you are interested in the projection of *q* onto *M*. Ray-casting, e.g., `GeRayCollider`

, will not help you much here I would say, since coming up with a ray-casting direction is the same problem as the one you are trying to solve; as you already did find out yourself.

Cinema 4D's Python SDK has no projection helper class, so, you would have to do that on your own. The general procedure would be:

- Find the the vertex
*v* in *M* that is closest to *q*.
- Get the list
*L* of all polygons that are attached to *v* - you can use `c4d.utils.Neighbor`

for that.
- Project
*q* onto all polygons in *L* and store the results in *R*. Principally, what one has to do here is point-plane projections. The concrete procedure is something like the following for a single polygon *P*.

a. Compute the point-plane projection *proj* of *q* for each triangle *T* in *P*.

b. Convert *proj* from Cartesian into Barycentric coordinates and clamp the point to the interval [0, 1]. We have to do this since there is no guarantee that the point we projected onto the plane of *T* actually does lie within *T*. So, we ware using Barycentric coordinates to rectify this.

c. Convert the clamped points back into Cartesian coordinates and then select the one closest to *q*. This point is the clamped projection of *q* onto *P*.
- Select the point in
*R* that is closest to *q*, that point is *p*, the projection of your query point *q* onto *M*.
- Define the normal of
*p* as one of the normals of the polygon *P* the point *p* is associated with. That polygon is already known to us due to the prior computations. How to compute the normal exactly depends on what you would consider to be the *object* normal.

For all that you do not need any fancy classes or libraries, but it can be a bit slow if you do this for very large meshes. The expensive part is the first step, finding the closest vertex *v* in *M*. Which is probably why Maxime mentioned kd-trees. They are a form Binary-Space-Partitioning, i.e., a performant way to find the closest point *p* out of a point cloud *C* for a query point *q*. Since the Cinema Python SDK has no kd-Tree, you would have to write your own BSP implementation, a octree would be enough in this case (which is effectively just a clever form of a 3D-lattice). But this is not really needed functionality-wise, it will just make your solution more performant.

Cheers,

Ferdinand