CRC Comparison between Different Geometries

Hello, thanks to this forum, I understood that it’s possible to check if an object has been modified by calculating its CRC. However, in the examples I’ve read, it’s always the CRC of a geometry compared to the CRC of the same geometry.

I wanted to know if the CRCs need to be calculated from the same object to be comparable?

For example, could this function trigger an OnChanges event both when the Mesh has been modified and when a new Mesh is assigned?

Mesh _mesh;
uint _crc;
void SetMesh(Mesh newMesh)
{
    var newCRC = newMesh.DataCRC(0);
    if (_crc != newCRC) {
        _crc  = newCRC;
        _mesh = newMesh;
        OnChanges?.Invoke(...);
    }
}

Thank you,
jmv

And can a CRC have a value of 0?
Is it certain that the comparison 0 == mesh.DataCRC(0) will never be equal?

I don’t understand how this pertains to the SetMesh method implementation you share. In this implementation you’re comparing the calculated CRC to the cached CRC. If they differ then you get into the body that triggers OnChanges.

A CRC can have a value of 0 if you start with remainder 0 and there is no data in the mesh.

I assume you mean geometry of the same rhino object at different points in time? There is not much sense in comparing CRCs of geometry from different objects.

Remember that Rhino geometry is always in world coordinates. If you have a plane and duplicate it, move the duplicate to another location then you will get different CRCs for the geometry of these objects simply because they are not exactly in the same location.

Yes, I want the OnChanges function to be called if a mesh is modified or a new mesh is passed.

I based it on the code example from Dale:
https://discourse.mcneel.com/t/did-the-implementation-of-geometryequals-change/154279/2

My final goal is to update the OpenGL buffers for rendering, whether it’s because we’ve assigned a new mesh or because we’ve moved it.

If you give a modified mesh to your SetMesh method the CRC won’t match the cached one, so you would get into the body that triggers OnChanges.

Obviously modifying _mesh outside the SetMesh method will not automatically trigger the OnChanges, unless you write in your update code also a CRC check and based on that you trigger OnChanges.

1 Like

OK, so a CRC can indeed have a value of 0 for empty meshes.

Thank you, Nathan, I’m starting to understand a bit better…
After a few tests, I found that indeed two triangles with their three points at the same coordinates have the same CRC.
If one triangle is moved by +10mm in the X direction, the CRC changes.
If the second triangle is also moved by +10mm in the X direction, both CRCs become identical.
If the triangles are moved by -10mm, the CRCs return to their original value.

So, I’m guessing the CRC for meshes is a kind of hash function based on the vertex positions?


In my code example, I could have added the public and private keywords to public void SetMesh(Mesh newMesh), since this is the only way to modify the private Mesh _mesh; variable, which shouldn’t cause any issues.

If you use 0 as the initial remainder yes.

I never use 0 as the initial remainder, but I guess that is a personal preference

1 Like

As I mentioned earlier geometry in Rhino is in world space.

For meshes the CRC is calculated over the mesh data, which means vertices and I believe also texture coordinates.

Yes, I catch on quickly, but it takes a long explanation! :slight_smile:

I just tested it—changing the UVs doesn’t seem to produce a different CRC.

You are correct, it is computed over vertices, face indices and normals