Skip to content

Commit

Permalink
Dimitrie/cnx 938 did not find a layer in cache (#468)
Browse files Browse the repository at this point in the history
* fix: adds a converter for displayable objects

* fix: ensures correct layer creation for collections with empty names
  • Loading branch information
didimitrie authored Jan 7, 2025
1 parent 3ea5677 commit 724e8fe
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public int GetLayerIndex(Collection[] collectionPath, string baseLayerName)
return existingLayerIndex;
}

throw new SpeckleException("Did not find a layer in the cache.");
throw new SpeckleException($"Did not find a layer in the cache with the name {layerFullName}");
}

/// <summary>
Expand All @@ -99,7 +99,8 @@ private int CreateLayerFromPath(Collection[] collectionPath, string baseLayerNam
Layer? previousLayer = currentDocument.Layers.FindName(currentLayerName);
foreach (Collection collection in collectionPath)
{
currentLayerName += s_pathSeparator + collection.name;
currentLayerName += s_pathSeparator + (string.IsNullOrWhiteSpace(collection.name) ? "unnamed" : collection.name);

currentLayerName = currentLayerName.Replace("{", "").Replace("}", ""); // Rhino specific cleanup for gh (see RemoveInvalidRhinoChars)
if (_hostLayerCache.TryGetValue(currentLayerName, out int value))
{
Expand Down Expand Up @@ -133,6 +134,10 @@ out int mIndex
}

int index = currentDocument.Layers.Add(newLayer);
if (index == -1)
{
throw new SpeckleException($"Could not create layer {currentLayerName}.");
}
_hostLayerCache.Add(currentLayerName, index);
previousLayer = currentDocument.Layers.FindIndex(index); // note we need to get the correct id out, hence why we're double calling this
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;

namespace Speckle.Converters.Rhino.ToHost.TopLevel;

[NameAndRankValue(nameof(DisplayableObject), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class DisplayableObjectConverter
: IToHostTopLevelConverter,
ITypedConverter<DisplayableObject, List<(RG.GeometryBase a, Base b)>>
{
private readonly ITypedConverter<SOG.Point, RG.Point> _pointConverter;
private readonly ITypedConverter<SOG.Line, RG.LineCurve> _lineConverter;
private readonly ITypedConverter<SOG.Polyline, RG.PolylineCurve> _polylineConverter;
private readonly ITypedConverter<SOG.Arc, RG.ArcCurve> _arcConverter;
private readonly ITypedConverter<SOG.Mesh, RG.Mesh> _meshConverter;
private readonly IConverterSettingsStore<RhinoConversionSettings> _settingsStore;

public DisplayableObjectConverter(
ITypedConverter<SOG.Point, RG.Point> pointConverter,
ITypedConverter<SOG.Line, RG.LineCurve> lineConverter,
ITypedConverter<SOG.Polyline, RG.PolylineCurve> polylineConverter,
ITypedConverter<SOG.Arc, RG.ArcCurve> arcConverter,
ITypedConverter<SOG.Mesh, RG.Mesh> meshConverter,
IConverterSettingsStore<RhinoConversionSettings> settingsStore
)
{
_pointConverter = pointConverter;
_lineConverter = lineConverter;
_polylineConverter = polylineConverter;
_arcConverter = arcConverter;
_meshConverter = meshConverter;
_settingsStore = settingsStore;
}

public object Convert(Base target) => Convert((DisplayableObject)target);

public List<(RG.GeometryBase a, Base b)> Convert(DisplayableObject target)
{
var result = new List<RG.GeometryBase>();
foreach (var item in target.displayValue)
{
RG.GeometryBase x = item switch
{
SOG.Line line => _lineConverter.Convert(line),
SOG.Polyline polyline => _polylineConverter.Convert(polyline),
SOG.Arc arc => _arcConverter.Convert(arc),
SOG.Mesh mesh => _meshConverter.Convert(mesh),
SOG.Point point => _pointConverter.Convert(point),
_ => throw new ConversionException($"Found unsupported fallback geometry: {item.GetType()}")
};
x.Transform(GetUnitsTransform(item));
result.Add(x);
}

return result.Zip(target.displayValue, (a, b) => (a, b)).ToList();
}

private RG.Transform GetUnitsTransform(Base speckleObject)
{
/*
* POC: CNX-9270 Looking at a simpler, more performant way of doing unit scaling on `ToNative`
* by fully relying on the transform capabilities of the HostApp, and only transforming top-level stuff.
* This may not hold when adding more complex conversions, but it works for now!
*/
if (speckleObject["units"] is string units)
{
var scaleFactor = Units.GetConversionFactor(units, _settingsStore.Current.SpeckleUnits);
var scale = RG.Transform.Scale(RG.Point3d.Origin, scaleFactor);
return scale;
}

return RG.Transform.Identity;
}
}

0 comments on commit 724e8fe

Please sign in to comment.