Compare commits

...

8 Commits

Author SHA1 Message Date
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
80 changed files with 3072 additions and 244 deletions
@@ -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",
@@ -290,6 +285,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 Task<TOutput> PerformTask(TInput input, CancellationToken cancellationToken = default)
{
/*using*/var scope = PriorityLoader.Container.CreateScope(); // NOTE: this component does not work as intended in e.g the receive component; the scope gets disposed before the task completes.
return PerformScopedTask(input, scope, cancellationToken);
}
protected abstract Task<TOutput> PerformScopedTask(
TInput input,
IServiceScope scope,
CancellationToken cancellationToken = default
);
}
@@ -0,0 +1,60 @@
using Grasshopper.Kernel;
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);
}
return;
}
if (!GetSolveResults(da, out TOutput result))
{
// 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 (SpeckleException e)
{
Console.WriteLine(e);
return;
}
}
if (result is not null)
{
SetOutput(da, result);
}
}
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,165 @@
using Grasshopper.Kernel;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Sdk;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
public record CreateCollectionComponentInput(
Collection? Collection,
string? Name,
List<Base>? Elements,
List<Collection>? Collections
);
public record CreateCollectionComponentOutput(Collection Collection);
public class CreateCollectionComponent
: SpeckleTaskCapableComponent<CreateCollectionComponentInput, CreateCollectionComponentOutput>
{
public CreateCollectionComponent()
: base("Create Collection", "CrCol", "Creates a new collection", "Speckle", "Collections") { }
public override Guid ComponentGuid => new("6A9EDFDE-8AC4-4E28-B455-45DF42E2172B");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
var colIndex = pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.item),
"collection",
"Collection",
"Collection",
GH_ParamAccess.item
);
var nameIndex = pManager.AddTextParameter("Name", "Name", "Name of the collection", GH_ParamAccess.item);
var elementsIndex = pManager.AddParameter(
new SpeckleObjectParam(GH_ParamAccess.list),
"elements",
"Elements",
"Elements of the collection",
GH_ParamAccess.list
);
var collectionsIndex = pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.list),
"collections",
"Collections",
"Sub-collections of the collection",
GH_ParamAccess.list
);
pManager[colIndex].Optional = true;
pManager[nameIndex].Optional = true;
pManager[elementsIndex].Optional = true;
pManager[collectionsIndex].Optional = true;
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
var colIndex = pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.item),
"collection",
"Collection",
"Collection",
GH_ParamAccess.item
);
var nameIndex = pManager.AddTextParameter("Name", "Name", "Name of the collection", GH_ParamAccess.item);
var elementsIndex = pManager.AddParameter(
new SpeckleObjectParam(GH_ParamAccess.list),
"elements",
"Elements",
"Elements of the collection",
GH_ParamAccess.list
);
var collectionsIndex = pManager.AddParameter(
new SpeckleCollectionParam(GH_ParamAccess.list),
"collections",
"Collections",
"Sub-collections of the collection",
GH_ParamAccess.list
);
pManager[colIndex].Optional = true;
pManager[nameIndex].Optional = true;
pManager[elementsIndex].Optional = true;
pManager[collectionsIndex].Optional = true;
}
protected override CreateCollectionComponentInput GetInput(IGH_DataAccess da)
{
Collection? collection = null;
string? name = "";
List<Base>? elements = new List<Base>();
List<Collection>? collections = new List<Collection>();
da.GetData(0, ref collection);
da.GetData(1, ref name);
da.GetDataList(2, elements);
da.GetDataList(3, collections);
return new CreateCollectionComponentInput(collection, name, elements, collections);
}
protected override void SetOutput(IGH_DataAccess da, CreateCollectionComponentOutput result)
{
da.SetData(0, result.Collection);
da.SetData(1, result.Collection.name);
da.SetDataList(2, result.Collection.elements.Where(e => e is not Collection));
da.SetDataList(3, result.Collection.elements.Where(e => e is Collection));
}
protected override Task<CreateCollectionComponentOutput> PerformTask(
CreateCollectionComponentInput input,
CancellationToken cancellationToken = default
)
{
if (input.Collection is null)
{
// Create new collection
if (input.Name is null)
{
throw new SpeckleException("New collections must have a name");
}
var collection = new Collection(input.Name) { elements = input.Elements ?? new List<Base>() };
var result = new CreateCollectionComponentOutput(collection);
return Task.FromResult(result);
}
else
{
var collection = new Collection(input.Collection.name) { elements = input.Collection.elements };
// Create new collection
if (input.Name is not null && input.Name.Length != 0)
{
collection.name = input.Name;
}
var elements = new List<Base>();
if (input.Elements is not null && input.Elements.Count != 0)
{
elements.AddRange(input.Elements);
}
else
{
elements.AddRange(collection.elements.Where(e => e is not Collection));
}
if (input.Collections is not null && input.Collections.Count != 0)
{
elements.AddRange(input.Collections);
}
else
{
elements.AddRange(collection.elements.Where(e => e is Collection));
}
var result = new CreateCollectionComponentOutput(collection);
return Task.FromResult(result);
}
}
}
@@ -0,0 +1,257 @@
using System.Collections;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Rhino.Display;
using Rhino.Geometry;
using Speckle.Connectors.Grasshopper8.HostApp;
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.AddGenericParameter("Collection", "C", "Collection to unpack", GH_ParamAccess.item);
protected override void RegisterOutputParams(GH_OutputParamManager pManager) { }
private List<SpeckleGrasshopperObject> _previewObjects = new();
protected override void SolveInstance(IGH_DataAccess da)
{
Collection res = new();
da.GetData("Collection", ref res);
var c = res;
Name = c.name;
NickName = c.name;
var objects = c.elements.Where(el => el is not Collection).OfType<SpeckleGrasshopperObject>().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 = "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));
}
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["treePath"] as string; // Note: this is a reminder for the future
var nickName = collection.name;
if (collection.name.Length > 12)
{
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<SpeckleGrasshopperObject>());
}
outputParams.Add(new OutputParamWrapper(param, hasInnerCollections ? collection : collection.elements));
}
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 void FlattenForPreview(Collection c)
{
foreach (var element in c.elements)
{
if (element is Collection subCol)
{
FlattenForPreview(subCol);
}
if (element is SpeckleGrasshopperObject sg)
{
_previewObjects.Add(sg);
}
}
}
// 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);
using var displayMat = new DisplayMaterial(Color.CornflowerBlue, 0.1); // note can be coming from the actual render mat
foreach (var elem in _previewObjects)
{
switch (elem.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;
}
}
}
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);
@@ -0,0 +1,66 @@
using Grasshopper.Kernel;
using Rhino.Geometry;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
#pragma warning disable CA1711
public class FlattenCollection : GH_Component
#pragma warning restore CA1711
{
public override Guid ComponentGuid => new Guid("720ED4BE-BA4B-4E85-8220-412B3DA1D2B7");
public FlattenCollection()
: base("Flatten Collection", "flatten", "Flattens a collection into objects and paths", "Speckle", "Collections")
{ }
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddGenericParameter("Collection", "C", "Collection to unpack", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddGenericParameter("Objects", "O", "Objects", GH_ParamAccess.list);
pManager.AddGenericParameter("Paths", "P", "Collection paths", GH_ParamAccess.list);
}
protected override void SolveInstance(IGH_DataAccess dataAccess)
{
Collection res = new();
dataAccess.GetData("Collection", ref res);
_sgos = new();
Flatten(res);
var paths = new List<string>();
var objs = new List<GeometryBase>();
foreach (var sg in _sgos)
{
var path = string.Join("::", sg.Path.Select(c => c.name));
paths.Add(path);
objs.Add(sg.GeometryBase);
}
dataAccess.SetDataList(0, objs);
dataAccess.SetDataList(1, paths);
}
private List<SpeckleGrasshopperObject> _sgos = new();
public void Flatten(Collection c)
{
foreach (var element in c.elements)
{
if (element is Collection subCol)
{
Flatten(subCol);
}
if (element is SpeckleGrasshopperObject sg)
{
_sgos.Add(sg);
}
}
}
}
@@ -0,0 +1,195 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common.Conversion;
using Speckle.Connectors.Common.Instances;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.Grasshopper8.Components.BaseComponents;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Sdk;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
using Speckle.Sdk.Models.Instances;
namespace Speckle.Connectors.Grasshopper8.Components.Collections;
public record UnpackRootObjectComponentInput(Base RootObject) { }
public record UnpackRootObjectComponentOutput(
List<Base> Elements,
List<string> ElementPaths,
List<IInstanceComponent> Instances,
List<string> InstancePaths
) { }
public class UnpackRootObjectComponent
: SpeckleScopedTaskCapableComponent<UnpackRootObjectComponentInput, UnpackRootObjectComponentOutput>
{
public UnpackRootObjectComponent()
: base("Unpack Root Object", "SURO", "Unpacks the root object from a receive operation", "Speckle", "Collections")
{ }
public override Guid ComponentGuid => new Guid("3C770686-20D5-434C-99E3-BDE735E8267F");
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddParameter(new SpeckleObjectParam(GH_ParamAccess.item));
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddTextParameter("Element Paths", "EP", "Path to the element in the collection tree", GH_ParamAccess.list);
pManager.AddParameter(new SpeckleObjectParam(), "Elements", "E", "Elements", GH_ParamAccess.list);
pManager.AddTextParameter(
"Instance Paths",
"IP",
"Path to the instance in the collection tree",
GH_ParamAccess.list
);
pManager.AddParameter(new SpeckleObjectParam(), "Instances", "I", "Instances", GH_ParamAccess.list);
}
protected override UnpackRootObjectComponentInput GetInput(IGH_DataAccess da)
{
Base? baseObject = null;
da.GetData(0, ref baseObject);
if (baseObject == null)
{
throw new SpeckleException("No base object provided");
}
return new UnpackRootObjectComponentInput(baseObject);
}
protected override void SetOutput(IGH_DataAccess da, UnpackRootObjectComponentOutput result)
{
da.SetDataList(0, result.ElementPaths);
da.SetDataList(1, result.Elements);
da.SetDataList(2, result.InstancePaths);
da.SetDataList(3, result.Instances);
}
protected override async Task<UnpackRootObjectComponentOutput> PerformScopedTask(
UnpackRootObjectComponentInput input,
IServiceScope scope,
CancellationToken cancellationToken = default
)
{
var rootObjectUnpacker = scope.ServiceProvider.GetRequiredService<RootObjectUnpacker>();
var contextUnpacker = scope.ServiceProvider.GetRequiredService<TraversalContextUnpacker>();
var unpackedRoot = rootObjectUnpacker.Unpack(input.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);
}
var applicationIdMap = new Dictionary<string, Base>();
atomicObjectsWithPath.ForEach(a => applicationIdMap.Add(a.current.applicationId ?? a.current.id, a.current));
var instanceResult = await ProcessInstances(instanceComponentsWithPath, applicationIdMap).ConfigureAwait(false);
foreach (string objId in instanceResult.ConsumedObjectIds)
{
var indexAtomic = atomicObjectsWithPath.FindIndex(o => o.current.id == objId);
if (indexAtomic != -1)
{
atomicObjectsWithPath.RemoveAt(indexAtomic);
}
// HACK: Why is instancecomponent not ISpeckleObject?
var indexInstance = instanceComponentsWithPath.FindIndex(o => ((Base)o.instance).id == objId);
if (indexInstance != -1)
{
instanceComponentsWithPath.RemoveAt(indexInstance);
}
}
var elements = new List<Base>();
var instances = new List<IInstanceComponent>();
var elementPaths = new List<string>();
var instancePaths = new List<string>();
atomicObjectsWithPath.ForEach(atomicObj =>
{
var names = atomicObj.path.Select(p => p.name);
elements.Add(atomicObj.current);
elementPaths.Add(string.Join("::", names));
});
instanceComponentsWithPath.ForEach(instanceObj =>
{
var names = instanceObj.path.Select(p => p.name);
instances.Add(instanceObj.instance);
instancePaths.Add(string.Join("::", names));
});
var output = new UnpackRootObjectComponentOutput(elements, elementPaths, instances, instancePaths);
return output;
}
public Task<BakeResult> ProcessInstances(
IReadOnlyCollection<(Collection[] collectionPath, IInstanceComponent obj)> instanceComponents,
Dictionary<string, Base> applicationIdMap
)
{
var sortedInstanceComponents = instanceComponents
.OrderByDescending(x => x.obj.maxDepth) // Sort by max depth, so we start baking from the deepest element first
.ThenBy(x => x.obj is InstanceDefinitionProxy ? 0 : 1) // Ensure we bake the deepest definition first, then any instances that depend on it
.ToList();
var definitionObjectsMap = new Dictionary<string, (InstanceDefinitionProxy, List<Base>)>();
var consumedObjectIds = new List<string>();
foreach (var (layerCollection, instanceOrDefinition) in sortedInstanceComponents)
{
try
{
if (instanceOrDefinition is InstanceDefinitionProxy definitionProxy)
{
var currentSpeckleObjects = definitionProxy
.objects.Where(applicationIdMap.ContainsKey)
.Select(x => applicationIdMap[x])
.ToList();
definitionObjectsMap.Add(
definitionProxy.applicationId ?? definitionProxy.id,
(definitionProxy, currentSpeckleObjects)
);
consumedObjectIds.AddRange(currentSpeckleObjects.Select(o => o.id));
consumedObjectIds.Add(definitionProxy.id);
}
if (
instanceOrDefinition is InstanceProxy instanceProxy
&& definitionObjectsMap.TryGetValue(instanceProxy.definitionId, out var definition)
)
{
instanceProxy["__geometry"] = definition.Item2;
instanceProxy["__definition"] = definition.Item1;
applicationIdMap[instanceProxy.applicationId ?? instanceProxy.id] = instanceProxy;
}
}
catch (Exception ex) when (!ex.IsFatal())
{
//_logger.LogError(ex, "Failed to create an instance from proxy");
}
}
//await Task.Yield();
BakeResult processInstances = new(new List<string>(), consumedObjectIds, new List<ReceiveConversionResult>());
return Task.FromResult(processInstances);
}
}
@@ -0,0 +1,156 @@
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.DoubleNumerics;
using Speckle.Sdk;
using Speckle.Sdk.Common;
using Speckle.Sdk.Common.Exceptions;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Instances;
namespace Speckle.Connectors.Grasshopper8.Components.Operations.Conversion;
public static class RhinoUnitsExtension
{
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 class ToNativeConversion()
: SpeckleScopedTaskCapableComponent<Base, List<GeometryBase>>(
"ToNativeConversion",
"STN",
"Converts a speckle object to rhino",
"Speckle",
"Conversion"
)
{
public override Guid ComponentGuid => new Guid("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>();
if (input is InstanceProxy proxy)
{
var geometries = proxy["__geometry"] as List<Base>;
var converted = geometries.SelectMany(g => Convert(g, rootConverter)).ToList();
var transform = MatrixToTransform(proxy.transform, proxy.units);
converted.ForEach(c => c.Transform(transform));
return Task.FromResult(converted);
}
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");
}
private 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;
}
}
@@ -0,0 +1,253 @@
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.Components.Operations.Conversion;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Connectors.Grasshopper8.Parameters;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.DoubleNumerics;
using Speckle.Sdk;
using Speckle.Sdk.Api;
using Speckle.Sdk.Common;
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 Collection 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 SpeckleObjectParam(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 rething 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);
var localToGlobalMaps = localToGlobalUnpacker.Unpack(
unpackedRoot.DefinitionProxies,
unpackedRoot.ObjectsToConvert.ToList()
);
var collGen = new CollectionRebuilder((root as Collection) ?? new Collection() { name = "unnamed" });
var results = new List<SpeckleGrasshopperObject>();
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 = MatrixToTransform(matrix, "meters");
converted.ForEach(res => res.Transform(mat));
}
foreach (var geometryBase in converted)
{
var gh = new SpeckleGrasshopperObject()
{
OriginalObject = map.AtomicObject,
Path = path,
GeometryBase = geometryBase
};
collGen.AppendSpeckleGrasshopperObject(gh);
}
}
catch (ConversionException)
{
// TODO
}
}
// var x = new SpeckleCollectionGoo { Value = collGen.RootCollection };
return new ReceiveComponentOutput { RootObject = collGen.RootCollection };
}
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;
}
else 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");
}
private 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;
}
}
// NOTE: We will need GrasshopperCollections (with an extra path element)
// these will need to be handled now
public 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(SpeckleGrasshopperObject speckleGrasshopperObject)
{
// TODO
var collection = GetOrCreateCollectionFromPath(speckleGrasshopperObject.Path);
collection.elements.Add(speckleGrasshopperObject);
}
public 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 };
_cache[currentLayerName] = newCollection;
previousCollection.elements.Add(newCollection);
previousCollection = newCollection;
}
return previousCollection;
}
}
@@ -0,0 +1,147 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Rhino;
using Rhino.Geometry;
using Speckle.Connectors.Common.Operations;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Converters.Common;
using Speckle.Converters.Rhino;
using Speckle.Sdk.Common;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Models;
namespace Speckle.Connectors.Grasshopper8.Components;
public class SpeckleFirstComponent : GH_TaskCapableComponent<List<object?>>
{
private readonly AccountManager _accountManager;
/// <summary>
/// Each implementation of GH_Component must provide a public
/// constructor without any arguments.
/// Category represents the Tab in which the component will appear,
/// Subcategory the panel. If you use non-existing tab or panel names,
/// new tabs/panels will automatically be created.
/// </summary>
public SpeckleFirstComponent()
: base("First Speckle Component", "STP", "Sends objects to speckle", "Speckle", "Other")
{
_accountManager = PriorityLoader.Container.NotNull().GetRequiredService<AccountManager>();
}
protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddTextParameter("Model/Version URL", "url", "The model or version url to receive", GH_ParamAccess.item);
}
protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddGenericParameter("Result", "R", "Result", GH_ParamAccess.item);
}
protected override void SolveInstance(IGH_DataAccess da)
{
if (InPreSolve)
{
// Collect the data and create the task
string url = GetInput(da);
Message = "Receiving...";
TaskList.Add(PerformReceiveOperation(url, CancelToken));
return;
}
if (!GetSolveResults(da, out List<object?> result))
{
// INFO: This will run synchronously. Useful for Rhino.Compute runs, but can also be enabled by user.
string url = GetInput(da);
var syncResult = PerformReceiveOperation(url).Result;
SetOutput(da, syncResult);
}
if (result is not null)
{
SetOutput(da, result);
}
}
private void SetOutput(IGH_DataAccess da, List<object?> result)
{
da.SetDataList(0, result);
Message = "Done";
}
private string GetInput(IGH_DataAccess da)
{
string url = "";
da.GetData(0, ref url);
return url;
}
private async Task<List<object?>> PerformReceiveOperation(string url, CancellationToken cancellationToken = default)
{
// TODO: URL Parsing must be done here
Console.WriteLine($"Receiving from fake url, skipping input: {url}");
var account = _accountManager.GetDefaultAccount();
if (account is null)
{
throw new SpeckleAccountManagerException($"No default account was found");
}
var receiveInfo = new ReceiveInfo(
account.id,
new Uri(account.serverInfo.url),
"2295cb26a0",
"",
"bd1fd98086",
"",
"832e036b91",
""
);
var progress = new Progress<CardProgress>(progress =>
{
// TODO: Progress only makes sense in non-blocking async receive, which is not supported yet.
// Message = $"{progress.Status}: {progress.Progress}";
});
using var scope = PriorityLoader.Container.CreateScope();
IRhinoConversionSettingsFactory rhinoConversionSettingsFactory =
scope.ServiceProvider.GetRequiredService<IRhinoConversionSettingsFactory>();
scope
.ServiceProvider.GetRequiredService<IConverterSettingsStore<RhinoConversionSettings>>()
.Initialize(rhinoConversionSettingsFactory.Create(RhinoDoc.ActiveDoc));
var receiveOperation = scope.ServiceProvider.GetRequiredService<ReceiveOperation>();
var result = await receiveOperation.Execute(receiveInfo, progress, cancellationToken).ConfigureAwait(false);
List<object?> results = new();
// HACK: GrashhopperHostObjectBuilder returns a specific subclass that contains the result object as well.
foreach (var conversionResult in result.ConversionResults)
{
if (conversionResult is not GrasshopperReceiveConversionResult ghConversionResult)
{
throw new NotSupportedException($"Unsupported conversion result type: {conversionResult}");
}
//results.Add(ghConversionResult.Source);
if (ghConversionResult.Result is GeometryBase geometryBase)
{
results.Add(geometryBase);
}
else if (ghConversionResult.Result is List<GeometryBase> geometryBases) // one to many raw encoding case
{
results.AddRange(geometryBases);
}
else if (ghConversionResult.Result is IEnumerable<(object, Base)> fallbackConversionResult) // one to many fallback conversion
{
results.AddRange(fallbackConversionResult.Select(o => o.Item1));
}
}
return results;
}
public override Guid ComponentGuid => new Guid("c123402d-6b40-4619-bb3b-88eb3fc8bb7a");
}
@@ -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,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,77 @@
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using Rhino.Geometry;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.HostApp;
public class SpeckleGrasshopperObject : 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 class SpeckleGrasshopperObjectGoo : GH_Goo<SpeckleGrasshopperObject>
{
public override IGH_Goo Duplicate() => throw new NotImplementedException();
public override string ToString() => $@"Speckle Object [{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 SpeckleGrasshopperObject speckleGrasshopperObject:
Value = speckleGrasshopperObject;
return true;
case GH_Goo<SpeckleGrasshopperObject> 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;
}
if (type == typeof(GH_Extrusion) && Value.GeometryBase is Extrusion)
{
target = (T)(object)new GH_Extrusion() { Value = Value.GeometryBase as Extrusion };
return true;
}
return false;
}
}
public class SpeckleGrasshopperObjectParam : GH_Param<SpeckleGrasshopperObjectGoo>
{
public SpeckleGrasshopperObjectParam()
: this(GH_ParamAccess.item) { }
public SpeckleGrasshopperObjectParam(IGH_InstanceDescription tag)
: base(tag) { }
public SpeckleGrasshopperObjectParam(IGH_InstanceDescription tag, GH_ParamAccess access)
: base(tag, access) { }
public SpeckleGrasshopperObjectParam(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,69 @@
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 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 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 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");
}
@@ -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,82 @@
using Grasshopper.Kernel.Types;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Parameters;
public class SpeckleCollectionGoo : GH_Goo<Collection>
{
// TODO: Massive hack for setup only!!! We need some sort of `ShallowCopy` or a transparent wrapper for Speckle Objects
// to prevent backwards propagation of changes of the same instance.
public override IGH_Goo Duplicate() => new SpeckleCollectionGoo { Value = m_value };
public override string ToString() => $"Speckle Collection [{m_value.name}]";
public override bool IsValid => true;
public override string TypeName => "SpeckleCollection";
public override string TypeDescription => "A Speckle Collection";
public override bool CastFrom(object source)
{
Collection? obj = null;
switch (source)
{
case Collection speckleCollection:
obj = speckleCollection;
break;
case SpeckleObjectGoo speckleObjectGoo:
if (speckleObjectGoo.Value is Collection collection)
{
obj = collection;
}
break;
case SpeckleCollectionGoo speckleCollectionGoo:
obj = speckleCollectionGoo.Value;
break;
case GH_Goo<ISpeckleObject> speckleObjectGoo:
if (speckleObjectGoo.Value is Collection collection2)
{
obj = collection2;
}
break;
default:
obj = null;
break;
}
if (obj is null)
{
return false;
}
Value = obj;
return true;
}
public override bool CastTo<TOut>(ref TOut target)
{
var type = typeof(TOut);
var success = false;
if (type == typeof(SpeckleObjectGoo))
{
target = (TOut)(object)new SpeckleObjectGoo { Value = Value };
success = true;
}
else if (type == typeof(SpeckleCollectionGoo))
{
target = (TOut)(object)new SpeckleObjectGoo { Value = Value };
success = true;
}
else if (type == typeof(Collection))
{
target = (TOut)(object)Value;
success = true;
}
else if (type == typeof(Base))
{
target = (TOut)(object)Value;
success = true;
}
return success;
}
}
@@ -0,0 +1,23 @@
using Grasshopper.Kernel;
using Speckle.Connectors.Grasshopper8.HostApp;
namespace Speckle.Connectors.Grasshopper8.Parameters;
public class SpeckleCollectionParam : GH_Param<SpeckleCollectionGoo>
{
public SpeckleCollectionParam()
: this(GH_ParamAccess.item) { }
public SpeckleCollectionParam(IGH_InstanceDescription tag)
: base(tag) { }
public SpeckleCollectionParam(IGH_InstanceDescription tag, GH_ParamAccess access)
: base(tag, access) { }
public SpeckleCollectionParam(GH_ParamAccess access)
: base("Speckle Collection", "SpcklCol", "XXX", "Speckle", "Params", access) { }
public override Guid ComponentGuid => new("F397D941-6B4D-4143-B535-A11F7F776BA1");
protected override Bitmap Icon => BitmapBuilder.CreateHexagonalBitmap("C");
}
@@ -0,0 +1,60 @@
using Grasshopper.Kernel.Types;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Collections;
namespace Speckle.Connectors.Grasshopper8.Parameters;
public class SpeckleObjectGoo : GH_Goo<Base>
{
// TODO: Massive hack for setup only!!! We need some sort of `ShallowCopy` or a transparent wrapper for Speckle Objects
// to prevent backwards propagation of changes of the same instance.
public override IGH_Goo Duplicate() => new SpeckleObjectGoo { Value = m_value };
public override string ToString() => $"Speckle Object [{m_value.GetType().Name}]";
public override bool IsValid => true;
public override string TypeName => "SpeckleObject";
public override string TypeDescription => "A Speckle Object";
public override bool CastFrom(object source)
{
Base? obj = source switch
{
Base speckleObject => speckleObject,
SpeckleObjectGoo speckleObjectGoo => speckleObjectGoo.Value,
SpeckleCollectionGoo speckleCollectionGoo => speckleCollectionGoo.Value,
GH_Goo<Base> speckleObjectGoo => speckleObjectGoo.Value,
_ => null
};
if (obj is null)
{
return false;
}
Value = obj;
return true;
}
public override bool CastTo<TOut>(ref TOut target)
{
var type = typeof(TOut);
var success = false;
if (type == typeof(SpeckleObjectGoo))
{
target = (TOut)(object)new SpeckleObjectGoo { Value = Value };
success = true;
}
else if (type == typeof(SpeckleCollectionGoo) && Value is Collection collection)
{
target = (TOut)(object)new SpeckleCollectionGoo { Value = collection };
success = true;
}
else if (type == typeof(Base))
{
target = (TOut)(object)Value;
success = true;
}
return success;
}
}
@@ -0,0 +1,20 @@
using Grasshopper.Kernel;
namespace Speckle.Connectors.Grasshopper8.Parameters;
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 Object", "SpklObj", "XXXXX", "Speckle", "Params", access) { }
public override Guid ComponentGuid => new("F708F88C-FE00-44EF-8D30-02AB6CF5F728");
}
@@ -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,55 @@
using Grasshopper.Kernel;
using Microsoft.Extensions.DependencyInjection;
using Speckle.Connectors.Common;
using Speckle.Connectors.Common.Builders;
using Speckle.Connectors.Common.Operations.Receive;
using Speckle.Connectors.Grasshopper8.HostApp;
using Speckle.Converters.Rhino;
using Speckle.Sdk;
using Speckle.Sdk.Credentials;
using Speckle.Sdk.Host;
using Speckle.Sdk.Models.GraphTraversal;
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().AddConnectorUtils();
services.AddTransient<IHostObjectBuilder, GrasshopperHostObjectBuilder>();
services.AddTransient<GrasshopperReceiveOperation>();
services.AddSingleton(DefaultTraversal.CreateTraversalFunc());
services.AddScoped<RootObjectUnpacker>();
services.AddTransient<TraversalContextUnpacker>();
services.AddTransient<AccountManager>();
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,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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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.191, )"
}
},
"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, )",
@@ -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.191, )"
}
},
"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.191, )"
}
},
"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="Tekla.Structures.Dialog" Version="2024.0.4" PrivateAssets="all" IncludeAssets="compile; build" />
<PackageVersion Include="Tekla.Structures.Drawing" Version="2024.0.4" />
@@ -49,4 +51,4 @@
<GlobalPackageReference Include="Speckle.InterfaceGenerator" Version="0.9.6" />
<GlobalPackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
</ItemGroup>
</Project>
</Project>
@@ -37,7 +37,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 List<(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, )",
+9
View File
@@ -189,6 +189,8 @@ 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}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -484,6 +486,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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -570,6 +578,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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EE253116-7070-4E9A-BCE8-2911C251B8C8}