Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diffing_Engine: Hash and Diff to leverage new GeometryHash #3268

Merged
merged 19 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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