feat(gh): allow for dataobjects with no geometry in grasshopper (#1287)

* first pass

* missing return

* better warning message

* fix order of operations

* hasGeometries

* fix early exclusion from category
This commit is contained in:
Mucahit Bilal GOKER
2026-02-20 17:55:01 +03:00
committed by GitHub
parent 389204a0d1
commit 94eca4e031
2 changed files with 40 additions and 27 deletions
@@ -104,9 +104,19 @@ public class SpeckleDataObjectPassthrough()
}
List<SpeckleGeometryWrapperGoo> inputGeometry = new();
if (!da.GetDataList(1, inputGeometry) && result == null)
bool hasGeometries = da.GetDataList(1, inputGeometry);
string? inputName = null;
da.GetData(2, ref inputName);
SpecklePropertyGroupGoo? inputProperties = null;
da.GetData(3, ref inputProperties);
bool hasAppId = TryGetApplicationIdInput(da, out string? inputAppId);
if (result == null && !hasGeometries && inputName == null && inputProperties == null && !hasAppId)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Pass in a Speckle DataObject or Geometries");
AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Pass in a DataObject or at least one input.");
return;
}
@@ -119,19 +129,25 @@ public class SpeckleDataObjectPassthrough()
}
}
string? inputName = null;
da.GetData(2, ref inputName);
SpecklePropertyGroupGoo? inputProperties = null;
da.GetData(3, ref inputProperties);
// process geometry
if (result == null)
{
result = new SpeckleDataObjectWrapperGoo().Value;
}
if (inputGeometry.Count > 0)
// process name first (geometry loop must use the final name)
if (inputName != null)
{
result.Name = inputName;
}
// process properties first (geometry loop must use the final properties)
if (inputProperties != null)
{
result.Properties = inputProperties;
}
if (hasGeometries)
{
result.Geometries.Clear();
foreach (var inputGeo in inputGeometry)
@@ -148,21 +164,18 @@ public class SpeckleDataObjectPassthrough()
result.Geometries.Add(mutatingGeo);
}
}
// process name
if (inputName != null)
else if (inputName != null || inputProperties != null)
{
result.Name = inputName;
}
// process properties
if (inputProperties != null)
{
result.Properties = inputProperties;
// keep existing geometries in sync when only name/properties are overridden
foreach (var geo in result.Geometries)
{
geo.Base[Constants.NAME_PROP] = result.Name;
geo.Properties = result.Properties;
}
}
// process application id (only if user provided one)
if (TryGetApplicationIdInput(da, out string? inputAppId))
if (hasAppId)
{
result.ApplicationId = inputAppId;
}
@@ -140,13 +140,7 @@ internal sealed class LocalToGlobalMapHandler
_materialUnpacker
);
// nothing converted - nothing to do
if (converted.Count == 0)
{
return;
}
// handle normal DataObject (has converted geometry)
// handle all DataObjects
if (obj is DataObject normalDataObject)
{
var geometries = ConvertToGeometryWrappers(converted);
@@ -156,6 +150,12 @@ internal sealed class LocalToGlobalMapHandler
return;
}
// nothing converted - nothing to do (for non-DataObjects)
if (converted.Count == 0)
{
return;
}
// handle normal geometry (not DataObject)
SpecklePropertyGroupGoo propertyGroup = new();
if (obj[Constants.PROPERTIES_PROP] is Dictionary<string, object?> props)