OK, so i’m trying to find the fastest way to calculate Face Normals and Face Center in my own C# code, but so far I’m not impressed by my achievements.
Edit: Ops. forgot the gh definition: TriNormalAndCenter.gh (17.4 KB)
Fig 1. Processing triangle legs “A” and “B” some 210.000 times:
The picture above is manually drawn, and the processing time is all internal, and the resulting normals and center points were output into two arrays (N and C)
The essential code I’ve tried.
// =======
// NORMALS (CROSS PRODUCT)
// =======
// Right hand rule of lines a\/b
m_normals[i] = Vector3d.CrossProduct(line_b.Direction, line_a.Direction);
m_normals[i].Unitize();
// =======
// CENTER
// =======
var mida = line_a.PointAt(0.5);
var midb = line_b.PointAt(0.5);
// Criss-cross lines for intersection point at triangle center
var mida_c = (new Line(mida, line_b.To));
var midb_b = (new Line(midb, line_a.To));
// Line-Line Intersect
var _a = double.MinValue;
var _b = double.MinValue;
if (!Rhino.Geometry.Intersect.Intersection.LineLine(mida_c, midb_b, out _a, out _b))
return false;
m_centers[i] = mida_c.PointAt(_a);
(Far below some “manual” equivalents to Rhino’s Vector3d.CrossProduct
and Line.PointAt(t)
but that didn’t make much of a difference either).
The parallel loop was partitioned so as to not cause extra overhead for multiple small operations
if (parallel)
{
var partitioner = System.Collections.Concurrent.Partitioner.Create(0, count);
System.Threading.Tasks.Parallel.ForEach(partitioner, (range, loopState) =>
{
// Loop over each range element
for (int j = range.Item1; j < range.Item2; j++)
{
NormalAndCenterFromLines(j, line_a, line_b);
}
});
}
Placing the code meat inline in the loop didn’t make much of a difference. Also, since there are only three inputs and the loop just repeats itself, it shouldn’t matter much that this was tested in a C# ScriptComponent instead of VS component. Is it the Line-Line intersetion test which consumes all this processing time?
Anyway, the final solution is meant to traverse Mesh edges and do the same (Rhino Mesh of course has methods for all this, but I need to do some tweaks and also make my own classes or structs for some of my mesh manipulations).
Anyone?
// Rolf
Addendum: “Manual” equivalents to Rhino’s Vector3d.CrossProduct
and Line.PointAt(t)
// =======
// NORMALS (CROSS PRODUCT)
// =======
// Right hand rule for lines a\/b
var a = line_b.Direction;
var b = line_a.Direction;
m_normals[i].X = (a.Y * b.Z) - (a.Z * b.Y);
m_normals[i].Y = (a.Z * b.X) - (a.X * b.Z);
m_normals[i].Z = (a.X * b.Y) - (a.Y * b.X);
m_normals[i].Unitize();
and Line.PointAt(t)
// "point on line" in Vector form
// (x,y,z) = (x0,y0,z0) + t(a,b,c)
var mid_a = line_a.From + 0.5 * line_a.Direction;
var mid_b = line_b.From + 0.5 * line_b.Direction;