How To ... Generate Hash Checksums Using DotNet

How To > Use DotNet > Generate Hash Checksums

The following tutorials demonstrates the use of the .GetHashCode() method exposed by the "System.String " dotNetObject for determining whether specific data collected in the form of a string has changed between two runs of the script.

Related topics:

DotNet In MAXScript

dotNetObject

NATURAL LANGUAGE

Define a MAXScript function to calculate the Hash code of all scene objects.

Collect the name, transformation matrix and parent of every object in a string.

Get the HashCode of the string and return it.

EXAMPLE

fn getHashCodeFromGeometry = (
  local hashStr = stringstream ""
  for obj in objects do (
    print obj.name to:hashStr
    print obj.transform to:hashStr
    if obj.parent != undefined then print obj.parent.name to:hashStr
  )--end for loop
  (dotNetObject "System.String" hashStr).GetHashCode()
)--end function 

Step-By-Step

fn getHashCodeFromGeometry = (

Define a MAXScript function to be called by the Timer.

local hashStr = stringstream ""

Create an empty string stream to collect the data to convert to Hash Code.

for obj in objects do (

Loop through all scene objects...

print obj.name to:hashStr print obj.transform to:hashStr

And print the name and transform of the current object to the stream.

if obj.parent != undefined then print obj.parent.name to:hashStr

If the object has a parent, also print the parent's name to the stream.

)
(dotNetObject "System.String" hashStr).GetHashCode()

Finally, create an instance of the System.String class from the collected string stream and get its Hash Code.

)--end function

Practical Use

Let's see how this function could be useful in a real-world situation.

Let's assume we are developing a script which has to perform complex time consuming calculations when the scene content has changed. For example, it would have to rebuild all its data when

It would be useful to cache the last results and return the same value next time the script is executed if the scene has not changed since the previous run. If checking the scene for changes is significantly faster than actually processing the data again, this would lead to a nice speed up.

One possible approach would be to store all this scene state data in some user variables - assign the objects.count value to a variable, collect the names, transformation matrices and parent names of all objects into arrays the first time the script is run and then, the next time the script has to determine whether it needs to recalculate its initial data, it could collect the same information once again and compare all values with the results from the previous run.

Obviously, if the scene contains 10,000+ objects, the amount of data to store (and the time needed to collect and compare the two data sets) would be quite substantial.

But since we are not interested in the actual data values but only want to know whether they have changed between runs, we can use the HashCode value which represents ALL the above conditions with a single long integer value. All we have to do is run the function once to get a HashCode number reflecting the count, names, transforms and parents of all scene objects, then if we want to know if any of these properties have changed since the last time we run our script, we can call the function again and compare the two values. If the numbers are the same, the scene has not changed. In that case we can skip any data rebuilding steps since we can be confident the scene is in the same state as before. If the hash values are different, we must reprocess the scene to collect the actual data.

Of course, the above function is just one example of possible HashCode usage. It can be changed to reflect more or less properties of objects, or could be used to track the state of other values that can be represented as strings.

See Also