PointCloud commit changes (or replace) causes RAM usage creep?

I am building large-ish point clouds and updating the document periodically to show progress. I have noticed Rhino using excessive RAM if I use Rhino.DocObjects.RhinoObject.CommitChanges() (also scriptcontext.doc.replace()). The RAM creeps up as the point cloud is updated, and is never recovered after the script completes, or even if everything is deleted from the document.

This script demonstrates the behavior using two different methods to build the point cloud. Run either function and watch RAM. I’m hoping someone can give me a hint on what is going on. If not I’ll try a conduit.

Thanks.

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino as R
import random

def make_sub_pc(count=100):
    sub_pc = R.Geometry.PointCloud()
    for _ in range(count):
        sub_pc.Add(R.Geometry.Point3d(random.random(), random.random(), random.random()))
    return sub_pc
    
def add_by_range(pc, count=100):
    point_collection = R.Collections.Point3dList()
    for _ in range(count):
        point_collection.Add(random.random(), random.random(), random.random())
    pc.AddRange(point_collection)

def test_sub_pc_commitchanges(n=1000):
    pc = R.Geometry.PointCloud()
    pc_guid = None
    pc_robj = None
    for i in range(n):
        if sc.escape_test(False, False):
            break
        R.RhinoApp.Wait()
        sub_pc = make_sub_pc(1000)
        if not pc_robj:
            pc.Merge(sub_pc)
            pc_guid = sc.doc.Objects.AddPointCloud(pc)
            pc_robj = sc.doc.Objects.Find(pc_guid)
            sc.doc.Views.Redraw()
        else:
            pc_robj.Geometry.Merge(sub_pc)  # if use pc.Merge() here then CommitChanges doesn't work.
            print pc_robj.CommitChanges()
            sc.doc.Views.Redraw()
        sub_pc.Dispose()  # doesn't seem to matter
        
def test_addrange_pc_commitchanges(n=1000):
    # this still causes memory creep, so must not be the sub point cloud object hanging around.
    pc = R.Geometry.PointCloud()
    pc_guid = None
    pc_robj = None
    for i in range(n):
        if sc.escape_test(False, False):
            break
        R.RhinoApp.Wait()
        
        if not pc_robj:
            add_by_range(pc, 100)
            pc_guid = sc.doc.Objects.AddPointCloud(pc)
            pc_robj = sc.doc.Objects.Find(pc_guid)
            sc.doc.Views.Redraw()
        else:
            add_by_range(pc_robj.Geometry, 100)
            pc_robj.CommitChanges()
            sc.doc.Views.Redraw()
        

# choose one or the other

#test_sub_pc_commitchanges()

test_addrange_pc_commitchanges()

Did you try clearing Undo’s? (Use the _ClearUndo command).

Clearing out the undos first seems to keep it in check. I don’t want to clear out all undos though so I’ll have to figure out how to get the current undoserialnumber to end only the command’s recording.

Guess I spoke too soon. Even with:

sc.doc.EndUndoRecord(sc.doc.CurrentUndoRecordSerialNumber)
sc.doc.UndoRecordingEnabled = False

It still seems excessive. However the above does seem to prevent the undo as I can’t undo the result of the script now.

Without the undo record, it seems like if I delete the resultant point cloud, Rhino now drops some memory, but Windows is still saying it is in-use…maybe that is by design.

I’m not sure what is going on but it is definitely proportional to use of CommitChanges(). If I don’t update the cloud until the end, much less memory is used.

I’ll try the conduit approach.