Compare commits

...

17 Commits

Author SHA1 Message Date
Claire Kuang 734208c0a8 Merge branch 'dev' into alan/grasshopper-v3 2024-12-15 19:05:46 +00:00
Claire Kuang c3c9478364 Merge branch 'dev' into alan/grasshopper-v3 2024-12-11 16:02:26 +00:00
Alan Rynne 26b41b6ff7 feat: Bring back conversion components for easier dev/debug 2024-12-11 11:19:10 +01:00
Claire Kuang 12685e7803 Merge branch 'dev' into alan/grasshopper-v3 2024-12-11 09:23:41 +00:00
Alan Rynne 4b65aa4386 feat: POC Send node 2024-12-10 23:52:07 +01:00
Alan Rynne f4a3b24b5a fix: Build IDE0040 warnings in imported class 2024-12-10 17:02:13 +01:00
Alan Rynne ecc0b5e31d fix: Minor fixes in shared base components 2024-12-10 16:57:28 +01:00
Alan Rynne 020acbe13a Merge branch 'dim/grassopper-v3-wip' into alan/grasshopper-v3 2024-12-10 16:56:59 +01:00
Dimitrie Stefanescu 729d1a4698 feat: adds value type component, all is very raw and wip 2024-12-09 16:04:16 +00:00
Dimitrie Stefanescu 4f74328ffc wip 2024-12-07 15:34:49 +00:00
Dimitrie Stefanescu 54370f3188 wip 2024-12-07 14:27:48 +00:00
Dimitrie Stefanescu 4a51eae628 feat: total wip expand collection node 2024-12-06 14:52:23 +00:00
Dimitrie Stefanescu 34241385f9 feat: unpacking logic wip 2024-12-06 11:56:33 +00:00
Alan Rynne 7ec01ed39f feat: Working initial nodes
Receive, Collection, URL parsing for models, root object unpacking
2024-12-05 11:00:37 +01:00
Alan Rynne 1ff861f9db v3 Receive outputs most objects, very basic 2024-11-28 12:42:44 +01:00
Alan Rynne 4c125afd7b Working POC receive with working Rhino conversions 2024-11-28 11:35:27 +01:00
Alan Rynne e561980e7f feat: Boilerplate project for Grasshopper v3 2024-11-25 16:04:52 +01:00
84 changed files with 4761 additions and 261 deletions
+3
View File
@@ -311,6 +311,9 @@ dotnet_diagnostic.NUnit2037.severity = warning # Consider using Assert.That(coll
dotnet_diagnostic.NUnit2038.severity = warning # Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual)
dotnet_diagnostic.NUnit2039.severity = warning # Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual)
# note: added to allow the copy paste from rhino inside of the ValueSet component
dotnet_diagnostic.CA1033.severity = none
[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 2
@@ -132,11 +132,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -279,6 +274,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -312,6 +307,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -312,6 +307,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -313,6 +308,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -121,11 +121,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -269,6 +264,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -322,6 +317,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -322,6 +317,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -322,6 +317,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -279,6 +274,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -158,11 +158,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -333,6 +328,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -158,11 +158,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -333,6 +328,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -158,11 +158,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -333,6 +328,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -143,11 +143,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -283,6 +278,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -0,0 +1,24 @@
using Microsoft.Extensions.DependencyInjection;
namespace Speckle.Connectors.Grasshopper8.Components.BaseComponents;
public abstract class SpeckleScopedTaskCapableComponent<TInput, TOutput>(
string name,
string nickname,
string description,
string category,
string subCategory
) : SpeckleTaskCapableComponent<TInput, TOutput>(name, nickname, description, category, subCategory)
{
protected override async Task<TOutput> PerformTask(TInput input, CancellationToken cancellationToken = default)
{
using var scope = PriorityLoader.Container.CreateScope();
return await PerformScopedTask(input, scope, cancellationToken).ConfigureAwait(false);
}
protected abstract Task<TOutput> PerformScopedTask(
TInput input,
IServiceScope scope,
CancellationToken cancellationToken = default
);
}
@@ -0,0 +1,85 @@
using Grasshopper.Kernel;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Sdk;
namespace Speckle.Connectors.Grasshopper8.Components.BaseComponents;
public abstract class SpeckleTaskCapableComponent<TInput, TOutput>(
string name,
string nickname,
string description,
string category,
string subCategory
) : GH_TaskCapableComponent<TOutput>(name, nickname, description, category, subCategory)
{
protected override void SolveInstance(IGH_DataAccess da)
{
//TODO: We're missing activity and logging here. Will enable it for all inherited classes.
if (InPreSolve)
{
// Collect the data and create the task
try
{
var input = GetInput(da);
TaskList.Add(PerformTask(input, CancelToken));
}
catch (SpeckleException e)
{
Console.WriteLine(e);
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
}
return;
}
bool solveResults = false;
TOutput? result = default;
try
{
solveResults = GetSolveResults(da, out result);
}
catch (AggregateException e)
{
Console.WriteLine(e);
foreach (var inner in e.InnerExceptions)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, inner.Message);
}
}
if (!solveResults)
{
// INFO: This will run synchronously. Useful for Rhino.Compute runs, but can also be enabled by user.
try
{
TInput input = GetInput(da);
var syncResult = PerformTask(input).Result;
result = syncResult;
}
catch (AggregateException e)
{
foreach (var inner in e.InnerExceptions)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, inner.Message);
}
return;
}
}
if (result is not null)
{
SetOutput(da, result);
}
}
protected override Bitmap Icon => BitmapBuilder.CreateSquareIconBitmap(IconText);
protected string IconText => string.Join("", Name.Split(' ').Select(s => s.First()));
protected abstract TInput GetInput(IGH_DataAccess da);
protected abstract void SetOutput(IGH_DataAccess da, TOutput result);
protected abstract Task<TOutput> PerformTask(TInput input, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,55 @@
using Grasshopper.Kernel.Types;
using Speckle.Connectors.Grasshopper8.HostApp.Special;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
public class CollectionPathsSelector : ValueSet<IGH_Goo>
{
public CollectionPathsSelector()
: base(
"Collection Paths Selector",
"Paths",
"Allows you to select a set of collection paths for filtering",
"Speckle",
"Collections"
) { }
public override Guid ComponentGuid => new Guid("65FC4D58-2209-41B6-9B22-BE51C8B28604");
protected override void LoadVolatileData()
{
var collections = VolatileData.AllData(true).OfType<SpeckleCollectionGoo>().Select(goo => goo.Value).ToList();
if (collections.Count == 0)
{
return;
}
// NOTE: supporting multiple collections? maybe? not really?
var myCollection = GetPaths(collections.First());
m_data.AppendRange(myCollection.Select(s => new GH_String(s)));
}
private List<string> GetPaths(Collection c)
{
var currentPath = new List<string>();
var allPaths = new HashSet<string>();
void GetPathsInternal(Collection col)
{
currentPath.Add(col.name);
allPaths.Add(string.Join(" > ", currentPath));
var subCols = col.elements.OfType<Collection>();
foreach (var subCol in subCols)
{
GetPathsInternal(subCol);
}
currentPath.RemoveAt(currentPath.Count - 1);
}
GetPathsInternal(c);
return allPaths.ToList();
}
}
@@ -0,0 +1,245 @@
using System.Collections;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Rhino.Geometry;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
#pragma warning disable CA1711
public class ExpandCollection : GH_Component, IGH_VariableParameterComponent
#pragma warning restore CA1711
{
public override Guid ComponentGuid => new("69BC8CFB-A72F-4A83-9263-F3399DDA2E5E");
public ExpandCollection()
: base("Expand Collection", "expand", "Expands a new collection", "Speckle", "Collections") { }
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(
new SpeckleCollectionWrapperParam(GH_ParamAccess.item),
"Data",
"D",
"The data you want to expand",
GH_ParamAccess.item
);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
private List<SpeckleObject> _previewObjects = new();
protected override void SolveInstance(IGH_DataAccess da)
{
SpeckleCollectionGoo res = new();
da.GetData(0, ref res);
var c = res.Value;
Name = c.name;
NickName = c.name;
var objects = c
.elements.Where(el => el is not Collection)
.OfType<SpeckleObject>()
.Select(o => new SpeckleObjectGoo(o))
.ToList();
var collections = c.elements.Where(el => el is Collection).OfType<Collection>().ToList();
var outputParams = new List<OutputParamWrapper>();
if (objects.Count != 0)
{
var param = new Param_GenericObject()
{
Name = "Inner objects",
NickName = "Inner Objs",
Description =
"Some collections may contain a mix of objects and other collections. Here we output the atomic objects from within this collection.",
Access = GH_ParamAccess.list // NOTE: todo check on list if it's tree path-based
};
outputParams.Add(new OutputParamWrapper(param, objects, false));
}
foreach (var collection in collections)
{
// skip empty
if (collection.elements.Count == 0)
{
continue;
}
var hasInnerCollections = collection.elements.Any(el => el is Collection);
var isPathBasedCollection = collection["path"] as string; // Note: this is a reminder for the future
var nickName = collection.name;
if (collection.name.Length > 16)
{
nickName = collection.name[..3];
nickName += "..." + collection.name[^3..];
}
var param = new Param_GenericObject()
{
Name = collection.name,
NickName = nickName,
Access = hasInnerCollections ? GH_ParamAccess.item : GH_ParamAccess.list // we will directly set objects out; note access can be list or tree based on whether it will be a path based collection
};
if (!hasInnerCollections)
{
_previewObjects.AddRange(collection.elements.Cast<SpeckleObject>());
}
outputParams.Add(
new OutputParamWrapper(
param,
hasInnerCollections
? new SpeckleCollectionGoo(collection)
: collection.elements.OfType<SpeckleObject>().Select(o => new SpeckleObjectGoo(o)).ToList(),
hasInnerCollections
)
);
}
if (da.Iteration == 0 && OutputMismatch(outputParams))
{
OnPingDocument()
.ScheduleSolution(
5,
_ =>
{
CreateOutputs(outputParams);
}
);
}
else
{
_previewObjects = new();
FlattenForPreview(c);
for (int i = 0; i < outputParams.Count; i++)
{
var outParam = Params.Output[i];
switch (outParam.Access)
{
case GH_ParamAccess.item:
da.SetData(i, outputParams[i].Values);
break;
case GH_ParamAccess.list:
da.SetDataList(i, outputParams[i].Values as IList);
break;
case GH_ParamAccess.tree:
//TODO: means we need to convert the collection to a tree
break;
}
}
}
}
private BoundingBox _clippingBox;
public override BoundingBox ClippingBox => _clippingBox;
private void FlattenForPreview(Collection c)
{
_clippingBox = new BoundingBox();
foreach (var element in c.elements)
{
if (element is Collection subCol)
{
FlattenForPreview(subCol);
}
if (element is SpeckleObject sg)
{
_previewObjects.Add(sg);
var box = sg.GeometryBase.GetBoundingBox(false);
_clippingBox.Union(box);
}
}
}
// public override void DrawViewportWires(IGH_PreviewArgs args) => base.DrawViewportWires(args);
public override void DrawViewportMeshes(IGH_PreviewArgs args)
{
if (_previewObjects.Count == 0)
{
return;
}
var isSelected = args.Document.SelectedObjects().Contains(this);
foreach (var elem in _previewObjects)
{
elem.DrawPreview(args, isSelected);
}
}
private bool OutputMismatch(List<OutputParamWrapper> outputParams)
{
if (Params.Output.Count != outputParams.Count)
{
return true;
}
var count = 0;
foreach (var newParam in outputParams)
{
var oldParam = Params.Output[count];
if (
oldParam.NickName != newParam.Param.NickName
|| oldParam.Name != newParam.Param.Name
|| oldParam.Access != newParam.Param.Access
)
{
return true;
}
count++;
}
return false;
}
private void CreateOutputs(List<OutputParamWrapper> outputParams)
{
while (Params.Output.Count > 0)
{
Params.UnregisterOutputParameter(Params.Output[^1]);
}
foreach (var newParam in outputParams)
{
var param = new Param_GenericObject
{
Name = newParam.Param.Name,
NickName = newParam.Param.NickName,
MutableNickName = false,
Access = newParam.Param.Access // count == 0 ? GH_ParamAccess.list : GH_ParamAccess.item, // TODO: objects should always be a list or a tree, depending on whether the collection is a gh collection with a path prop
};
Params.RegisterOutputParam(param);
}
Params.OnParametersChanged();
VariableParameterMaintenance();
ExpireSolution(false);
}
public void VariableParameterMaintenance() { }
public bool CanInsertParameter(GH_ParameterSide side, int index) => false;
public bool CanRemoveParameter(GH_ParameterSide side, int index) => false;
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
{
var myParam = new Param_GenericObject
{
Name = GH_ComponentParamServer.InventUniqueNickname("ABCD", Params.Input),
MutableNickName = true,
Optional = true
};
myParam.NickName = myParam.Name;
return myParam;
}
public bool DestroyParameter(GH_ParameterSide side, int index) => side == GH_ParameterSide.Output;
}
public record OutputParamWrapper(Param_GenericObject Param, object Values, bool IsCollection);
@@ -0,0 +1,83 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Rhino;
using Rhino.Geometry;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Models;
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Conversion;
public class ToHostConversionComponent()
: SpeckleScopedTaskCapableComponent<Base, List<GeometryBase>>(
"To Host Conversion",
"THC",
"Converts a speckle object to rhino",
"Speckle",
"Dev"
)
{
public override Guid ComponentGuid => new("38BAB10C-4D80-4E0C-8235-A87C3E66F55F");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleObjectParam(GH_ParamAccess.item));
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddGeometryParameter("Geometry", "Geometry", "Geometry", GH_ParamAccess.list);
}
protected override Base GetInput(IGH_DataAccess da)
{
Base? input = null;
if (!da.GetData(0, ref input) || input is null)
{
throw new SpeckleException("Input is not valid");
}
return input;
}
protected override void SetOutput(IGH_DataAccess da, List<GeometryBase> result)
{
da.SetDataList(0, result);
}
protected override Task<List<GeometryBase>> PerformScopedTask(
Base input,
IServiceScope scope,
CancellationToken cancellationToken = default
)
{
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
var rootConverter = scope.ServiceProvider.GetRequiredService<IRootToHostConverter>();
return Task.FromResult(Convert(input, rootConverter));
}
private List<GeometryBase> Convert(Base input, IRootToHostConverter rootConverter)
{
var result = rootConverter.Convert(input);
if (result is GeometryBase geometry)
{
return new List<GeometryBase> { geometry };
}
else if (result is List<GeometryBase> geometryList)
{
return geometryList;
}
throw new SpeckleException("Failed to convert input to rhino");
}
}
@@ -0,0 +1,63 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Rhino;
using Rhino.Geometry;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models;
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Conversion;
public class ToSpeckleConversionComponent()
: SpeckleScopedTaskCapableComponent<GeometryBase, Base>(
"To Speckle Conversion",
"TSC",
"To Speckle Conversion",
"Speckle",
"Dev"
)
{
public override Guid ComponentGuid => new("ED3EC26D-681D-4E45-8FD8-DC4846F82B12");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddGeometryParameter("Geometry", "Geometry", "Geometry to convert.", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(new SpeckleObjectParam());
}
protected override GeometryBase GetInput(IGH_DataAccess da)
{
GeometryBase? geom = null;
da.GetData(0, ref geom);
return geom.NotNull();
}
protected override void SetOutput(IGH_DataAccess da, Base result)
{
da.SetData(0, result);
}
protected override Task<Base> PerformScopedTask(
GeometryBase input,
IServiceScope scope,
CancellationToken cancellationToken = default
)
{
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
var rootConverter = scope.ServiceProvider.GetRequiredService<IRootToSpeckleConverter>();
return Task.FromResult(rootConverter.Convert(input));
}
}
@@ -0,0 +1,229 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Rhino;
using Rhino.Geometry;
using Speckle.Connectors.Common.Instances;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Api;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Receive;
public class ReceiveComponentOutput
{
public SpeckleCollectionGoo RootObject { get; set; }
}
public class ReceiveComponent : SpeckleScopedTaskCapableComponent<SpeckleUrlModelResource, ReceiveComponentOutput>
{
public ReceiveComponent()
: base("Receive from Speckle", "RFS", "Receive objects from speckle", "Speckle", "Operations") { }
public override Guid ComponentGuid => new("74954F59-B1B7-41FD-97DE-4C6B005F2801");
protected override Bitmap Icon => BitmapBuilder.CreateSquareIconBitmap("R");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam(GH_ParamAccess.item));
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(
new SpeckleCollectionWrapperParam(GH_ParamAccess.item),
"Model",
"model",
"The model object for the received version",
GH_ParamAccess.item
);
}
protected override SpeckleUrlModelResource GetInput(IGH_DataAccess da)
{
SpeckleUrlModelResource? url = null;
da.GetData(0, ref url);
if (url is null)
{
throw new SpeckleException("Speckle url is null");
}
return url;
}
protected override void SetOutput(IGH_DataAccess da, ReceiveComponentOutput result)
{
da.SetData(0, result.RootObject);
Message = "Done";
}
protected override async Task<ReceiveComponentOutput> PerformScopedTask(
SpeckleUrlModelResource input,
IServiceScope scope,
CancellationToken cancellationToken = default
)
{
// TODO: Resolving dependencies here may be overkill in most cases. Must re-evaluate.
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
var rootConverter = scope.ServiceProvider.GetService<IRootToHostConverter>();
var accountManager = scope.ServiceProvider.GetRequiredService<AccountService>();
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
var receiveOperation = scope.ServiceProvider.GetRequiredService<GrasshopperReceiveOperation>();
// Do the thing 👇🏼
// TODO: Get any account for this server, as we don't have a mechanism yet to pass accountIds through
var account = accountManager.GetAccountWithServerUrlFallback("", new Uri(input.Server));
if (account is null)
{
throw new SpeckleAccountManagerException($"No default account was found");
}
using var client = clientFactory.Create(account);
var receiveInfo = await input.GetReceiveInfo(client, cancellationToken).ConfigureAwait(false);
var progress = new Progress<CardProgress>(_ =>
{
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
// Message = $"{progress.Status}: {progress.Progress}";
});
var root = await receiveOperation
.ReceiveCommitObject(receiveInfo, progress, cancellationToken)
.ConfigureAwait(false);
// We need to rethink these lovely unpackers, there's a bit too many of 'em
var rootObjectUnpacker = scope.ServiceProvider.GetService<RootObjectUnpacker>();
var localToGlobalUnpacker = new LocalToGlobalUnpacker();
var traversalContextUnpacker = new TraversalContextUnpacker();
var unpackedRoot = rootObjectUnpacker.Unpack(root);
// "flatten" block instances
var localToGlobalMaps = localToGlobalUnpacker.Unpack(
unpackedRoot.DefinitionProxies,
unpackedRoot.ObjectsToConvert.ToList()
);
var collGen = new CollectionRebuilder((root as Collection) ?? new Collection() { name = "unnamed" });
foreach (var map in localToGlobalMaps)
{
try
{
var converted = Convert(map.AtomicObject, rootConverter);
var path = traversalContextUnpacker.GetCollectionPath(map.TraversalContext).ToList();
foreach (var matrix in map.Matrix)
{
var mat = GrasshopperHelpers.MatrixToTransform(matrix, "meters");
converted.ForEach(res => res.Transform(mat));
}
// note one to many not handled too nice here
foreach (var geometryBase in converted)
{
var gh = new SpeckleObject()
{
OriginalObject = map.AtomicObject,
Path = path,
GeometryBase = geometryBase
};
collGen.AppendSpeckleGrasshopperObject(gh);
}
}
catch (ConversionException)
{
// TODO
}
}
// var x = new SpeckleCollectionGoo { Value = collGen.RootCollection };
var goo = new SpeckleCollectionGoo(collGen.RootCollection);
return new ReceiveComponentOutput { RootObject = goo };
}
private List<GeometryBase> Convert(Base input, IRootToHostConverter rootConverter)
{
var result = rootConverter.Convert(input);
if (result is GeometryBase geometry)
{
return [geometry];
}
if (result is List<GeometryBase> geometryList)
{
return geometryList;
}
if (result is IEnumerable<(object, Base)> fallbackConversionResult)
{
// note special handling for proxying render materials OR we don't care about revit
return fallbackConversionResult.Select(t => t.Item1).Cast<GeometryBase>().ToList();
}
throw new SpeckleException("Failed to convert input to rhino");
}
}
// NOTE: We will need GrasshopperCollections (with an extra path element)
// these will need to be handled now
internal sealed class CollectionRebuilder
{
public Collection RootCollection { get; }
private readonly Dictionary<string, Collection> _cache = new();
public CollectionRebuilder(Collection baseCollection)
{
RootCollection = new Collection() { name = baseCollection.name, applicationId = baseCollection.applicationId };
}
public void AppendSpeckleGrasshopperObject(SpeckleObject speckleGrasshopperObject)
{
var collection = GetOrCreateCollectionFromPath(speckleGrasshopperObject.Path);
collection.elements.Add(speckleGrasshopperObject);
}
private Collection GetOrCreateCollectionFromPath(IEnumerable<Collection> path)
{
// TODO - this flows but it can be optimised (ie, concat path first, check cache, iterate only if not in cache)
var currentLayerName = "";
Collection previousCollection = RootCollection;
foreach (var collection in path)
{
currentLayerName += collection.name;
if (_cache.TryGetValue(currentLayerName, out Collection col))
{
previousCollection = col;
continue;
}
var newCollection = new Collection() { name = collection.name, applicationId = collection.applicationId };
if (collection["path"] != null)
{
newCollection["path"] = collection["path"];
}
_cache[currentLayerName] = newCollection;
previousCollection.elements.Add(newCollection);
previousCollection = newCollection;
}
return previousCollection;
}
}
@@ -0,0 +1,124 @@
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using Microsoft.Extensions.DependencyInjection;
using Rhino;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Api;
using Speckle.Sdk.Common;
using Speckle.Sdk.Credentials;
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Send;
public class SendComponentInput
{
public SpeckleUrlModelResource Resource { get; }
public Dictionary<string, GH_Structure<IGH_Goo>> Inputs { get; }
public SendComponentInput(SpeckleUrlModelResource resource, Dictionary<string, GH_Structure<IGH_Goo>> inputs)
{
Resource = resource;
Inputs = inputs;
}
}
public class SendComponentOutput(SpeckleUrlModelObjectResource resource)
{
public SpeckleUrlModelObjectResource Resource { get; } = resource;
}
public class SendComponent()
: SpeckleScopedTaskCapableComponent<SendComponentInput, SendComponentOutput>(
"Send",
"SS",
"Speckle Send",
"Speckle",
"Operations"
)
{
public override Guid ComponentGuid => new("0CF0D173-BDF0-4AC2-9157-02822B90E9FB");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam());
pManager.AddGenericParameter("A", "A", "A", GH_ParamAccess.tree);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam());
}
protected override SendComponentInput GetInput(IGH_DataAccess da)
{
if (da.Iteration != 0)
{
throw new SpeckleException("No more than 1 resource allowed");
}
SpeckleUrlModelResource? resource = null;
if (!da.GetData(0, ref resource))
{
throw new SpeckleException("Failed to get resource");
}
var name = Params.Input[1].Name;
da.GetDataTree(1, out GH_Structure<IGH_Goo> tree);
var inputDict = new Dictionary<string, GH_Structure<IGH_Goo>> { { name, tree } };
return new SendComponentInput(resource.NotNull(), inputDict);
}
protected override void SetOutput(IGH_DataAccess da, SendComponentOutput result)
{
da.SetData(0, result.Resource);
}
protected override async Task<SendComponentOutput> PerformScopedTask(
SendComponentInput input,
IServiceScope scope,
CancellationToken cancellationToken = default
)
{
var rhinoConversionSettingsFactory = scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
var accountManager = scope.ServiceProvider.GetRequiredService<AccountService>();
var clientFactory = scope.ServiceProvider.GetRequiredService<IClientFactory>();
var sendOperation = scope.ServiceProvider.GetRequiredService<GrasshopperSendOperation>();
// TODO: Get any account for this server, as we don't have a mechanism yet to pass accountIds through
var account = accountManager.GetAccountWithServerUrlFallback("", new Uri(input.Resource.Server));
if (account is null)
{
throw new SpeckleAccountManagerException($"No default account was found");
}
var progress = new Progress<CardProgress>(_ =>
{
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
// Message = $"{progress.Status}: {progress.Progress}";
});
using var client = clientFactory.Create(account);
var receiveInfo = await input.Resource.GetSendInfo(client, cancellationToken).ConfigureAwait(false);
var result = await sendOperation
.Execute(input.Inputs, receiveInfo, progress, cancellationToken)
.ConfigureAwait(false);
return new SendComponentOutput(
new SpeckleUrlModelObjectResource(receiveInfo.ServerUrl.ToString(), receiveInfo.ProjectId, result.RootId)
);
}
}
@@ -0,0 +1,48 @@
using Grasshopper.Kernel;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Connectors.Grasshopper8.Parameters;
namespace Speckle.Connectors.Grasshopper8.Components;
public class SpeckleResourceFromUrlComponent : SpeckleTaskCapableComponent<string, SpeckleUrlModelResource[]>
{
public SpeckleResourceFromUrlComponent()
: base("Speckle Resource From Url", "spcklUrl", "Speckle resource from url", "Speckle", "Resources") { }
public override Guid ComponentGuid => new("A55C74C6-D955-4822-84BB-2266A2B965EE");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddTextParameter("URL", "URL", "URL to send to resource", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddParameter(new SpeckleUrlModelResourceParam(GH_ParamAccess.list));
}
protected override string GetInput(IGH_DataAccess da)
{
string url = string.Empty;
da.GetData(0, ref url);
return url;
}
protected override void SetOutput(IGH_DataAccess da, SpeckleUrlModelResource[] result)
{
da.SetDataList(0, result);
}
protected override Task<SpeckleUrlModelResource[]> PerformTask(
string input,
CancellationToken cancellationToken = default
)
{
var resources = SpeckleResourceBuilder.FromUrlString(input);
// TODO: Here's where we can validate the resources and throw or not?
return Task.FromResult(resources);
}
}
@@ -0,0 +1,81 @@
using System.Drawing.Drawing2D;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public static class BitmapBuilder
{
public static Bitmap CreateSquareIconBitmap(string text, int width = 24, int height = 24)
{
Bitmap bitmap = new(width, height);
using Graphics graphics = Graphics.FromImage(bitmap);
// Enable high-quality rendering
graphics.SmoothingMode = SmoothingMode.AntiAlias;
// Set background to transparent
graphics.Clear(Color.Transparent);
// Rectangle with a 1px offset
Rectangle squareRect = new(1, 1, width - 2, height - 2);
using (Brush blueBrush = new SolidBrush(Color.Blue))
{
graphics.FillRectangle(blueBrush, squareRect);
}
// Draw white letters in the center
using (Font font = new("Arial", 8, FontStyle.Bold, GraphicsUnit.Pixel))
using (Brush whiteBrush = new SolidBrush(Color.White))
{
StringFormat format = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
graphics.DrawString(text, font, whiteBrush, new RectangleF(1, 1, width - 2, height - 2), format);
}
return bitmap;
}
public static Bitmap CreateHexagonalBitmap(string text, int width = 24, int height = 24)
{
Bitmap bitmap = new(width, height);
using Graphics graphics = Graphics.FromImage(bitmap);
// Enable high-quality rendering
graphics.SmoothingMode = SmoothingMode.AntiAlias;
// Set background to transparent
graphics.Clear(Color.Transparent);
// Calculate hexagon points centered within the bitmap
float side = (width - 2) / 2.236f; // 2.236f approximates 4 / √3 for regular hex dimensions
float h = side * (float)Math.Sqrt(3) / 2;
float centerX = width / 2f;
float centerY = height / 2f;
Point[] hexagonPoints =
[
new((int)(centerX - side / 2), (int)(centerY - h)),
new((int)(centerX + side / 2), (int)(centerY - h)),
new((int)(centerX + side), (int)centerY),
new((int)(centerX + side / 2), (int)(centerY + h)),
new((int)(centerX - side / 2), (int)(centerY + h)),
new((int)(centerX - side), (int)centerY)
];
using (Brush blueBrush = new SolidBrush(Color.Blue))
{
graphics.FillPolygon(blueBrush, hexagonPoints);
}
// Draw white letters in the center
using Font font = new("Monospace", 10, FontStyle.Bold, GraphicsUnit.Pixel);
using Brush whiteBrush = new SolidBrush(Color.White);
StringFormat format = new() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
graphics.DrawString(text, font, whiteBrush, new RectangleF(0, 1, width, height), format);
return bitmap;
}
}
@@ -0,0 +1,33 @@
using System.Reflection;
using Grasshopper.Kernel.Types;
using Speckle.Sdk;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public static class GrasshopperGooExtensions
{
public static T UnwrapGoo<T>(this IGH_Goo goo)
{
if (goo is GH_Goo<T> specificGoo)
{
return specificGoo.Value;
}
var valuePropInfo = goo.GetType()
.GetField("m_value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (valuePropInfo != null)
{
var tempValue = valuePropInfo.GetValue(goo);
if (tempValue is T value)
{
return value;
}
}
// TODO: Potentially unwrap new rhino objects
throw new SpeckleException(
$"Internal value of goo {goo.GetType().Name} was not the provided type {typeof(T).Name}"
);
}
}
@@ -0,0 +1,188 @@
using Rhino.Geometry;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Instances;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public sealed class GrasshopperReceiveConversionResult : ReceiveConversionResult
{
public object? Result { get; set; }
public Base Source { get; set; }
public GrasshopperReceiveConversionResult(
Status status,
Base source,
object? result,
string? resultId = null,
string? resultType = null,
Exception? exception = null
)
: base(status, source, resultId, resultType, exception)
{
Result = result;
Source = source;
}
}
public class GrasshopperHostObjectBuilder : IHostObjectBuilder
{
private readonly IRootToHostConverter _converter;
private readonly IConverterSettingsStore<RhinoConversionSettings> _converterSettings;
private readonly TraversalContextUnpacker _contextUnpacker;
private readonly RootObjectUnpacker _rootObjectUnpacker;
private readonly ISdkActivityFactory _activityFactory;
public GrasshopperHostObjectBuilder(
IRootToHostConverter converter,
IConverterSettingsStore<RhinoConversionSettings> converterSettings,
RootObjectUnpacker rootObjectUnpacker,
ISdkActivityFactory activityFactory,
TraversalContextUnpacker contextUnpacker
)
{
_converter = converter;
_converterSettings = converterSettings;
_rootObjectUnpacker = rootObjectUnpacker;
_activityFactory = activityFactory;
_contextUnpacker = contextUnpacker;
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public async Task<HostObjectBuilderResult> Build(
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
Base rootObject,
string projectName,
string modelName,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
using var activity = _activityFactory.Start("Build");
// POC: This is where the top level base-layer name is set. Could be abstracted or injected in the context?
var baseLayerName = $"Project {projectName}: Model {modelName}";
// 1 - Unpack objects and proxies from root commit object
var unpackedRoot = _rootObjectUnpacker.Unpack(rootObject);
// 2 - Split atomic objects and instance components with their path
var (atomicObjects, instanceComponents) = _rootObjectUnpacker.SplitAtomicObjectsAndInstances(
unpackedRoot.ObjectsToConvert
);
var atomicObjectsWithPath = _contextUnpacker.GetAtomicObjectsWithPath(atomicObjects);
var instanceComponentsWithPath = _contextUnpacker.GetInstanceComponentsWithPath(instanceComponents);
// 2.1 - these are not captured by traversal, so we need to re-add them here
if (unpackedRoot.DefinitionProxies != null && unpackedRoot.DefinitionProxies.Count > 0)
{
var transformed = unpackedRoot.DefinitionProxies.Select(proxy =>
(Array.Empty<Collection>(), proxy as IInstanceComponent)
);
instanceComponentsWithPath.AddRange(transformed);
}
// 3 - Bake materials and colors, as they are used later down the line by layers and objects
onOperationProgressed.Report(new("Converting materials and colors", null));
if (unpackedRoot.RenderMaterialProxies != null)
{
using var _ = _activityFactory.Start("Render Materials");
//_materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseLayerName);
}
if (unpackedRoot.ColorProxies != null)
{
//_colorBaker.ParseColors(unpackedRoot.ColorProxies);
}
// 5 - Convert atomic objects
List<ReceiveConversionResult> conversionResults = new();
Dictionary<string, List<string>> applicationIdMap = new(); // This map is used in converting blocks in stage 2. keeps track of original app id => resulting new app ids post baking
int count = 0;
using (var _ = _activityFactory.Start("Converting objects"))
{
foreach (var (path, obj) in atomicObjectsWithPath)
{
using (var convertActivity = _activityFactory.Start("Converting object"))
{
onOperationProgressed.Report(new("Converting objects", (double)++count / atomicObjects.Count));
try
{
// 0: get pre-created layer from cache in layer baker
// int layerIndex = _layerBaker.GetLayerIndex(path, baseLayerName);
// 1: create object attributes for baking
string name = obj["name"] as string ?? "";
// 2: convert
var result = _converter.Convert(obj);
// 3: bake
if (result is GeometryBase geometryBase)
{
//var guid = BakeObject(geometryBase, obj, atts);
}
else if (result is List<GeometryBase> geometryBases) // one to many raw encoding case
{
foreach (var gb in geometryBases)
{
//var guid = BakeObject(gb, obj, atts);
}
}
else if (result is IEnumerable<(object, Base)> fallbackConversionResult) // one to many fallback conversion
{
//var guids = BakeObjectsAsFallbackGroup(fallbackConversionResult, obj, atts, baseLayerName);
}
// 4: log
conversionResults.Add(
new GrasshopperReceiveConversionResult(Status.SUCCESS, obj, result, null, result.GetType().ToString())
);
// applicationIdMap[obj.applicationId ?? obj.id] = conversionIds;
convertActivity?.SetStatus(SdkActivityStatusCode.Ok);
}
catch (Exception ex) when (!ex.IsFatal())
{
// TODO: No conversion report yet
conversionResults.Add(new GrasshopperReceiveConversionResult(Status.ERROR, obj, null, null, null, ex));
convertActivity?.SetStatus(SdkActivityStatusCode.Error);
convertActivity?.RecordException(ex);
}
}
}
}
// 6 - Convert instances
using (var _ = _activityFactory.Start("Converting instances"))
{
// TODO: No instances yet
// var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = await _instanceBaker
// .BakeInstances(instanceComponentsWithPath, applicationIdMap, baseLayerName, onOperationProgressed)
// .ConfigureAwait(false);
// TODO: No conversion report yet
// conversionResults.RemoveAll(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId)); // remove all conversion results for atomic objects that have been consumed (POC: not that cool, but prevents problems on object highlighting)
// conversionResults.AddRange(instanceConversionResults); // add instance conversion results to our list
}
// 7 - Create groups
if (unpackedRoot.GroupProxies is not null)
{
// TODO: No groups yet
// _groupBaker.BakeGroups(unpackedRoot.GroupProxies, applicationIdMap, baseLayerName);
}
return new HostObjectBuilderResult([], conversionResults);
}
}
@@ -0,0 +1,100 @@
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Logging;
using Speckle.Sdk.Api;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Logging;
using Speckle.Sdk.Models;
using Speckle.Sdk.Transports;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public class GrasshopperReceiveOperation
{
private readonly AccountService _accountService;
private readonly IServerTransportFactory _serverTransportFactory;
private readonly IProgressDisplayManager _progressDisplayManager;
private readonly ISdkActivityFactory _activityFactory;
private readonly IOperations _operations;
private readonly IClientFactory _clientFactory;
public GrasshopperReceiveOperation(
AccountService accountService,
IServerTransportFactory serverTransportFactory,
IProgressDisplayManager progressDisplayManager,
ISdkActivityFactory activityFactory,
IOperations operations,
IClientFactory clientFactory
)
{
_accountService = accountService;
_serverTransportFactory = serverTransportFactory;
_progressDisplayManager = progressDisplayManager;
_activityFactory = activityFactory;
_operations = operations;
_clientFactory = clientFactory;
}
public async Task<Base> ReceiveCommitObject(
ReceiveInfo receiveInfo,
IProgress<CardProgress> onOperationProgressed,
CancellationToken cancellationToken
)
{
using var execute = _activityFactory.Start("Receive Operation");
execute?.SetTag("receiveInfo", receiveInfo);
// 2 - Check account exist
Account account = _accountService.GetAccountWithServerUrlFallback(receiveInfo.AccountId, receiveInfo.ServerUrl);
using Client apiClient = _clientFactory.Create(account);
using var userScope = ActivityScope.SetTag(Consts.USER_ID, account.GetHashedEmail());
var version = await apiClient
.Version.Get(receiveInfo.SelectedVersionId, receiveInfo.ProjectId, cancellationToken)
.ConfigureAwait(false);
using var transport = _serverTransportFactory.Create(account, receiveInfo.ProjectId);
double? previousPercentage = null;
_progressDisplayManager.Begin();
Base commitObject = await _operations
.Receive2(
new Uri(account.serverInfo.url),
receiveInfo.ProjectId,
version.referencedObject,
account.token,
onProgressAction: new PassthroughProgress(args =>
{
if (args.ProgressEvent == ProgressEvent.CacheCheck || args.ProgressEvent == ProgressEvent.DownloadBytes)
{
switch (args.ProgressEvent)
{
case ProgressEvent.CacheCheck:
previousPercentage = _progressDisplayManager.CalculatePercentage(args);
break;
}
}
if (!_progressDisplayManager.ShouldUpdate())
{
return;
}
switch (args.ProgressEvent)
{
case ProgressEvent.CacheCheck:
case ProgressEvent.DownloadBytes:
onOperationProgressed.Report(new("Checking and Downloading... ", previousPercentage));
break;
case ProgressEvent.DeserializeObject:
onOperationProgressed.Report(new("Deserializing ...", _progressDisplayManager.CalculatePercentage(args)));
break;
}
}),
cancellationToken: cancellationToken
)
.ConfigureAwait(false);
await apiClient
.Version.Received(new(version.id, receiveInfo.ProjectId, receiveInfo.SourceApplication), cancellationToken)
.ConfigureAwait(false);
return commitObject;
}
}
@@ -0,0 +1,74 @@
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using Rhino.Geometry;
using Speckle.Connectors.Common.Operations;
using Speckle.Converters.Common;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public class GrasshopperSendOperation
{
private readonly IRootObjectSender _baseObjectSender;
private readonly IRootToSpeckleConverter _converter;
public GrasshopperSendOperation(IRootObjectSender baseObjectSender, IRootToSpeckleConverter converter)
{
_baseObjectSender = baseObjectSender;
_converter = converter;
}
public async Task<GrashopperSendOperationResult> Execute(
IReadOnlyDictionary<string, GH_Structure<IGH_Goo>> objects,
SendInfo sendInfo,
IProgress<CardProgress> onOperationProgressed,
CancellationToken ct = default
)
{
var elements = new List<Base>();
foreach (var keypair in objects)
{
elements.Add(ConvertGhStructureToCollection(keypair.Key, keypair.Value));
}
var buildResult = new Collection("Grasshopper Model") { elements = elements, ["version"] = 3 };
var result = await _baseObjectSender.Send(buildResult, sendInfo, onOperationProgressed, ct).ConfigureAwait(false);
return new(result.RootId);
}
private Collection ConvertGhStructureToCollection(string name, GH_Structure<IGH_Goo> tree)
{
var result = tree.Paths.Select(path =>
{
var pathElements = tree.get_Branch(path) as IList<IGH_Goo>;
var convertedElements = new List<Base>();
pathElements.NotNull();
foreach (var pathElement in pathElements)
{
try
{
var goo = pathElement.UnwrapGoo<GeometryBase>();
var converted = _converter.Convert(goo);
convertedElements.Add(converted);
}
catch (Exception e) when (!e.IsFatal())
{
Console.WriteLine(e);
}
}
return new Collection(path.ToString()) { elements = convertedElements };
});
return new Collection(name) { elements = result.Cast<Base>().ToList() };
}
}
public record GrashopperSendOperationResult(string RootId);
@@ -0,0 +1,67 @@
using Rhino;
using Rhino.Geometry;
using Speckle.DoubleNumerics;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public static class GrasshopperHelpers
{
public static string ToSpeckleString(this UnitSystem unitSystem)
{
switch (unitSystem)
{
case UnitSystem.None:
return Units.Meters;
case UnitSystem.Millimeters:
return Units.Millimeters;
case UnitSystem.Centimeters:
return Units.Centimeters;
case UnitSystem.Meters:
return Units.Meters;
case UnitSystem.Kilometers:
return Units.Kilometers;
case UnitSystem.Inches:
return Units.Inches;
case UnitSystem.Feet:
return Units.Feet;
case UnitSystem.Yards:
return Units.Yards;
case UnitSystem.Miles:
return Units.Miles;
case UnitSystem.Unset:
return Units.Meters;
default:
throw new UnitNotSupportedException($"The Unit System \"{unitSystem}\" is unsupported.");
}
}
public static Transform MatrixToTransform(Matrix4x4 matrix, string units)
{
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
var conversionFactor = Units.GetConversionFactor(units, currentDoc.ModelUnitSystem.ToSpeckleString());
var t = Transform.Identity;
t.M00 = matrix.M11;
t.M01 = matrix.M12;
t.M02 = matrix.M13;
t.M03 = matrix.M14 * conversionFactor;
t.M10 = matrix.M21;
t.M11 = matrix.M22;
t.M12 = matrix.M23;
t.M13 = matrix.M24 * conversionFactor;
t.M20 = matrix.M31;
t.M21 = matrix.M32;
t.M22 = matrix.M33;
t.M23 = matrix.M34 * conversionFactor;
t.M30 = matrix.M41;
t.M31 = matrix.M42;
t.M32 = matrix.M43;
t.M33 = matrix.M44;
return t;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,104 @@
using Speckle.Connectors.Common.Operations;
using Speckle.Sdk.Api;
using Speckle.Sdk.Api.GraphQL.Models;
using Speckle.Sdk.Common;
using Version = Speckle.Sdk.Api.GraphQL.Models.Version;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public abstract record SpeckleUrlModelResource(string Server, string ProjectId)
{
public abstract Task<ReceiveInfo> GetReceiveInfo(Client client, CancellationToken cancellationToken = default);
public abstract Task<SendInfo> GetSendInfo(Client client, CancellationToken cancellationToken = default);
}
public record SpeckleUrlLatestModelVersionResource(string Server, string ProjectId, string ModelId)
: SpeckleUrlModelResource(Server, ProjectId)
{
public override async Task<ReceiveInfo> GetReceiveInfo(Client client, CancellationToken cancellationToken = default)
{
Project project = await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
ModelWithVersions model = await client
.Model.GetWithVersions(ModelId, ProjectId, 1, null, null, cancellationToken)
.ConfigureAwait(false);
Version version = model.versions.items[0];
var info = new ReceiveInfo(
client.Account.id,
new Uri(Server),
ProjectId,
project.name,
ModelId,
model.name,
version.id,
version.sourceApplication.NotNull()
);
return info;
}
public override async Task<SendInfo> GetSendInfo(Client client, CancellationToken cancellationToken = default)
{
// We don't care about the return info, we just want to be sure we have access and everything exists.
await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
await client.Model.Get(ModelId, ProjectId, cancellationToken).ConfigureAwait(false);
return new SendInfo(
client.Account.id,
new Uri(Server),
ProjectId,
ModelId,
"Grasshopper8" // TODO: Grab from the right place!
);
}
}
public record SpeckleUrlModelVersionResource(string Server, string ProjectId, string ModelId, string VersionId)
: SpeckleUrlModelResource(Server, ProjectId)
{
public override async Task<ReceiveInfo> GetReceiveInfo(Client client, CancellationToken cancellationToken = default)
{
Project project = await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
Model model = await client.Model.Get(ModelId, ProjectId, cancellationToken).ConfigureAwait(false);
Version version = await client.Version.Get(VersionId, ProjectId, cancellationToken).ConfigureAwait(false);
var info = new ReceiveInfo(
client.Account.id,
new Uri(Server),
ProjectId,
project.name,
ModelId,
model.name,
VersionId,
version.sourceApplication.NotNull()
);
return info;
}
public override async Task<SendInfo> GetSendInfo(Client client, CancellationToken cancellationToken = default)
{
// We don't care about the return info, we just want to be sure we have access and everything exists.
await client.Project.Get(ProjectId, cancellationToken).ConfigureAwait(false);
await client.Model.Get(ModelId, ProjectId, cancellationToken).ConfigureAwait(false);
return new SendInfo(
client.Account.id,
new Uri(Server),
ProjectId,
ModelId,
"Grasshopper8" // TODO: Grab from the right place!
);
}
}
public record SpeckleUrlModelObjectResource(string Server, string ProjectId, string ObjectId)
: SpeckleUrlModelResource(Server, ProjectId)
{
public override Task<ReceiveInfo> GetReceiveInfo(Client client, CancellationToken cancellationToken = default) =>
throw new NotImplementedException("Object Resources are not supported yet");
public override Task<SendInfo> GetSendInfo(Client client, CancellationToken cancellationToken = default) =>
throw new NotImplementedException("Object Resources are not supported yet");
}
@@ -0,0 +1,82 @@
using System.Text.RegularExpressions;
using Speckle.Sdk;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public record SpeckleResourceBuilder
{
/// <summary>
/// The ReGex pattern to determine if a URL's AbsolutePath is a Frontend2 URL or not.
/// </summary>
private static readonly Regex s_fe2UrlRegex =
new(
@"/projects/(?<projectId>[\w\d]+)(?:/models/(?<model>[\w\d]+(?:@[\w\d]+)?)(?:,(?<additionalModels>[\w\d]+(?:@[\w\d]+)?))*)?"
);
public static SpeckleUrlModelResource[] FromUrlString(string speckleModel)
{
var uri = new Uri(speckleModel);
var serverUrl = uri.GetLeftPart(UriPartial.Authority);
var match = s_fe2UrlRegex.Match(speckleModel);
var result = ParseFe2RegexMatch(serverUrl, match);
return result;
}
private static SpeckleUrlModelResource[] ParseFe2RegexMatch(string serverUrl, Match match)
{
var projectId = match.Groups["projectId"];
var model = match.Groups["model"];
var additionalModels = match.Groups["additionalModels"];
if (!projectId.Success)
{
throw new SpeckleException("The provided url is not a valid Speckle url");
}
if (!model.Success)
{
throw new SpeckleException("The provided url is not pointing to any model in the project.");
}
if (model.Value == "all")
{
throw new NotSupportedException("Fetching all models is not supported.");
}
if (model.Value.StartsWith("$"))
{
throw new NotSupportedException("Federation model urls are not supported");
}
var modelRes = GetUrlModelResource(serverUrl, projectId.Value, model.Value);
var result = new List<SpeckleUrlModelResource> { modelRes };
if (additionalModels.Success)
{
foreach (Capture additionalModelsCapture in additionalModels.Captures)
{
var extraModel = GetUrlModelResource(serverUrl, projectId.Value, additionalModelsCapture.Value);
result.Add(extraModel);
}
}
return result.ToArray();
}
private static SpeckleUrlModelResource GetUrlModelResource(string serverUrl, string projectId, string modelValue)
{
if (modelValue.Length == 32)
{
return new SpeckleUrlModelObjectResource(serverUrl, projectId, modelValue); // Model value is an ObjectID
}
if (!modelValue.Contains('@'))
{
return new SpeckleUrlLatestModelVersionResource(serverUrl, projectId, modelValue); // Model has no version attached
}
var res = modelValue.Split('@');
return new SpeckleUrlModelVersionResource(serverUrl, projectId, res[0], res[1]);
}
}
@@ -0,0 +1,49 @@
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Parameters;
// public class SpeckleCollectionWrapper : Base
// {
// public Collection OriginalObject { get; set; }
//
// public override string ToString() => $"{OriginalObject.name} [{OriginalObject.elements.Count}]";
// }
public class SpeckleCollectionGoo : GH_Goo<Collection> //, IGH_PreviewData // can be made previewable later
{
public override IGH_Goo Duplicate() => throw new NotImplementedException();
public override string ToString() => $"{Value.name} ({Value.elements.Count})";
public override bool IsValid => true;
public override string TypeName => "Speckle collection wrapper";
public override string TypeDescription => "Speckle collection wrapper";
public SpeckleCollectionGoo() { }
public SpeckleCollectionGoo(Collection value)
{
Value = value;
}
}
public class SpeckleCollectionWrapperParam : GH_Param<SpeckleCollectionGoo>
{
public SpeckleCollectionWrapperParam()
: this(GH_ParamAccess.item) { }
public SpeckleCollectionWrapperParam(IGH_InstanceDescription tag)
: base(tag) { }
public SpeckleCollectionWrapperParam(IGH_InstanceDescription tag, GH_ParamAccess access)
: base(tag, access) { }
public SpeckleCollectionWrapperParam(GH_ParamAccess access)
: base("Speckle Collection Wrapper", "SCO", "XXXXX", "Speckle", "Params", access) { }
public override Guid ComponentGuid => new("6E871D5B-B221-4992-882A-EFE6796F3010");
protected override Bitmap Icon => BitmapBuilder.CreateHexagonalBitmap("C");
}
@@ -0,0 +1,156 @@
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Rhino.Display;
using Rhino.Geometry;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Parameters;
/// <summary>
/// Wrapper around a received speckle object. It encapsulates the original object, its converted form and its original path.
/// </summary>
public class SpeckleObject : Base
{
public Base OriginalObject { get; set; }
public GeometryBase GeometryBase { get; set; }
public List<Collection> Path { get; set; }
// RenderMaterial, ColorProxies, Properties (?)
public override string ToString() => $"Speckle Wrapper [{GeometryBase.GetType().Name}]";
public void DrawPreview(IGH_PreviewArgs args, bool isSelected = false)
{
switch (GeometryBase)
{
case Mesh m:
args.Display.DrawMeshShaded(m, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
break;
case Brep b:
args.Display.DrawBrepShaded(b, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
args.Display.DrawBrepWires(
b,
isSelected ? args.WireColour_Selected : args.WireColour,
args.DefaultCurveThickness
);
break;
case Extrusion e:
args.Display.DrawMeshShaded(
e.GetMesh(MeshType.Any),
isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial
);
break;
case SubD d:
args.Display.DrawSubDShaded(d, isSelected ? args.ShadeMaterial_Selected : args.ShadeMaterial);
args.Display.DrawSubDWires(
d,
isSelected ? args.WireColour_Selected : args.WireColour,
args.DefaultCurveThickness
);
break;
case Curve c:
args.Display.DrawCurve(c, isSelected ? args.WireColour_Selected : args.WireColour, args.DefaultCurveThickness);
break;
}
}
public void DrawPreviewRaw(DisplayPipeline display, DisplayMaterial material)
{
switch (GeometryBase)
{
case Mesh m:
display.DrawMeshShaded(m, material);
break;
case Brep b:
display.DrawBrepShaded(b, material);
display.DrawBrepWires(b, material.Diffuse);
break;
case Extrusion e:
display.DrawMeshShaded(e.GetMesh(MeshType.Any), material);
break;
case SubD d:
display.DrawSubDShaded(d, material);
display.DrawSubDWires(d, material.Diffuse, display.DefaultCurveThickness);
break;
case Curve c:
display.DrawCurve(c, material.Diffuse);
break;
}
}
}
public class SpeckleObjectGoo : GH_Goo<SpeckleObject>, IGH_PreviewData
{
public override IGH_Goo Duplicate() => throw new NotImplementedException();
public override string ToString() => $@"Speckle Object Goo [{m_value.OriginalObject.speckle_type}]";
public override bool IsValid => true;
public override string TypeName => "Speckle object wrapper";
public override string TypeDescription => "A wrapper around speckle grasshopper objects.";
public override bool CastFrom(object source)
{
switch (source)
{
case SpeckleObject speckleGrasshopperObject:
Value = speckleGrasshopperObject;
return true;
case GH_Goo<SpeckleObject> speckleGrasshopperObjectGoo:
Value = speckleGrasshopperObjectGoo.Value;
return true;
}
return false;
}
public override bool CastTo<T>(ref T target)
{
var type = typeof(T);
if (type == typeof(IGH_GeometricGoo))
{
target = (T)(object)GH_Convert.ToGeometricGoo(Value.GeometryBase);
return true;
}
// TODO: cast to material, etc.
return false;
}
public void DrawViewportWires(GH_PreviewWireArgs args)
{
// TODO ?
}
public void DrawViewportMeshes(GH_PreviewMeshArgs args)
{
Value.DrawPreviewRaw(args.Pipeline, args.Material);
}
public BoundingBox ClippingBox => Value.GeometryBase.GetBoundingBox(false);
public SpeckleObjectGoo(SpeckleObject value)
{
Value = value;
}
public SpeckleObjectGoo() { }
}
public class SpeckleObjectParam : GH_Param<SpeckleObjectGoo>
{
public SpeckleObjectParam()
: this(GH_ParamAccess.item) { }
public SpeckleObjectParam(IGH_InstanceDescription tag)
: base(tag) { }
public SpeckleObjectParam(IGH_InstanceDescription tag, GH_ParamAccess access)
: base(tag, access) { }
public SpeckleObjectParam(GH_ParamAccess access)
: base("Speckle Grasshopper Object", "SGO", "XXXXX", "Speckle", "Params", access) { }
public override Guid ComponentGuid => new("22FD5510-D5D3-4101-8727-153FFD329E4F");
}
@@ -0,0 +1,40 @@
using Grasshopper.Kernel.Types;
using Speckle.Connectors.Grasshopper8.HostApp;
namespace Speckle.Connectors.Grasshopper8.Parameters;
public class SpeckleUrlModelResourceGoo : GH_Goo<SpeckleUrlModelResource>
{
public override IGH_Goo Duplicate() => new SpeckleUrlModelResourceGoo() { Value = Value };
public override string ToString() => Value.ToString();
public override bool IsValid => true;
public override string TypeName => "SpeckleUrlModelResource";
public override string TypeDescription => "Points to a model/version/object in a Speckle server";
public override bool CastFrom(object source)
{
switch (source)
{
case SpeckleUrlModelResource resource:
Value = resource;
return true;
default:
return false;
}
}
public override bool CastTo<TOut>(ref TOut target)
{
var type = typeof(TOut);
var success = false;
if (type == typeof(SpeckleUrlModelResource))
{
target = (TOut)(object)Value;
success = true;
}
return success;
}
}
@@ -0,0 +1,20 @@
using Grasshopper.Kernel;
namespace Speckle.Connectors.Grasshopper8.Parameters;
public class SpeckleUrlModelResourceParam : GH_Param<SpeckleUrlModelResourceGoo>
{
public SpeckleUrlModelResourceParam()
: this(GH_ParamAccess.item) { }
public SpeckleUrlModelResourceParam(IGH_InstanceDescription tag)
: base(tag) { }
public SpeckleUrlModelResourceParam(IGH_InstanceDescription tag, GH_ParamAccess access)
: base(tag, access) { }
public SpeckleUrlModelResourceParam(GH_ParamAccess access)
: base("Speckle URL", "spcklUrl", "A Speckle resource", "Speckle", "Resources", access) { }
public override Guid ComponentGuid => new Guid("E5421FC2-F10D-447F-BF23-5C934ABDB2D3");
}
@@ -0,0 +1,44 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Host;
namespace Speckle.Connectors.Grasshopper8;
public class PriorityLoader : GH_AssemblyPriority
{
private IDisposable? _disposableLogger;
public static ServiceProvider? Container { get; set; }
public override GH_LoadingInstruction PriorityLoad()
{
try
{
var services = new ServiceCollection();
_disposableLogger = services.Initialize(HostApplications.Grasshopper, GetVersion());
services.AddRhinoConverters().AddGrasshopper().AddConnectorUtils();
Container = services.BuildServiceProvider();
return GH_LoadingInstruction.Proceed;
}
catch (Exception e) when (!e.IsFatal())
{
// TODO: Top level exception handling here
return GH_LoadingInstruction.Abort;
}
}
private HostAppVersion GetVersion()
{
#if RHINO7
return HostAppVersion.v7;
#elif RHINO8
return HostAppVersion.v8;
#else
throw new NotImplementedException();
#endif
}
}
@@ -0,0 +1,20 @@
{
"profiles": {
"Rhino8Core": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
"commandLineArgs": "/netcore /runscript=\"_Grasshopper\"",
"environmentVariables": {
"RHINO_PACKAGE_DIRS": "$(ProjectDir)$(OutputPath)\\"
}
},
"Rhino8NetFx": {
"commandName": "Executable",
"executablePath": "C:\\Program Files\\Rhino 8\\System\\Rhino.exe",
"commandLineArgs": "/netfx /runscript=\"_Grasshopper\"",
"environmentVariables": {
"RHINO_PACKAGE_DIRS": "$(ProjectDir)$(OutputPath)\\"
}
}
}
}
@@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Models.GraphTraversal;
namespace Speckle.Connectors.Grasshopper8;
public static class ServiceRegistration
{
public static IServiceCollection AddGrasshopper(this IServiceCollection services)
{
services.AddTransient<IHostObjectBuilder, GrasshopperHostObjectBuilder>();
services.AddTransient<GrasshopperReceiveOperation>();
services.AddTransient<GrasshopperSendOperation>();
services.AddSingleton(DefaultTraversal.CreateTraversalFunc());
services.AddScoped<RootObjectUnpacker>();
services.AddTransient<TraversalContextUnpacker>();
services.AddTransient<AccountManager>();
return services;
}
}
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Select the framework(s) you wish to target.
Rhino 6: net45
Rhino 7: net48
Rhino 8 Windows: net48, net7.0, net7.0-windows, net7.0-windows10.0.22000.0, etc
Rhino 8 Mac: net7.0, net7.0-macos, net7.0-macos12.0, etc
-->
<TargetFramework>net48</TargetFramework>
<Configurations>Debug;Release;Local</Configurations>
<TargetExt>.gha</TargetExt>
<NoWarn>$(NoWarn);NU1701;NETSDK1086</NoWarn>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<UseWindowsForms>true</UseWindowsForms>
<DefineConstants>$(DefineConstants);GRASSHOPPER;RHINO8;RHINO7_OR_GREATER;RHINO8_OR_GREATER</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<Title>Speckle.Connectors.Grasshopper8</Title>
<Description>Description of Speckle.Connectors.Grasshopper8</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RhinoCommon" IncludeAssets="compile; build" PrivateAssets="all" />
<PackageReference Include="Grasshopper" IncludeAssets="compile; build" PrivateAssets="all"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Converters\Rhino\Speckle.Converters.Rhino8\Speckle.Converters.Rhino8.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,25 @@
using Grasshopper.Kernel;
namespace Speckle.Connectors.Grasshopper8;
public class Speckle_Connectors_Grasshopper8Info : GH_AssemblyInfo
{
public override string Name => "Speckle.Connector.Grasshopper8";
// Return a 24x24 pixel bitmap to represent this GHA library.
// public override Bitmap Icon => null;
// Return a short string describing the purpose of this GHA library.
public override string Description => "x";
public override Guid Id => new Guid("d711dd2a-9c17-483c-a92d-45c1fc736c46");
// Return a string identifying you or your company.
public override string AuthorName => "Speckle";
// Return a string representing your preferred contact details.
public override string AuthorContact => "info@speckle.systems";
// Return a string representing the version. This returns the same version as the assembly.
public override string AssemblyVersion => GetType().Assembly.GetName().Version.ToString();
}
@@ -0,0 +1,415 @@
{
"version": 2,
"dependencies": {
".NETFramework,Version=v4.8": {
"Grasshopper": {
"type": "Direct",
"requested": "[8.9.24194.18121, )",
"resolved": "8.9.24194.18121",
"contentHash": "ZQ7vT1urn9jG2KLMdT/aVhCsijN349lj2Lrg7+Cd5A84KOW+RIErG6IqH+133hc9HT9D10+7oi/XnIlgYZRzqQ==",
"dependencies": {
"RhinoCommon": "[8.9.24194.18121]"
}
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
"requested": "[1.0.3, )",
"resolved": "1.0.3",
"contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
"dependencies": {
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
}
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"PolySharp": {
"type": "Direct",
"requested": "[1.14.1, )",
"resolved": "1.14.1",
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
},
"RhinoCommon": {
"type": "Direct",
"requested": "[8.9.24194.18121, )",
"resolved": "8.9.24194.18121",
"contentHash": "XRMnm38sBFeMT5AAtRTJdSaql/YNtT02AGi8TEVP1VZ4fkm8VJ1q2nNioWN3tW/+H8Tdi4nV+DuhB/5uE41MCg=="
},
"Speckle.InterfaceGenerator": {
"type": "Direct",
"requested": "[0.9.6, )",
"resolved": "0.9.6",
"contentHash": "HKH7tYrYYlCK1ct483hgxERAdVdMtl7gUKW9ijWXxA1UsYR4Z+TrRHYmzZ9qmpu1NnTycSrp005NYM78GDKV1w=="
},
"GraphQL.Client": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "8yPNBbuVBpTptivyAlak4GZvbwbUcjeQTL4vN1HKHRuOykZ4r7l5fcLS6vpyPyLn0x8FsL31xbOIKyxbmR9rbA==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0",
"GraphQL.Client.Abstractions.Websocket": "6.0.0",
"System.Net.WebSockets.Client.Managed": "1.0.22",
"System.Reactive": "5.0.0"
}
},
"GraphQL.Client.Abstractions": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "h7uzWFORHZ+CCjwr/ThAyXMr0DPpzEANDa4Uo54wqCQ+j7qUKwqYTgOrb1W40sqbvNaZm9v/X7It31SUw0maHA==",
"dependencies": {
"GraphQL.Primitives": "6.0.0"
}
},
"GraphQL.Client.Abstractions.Websocket": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "Nr9bPf8gIOvLuXpqEpqr9z9jslYFJOvd0feHth3/kPqeR3uMbjF5pjiwh4jxyMcxHdr8Pb6QiXkV3hsSyt0v7A==",
"dependencies": {
"GraphQL.Client.Abstractions": "6.0.0"
}
},
"GraphQL.Primitives": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "yg72rrYDapfsIUrul7aF6wwNnTJBOFvuA9VdDTQpPa8AlAriHbufeXYLBcodKjfUdkCnaiggX1U/nEP08Zb5GA=="
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
"dependencies": {
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.CSharp": {
"type": "Transitive",
"resolved": "4.7.0",
"contentHash": "pTj+D3uJWyN3My70i2Hqo+OXixq3Os2D1nJ2x92FFo6sk8fYS1m1WLNTs0Dc1uPaViH0YvEEwvzddQ7y4rhXmA=="
},
"Microsoft.Data.Sqlite": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
"dependencies": {
"Microsoft.Data.Sqlite.Core": "7.0.5",
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
}
},
"Microsoft.Data.Sqlite.Core": {
"type": "Transitive",
"resolved": "7.0.5",
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"Microsoft.Extensions.Configuration": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "nOP8R1mVb/6mZtm2qgAJXn/LFm/2kMjHDAg/QJLFG6CuWYJtaD3p1BwQhufBVvRzL9ceJ/xF0SQ0qsI2GkDQAA==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "65MrmXCziWaQFrI0UHkQbesrX5wTwf9XPjY5yFm/VkgJKFJ5gqvXRoXjIZcf2wLi5ZlwGz/oMYfyURVCWbM5iw==",
"dependencies": {
"Microsoft.Extensions.Primitives": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "vJ9xvOZCnUAIHcGC3SU35r3HKmHTVIeHzo6u/qzlHAqD8m6xv92MLin4oJntTvkpKxVX3vI1GFFkIQtU3AdlsQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "UpZLNLBpIZ0GTebShui7xXYh6DmBHjWM8NxGxZbdQh/bPZ5e6YswqI+bru6BnEL5eWiOdodsXtEz3FROcgi/qg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Primitives": "2.2.0",
"System.ComponentModel.Annotations": "4.5.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "azyQtqbm4fSaDzZHD/J+V6oWMFaf2tWP4WEGIYePLCMw3+b2RQdj9ybgbQyjCshcitQKQ4lEDOZjmSlTTrHxUg==",
"dependencies": {
"System.Memory": "4.5.1",
"System.Runtime.CompilerServices.Unsafe": "4.5.1"
}
},
"Microsoft.NETFramework.ReferenceAssemblies.net48": {
"type": "Transitive",
"resolved": "1.0.3",
"contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"Speckle.DoubleNumerics": {
"type": "Transitive",
"resolved": "4.0.1",
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
},
"Speckle.Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.2",
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
},
"SQLitePCLRaw.bundle_e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
"dependencies": {
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
"SQLitePCLRaw.provider.dynamic_cdecl": "2.1.4"
}
},
"SQLitePCLRaw.core": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
"dependencies": {
"System.Memory": "4.5.3"
}
},
"SQLitePCLRaw.lib.e_sqlite3": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
},
"SQLitePCLRaw.provider.dynamic_cdecl": {
"type": "Transitive",
"resolved": "2.1.4",
"contentHash": "ZsaKKhgYF9B1fvcnOGKl3EycNAwd9CRWX7v0rEfuPWhQQ5Jjpvf2VEHahiLIGHio3hxi3EIKFJw9KvyowWOUAw==",
"dependencies": {
"SQLitePCLRaw.core": "2.1.4"
}
},
"System.Buffers": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "AwarXzzoDwX6BgrhjoJsk6tUezZEozOT5Y9QKF94Gl4JK91I4PIIBkBco9068Y9/Dra8Dkbie99kXB8+1BaYKw=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
"resolved": "4.5.0",
"contentHash": "UxYQ3FGUOtzJ7LfSdnYSFd7+oEv6M8NgUatatIN2HxNtDdlcvFAf+VIq4Of9cDMJEJC0aSRv/x898RYhB4Yppg=="
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
"dependencies": {
"System.Buffers": "4.4.0",
"System.Numerics.Vectors": "4.4.0",
"System.Runtime.CompilerServices.Unsafe": "4.5.2"
}
},
"System.Net.WebSockets.Client.Managed": {
"type": "Transitive",
"resolved": "1.0.22",
"contentHash": "WqEOxPlXjuZrIjUtXNE9NxEfU/n5E35iV2PtoZdJSUC4tlrqwHnTee+wvMIM4OUaJWmwrymeqcgYrE0IkGAgLA==",
"dependencies": {
"System.Buffers": "4.4.0",
"System.Numerics.Vectors": "4.4.0"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
},
"System.Reactive": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==",
"dependencies": {
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "4.5.3",
"contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"speckle.connectors.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
"Speckle.Connectors.Logging": "[1.0.0, )",
"Speckle.Objects": "[3.1.0-dev.191, )",
"Speckle.Sdk": "[3.1.0-dev.191, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )"
}
},
"speckle.connectors.dui": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Sdk": "[3.1.0-dev.191, )",
"Speckle.Sdk.Dependencies": "[3.1.0-dev.191, )",
"System.Threading.Tasks.Dataflow": "[6.0.0, )"
}
},
"speckle.connectors.dui.webview": {
"type": "Project",
"dependencies": {
"Microsoft.Web.WebView2": "[1.0.1938.49, )",
"Speckle.Connectors.DUI": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
"type": "Project"
},
"speckle.connectors.rhino7": {
"type": "Project",
"dependencies": {
"RhinoCommon": "[7.13.21348.13001, )",
"RhinoWindows": "[7.13.21348.13001, )",
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Connectors.DUI.WebView": "[1.0.0, )",
"Speckle.Converters.Rhino7": "[1.0.0, )"
}
},
"speckle.converters.common": {
"type": "Project",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
"Speckle.Objects": "[3.1.0-dev.191, )"
}
},
"speckle.converters.rhino7": {
"type": "Project",
"dependencies": {
"RhinoCommon": "[7.13.21348.13001, )",
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"speckle.converters.rhino8": {
"type": "Project",
"dependencies": {
"RhinoCommon": "[8.9.24194.18121, )",
"Speckle.Converters.Common": "[1.0.0, )"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "MZtBIwfDFork5vfjpJdG5g8wuJFt7d/y3LOSVVtDK/76wlbtz6cjltfKHqLx2TKVqTj5/c41t77m1+h20zqtPA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "Nxqhadc9FCmFHzU+fz3oc8sFlE6IadViYg8dfUdGzJZ2JUxnCsRghBhhOWdM4B2zSZqEc+0BjliBh/oNdRZuig==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.2.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging.Abstractions": "2.2.0",
"Microsoft.Extensions.Options": "2.2.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
"resolved": "2.2.0",
"contentHash": "B2WqEox8o+4KUOpL7rZPyh6qYjik8tHi2tN8Z9jZkHzED8ElYgZa/h6K+xliB435SqUcWT290Fr2aa8BtZjn8A=="
},
"Microsoft.Web.WebView2": {
"type": "CentralTransitive",
"requested": "[1.0.1938.49, )",
"resolved": "1.0.1938.49",
"contentHash": "z8KnFnaTYzhA/ZnyRX0qGfS1NU5ZBJeClAH64F0fVDvdDJTvME7xl6zTJ0Jlfe1BtL3C0NH9xTy64shg2baKdw=="
},
"RhinoWindows": {
"type": "CentralTransitive",
"requested": "[8.9.24194.18121, )",
"resolved": "7.13.21348.13001",
"contentHash": "V94T8emmJmFfmbd5cu+uTNS0neZApx1Q5MXvsQGFtt/mEGEbdHE+dFOETNgbOOJXSdNboAnCR3uo0GosOFX+/g==",
"dependencies": {
"RhinoCommon": "[7.13.21348.13001]"
}
},
"Speckle.Objects": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.191, )",
"resolved": "3.1.0-dev.191",
"contentHash": "+m7jRFm0ABbkcSz2UphdxAsislY10IpQ1u79c8a3aVvegLjnsVQZ1sXfRIRO1aFdulkhjYKXYpB3N9M8Z+epgQ==",
"dependencies": {
"Speckle.Sdk": "3.1.0-dev.191"
}
},
"Speckle.Sdk": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.191, )",
"resolved": "3.1.0-dev.191",
"contentHash": "VVT3LJiYlhqnggxxdeTt1QLrqfxDb044x0yX6kxS9b5MRzeDvK2Vz86pLDfuHs+SXvDimRVfYx1M42IW/aPcTQ==",
"dependencies": {
"GraphQL.Client": "6.0.0",
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
"Microsoft.CSharp": "4.7.0",
"Microsoft.Data.Sqlite": "7.0.5",
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
"Microsoft.Extensions.Logging": "2.2.0",
"Speckle.DoubleNumerics": "4.0.1",
"Speckle.Newtonsoft.Json": "13.0.2",
"Speckle.Sdk.Dependencies": "3.1.0-dev.191"
}
},
"Speckle.Sdk.Dependencies": {
"type": "CentralTransitive",
"requested": "[3.1.0-dev.191, )",
"resolved": "3.1.0-dev.191",
"contentHash": "EmEOyjsGsNi56Z/ZoBOn8WirTmIT2yqWvlUeUh0BSPX2TDMZXHTKOM/kHmP6HSd10KVFn2Zo/ItY7/K9iRtL1Q=="
},
"System.Threading.Tasks.Dataflow": {
"type": "CentralTransitive",
"requested": "[6.0.0, )",
"resolved": "6.0.0",
"contentHash": "+tyDCU3/B1lDdOOAJywHQoFwyXIUghIaP2BxG79uvhfTnO+D9qIgjVlL/JV2NTliYbMHpd6eKDmHp2VHpij7MA=="
}
}
}
}
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -321,6 +316,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -21,6 +21,7 @@
<ProjectReference Include="..\..\..\Converters\Rhino\Speckle.Converters.Rhino8\Speckle.Converters.Rhino8.csproj" />
<ProjectReference Include="..\..\..\Sdk\Speckle.Connectors.Common\Speckle.Connectors.Common.csproj" />
<ProjectReference Include="..\..\..\DUI3\Speckle.Connectors.DUI.WebView\Speckle.Connectors.DUI.WebView.csproj" />
<ProjectReference Include="..\Speckle.Connectors.Grasshopper8\Speckle.Connectors.Grasshopper8.csproj" />
</ItemGroup>
<ItemGroup>
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -295,6 +290,13 @@
"Speckle.Connectors.DUI": "[1.0.0, )"
}
},
"speckle.connectors.grasshopper8": {
"type": "Project",
"dependencies": {
"Speckle.Connectors.Common": "[1.0.0, )",
"Speckle.Converters.Rhino8": "[1.0.0, )"
}
},
"speckle.connectors.logging": {
"type": "Project"
},
@@ -321,6 +323,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -178,11 +178,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -381,6 +376,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -192,11 +192,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -462,6 +457,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -126,11 +126,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -227,6 +222,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -305,6 +300,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -121,11 +121,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -261,6 +256,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -275,6 +270,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -275,6 +270,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -139,11 +139,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -275,6 +270,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -270,6 +265,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -189,11 +189,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -355,6 +350,12 @@
"NUnit": "[4.1.0, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -189,11 +189,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -355,6 +350,12 @@
"NUnit": "[4.1.0, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -189,11 +189,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -355,6 +350,12 @@
"NUnit": "[4.1.0, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -121,11 +121,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -222,6 +217,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -189,11 +189,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -355,6 +350,12 @@
"NUnit": "[4.1.0, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -266,6 +261,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -11,27 +11,44 @@ public static class DisplayMeshExtractor
var renderMeshes = obj.GetMeshes(RG.MeshType.Render);
if (renderMeshes.Length == 0)
{
switch (obj)
{
case BrepObject brep:
renderMeshes = RG.Mesh.CreateFromBrep(brep.BrepGeometry, new(0.05, 0.05));
break;
case ExtrusionObject extrusion:
renderMeshes = RG.Mesh.CreateFromBrep(extrusion.ExtrusionGeometry.ToBrep(), new(0.05, 0.05));
break;
case SubDObject subDObject:
#pragma warning disable CA2000
var mesh = RG.Mesh.CreateFromSubD(subDObject.Geometry as RG.SubD, 0);
#pragma warning restore CA2000
renderMeshes = [mesh];
break;
default:
throw new ConversionException($"Unsupported object for display mesh generation {obj.GetType().FullName}");
}
renderMeshes = GetDisplayMeshes(obj.Geometry);
}
var joinedMesh = new RG.Mesh();
joinedMesh.Append(renderMeshes);
return joinedMesh;
}
public static RG.Mesh GetDisplayMesh(RG.GeometryBase obj)
{
// note: unsure this is nice, we get bigger meshes - we should to benchmark (conversion time vs size tradeoffs)
var renderMeshes = GetDisplayMeshes(obj);
var joinedMesh = new RG.Mesh();
joinedMesh.Append(renderMeshes);
return joinedMesh;
}
private static RG.Mesh[] GetDisplayMeshes(RG.GeometryBase obj)
{
RG.Mesh[] renderMeshes;
switch (obj)
{
case RG.Brep brep:
renderMeshes = RG.Mesh.CreateFromBrep(brep, new(0.05, 0.05));
break;
case RG.Extrusion extrusion:
renderMeshes = RG.Mesh.CreateFromBrep(extrusion.ToBrep(), new(0.05, 0.05));
break;
case RG.SubD subDObject:
#pragma warning disable CA2000
var mesh = RG.Mesh.CreateFromSubD(subDObject, 0);
#pragma warning restore CA2000
renderMeshes = [mesh];
break;
default:
throw new ConversionException($"Unsupported object for display mesh generation {obj.GetType().FullName}");
}
return renderMeshes;
}
}
@@ -0,0 +1,41 @@
using Speckle.Converters.Common;
using Speckle.Converters.Common.Objects;
using Speckle.Converters.Rhino.ToSpeckle.Encoding;
using Speckle.Converters.Rhino.ToSpeckle.Meshing;
using Speckle.Sdk.Models;
namespace Speckle.Converters.Rhino.ToSpeckle.TopLevel;
[NameAndRankValue(nameof(RG.Brep), NameAndRankValueAttribute.SPECKLE_DEFAULT_RANK)]
public class BrepToSpeckleTopLevelConverter : IToSpeckleTopLevelConverter
{
private readonly ITypedConverter<RG.Mesh, SOG.Mesh> _meshConverter;
private readonly IConverterSettingsStore<RhinoConversionSettings> _settingsStore;
public BrepToSpeckleTopLevelConverter(
ITypedConverter<RG.Mesh, SOG.Mesh> meshConverter,
IConverterSettingsStore<RhinoConversionSettings> settingsStore
)
{
_meshConverter = meshConverter;
_settingsStore = settingsStore;
}
public Base Convert(object target)
{
var brepObject = (RG.Brep)target;
var brepEncoding = RawEncodingCreator.Encode(brepObject, _settingsStore.Current.Document);
var mesh = DisplayMeshExtractor.GetDisplayMesh(brepObject);
var displayValue = new List<SOG.Mesh> { _meshConverter.Convert(mesh) };
var bx = new SOG.BrepX()
{
displayValue = displayValue,
encodedValue = brepEncoding,
units = _settingsStore.Current.SpeckleUnits
};
return bx;
}
}
@@ -147,11 +147,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -303,6 +298,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -152,11 +152,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -344,6 +339,12 @@
"Speckle.Objects": "[3.1.0-dev.216, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -180,11 +180,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -358,6 +353,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -130,11 +130,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -291,6 +286,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -473,11 +474,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -599,6 +595,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -167,11 +167,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -337,6 +332,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
+1 -1
View File
@@ -31,7 +31,7 @@
<!-- Logging -->
CA1848;CA2254;CA1727;
<!-- Others we don't want -->
CA1815;CA1725;
CA1815;CA1725;CA1501;
<!-- Package using wrong RIDs (Net8 changed them). Usually fixable by updating. -->
NETSDK1206;
$(NoWarn)
+3 -1
View File
@@ -7,6 +7,7 @@
<PackageVersion Include="FluentAssertions" Version="6.12.1" />
<PackageVersion Include="Glob" Version="1.1.9" />
<PackageVersion Include="ILRepack.FullAuto" Version="1.6.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageVersion Include="Moq" Version="4.20.70" />
<PackageVersion Include="Microsoft.Build" Version="17.11.4" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
@@ -19,6 +20,7 @@
<PackageVersion Include="NUnit3TestAdapter" version="4.6.0" />
<PackageVersion Include="Revit.Async" Version="2.1.1" />
<PackageVersion Include="RhinoCommon" Version="8.9.24194.18121" />
<PackageVersion Include="Grasshopper" Version="8.9.24194.18121" />
<PackageVersion Include="RhinoWindows" Version="8.9.24194.18121" />
<PackageVersion Include="Speckle.CSI.API" Version="2.4.0" />
<PackageVersion Include="Tekla.Structures.Dialog" Version="2024.0.4" PrivateAssets="all" IncludeAssets="compile; build" />
@@ -50,4 +52,4 @@
<GlobalPackageReference Include="Speckle.InterfaceGenerator" Version="0.9.6" />
<GlobalPackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
</ItemGroup>
</Project>
</Project>
@@ -38,7 +38,8 @@ public sealed class SendConversionResult : ConversionResult
}
}
public sealed class ReceiveConversionResult : ConversionResult
// HACK: I've unsealed this for Grasshopper, non-ideal. Should be discussed and a better pattern may be implemented.
public class ReceiveConversionResult : ConversionResult
{
public ReceiveConversionResult(
Status status,
@@ -8,7 +8,7 @@ namespace Speckle.Connectors.Common.Operations.Receive;
/// <summary>
/// Utility class to unpack layer structure from path of collections or property tree.
/// </summary>
public abstract class TraversalContextUnpacker
public class TraversalContextUnpacker
{
public IReadOnlyCollection<(Collection[] path, Base current)> GetAtomicObjectsWithPath(
IEnumerable<TraversalContext> atomicObjects
@@ -173,11 +173,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -324,6 +319,12 @@
"speckle.connectors.logging": {
"type": "Project"
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -199,15 +199,6 @@
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.Extensions.Diagnostics.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
@@ -379,6 +370,16 @@
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -180,11 +180,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -348,6 +343,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -189,11 +189,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -342,6 +337,12 @@
"NUnit": "[4.1.0, )"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
@@ -74,7 +74,7 @@ public sealed class ConverterWithFallback : IRootToHostConverter
// if the host app returns a list of objects as the result of the fallback conversion, we zip them together with the original base display value objects that generated them.
if (conversionResult is IEnumerable<object> result)
{
return result.Zip(displayValue, (a, b) => (a, b));
return result.Zip(displayValue, (a, b) => (a, b)).ToList();
}
// if not, and the host app "merges" together somehow multiple display values into one entity, we return that.
@@ -147,11 +147,6 @@
"Microsoft.Extensions.Configuration": "2.2.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "2.2.0",
@@ -295,6 +290,12 @@
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "2.2.0",
"contentHash": "f9hstgjVmr6rmrfGSpfsVOl2irKAgr1QjrSi3FgnS7kulxband50f2brRLwySAQTADPZeTdow0mpSMcoAdadCw=="
},
"Microsoft.Extensions.Logging": {
"type": "CentralTransitive",
"requested": "[2.2.0, )",
+8
View File
@@ -189,6 +189,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connector.Tekla2023
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Converter.Tekla2023", "Converters\Tekla\Speckle.Converter.Tekla2023\Speckle.Converter.Tekla2023.csproj", "{8F9181C2-1808-44C0-A33A-5BAE40C49E63}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Connectors.Grasshopper8", "Connectors\Rhino\Speckle.Connectors.Grasshopper8\Speckle.Connectors.Grasshopper8.csproj", "{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CSi", "CSi", "{073F40A8-6C95-41C1-A2F3-369FFFCB9520}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Speckle.Connectors.ETABS22", "Connectors\CSi\Speckle.Connectors.ETABS22\Speckle.Connectors.ETABS22.csproj", "{7C49337A-6F7B-47AB-B549-42E799E89CF2}"
@@ -508,6 +509,12 @@ Global
{8F9181C2-1808-44C0-A33A-5BAE40C49E63}.Local|Any CPU.Build.0 = Local|Any CPU
{8F9181C2-1808-44C0-A33A-5BAE40C49E63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F9181C2-1808-44C0-A33A-5BAE40C49E63}.Release|Any CPU.Build.0 = Release|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Local|Any CPU.ActiveCfg = Debug|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Local|Any CPU.Build.0 = Debug|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085}.Release|Any CPU.Build.0 = Release|Any CPU
{7C49337A-6F7B-47AB-B549-42E799E89CF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C49337A-6F7B-47AB-B549-42E799E89CF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C49337A-6F7B-47AB-B549-42E799E89CF2}.Local|Any CPU.ActiveCfg = Debug|Any CPU
@@ -618,6 +625,7 @@ Global
{C552C165-5023-47AB-9EE1-1EA61819D2B1} = {696086E4-D8CC-4FE0-A9B3-5F10B9089B55}
{025C85F8-F741-4600-BC46-5FEAD754B65D} = {C552C165-5023-47AB-9EE1-1EA61819D2B1}
{8F9181C2-1808-44C0-A33A-5BAE40C49E63} = {C552C165-5023-47AB-9EE1-1EA61819D2B1}
{8F6AD59B-FE43-41AE-8F47-7B9752BA0085} = {5929C9C7-F971-449E-BC5B-4486016BD11F}
{073F40A8-6C95-41C1-A2F3-369FFFCB9520} = {42826721-9A18-4762-8BA9-F1429DD5C5B1}
{7C49337A-6F7B-47AB-B549-42E799E89CF2} = {C6CD9332-874A-49DA-BEB6-3FAA5A700793}
{C6CD9332-874A-49DA-BEB6-3FAA5A700793} = {073F40A8-6C95-41C1-A2F3-369FFFCB9520}