1- The constructor is lacks options. The user can only construct a PointCloud object with point information - no normal, no color, no value.
2- The AddRange function lacks options. The user cannot add only points and extra values - or can the user use the System.Void AddRange(IEnumerable points, IEnumerable normals, IEnumerable colors, IEnumerable values) function, giving null to the other enumerables? If that is the case, then just one AddRange function with better description would suffice.
For the basic cases, yes. But the issue is that you need really speed when you are dealing with point clouds.
I didn’t test it, but I have reasons to believe that it wouldn’t be applicable for large clouds because:
1- Likely the construction of a https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.pointclouditem would be an important overhead.
2- Likely it allocates memory at the internal arrays for normals, colors and values when perhaps the user doesn’t need.
3- It would, I suppose, make a marshalled round-trip for each and every point and subvalue change.
I had to write this code which is much, much faster. But note that then one case is missing at the end - the one where the cloud only has points and values.
public static PointCloud RemoveIndices_Fast(this PointCloud pc, int[] indices)
{
if (indices == null || indices.Length == 0) return pc;
Point3d[] originalPoints = pc.GetPoints();
Point3d[] subPoints = new Point3d[pc.Count - indices.Length];
{
int dest_i = 0;
int ignore_i = 0;
for (int orig_i = 0; orig_i < originalPoints.Length;)
{
if (orig_i == indices[ignore_i]) // This index must be ignored
{
ignore_i++;
}
else
{
subPoints[dest_i] = originalPoints[orig_i];
dest_i++;
}
orig_i++;
}
}
Vector3d[] subNormals = null;
if (pc.ContainsNormals) // Has normals
{
Vector3d[] original = pc.GetNormals();
subNormals = new Vector3d[pc.Count - indices.Length];
int dest_i = 0;
int ignore_i = 0;
for (int orig_i = 0; orig_i < originalPoints.Length;)
{
if (orig_i == indices[ignore_i]) // This index must be ignored
{
ignore_i++;
}
else
{
subNormals[dest_i] = original[orig_i];
dest_i++;
}
orig_i++;
}
}
Color[] subColors = null;
if (pc.ContainsColors) // Has colours
{
Color[] original = pc.GetColors();
subColors = new Color[pc.Count - indices.Length];
int dest_i = 0;
int ignore_i = 0;
for (int orig_i = 0; orig_i < originalPoints.Length;)
{
if (orig_i == indices[ignore_i]) // This index must be ignored
{
ignore_i++;
}
else
{
subColors[dest_i] = original[orig_i];
dest_i++;
}
orig_i++;
}
}
double[] subValues = null;
if (pc.ContainsPointValues) // Has values
{
double[] original = pc.GetPointValues();
subValues = new double[pc.Count - indices.Length];
int dest_i = 0;
int ignore_i = 0;
for (int orig_i = 0; orig_i < originalPoints.Length;)
{
if (orig_i == indices[ignore_i]) // This index must be ignored
{
ignore_i++;
}
else
{
subValues[dest_i] = original[orig_i];
dest_i++;
}
orig_i++;
}
}
PointCloud subPc = new PointCloud();
// Try only one call with nulls. TRIED - didn't work.
if (subNormals == null && subColors == null && subValues == null) subPc.AddRange(subPoints);
else if (subNormals != null && subColors == null && subValues == null) subPc.AddRange(subPoints, subNormals);
else if (subNormals == null && subColors != null && subValues == null) subPc.AddRange(subPoints, subColors);
else if (subNormals != null && subColors != null && subValues == null) subPc.AddRange(subPoints, subNormals, subColors);
else if (subNormals != null && subColors != null && subValues != null) subPc.AddRange(subPoints, subNormals, subColors, subValues);
return subPc;
}
Of course, perhaps I am saying bullocks here because I don’t have access to your code to know exactly how things are done.