Clearing color from point clouds using RhinoCommon ClearColors in C#

RhinoCommon has a PointCloud class having a method to clear color from a given point cloud which is ClearColors.

The following code using this method runs without causing any error, but don’t effectively remove the color information of the point cloud.

How can this behaviour explained ?

        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            Result rc = Rhino.Input.RhinoGet.GetMultipleObjects(
                            "Select point cloud(s)",
                            false,
                            Rhino.DocObjects.ObjectType.PointSet,
                            out Rhino.DocObjects.ObjRef[] obj_refs
                        );
            if (rc != Result.Success)
                return rc;
            foreach (Rhino.DocObjects.ObjRef o_ref in obj_refs)
            {
                Rhino.Geometry.PointCloud pointCloud = o_ref.PointCloud();
                pointCloud.ClearColors();
            }
            doc.Objects.UnselectAll();
            doc.Views.Redraw();
            return Result.Success;
        }

Hi @AymericBr,

Does this work any better?

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var rc = RhinoGet.GetMultipleObjects("Select point cloud", false, ObjectType.PointSet, out var obj_refs);
  if (rc != Result.Success)
    return rc;

  foreach (var obj_ref in obj_refs)
  {
    var old_pointcloud = obj_ref.PointCloud();
    if (null != old_pointcloud)
    {
      var new_pointcloud = new PointCloud(old_pointcloud);
      new_pointcloud.ClearColors();
      doc.Objects.Replace(obj_ref, new_pointcloud);
    }
  }
  doc.Views.Redraw();

  return Result.Success;
}

– Dale

Hi @dale,

Thank you for your reply.

Unfortunately, the point clouds still seem to have their color information after using the doc.Objects.Replace approach you suggested.

Sigh, yes, I can see that. I’ve logged the issue.

https://mcneel.myjetbrains.com/youtrack/issue/RH-64645

– Dale

Hey @dale I’m sorry that I have to dig this up but there still seems to be a lot wrong with PointCloud.ClearNormals(), PointCloud.ClearColors() and the setter for PointCloudItem.PointValue as well. I have adapted your test script from youtrack and it gives me the following results:

import Rhino
import scriptcontext as sc
from random import random as rnd

def test_clear_pointcloud_colors():
    filter = Rhino.DocObjects.ObjectType.PointSet
    rc, objref = Rhino.Input.RhinoGet.GetOneObject("Select pointcloud", False, filter)
    if not objref or rc != Rhino.Commands.Result.Success:
        return
    
    old_pointcloud = objref.PointCloud()
    if not old_pointcloud or not old_pointcloud.ContainsColors:
        return
        
    new_pointcloud = Rhino.Geometry.PointCloud(old_pointcloud)
    new_pointcloud.ClearColors()
    

    for i, p in enumerate(new_pointcloud):
        # this will not work
        p.PointValue = rnd()
        # this will work, but it will be impossible to get rid of the normals
        # without completely rebuilding the cloud
        p.Normal = Rhino.Geometry.Vector3d.Unset
    
    # this will print True
    print new_pointcloud.ContainsNormals
    
    # this will print True, regardless of ClearColors!
    print new_pointcloud.ContainsColors
    
    # attempt to clear the normals
    new_pointcloud.ClearNormals()
    
    # this will still print True, regardless of ClearNormals!
    print new_pointcloud.ContainsNormals
    
    # this will print False but should print True!
    print new_pointcloud.ContainsPointValues
    
    # this will now print False, since ClearNormals actually clears the colors!
    print new_pointcloud.ContainsColors
    
    sc.doc.Objects.Replace(objref, new_pointcloud)
    sc.doc.Views.Redraw()

if __name__ == "__main__":

I am also attaching your demo/test file to reproduce the errors:
colorful_pointcloud.3dm (43.5 KB)

This is under Rhino Version 7 SR8 (7.8.21196.5001, 2021-07-15)

A fix would be greatly appreciated since this really gets in the way when working with PointClouds :confused:

Hi @efestwin,

With a slightly modified version of your script, to make it clear what’s being printed, here is the results I get:

Has normals = True
Has colors = False
Has normals = False
Has values = False
Has colors = False

test.py (1.7 KB)

1.) The fix for https://mcneel.myjetbrains.com/youtrack/issue/RH-64645 is available in the Rhino 7.9 release candidate. You mentioned you are using 7.8.

2.) Unless the number of point cloud values equals the number of point cloud points, PointCloud.ContainsPointValues will return false.

3.) The PointCloudItem, returned by PointCloud.Item, is not connected to the point cloud. So setting values on a PointCloudItem class object doesn’t modify the point cloud itself.

Hope this helps.

– Dale

Thank you for the clarification! :slight_smile: Although, I’m not sure I completely understand this…

Are you saying that in the script calling p.PointValue = rnd() will have no effect on the PointCloud at all? The way I understand it, calling p.Normal = Rhino.Geometry.Vector.Unset actually modified the normals of the PointCloud, doesn’t it?

If p.PointValue = rnd() doesn’t work, is there any way to set the value attached to a point outside of Add or AddRange etc.?

Hope you don’t mind my persistent asking, I just really want to understand the whole picture :smiley:

Hi @efestwin,

I recall fixing more than just the colors issue reported above.

Get the SR9 release candidate and see if your script works.

– Dale

Ah I see what’s going on. I’ll push a fix into next week’s SR7.9 that will fix this.

https://mcneel.myjetbrains.com/youtrack/issue/RH-65217

Thanks for finding.

– Dale

Thank you so much for taking care! Looking forward to SR7.9 and getting rid of a lot of workaround code :smiley:

RH-65217 is fixed in Rhino 7 Service Release 9

1 Like