Skip to content

Commit

Permalink
Diffing_Engine: Hash and Diff to leverage new GeometryHash (#3268)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fraser Greenroyd authored Feb 1, 2024
2 parents b93e562 + e360db1 commit c74b262
Show file tree
Hide file tree
Showing 3 changed files with 448 additions and 105 deletions.
24 changes: 14 additions & 10 deletions BHoM_Engine/Query/Hash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ private static string HashString(object obj, BaseComparisonConfig cc, int nestin
if (BH.Engine.Base.Compute.TryRunExtensionMethod(obj, "HashString", parameters, out hashStringFromExtensionMethod))
return (string)hashStringFromExtensionMethod;

if (cc.UseGeometryHash && typeof(IGeometry).IsAssignableFrom(type))
{
return GeometryHash((IGeometry)obj, cc, currentPropertyFullName);
}

// If the object is an IObject (= a BHoM class), let's look at its properties.
// We only do this for IObjects (BHoM types) since we cannot guarantee full compatibility of the following procedure with any possible (non-BHoM) type.
PropertyInfo[] properties = type.GetProperties();
Expand Down Expand Up @@ -285,24 +290,23 @@ private static string HashString(object obj, BaseComparisonConfig cc, int nestin

/***************************************************/

private static double GeometryHash(this IGeometry igeom)
private static string GeometryHash(this IGeometry igeom, BaseComparisonConfig comparisonConfig, string fullName)
{
if (igeom == null)
return default(double);
return null;

if (m_GeomHashFunc == null)
{
var mis = Query.ExtensionMethods(typeof(IGeometry), "GeometryHash");
m_GeomHashFunc = (Func<IGeometry, double>)Delegate.CreateDelegate(typeof(Func<IGeometry, double>), mis.First());
if (!mis?.Any() ?? true)
throw new InvalidOperationException("Could not dynamically load the GeometryHash method.");

m_GeomHashFunc = (Func<IGeometry, BaseComparisonConfig, string, string>)Delegate.CreateDelegate(typeof(Func<IGeometry, BaseComparisonConfig, string, string>), mis.First());
}

return m_GeomHashFunc(igeom);
return m_GeomHashFunc(igeom, comparisonConfig, fullName);
}

private static Func<IGeometry, double> m_GeomHashFunc = null;
private static Func<IGeometry, BaseComparisonConfig, string, string> m_GeomHashFunc = null;
}
}




}
34 changes: 28 additions & 6 deletions Geometry_Engine/Query/GeometryHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ public static partial class Query
"\nAdditionally, the resulting points are transformed based on the source geometry type, to remove or minimize collisions." +
"\n(Any transformation so performed is translational only, in order to support geometrical tolerance, i.e. numerical distance, when comparing GeometryHashes downstream).")]
[Input("bhomObj", "Input BHoMObject whose geometry will be queried by IGeometry() and which will be used for computing a Geometry Hash.")]
[Output("geomHash", "Number representing a unique signature of the input object's geometry.")]
public static string GeometryHash(this IBHoMObject bhomObj)
[Output("geomHash", "Value representing a unique signature of the input object's geometry.")]
public static string GeometryHash(this IBHoMObject bhomObj, BaseComparisonConfig comparisonConfig = null)
{
IGeometry igeom = bhomObj.IGeometry();

return GeometryHash(igeom);
return GeometryHash(igeom, comparisonConfig);
}

/***************************************************/
Expand All @@ -66,13 +66,32 @@ public static string GeometryHash(this IBHoMObject bhomObj)
"\nThe number of points is reduced to the minimum essential to determine uniquely any geometry." +
"\nAdditionally, the resulting points are transformed based on the source geometry type, to remove or minimize collisions." +
"\n(Any transformation so performed is translational only, in order to support geometrical tolerance, i.e. numerical distance, when comparing GeometryHashes downstream).")]
[Output("geomHash", "Number representing a unique signature of the input geometry.")]
public static string GeometryHash(this IGeometry igeometry)
[Output("geomHash", "Value representing a unique signature of the input geometry.")]
public static string GeometryHash(this IGeometry igeometry, BaseComparisonConfig comparisonConfig = null)
{
return GeometryHash(igeometry, comparisonConfig, null);
}

/***************************************************/

[Description("Returns a signature of the input geometry, useful for diffing." +
"\nThe hash is computed as a serialised array representing the coordinate of significant points taken on the geometry." +
"\nThe number of points is reduced to the minimum essential to determine uniquely any geometry." +
"\nAdditionally, the resulting points are transformed based on the source geometry type, to remove or minimize collisions." +
"\n(Any transformation so performed is translational only, in order to support geometrical tolerance, i.e. numerical distance, when comparing GeometryHashes downstream).")]
[Input("igeometry", "Geometry you want to compute the hash for.")]
[Input("comparisonConfig", "Configurations on how the hash is computed, with options for numerical approximation, type exceptions and many others.")]
[Input("fullName", "Name of the property that holds the target object to calculate the hash for. This name will be used to seek any matching custom configuration to apply against the `comparisonConfig` input.")]
[Output("geomHash", "Value representing a unique signature of the input geometry.")]
public static string GeometryHash(this IGeometry igeometry, BaseComparisonConfig comparisonConfig, string fullName)
{
if (igeometry == null)
return null;

double[] hashArray = IHashArray(igeometry);
double[] hashArray = IHashArray(igeometry, comparisonConfig, fullName);
if (hashArray == null)
return null;

byte[] byteArray = GetBytes(hashArray);

if (m_SHA256Algorithm == null)
Expand All @@ -93,6 +112,9 @@ public static string GeometryHash(this IGeometry igeometry)

private static byte[] GetBytes(this double[] values)
{
if (values == null)
return default;

return values.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
}

Expand Down
Loading

0 comments on commit c74b262

Please sign in to comment.