Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Speckle.Connectors.Common.Cancellation;
using Speckle.Connectors.DUI.Bindings;
using Speckle.Connectors.DUI.Bridge;
using Speckle.Connectors.DUI.Settings;
using Speckle.Connectors.Rhino.Operations.Receive.Settings;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;

Expand All @@ -12,14 +14,19 @@ public class RhinoReceiveBinding(
ICancellationManager cancellationManager,
IBrowserBridge parent,
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory,
IReceiveOperationManagerFactory receiveOperationManagerFactory
IReceiveOperationManagerFactory receiveOperationManagerFactory,
IToHostSettingsManager toHostSettingsManager
) : IReceiveBinding
{
public string Name => "receiveBinding";
public IBrowserBridge Parent { get; } = parent;

private ReceiveBindingUICommands Commands { get; } = new(parent);

#pragma warning disable CA1024
public List<ICardSetting> GetReceiveSettings() => [new ConvertMeshesToBrepsSetting()];
#pragma warning restore CA1024

public void CancelReceive(string modelCardId) => cancellationManager.CancelOperation(modelCardId);

public async Task Receive(string modelCardId)
Expand All @@ -32,7 +39,13 @@ await manager.Process(
(sp, card) =>
{
sp.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc, true));
.Initialize(
rhinoConversionSettingsFactory.Create(
RhinoDoc.ActiveDoc,
true,
toHostSettingsManager.GetConvertMeshesToBrepsSetting(card)
)
);
},
async (modelName, processor) =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Speckle.Connectors.DUI.Settings;

namespace Speckle.Connectors.Rhino.Operations.Receive.Settings;

public class ConvertMeshesToBrepsSetting(bool value = false) : ICardSetting
{
public const string SETTING_ID = "convertMeshesToBreps";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convertMeshesToPolysurfaces


public string? Id { get; set; } = SETTING_ID;
public string? Title { get; set; } = "Convert solid meshes to Breps";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert meshes to polysurfaces

public string? Type { get; set; } = "boolean";
public object? Value { get; set; } = value;
public List<string>? Enum { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Speckle.Connectors.DUI.Models.Card;
using Speckle.InterfaceGenerator;

namespace Speckle.Connectors.Rhino.Operations.Receive.Settings;

[GenerateAutoInterface]
public class ToHostSettingsManager : IToHostSettingsManager
{
public bool GetConvertMeshesToBrepsSetting(ModelCard modelCard)
{
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == ConvertMeshesToBrepsSetting.SETTING_ID)?.Value as bool?;
return value is true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using Speckle.Connectors.Rhino.HostApp.Properties;
using Speckle.Connectors.Rhino.Mapper.Revit;
using Speckle.Connectors.Rhino.Operations.Receive;
using Speckle.Connectors.Rhino.Operations.Receive.Settings;
using Speckle.Connectors.Rhino.Operations.Send;
using Speckle.Connectors.Rhino.Operations.Send.Settings;
using Speckle.Connectors.Rhino.Plugin;
Expand Down Expand Up @@ -62,6 +63,9 @@ public static void AddRhino(this IServiceCollection serviceCollection, bool isCo
// register send settings
serviceCollection.AddScoped<ToSpeckleSettingsManager>();

// register receive settings
serviceCollection.AddSingleton<IToHostSettingsManager, ToHostSettingsManager>();

// register send conversion cache
serviceCollection.AddSingleton<ISendConversionCache, SendConversionCache>();
serviceCollection.AddSingleton<IAppIdleManager, RhinoIdleManager>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Mapper\Revit\RevitMappingResolver.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RhinoSelectionFilter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\RhinoLayersFilter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\Settings\ConvertMeshesToBrepsSetting.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Receive\Settings\ToHostSettingsManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\AddVisualizationProperties.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManager.cs" />
<Compile Include="$(MSBuildThisFileDirectory)RhinoEvents.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,23 @@ private List<DisplayValueResult> ProcessGeometryCollections(
DB.Transform? curveTransform
)
{
var meshesByMaterial = GetMeshesByMaterial(collections.Meshes, collections.Solids);
var displayMeshes = _meshByMaterialConverter.Convert(
(meshesByMaterial, element.Id, ShouldSetElementDisplayToTransparent(element))
);
bool makeTransparent = ShouldSetElementDisplayToTransparent(element);

// Native meshes
var meshesByMaterial = GetMeshesByMaterialFromMeshes(collections.Meshes);
var displayMeshes = _meshByMaterialConverter.Convert((meshesByMaterial, element.Id, makeTransparent));

// Solid-origin meshes — processed separately and tagged
var solidMeshesByMaterial = GetMeshesByMaterialFromSolids(collections.Solids);
var solidDisplayMeshes = _meshByMaterialConverter.Convert((solidMeshesByMaterial, element.Id, makeTransparent));
foreach (var solidMesh in solidDisplayMeshes)
{
solidMesh["fromSolid"] = true;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we would need this flag at all? Why not to just try to convert all upcoming meshes in rhino. theoratically we should not touch anything on revit side.

}

List<DisplayValueResult> displayValue = new(collections.TotalCount);

foreach (var mesh in displayMeshes)
foreach (var mesh in displayMeshes.Concat(solidDisplayMeshes))
{
// if we have a transform, keep mesh in symbol space and attach transform
displayValue.Add(
Expand Down Expand Up @@ -388,10 +397,7 @@ private Matrix4x4 TransformToMatrix(DB.Transform transform) =>
return null;
}

private static Dictionary<DB.ElementId, List<DB.Mesh>> GetMeshesByMaterial(
List<DB.Mesh> meshes,
List<DB.Solid> solids
)
private static Dictionary<DB.ElementId, List<DB.Mesh>> GetMeshesByMaterialFromMeshes(List<DB.Mesh> meshes)
{
var meshesByMaterial = new Dictionary<DB.ElementId, List<DB.Mesh>>();
foreach (var mesh in meshes)
Expand All @@ -406,6 +412,12 @@ private Matrix4x4 TransformToMatrix(DB.Transform transform) =>
value.Add(mesh);
}

return meshesByMaterial;
}

private static Dictionary<DB.ElementId, List<DB.Mesh>> GetMeshesByMaterialFromSolids(List<DB.Solid> solids)
{
var meshesByMaterial = new Dictionary<DB.ElementId, List<DB.Mesh>>();
foreach (var solid in solids)
{
foreach (DB.Face face in solid.Faces)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ namespace Speckle.Converters.Rhino;
/// <summary>
/// Represents the settings used for Rhino and Grasshopper conversions.
/// </summary>
public record RhinoConversionSettings(RhinoDoc Document, string SpeckleUnits, bool AddVisualizationProperties);
public record RhinoConversionSettings(
RhinoDoc Document,
string SpeckleUnits,
bool AddVisualizationProperties,
bool ConvertMeshesToBreps = false
);
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,16 @@ IConverterSettingsStore<RhinoConversionSettings> settingsStore

public RhinoConversionSettings Create(RhinoDoc document, bool addVisualizationProperties) =>
new(document, unitsConverter.ConvertOrThrow(RhinoDoc.ActiveDoc.ModelUnitSystem), addVisualizationProperties);

public RhinoConversionSettings Create(
RhinoDoc document,
bool addVisualizationProperties,
bool convertMeshesToBreps
) =>
new(
document,
unitsConverter.ConvertOrThrow(RhinoDoc.ActiveDoc.ModelUnitSystem),
addVisualizationProperties,
convertMeshesToBreps
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;

namespace Speckle.Converters.Rhino.ToHost.Helpers;

public interface IMeshToHostConversionHelper
{
RG.GeometryBase ConvertMesh(SOG.Mesh mesh);
}

public class MeshToHostConversionHelper(
ITypedConverter<SOG.Mesh, RG.Mesh> meshConverter,
IConverterSettingsStore<RhinoConversionSettings> settingsStore
) : IMeshToHostConversionHelper
{
#pragma warning disable CA1508 // Brep.CreateFromMesh can return null for degenerate meshes
public RG.GeometryBase ConvertMesh(SOG.Mesh mesh)
{
var rhinoMesh = meshConverter.Convert(mesh);

if (settingsStore.Current.ConvertMeshesToBreps && mesh["fromSolid"] is true)
{
var brep = RG.Brep.CreateFromMesh(rhinoMesh, true);
if (brep is not null)
{
brep.MergeCoplanarFaces(
settingsStore.Current.Document.ModelAbsoluteTolerance,
settingsStore.Current.Document.ModelAngleToleranceRadians
);
return brep;
}
}

return rhinoMesh;
}
#pragma warning restore CA1508
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.Common.ToHost;
using Speckle.Converters.Rhino.ToHost.Helpers;
using Speckle.Objects.Data;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
Expand All @@ -21,7 +22,7 @@ public class DataObjectConverter
private readonly ITypedConverter<SOG.Ellipse, RG.NurbsCurve> _ellipseConverter;
private readonly ITypedConverter<SOG.ExtrusionX, List<RG.GeometryBase>> _extrusionConverter;
private readonly ITypedConverter<SOG.Line, RG.LineCurve> _lineConverter;
private readonly ITypedConverter<SOG.Mesh, RG.Mesh> _meshConverter;
private readonly IMeshToHostConversionHelper _meshConversionHelper;
private readonly ITypedConverter<SOG.Pointcloud, RG.PointCloud> _pointcloudConverter;
private readonly ITypedConverter<SOG.Point, RG.Point> _pointConverter;
private readonly ITypedConverter<SOG.Polycurve, RG.PolyCurve> _polycurveConverter;
Expand All @@ -39,7 +40,7 @@ public DataObjectConverter(
ITypedConverter<SOG.Ellipse, RG.NurbsCurve> ellipseConverter,
ITypedConverter<SOG.ExtrusionX, List<RG.GeometryBase>> extrusionConverter,
ITypedConverter<SOG.Line, RG.LineCurve> lineConverter,
ITypedConverter<SOG.Mesh, RG.Mesh> meshConverter,
IMeshToHostConversionHelper meshConversionHelper,
ITypedConverter<SOG.Pointcloud, RG.PointCloud> pointcloudConverter,
ITypedConverter<SOG.Point, RG.Point> pointConverter,
ITypedConverter<SOG.Polyline, RG.PolylineCurve> polylineConverter,
Expand All @@ -57,7 +58,7 @@ IDataObjectInstanceRegistry dataObjectInstanceRegistry
_ellipseConverter = ellipseConverter;
_extrusionConverter = extrusionConverter;
_lineConverter = lineConverter;
_meshConverter = meshConverter;
_meshConversionHelper = meshConversionHelper;
_pointcloudConverter = pointcloudConverter;
_pointConverter = pointConverter;
_polycurveConverter = polycurveConverter;
Expand Down Expand Up @@ -107,7 +108,7 @@ IDataObjectInstanceRegistry dataObjectInstanceRegistry
SOG.Ellipse ellipse => new() { _ellipseConverter.Convert(ellipse) },
SOG.ExtrusionX extrusion => _extrusionConverter.Convert(extrusion),
SOG.Line line => new() { _lineConverter.Convert(line) },
SOG.Mesh mesh => new() { _meshConverter.Convert(mesh) },
SOG.Mesh mesh => new() { _meshConversionHelper.ConvertMesh(mesh) },
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't believe we need another wrapper/helper class for this operation. Just use utility in the converter class.

SOG.Pointcloud pointcloud => new() { _pointcloudConverter.Convert(pointcloud) },
SOG.Point point => new() { _pointConverter.Convert(point) },
SOG.Polycurve polycurve => new() { _polycurveConverter.Convert(polycurve) },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.Rhino.ToHost.Helpers;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
Expand All @@ -15,23 +16,23 @@ public class DisplayableObjectConverter
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 IMeshToHostConversionHelper _meshConversionHelper;
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,
IMeshToHostConversionHelper meshConversionHelper,
IConverterSettingsStore<RhinoConversionSettings> settingsStore
)
{
_pointConverter = pointConverter;
_lineConverter = lineConverter;
_polylineConverter = polylineConverter;
_arcConverter = arcConverter;
_meshConverter = meshConverter;
_meshConversionHelper = meshConversionHelper;
_settingsStore = settingsStore;
}

Expand All @@ -47,7 +48,7 @@ IConverterSettingsStore<RhinoConversionSettings> settingsStore
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.Mesh mesh => _meshConversionHelper.ConvertMesh(mesh),
SOG.Point point => _pointConverter.Convert(point),
_ => throw new ConversionException($"Found unsupported fallback geometry: {item.GetType()}")
};
Expand Down