Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 295162127a | |||
| 6d336fbac4 | |||
| 6b2078fadb | |||
| bfd465449a | |||
| a9a4893bdb | |||
| 21066eebbb | |||
| 9d5ff85cff | |||
| 64befa758d | |||
| d9a0cbb4bf | |||
| 50807b1e88 | |||
| 7780071073 | |||
| be63b4ab55 | |||
| 63c5bb26cb | |||
| f7a1d98d8a | |||
| a14de5bdde | |||
| a89407ae3c | |||
| a3285a4f67 | |||
| ae4b1b0ab5 | |||
| ed9d81d206 | |||
| a2fc846613 | |||
| 184953f5f0 | |||
| d71b36c2f7 | |||
| f152cff619 | |||
| 4aed602089 | |||
| 63c4d31467 | |||
| b807be35ff | |||
| 32ea041c5e | |||
| 950c8373d9 | |||
| 9d5faa92e8 | |||
| fd88fc2eeb | |||
| 9d2ae1ca55 | |||
| 670a562d48 | |||
| e6d983302c | |||
| fe5b77e766 | |||
| 663fe445bf | |||
| 74d2d2860c | |||
| 2e405b2f28 | |||
| 331c631b35 | |||
| ddd6039722 | |||
| 835e3ba005 | |||
| af548ba626 | |||
| 3ff40757e0 | |||
| a8571fdd61 | |||
| f8a6d27c6d | |||
| 4e1604f77e | |||
| 00af4ad338 | |||
| 7fed9e03e9 | |||
| e9c2c85a7f | |||
| 82c7877425 | |||
| 2338be46c2 | |||
| 8f72eb35d3 | |||
| a3f7069c37 | |||
| 3842e109b6 | |||
| 4ae2106608 | |||
| 3656587081 | |||
| b315cebf3a | |||
| fb18466aba | |||
| b721c2fb31 | |||
| 76aa953210 | |||
| 52d15dc827 | |||
| dbbc4f7fcd | |||
| 85b4a88407 | |||
| 65a2e674bb | |||
| 9a84e4469e | |||
| b8a49d5fed | |||
| 12dcf471d3 | |||
| 42e45affbd | |||
| fcce4e3f63 | |||
| 370c5b2064 | |||
| 39dfb0f426 | |||
| 1c62fbbe99 | |||
| 6f03aa8678 | |||
| f882b0f5bd | |||
| 4ffe9fe4b0 | |||
| d50b095683 | |||
| daebbbef1c | |||
| b43631e46b | |||
| ea9768b1f2 | |||
| 2756555eb9 | |||
| 1f1422900e | |||
| 45a76eada4 | |||
| 0e65b6aa57 | |||
| 5c2c0ff303 | |||
| a6fd4547ea | |||
| 0d27eadfeb |
@@ -9,10 +9,10 @@
|
||||
],
|
||||
"rollForward": false
|
||||
},
|
||||
"gitversion.tool": {
|
||||
"version": "6.0.2",
|
||||
"dotnet-affected": {
|
||||
"version": "5.0.0",
|
||||
"commands": [
|
||||
"dotnet-gitversion"
|
||||
"dotnet-affected"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
|
||||
@@ -2,12 +2,14 @@ name: .NET Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main", "dev", "release/*"] # Continuous delivery on every long-lived branch
|
||||
branches: ["main", "installer-test/**"]
|
||||
tags: ["v3.*"] # Manual delivery on every 3.x tag
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
SPECKLE_VERSION: "unset"
|
||||
outputs:
|
||||
version: ${{ steps.set-version.outputs.version }}
|
||||
steps:
|
||||
@@ -27,38 +29,35 @@ jobs:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run GitVersion on Windows
|
||||
run: ./build.ps1 build-server-version
|
||||
|
||||
- name: ⚒️ Run build on Windows
|
||||
run: ./build.ps1
|
||||
run: ./build.ps1 zip
|
||||
|
||||
- name: ⬆️ Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: output-${{ env.GitVersion_FullSemVer }}
|
||||
name: output-${{ env.SPECKLE_VERSION }}
|
||||
path: output/*.*
|
||||
compression-level: 0 # no compression
|
||||
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
compression-level: 0 # no compression
|
||||
- id: set-version
|
||||
name: Set version to output
|
||||
run: echo "version=${{ env.GitVersion_FullSemVer }}" >> "$Env:GITHUB_OUTPUT"
|
||||
run: echo "version=${{ env.SPECKLE_VERSION }}" >> "$Env:GITHUB_OUTPUT"
|
||||
|
||||
deploy-installers:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-windows
|
||||
env:
|
||||
IS_TAG_BUILD: ${{ github.ref_type == 'tag' }}
|
||||
IS_RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release/') || github.ref_name == 'main'}}
|
||||
IS_PUBLIC_RELEASE: ${{ github.ref_type == 'tag' }}
|
||||
IS_TEST_INSTALLER: ${{ github.ref_type != 'tag' }}
|
||||
steps:
|
||||
- name: 🔫 Trigger Build Installers
|
||||
uses: ALEEF02/workflow-dispatch@v3.0.0
|
||||
continue-on-error: true
|
||||
with:
|
||||
workflow: Build Installers
|
||||
repo: specklesystems/connector-installers
|
||||
token: ${{ secrets.CONNECTORS_GH_TOKEN }}
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build-windows.outputs.version }}", "public_release": ${{ env.IS_TAG_BUILD }}, "store_artifacts": ${{ env.IS_RELEASE_BRANCH }} }'
|
||||
inputs: '{ "run_id": "${{ github.run_id }}", "version": "${{ needs.build-windows.outputs.version }}", "public_release": ${{ env.IS_PUBLIC_RELEASE }}, "store_artifacts": ${{ env.IS_TEST_INSTALLER }} }'
|
||||
ref: main
|
||||
wait-for-completion: true
|
||||
wait-for-completion-interval: 10s
|
||||
@@ -89,9 +88,6 @@ jobs:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
|
||||
- name: ⚒️ Run GitVersion on Linux
|
||||
run: ./build.sh build-server-version
|
||||
|
||||
- name: ⚒️ Run tests on Linux
|
||||
run: ./build.sh test-only
|
||||
|
||||
@@ -105,4 +101,5 @@ jobs:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Push to nuget.org
|
||||
if: (github.ref_type == 'tag')
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
using GlobExpressions;
|
||||
using Microsoft.Build.Construction;
|
||||
using static SimpleExec.Command;
|
||||
|
||||
namespace Build;
|
||||
|
||||
public static class Affected
|
||||
{
|
||||
public static readonly string Root = Environment.CurrentDirectory;
|
||||
public const string AFFECTED_PROJECT = "affected.proj";
|
||||
|
||||
private static IEnumerable<string> GetAffectedProjects()
|
||||
{
|
||||
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
|
||||
Console.WriteLine("Affected project file: " + projFile);
|
||||
var project = ProjectRootElement.Open(projFile) ?? throw new InvalidOperationException();
|
||||
var references = project.ItemGroups.SelectMany(x => x.Items).Where(x => x.ItemType == "ProjectReference");
|
||||
|
||||
foreach (var refe in references)
|
||||
{
|
||||
var referencePath = refe.Include[(Root.Length + 1)..];
|
||||
referencePath = Path.GetDirectoryName(referencePath) ?? throw new InvalidOperationException();
|
||||
if (Path.DirectorySeparatorChar != '/')
|
||||
{
|
||||
referencePath = referencePath.Replace(Path.DirectorySeparatorChar, '/');
|
||||
}
|
||||
|
||||
yield return referencePath;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<IEnumerable<string>> GetTestProjects()
|
||||
{
|
||||
await ComputeAffected();
|
||||
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
|
||||
if (File.Exists(projFile))
|
||||
{
|
||||
var references = GetAffectedProjects();
|
||||
return references.Where(x => x.Contains("Tests"));
|
||||
}
|
||||
return Glob.Files(Root, "**/*.Tests.csproj");
|
||||
}
|
||||
|
||||
public static async Task<ProjectGroup[]> GetAffectedProjectGroups()
|
||||
{
|
||||
await ComputeAffected();
|
||||
var projFile = Path.Combine(Root, AFFECTED_PROJECT);
|
||||
if (File.Exists(projFile))
|
||||
{
|
||||
var references = GetAffectedProjects().ToList();
|
||||
var groups = new List<ProjectGroup>();
|
||||
foreach (var projectGroup in Consts.ProjectGroups)
|
||||
{
|
||||
foreach (var referencePath in references)
|
||||
{
|
||||
if (projectGroup.Projects.Any(x => x.ProjectPath.Contains(referencePath)))
|
||||
{
|
||||
groups.Add(projectGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
Console.WriteLine("Affected project group being built: " + group.HostAppSlug);
|
||||
}
|
||||
|
||||
if (groups.Count > 0)
|
||||
{
|
||||
return groups.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("Using all project groups: " + string.Join(',', Consts.ProjectGroups));
|
||||
return Consts.ProjectGroups;
|
||||
}
|
||||
|
||||
private static bool s_affectedComputed;
|
||||
|
||||
public static async Task ComputeAffected()
|
||||
{
|
||||
if (s_affectedComputed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var currentTag = await Versions.GetCurrentTag();
|
||||
var currentVersion = await Versions.ComputeVersion();
|
||||
var lastTag = await Versions.GetPreviousTag(currentTag);
|
||||
var lastVersion = await Versions.ComputePreviousVersion(currentTag);
|
||||
|
||||
Console.WriteLine($"Last tag: {lastTag}, Current tag: {currentTag}");
|
||||
Console.WriteLine($"Last parsed version: {lastVersion}, Current parsed version: {currentVersion}");
|
||||
|
||||
var sort = currentVersion.CompareSortOrderTo(lastVersion);
|
||||
if (sort == -1)
|
||||
{
|
||||
Console.WriteLine($"Current version {currentVersion} is less than: {lastVersion}");
|
||||
s_affectedComputed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var majorEquals = currentVersion.Major == lastVersion.Major;
|
||||
if (!majorEquals)
|
||||
{
|
||||
Console.WriteLine($"Current version {currentVersion} is not matching major version: {lastVersion}");
|
||||
s_affectedComputed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//use tags no matter the version if major versions match
|
||||
var (currentCommit, _) = await ReadAsync("git", $"rev-list -n 1 {currentTag}");
|
||||
var (lastCommit, _) = await ReadAsync("git", $"rev-list -n 1 {lastTag}");
|
||||
await RunAsync("dotnet", $"affected -v --from {currentCommit.Trim()} --to {lastCommit.Trim()}", Root);
|
||||
|
||||
s_affectedComputed = true;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
<PackageReference Include="Bullseye" />
|
||||
<PackageReference Include="Glob" />
|
||||
<PackageReference Include="Microsoft.Build" />
|
||||
<PackageReference Include="Semver" />
|
||||
<PackageReference Include="SimpleExec" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@ public static class Consts
|
||||
{
|
||||
public static readonly string[] Solutions = ["Speckle.Connectors.sln"];
|
||||
|
||||
public static readonly InstallerProject[] InstallerManifests =
|
||||
public static readonly ProjectGroup[] ProjectGroups =
|
||||
{
|
||||
new("arcgis", [new("Connectors/ArcGIS/Speckle.Connectors.ArcGIS3", "net6.0-windows")]),
|
||||
new(
|
||||
@@ -53,7 +53,7 @@ public static class Consts
|
||||
]
|
||||
),
|
||||
new(
|
||||
"tekla-structures",
|
||||
"teklastructures",
|
||||
[
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2023", "net48"),
|
||||
new("Connectors/Tekla/Speckle.Connector.Tekla2024", "net48")
|
||||
@@ -69,7 +69,7 @@ public static class Consts
|
||||
};
|
||||
}
|
||||
|
||||
public readonly record struct InstallerProject(string HostAppSlug, IReadOnlyList<InstallerAsset> Projects)
|
||||
public readonly record struct ProjectGroup(string HostAppSlug, IReadOnlyList<InstallerAsset> Projects)
|
||||
{
|
||||
public override string ToString() => $"{HostAppSlug}";
|
||||
}
|
||||
|
||||
+82
-78
@@ -12,13 +12,12 @@ const string TEST = "test";
|
||||
const string TEST_ONLY = "test-only";
|
||||
const string FORMAT = "format";
|
||||
const string ZIP = "zip";
|
||||
const string VERSION = "version";
|
||||
const string RESTORE_TOOLS = "restore-tools";
|
||||
const string BUILD_SERVER_VERSION = "build-server-version";
|
||||
const string CLEAN_LOCKS = "clean-locks";
|
||||
const string CHECK_SOLUTIONS = "check-solutions";
|
||||
const string DEEP_CLEAN = "deep-clean";
|
||||
const string DEEP_CLEAN_LOCAL = "deep-clean-local";
|
||||
const string DETECT_AFFECTED = "detect-affected";
|
||||
|
||||
//need to pass arguments
|
||||
/*var arguments = new List<string>();
|
||||
@@ -34,14 +33,14 @@ void Build(string solution, string configuration)
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Building solution '{solution}' as '{configuration}'");
|
||||
Console.WriteLine();
|
||||
Run("dotnet", $"build .\\{solution} --configuration {configuration} --no-restore");
|
||||
Run("dotnet", $"build \".\\{solution}\" --configuration {configuration} --no-restore");
|
||||
}
|
||||
void Restore(string solution)
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Restoring solution '{solution}'");
|
||||
Console.WriteLine();
|
||||
Run("dotnet", $"restore .\\{solution} --no-cache");
|
||||
Run("dotnet", $"restore \".\\{solution}\" --no-cache");
|
||||
}
|
||||
void DeleteFiles(string pattern)
|
||||
{
|
||||
@@ -125,17 +124,6 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
VERSION,
|
||||
async () =>
|
||||
{
|
||||
var (output, _) = await ReadAsync("dotnet", "minver -v w");
|
||||
output = output.Trim();
|
||||
Console.WriteLine($"Version: {output}");
|
||||
Run("echo", $"\"version={output}\" >> $GITHUB_OUTPUT");
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
RESTORE_TOOLS,
|
||||
() =>
|
||||
@@ -144,6 +132,18 @@ Target(
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
DETECT_AFFECTED,
|
||||
DependsOn(RESTORE_TOOLS),
|
||||
async () =>
|
||||
{
|
||||
foreach (var group in await Affected.GetAffectedProjectGroups())
|
||||
{
|
||||
Console.WriteLine("Affected project group being built: " + group.HostAppSlug);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
FORMAT,
|
||||
DependsOn(RESTORE_TOOLS),
|
||||
@@ -155,20 +155,14 @@ Target(
|
||||
|
||||
Target(
|
||||
RESTORE,
|
||||
DependsOn(FORMAT),
|
||||
DependsOn(FORMAT, DETECT_AFFECTED),
|
||||
Consts.Solutions,
|
||||
s =>
|
||||
async s =>
|
||||
{
|
||||
Run("dotnet", $"restore {s} --locked-mode");
|
||||
}
|
||||
);
|
||||
|
||||
Target(
|
||||
BUILD_SERVER_VERSION,
|
||||
DependsOn(RESTORE_TOOLS),
|
||||
() =>
|
||||
{
|
||||
Run("dotnet", "tool run dotnet-gitversion /output json /output buildserver");
|
||||
var version = await Versions.ComputeVersion();
|
||||
var fileVersion = await Versions.ComputeFileVersion();
|
||||
Console.WriteLine($"Restoring: {s} - Version: {version} & {fileVersion}");
|
||||
await RunAsync("dotnet", $"restore \"{s}\" --locked-mode");
|
||||
}
|
||||
);
|
||||
|
||||
@@ -176,14 +170,14 @@ Target(
|
||||
BUILD,
|
||||
DependsOn(RESTORE),
|
||||
Consts.Solutions,
|
||||
s =>
|
||||
async s =>
|
||||
{
|
||||
var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
|
||||
var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0";
|
||||
Console.WriteLine($"Version: {version} & {fileVersion}");
|
||||
Run(
|
||||
var version = await Versions.ComputeVersion();
|
||||
var fileVersion = await Versions.ComputeFileVersion();
|
||||
Console.WriteLine($"Restoring: {s} - Version: {version} & {fileVersion}");
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"build {s} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
$"build \"{s}\" -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -193,23 +187,26 @@ Target(CHECK_SOLUTIONS, Solutions.CompareConnectorsToLocal);
|
||||
Target(
|
||||
TEST,
|
||||
DependsOn(BUILD, CHECK_SOLUTIONS),
|
||||
Glob.Files(".", "**/*.Tests.csproj"),
|
||||
file =>
|
||||
async () =>
|
||||
{
|
||||
Run("dotnet", $"test {file} -c Release --no-build --no-restore --verbosity=minimal");
|
||||
foreach (var s in await Affected.GetTestProjects())
|
||||
{
|
||||
await RunAsync("dotnet", $"test \"{s}\" -c Release --no-build --no-restore --verbosity=minimal");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//all tests on purpose
|
||||
Target(
|
||||
TEST_ONLY,
|
||||
DependsOn(FORMAT),
|
||||
Glob.Files(".", "**/*.Tests.csproj"),
|
||||
file =>
|
||||
{
|
||||
Run("dotnet", $"build {file} -c Release --no-incremental");
|
||||
Run("dotnet", $"build \"{file}\" -c Release --no-incremental");
|
||||
Run(
|
||||
"dotnet",
|
||||
$"test {file} -c Release --no-build --verbosity=minimal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage /p:AltCoverVerbosity=Warning"
|
||||
$"test \"{file}\" -c Release --no-build --verbosity=minimal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage /p:AltCoverVerbosity=Warning"
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -218,20 +215,20 @@ Target(
|
||||
BUILD_LINUX,
|
||||
DependsOn(FORMAT),
|
||||
Glob.Files(".", "**/Speckle.Importers.Ifc.csproj"),
|
||||
file =>
|
||||
async file =>
|
||||
{
|
||||
Run("dotnet", $"restore {file} --locked-mode");
|
||||
var version = Environment.GetEnvironmentVariable("GitVersion_FullSemVer") ?? "3.0.0-localBuild";
|
||||
var fileVersion = Environment.GetEnvironmentVariable("GitVersion_AssemblySemFileVer") ?? "3.0.0.0";
|
||||
await RunAsync("dotnet", $"restore \"{file}\" --locked-mode");
|
||||
var version = await Versions.ComputeVersion();
|
||||
var fileVersion = await Versions.ComputeFileVersion();
|
||||
Console.WriteLine($"Version: {version} & {fileVersion}");
|
||||
Run(
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"build {file} -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
$"build \"{file}\" -c Release --no-restore -warnaserror -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
|
||||
RunAsync(
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"pack {file} -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
$"pack \"{file}\" -c Release -o output --no-build -p:Version={version} -p:FileVersion={fileVersion} -v:m"
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -239,47 +236,54 @@ Target(
|
||||
Target(
|
||||
ZIP,
|
||||
DependsOn(TEST),
|
||||
Consts.InstallerManifests,
|
||||
x =>
|
||||
async () =>
|
||||
{
|
||||
var outputDir = Path.Combine(".", "output");
|
||||
var slugDir = Path.Combine(outputDir, x.HostAppSlug);
|
||||
|
||||
Directory.CreateDirectory(outputDir);
|
||||
Directory.CreateDirectory(slugDir);
|
||||
|
||||
foreach (var asset in x.Projects)
|
||||
var version = await Versions.ComputeVersion();
|
||||
foreach (var group in await Affected.GetAffectedProjectGroups())
|
||||
{
|
||||
var fullPath = Path.Combine(".", asset.ProjectPath, "bin", "Release", asset.TargetName);
|
||||
if (!Directory.Exists(fullPath))
|
||||
Console.WriteLine($"Zipping: {group.HostAppSlug} as {version}");
|
||||
var outputDir = Path.Combine(".", "output");
|
||||
var slugDir = Path.Combine(outputDir, group.HostAppSlug);
|
||||
|
||||
Directory.CreateDirectory(outputDir);
|
||||
Directory.CreateDirectory(slugDir);
|
||||
|
||||
foreach (var asset in group.Projects)
|
||||
{
|
||||
throw new InvalidOperationException("Could not find: " + fullPath);
|
||||
var fullPath = Path.Combine(".", asset.ProjectPath, "bin", "Release", asset.TargetName);
|
||||
if (!Directory.Exists(fullPath))
|
||||
{
|
||||
throw new InvalidOperationException("Could not find: " + fullPath);
|
||||
}
|
||||
|
||||
var assetName = Path.GetFileName(asset.ProjectPath);
|
||||
var connectorDir = Path.Combine(slugDir, assetName);
|
||||
|
||||
Directory.CreateDirectory(connectorDir);
|
||||
foreach (var directory in Directory.EnumerateDirectories(fullPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
Directory.CreateDirectory(directory.Replace(fullPath, connectorDir));
|
||||
}
|
||||
|
||||
foreach (var file in Directory.EnumerateFiles(fullPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
Console.WriteLine(file);
|
||||
File.Copy(file, file.Replace(fullPath, connectorDir), true);
|
||||
}
|
||||
}
|
||||
|
||||
var assetName = Path.GetFileName(asset.ProjectPath);
|
||||
var connectorDir = Path.Combine(slugDir, assetName);
|
||||
|
||||
Directory.CreateDirectory(connectorDir);
|
||||
foreach (var directory in Directory.EnumerateDirectories(fullPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
Directory.CreateDirectory(directory.Replace(fullPath, connectorDir));
|
||||
}
|
||||
|
||||
foreach (var file in Directory.EnumerateFiles(fullPath, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
Console.WriteLine(file);
|
||||
File.Copy(file, file.Replace(fullPath, connectorDir), true);
|
||||
}
|
||||
var outputPath = Path.Combine(outputDir, $"{group.HostAppSlug}.zip");
|
||||
File.Delete(outputPath);
|
||||
Console.WriteLine($"Zipping: '{slugDir}' to '{outputPath}'");
|
||||
ZipFile.CreateFromDirectory(slugDir, outputPath);
|
||||
}
|
||||
|
||||
var outputPath = Path.Combine(outputDir, $"{x.HostAppSlug}.zip");
|
||||
File.Delete(outputPath);
|
||||
Console.WriteLine($"Zipping: '{slugDir}' to '{outputPath}'");
|
||||
ZipFile.CreateFromDirectory(slugDir, outputPath);
|
||||
// Directory.Delete(slugDir, true);
|
||||
string githubEnv = Environment.GetEnvironmentVariable("GITHUB_ENV") ?? "Unset";
|
||||
Console.WriteLine($"GITHUB_ENV: {githubEnv}");
|
||||
File.AppendAllText(githubEnv, $"SPECKLE_VERSION={version}{Environment.NewLine}");
|
||||
}
|
||||
);
|
||||
|
||||
Target("default", DependsOn(FORMAT, ZIP), () => Console.WriteLine("Done!"));
|
||||
Target("default", DependsOn(TEST), () => Console.WriteLine("Done!"));
|
||||
|
||||
await RunTargetsAndExitAsync(args).ConfigureAwait(true);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
using Semver;
|
||||
using static SimpleExec.Command;
|
||||
|
||||
namespace Build;
|
||||
|
||||
public static class Versions
|
||||
{
|
||||
private static string? s_currentTag;
|
||||
private static SemVersion? s_currentVersion;
|
||||
|
||||
public static async Task<string> GetCurrentTag()
|
||||
{
|
||||
if (s_currentTag is not null)
|
||||
{
|
||||
return s_currentTag;
|
||||
}
|
||||
//finds current tag or makes one
|
||||
var (currentTag, _) = await ReadAsync("git", "describe --tags");
|
||||
currentTag = currentTag.Trim();
|
||||
s_currentTag = currentTag;
|
||||
return s_currentTag;
|
||||
}
|
||||
|
||||
public static async Task<SemVersion> ComputeVersion()
|
||||
{
|
||||
if (s_currentVersion is not null)
|
||||
{
|
||||
return s_currentVersion;
|
||||
}
|
||||
var currentTag = await GetCurrentTag();
|
||||
|
||||
if (!SemVersion.TryParse(currentTag, SemVersionStyles.AllowLowerV, out var currentVersion))
|
||||
{
|
||||
throw new InvalidOperationException($"Could not parse version: '{currentTag}'");
|
||||
}
|
||||
s_currentVersion = currentVersion;
|
||||
return s_currentVersion;
|
||||
}
|
||||
|
||||
private static string? s_currentFileVersion;
|
||||
|
||||
public static async Task<string> ComputeFileVersion()
|
||||
{
|
||||
if (s_currentFileVersion is not null)
|
||||
{
|
||||
return s_currentFileVersion;
|
||||
}
|
||||
var currentVersion = await ComputeVersion();
|
||||
s_currentFileVersion = currentVersion.WithoutPrereleaseOrMetadata() + ".0";
|
||||
return s_currentFileVersion;
|
||||
}
|
||||
|
||||
public static async Task<string> GetPreviousTag(string currentTag)
|
||||
{
|
||||
//finds a tag starting with current tag and adds no abbrevation
|
||||
var (lastTag, _) = await ReadAsync("git", $"describe --abbrev=0 --tags {currentTag}^");
|
||||
lastTag = lastTag.Trim();
|
||||
|
||||
return lastTag;
|
||||
}
|
||||
|
||||
private static SemVersion? s_previousVersion;
|
||||
|
||||
public static async Task<SemVersion> ComputePreviousVersion(string currentTag)
|
||||
{
|
||||
if (s_previousVersion is not null)
|
||||
{
|
||||
return s_previousVersion;
|
||||
}
|
||||
var lastTag = await GetPreviousTag(currentTag);
|
||||
|
||||
if (!SemVersion.TryParse(lastTag, SemVersionStyles.AllowLowerV, out var lastVersion))
|
||||
{
|
||||
throw new InvalidOperationException($"Could not parse version: '{lastTag}'");
|
||||
}
|
||||
s_previousVersion = lastVersion;
|
||||
return s_previousVersion;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,15 @@
|
||||
"resolved": "1.14.1",
|
||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
||||
},
|
||||
"Semver": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.0.0, )",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "9jZCicsVgTebqkAujRWtC9J1A5EQVlu0TVKHcgoCuv345ve5DYf4D1MjhKEnQjdRZo6x/vdv6QQrYFs7ilGzLA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "5.0.1"
|
||||
}
|
||||
},
|
||||
"SimpleExec": {
|
||||
"type": "Direct",
|
||||
"requested": "[12.0.0, )",
|
||||
@@ -75,6 +84,11 @@
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.1",
|
||||
"contentHash": "5WPSmL4YeP7eW+Vc8XZ4DwjYWBAiSwDV9Hm63JJWcz1Ie3Xjv4KuJXzgCstj48LkLfVCYa7mLcx7y+q6yqVvtw=="
|
||||
},
|
||||
"Microsoft.NET.StringTools": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.11.4",
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Core;
|
||||
using ArcGIS.Desktop.Editing.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -45,6 +46,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IArcGISConversionSettingsFactory _arcGISConversionSettingsFactory;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to aggregate the changed objects' id. Note we're using a concurrent dictionary here as the expiry check method is not thread safe, and this was causing problems. See:
|
||||
@@ -70,6 +72,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
IArcGISConversionSettingsFactory arcGisConversionSettingsFactory,
|
||||
MapMembersUtils mapMemberUtils,
|
||||
IThreadContext threadContext,
|
||||
ISpeckleApplication speckleApplication,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
)
|
||||
{
|
||||
@@ -84,6 +87,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_arcGISConversionSettingsFactory = arcGisConversionSettingsFactory;
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
_threadContext = threadContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
|
||||
Parent = parent;
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
@@ -101,7 +105,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
LayersRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForLayersRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
@@ -109,7 +113,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
StandaloneTablesRemovedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForStandaloneTablesRemovedEvent(a))
|
||||
),
|
||||
true
|
||||
);
|
||||
@@ -117,7 +121,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapPropertyChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () => await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapPropertyChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // Map units, CRS etc.
|
||||
@@ -125,8 +129,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
MapMemberPropertiesChangedEvent.Subscribe(
|
||||
a =>
|
||||
_topLevelExceptionHandler.FireAndForget(
|
||||
async () =>
|
||||
await _threadContext.RunOnWorkerAsync(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
async () => await QueuedTask.Run(async () => await GetIdsForMapMemberPropertiesChangedEvent(a))
|
||||
),
|
||||
true
|
||||
); // e.g. Layer name
|
||||
@@ -135,7 +138,7 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
_ =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await _threadContext.RunOnWorker(SubscribeToMapMembersDataSourceChange);
|
||||
await QueuedTask.Run(SubscribeToMapMembersDataSourceChange);
|
||||
}),
|
||||
true
|
||||
);
|
||||
@@ -376,21 +379,25 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
List<MapMember> mapMembers = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
List<MapMember> mapMembers = await QueuedTask.Run(() =>
|
||||
{
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<ArcGISConversionSettings>>()
|
||||
.Initialize(
|
||||
_arcGISConversionSettingsFactory.Create(
|
||||
Project.Current,
|
||||
MapView.Active.Map,
|
||||
new CRSoffsetRotation(MapView.Active.Map)
|
||||
)
|
||||
);
|
||||
|
||||
return modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(id => (MapMember)MapView.Active.Map.FindLayer(id) ?? MapView.Active.Map.FindStandaloneTable(id))
|
||||
.Where(obj => obj != null)
|
||||
.ToList();
|
||||
});
|
||||
|
||||
if (mapMembers.Count == 0)
|
||||
{
|
||||
@@ -398,24 +405,27 @@ public sealed class ArcGISSendBinding : ISendBinding
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
}
|
||||
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
await QueuedTask.Run(() =>
|
||||
{
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
// subscribe to the selected layer events
|
||||
foreach (MapMember mapMember in mapMembers)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
if (mapMember is FeatureLayer featureLayer)
|
||||
{
|
||||
SubscribeToFeatureLayerDataSourceChange(featureLayer);
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
else if (mapMember is StandaloneTable table)
|
||||
{
|
||||
SubscribeToTableDataSourceChange(table);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var sendResult = await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<MapMember>>()
|
||||
.Execute(
|
||||
mapMembers,
|
||||
modelCard.GetSendInfo("ArcGIS"), // POC: get host app name from settings? same for GetReceiveInfo
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ArcGIS.Core.Data;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
@@ -66,19 +67,20 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
return Task.CompletedTask;
|
||||
await HighlightObjectsOnView(objectIds.Select(x => new ObjectID(x)).ToList());
|
||||
}
|
||||
|
||||
public Task HighlightModel(string modelCardId)
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
|
||||
if (model is null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
var objectIds = new List<ObjectID>();
|
||||
@@ -95,22 +97,24 @@ public class BasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
if (objectIds is null)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
HighlightObjectsOnView(objectIds);
|
||||
return Task.CompletedTask;
|
||||
await HighlightObjectsOnView(objectIds);
|
||||
}
|
||||
|
||||
private void HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
private async Task HighlightObjectsOnView(IReadOnlyList<ObjectID> objectIds)
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
await QueuedTask.Run(() =>
|
||||
{
|
||||
MapView mapView = MapView.Active;
|
||||
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
List<MapMemberFeature> mapMembersFeatures = GetMapMembers(objectIds, mapView);
|
||||
ClearSelectionInTOC();
|
||||
ClearSelection();
|
||||
SelectMapMembersInTOC(mapMembersFeatures);
|
||||
SelectMapMembersAndFeatures(mapMembersFeatures);
|
||||
mapView.ZoomToSelected();
|
||||
});
|
||||
}
|
||||
|
||||
private List<MapMemberFeature> GetMapMembers(IReadOnlyList<ObjectID> objectIds, MapView mapView)
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ using Speckle.Connectors.Common;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
@@ -27,7 +28,7 @@ public static class ArcGISConnectorModule
|
||||
public static void AddArcGIS(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddConnectorUtils();
|
||||
serviceCollection.AddDUI<ArcGISThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUI<DefaultThreadContext, ArcGISDocumentStore>();
|
||||
serviceCollection.AddDUIView();
|
||||
|
||||
// Register bindings
|
||||
|
||||
@@ -184,6 +184,7 @@ public class ArcGISColorUnpacker
|
||||
if (StoredColor is int existingColorProxyId)
|
||||
{
|
||||
AddObjectIdToColorProxyCache(rowApplicationId, existingColorProxyId);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the color from the renderer and row
|
||||
|
||||
+15
-1
@@ -1,6 +1,7 @@
|
||||
using System.Diagnostics.Contracts;
|
||||
using ArcGIS.Core.CIM;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.Utils;
|
||||
@@ -60,6 +61,19 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
return QueuedTask.Run(
|
||||
() => BuildInternal(rootObject, projectName, modelName, onOperationProgressed, cancellationToken)
|
||||
);
|
||||
}
|
||||
|
||||
private HostObjectBuilderResult BuildInternal(
|
||||
Base rootObject,
|
||||
string projectName,
|
||||
string modelName,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// TODO get spatialRef and offsets & rotation from ProjectInfo in CommitObject
|
||||
// ATM, GIS commit CRS is stored per layer (in FeatureClass converter), but should be moved to the Root level too
|
||||
@@ -226,7 +240,7 @@ public class ArcGISHostObjectBuilder : IHostObjectBuilder
|
||||
bakedObjectIds.AddRange(createdLayerGroups.Values.Select(x => x.URI));
|
||||
|
||||
// TODO: validated a correct set regarding bakedobject ids
|
||||
return Task.FromResult(new HostObjectBuilderResult(bakedObjectIds, results));
|
||||
return new HostObjectBuilderResult(bakedObjectIds, results);
|
||||
}
|
||||
|
||||
private IReadOnlyCollection<LocalToGlobalMap> GetObjectsToConvert(Base rootObject)
|
||||
|
||||
+107
-10
@@ -1,5 +1,6 @@
|
||||
using ArcGIS.Core.Data.Raster;
|
||||
using ArcGIS.Core.Geometry;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.ArcGIS.HostApp;
|
||||
using Speckle.Connectors.ArcGIS.HostApp.Extensions;
|
||||
@@ -49,7 +50,14 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
_mapMemberUtils = mapMemberUtils;
|
||||
}
|
||||
|
||||
public async Task<RootObjectBuilderResult> Build(
|
||||
public Task<RootObjectBuilderResult> Build(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
) => QueuedTask.Run(() => BuildInternal(layers, __, onOperationProgressed, cancellationToken));
|
||||
|
||||
private async Task<RootObjectBuilderResult> BuildInternal(
|
||||
IReadOnlyList<ADM.MapMember> layers,
|
||||
SendInfo __,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
@@ -94,19 +102,26 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// We need to unpack the selected mapmembers into all leaf-level mapmembers (containing just objects) and build the root collection structure during unpacking.
|
||||
// Mapmember dynamically attached properties are also added at this step.
|
||||
List<ADM.MapMember> unpackedLayers;
|
||||
Dictionary<ADM.MapMember, long> layersWithFeatureCount;
|
||||
long allFeaturesCount;
|
||||
ADM.Map map = ADM.MapView.Active.Map;
|
||||
IEnumerable<ADM.MapMember> layersOrdered = _mapMemberUtils.GetMapMembersInOrder(map, layers);
|
||||
using (var _ = _activityFactory.Start("Unpacking selection"))
|
||||
{
|
||||
unpackedLayers = _layerUnpacker.UnpackSelection(layersOrdered, rootCollection);
|
||||
|
||||
// count number of features to convert. Raster layers are counter as 1 feature for now (not ideal)
|
||||
layersWithFeatureCount = CountAllFeaturesInLayers(unpackedLayers);
|
||||
allFeaturesCount = layersWithFeatureCount.Values.Sum();
|
||||
}
|
||||
|
||||
List<SendConversionResult> results = new(unpackedLayers.Count);
|
||||
onOperationProgressed.Report(new("Converting", null));
|
||||
using (var convertingActivity = _activityFactory.Start("Converting objects"))
|
||||
{
|
||||
int count = 0;
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
long count = 0;
|
||||
|
||||
foreach (var (layer, layerFeatureCount) in layersWithFeatureCount)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
string layerApplicationId = layer.GetSpeckleApplicationId();
|
||||
@@ -134,15 +149,33 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(featureLayer);
|
||||
List<Base> convertedFeatureLayerObjects = ConvertFeatureLayerObjects(
|
||||
featureLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedFeatureLayerObjects);
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(rasterLayer);
|
||||
List<Base> convertedRasterLayerObjects = ConvertRasterLayerObjects(
|
||||
rasterLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedRasterLayerObjects);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(lasDatasetLayer);
|
||||
List<Base> convertedLasDatasetObjects = ConvertLasDatasetLayerObjects(
|
||||
lasDatasetLayer,
|
||||
count,
|
||||
allFeaturesCount,
|
||||
onOperationProgressed,
|
||||
cancellationToken
|
||||
);
|
||||
layerCollection.elements.AddRange(convertedLasDatasetObjects);
|
||||
break;
|
||||
default:
|
||||
@@ -150,6 +183,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
sdkStatus = SdkActivityStatusCode.Error;
|
||||
break;
|
||||
}
|
||||
|
||||
count += layerFeatureCount;
|
||||
results.Add(new(status, layerApplicationId, layer.GetType().Name, layerCollection));
|
||||
convertingActivity?.SetStatus(sdkStatus);
|
||||
}
|
||||
@@ -166,7 +201,6 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
convertingActivity?.RecordException(ex);
|
||||
}
|
||||
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / layers.Count));
|
||||
await Task.Yield();
|
||||
}
|
||||
}
|
||||
@@ -182,7 +216,41 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
return new RootObjectBuilderResult(rootCollection, results);
|
||||
}
|
||||
|
||||
private List<Base> ConvertFeatureLayerObjects(ADM.FeatureLayer featureLayer)
|
||||
private Dictionary<ADM.MapMember, long> CountAllFeaturesInLayers(List<ADM.MapMember> unpackedLayers)
|
||||
{
|
||||
Dictionary<ADM.MapMember, long> layersFeatureCount = new();
|
||||
|
||||
foreach (ADM.MapMember layer in unpackedLayers)
|
||||
{
|
||||
switch (layer)
|
||||
{
|
||||
case ADM.FeatureLayer featureLayer:
|
||||
layersFeatureCount.Add(featureLayer, featureLayer.GetFeatureClass().GetCount());
|
||||
break;
|
||||
case ADM.RasterLayer rasterLayer:
|
||||
// count Raster layer as 1 feature: not optimal but this is the approach for now
|
||||
layersFeatureCount.Add(rasterLayer, 1);
|
||||
break;
|
||||
case ADM.LasDatasetLayer lasDatasetLayer:
|
||||
var dataset = lasDatasetLayer.GetLasDataset();
|
||||
// simple dataset.GetPointCount() keeps returning null, so switched to EstimatePointCount
|
||||
layersFeatureCount.Add(
|
||||
lasDatasetLayer,
|
||||
(long)dataset.EstimatePointCount(dataset.GetDefinition().GetExtent())
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return layersFeatureCount;
|
||||
}
|
||||
|
||||
private List<Base> ConvertFeatureLayerObjects(
|
||||
ADM.FeatureLayer featureLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = featureLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
@@ -196,6 +264,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
while (rowCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every feature
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Same IDisposable issue appears to happen on Row class too. Docs say it should always be disposed of manually by the caller.
|
||||
using (ACD.Row row = rowCursor.Current)
|
||||
{
|
||||
@@ -209,6 +280,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessFeatureLayerColor(row, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,19 +289,38 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
}
|
||||
|
||||
// POC: raster colors are stored as mesh vertex colors in RasterToSpeckleConverter. Should probably move to color unpacker.
|
||||
private List<Base> ConvertRasterLayerObjects(ADM.RasterLayer rasterLayer)
|
||||
private List<Base> ConvertRasterLayerObjects(
|
||||
ADM.RasterLayer rasterLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = rasterLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
Raster raster = rasterLayer.GetRaster();
|
||||
|
||||
// check cancellation token before conversion
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
Base converted = _rootToSpeckleConverter.Convert(raster);
|
||||
string applicationId = raster.GetSpeckleApplicationId(layerApplicationId);
|
||||
converted.applicationId = applicationId;
|
||||
convertedObjects.Add(converted);
|
||||
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
|
||||
return convertedObjects;
|
||||
}
|
||||
|
||||
private List<Base> ConvertLasDatasetLayerObjects(ADM.LasDatasetLayer lasDatasetLayer)
|
||||
private List<Base> ConvertLasDatasetLayerObjects(
|
||||
ADM.LasDatasetLayer lasDatasetLayer,
|
||||
long count,
|
||||
long allFeaturesCount,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
string layerApplicationId = lasDatasetLayer.GetSpeckleApplicationId();
|
||||
List<Base> convertedObjects = new();
|
||||
@@ -242,6 +334,9 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
{
|
||||
while (ptCursor.MoveNext())
|
||||
{
|
||||
// allow cancellation before every point
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using (ACD.Analyst3D.LasPoint pt = ptCursor.Current)
|
||||
{
|
||||
Base converted = _rootToSpeckleConverter.Convert(pt);
|
||||
@@ -252,6 +347,8 @@ public class ArcGISRootObjectBuilder : IRootObjectBuilder<ADM.MapMember>
|
||||
// process the object color
|
||||
_colorUnpacker.ProcessLasLayerColor(pt, applicationId);
|
||||
}
|
||||
// update report
|
||||
onOperationProgressed.Report(new("Converting", (double)++count / allFeaturesCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
|
||||
namespace Speckle.Connectors.ArcGIS.Utils;
|
||||
|
||||
//don't check for GUI as it's the same check we do in ThreadContext
|
||||
public class ArcGISThreadContext : ThreadContext
|
||||
{
|
||||
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return action();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(async () => await action());
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => QueuedTask.Run(async () => await action());
|
||||
|
||||
protected override Task<T> MainToWorker<T>(Func<T> action)
|
||||
{
|
||||
if (QueuedTask.OnWorker)
|
||||
{
|
||||
return Task.FromResult(action());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QueuedTask.Run(action);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => QueuedTask.Run(action);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Xml.Linq;
|
||||
using ArcGIS.Desktop.Core.Events;
|
||||
using ArcGIS.Desktop.Framework.Threading.Tasks;
|
||||
using ArcGIS.Desktop.Mapping;
|
||||
using ArcGIS.Desktop.Mapping.Events;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
@@ -82,8 +83,8 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
}
|
||||
|
||||
protected override void HostAppSaveState(string modelCardState) =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
// Read existing metadata - To prevent messing existing metadata. 🤞 Hope other add-in developers will do same :D
|
||||
@@ -112,8 +113,8 @@ public class ArcGISDocumentStore : DocumentModelStore
|
||||
.FireAndForget();
|
||||
|
||||
protected override void LoadState() =>
|
||||
_threadContext
|
||||
.RunOnWorker(() =>
|
||||
QueuedTask
|
||||
.Run(() =>
|
||||
{
|
||||
Map map = MapView.Active.Map;
|
||||
var metadata = map.GetMetadata();
|
||||
|
||||
@@ -226,9 +226,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -236,8 +236,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -261,7 +261,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -294,40 +294,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
"net6.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -294,7 +294,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -333,40 +333,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -294,7 +294,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -333,40 +333,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -295,7 +295,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -225,8 +225,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -251,7 +251,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -290,39 +290,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+2
@@ -79,6 +79,8 @@ public class AutocadBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
// POC: Will be addressed to move it into AutocadContext!
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public abstract class AutocadReceiveBaseBinding : IReceiveBinding
|
||||
{
|
||||
public string Name => "receiveBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadReceiveBinding> _logger;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
private ReceiveBindingUICommands Commands { get; }
|
||||
|
||||
protected AutocadReceiveBaseBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_cancellationManager = cancellationManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
protected abstract void InitializeSettings(IServiceProvider serviceProvider);
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
|
||||
|
||||
private async Task ReceiveInternal(string modelCardId)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
InitializeSettings(scope.ServiceProvider);
|
||||
|
||||
try
|
||||
{
|
||||
// Get receiver card
|
||||
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No download model card was found.");
|
||||
}
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Receive host objects
|
||||
var operationResults = await scope
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
operationResults.BakedObjectIds,
|
||||
operationResults.ConversionResults
|
||||
);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// reenable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
|
||||
// regenerate doc to flush graphics, sometimes some objects (ellipses, nurbs curves) do not appear fully visible after receive.
|
||||
// Adding a regen (must be run on main thread) here, but it doesn't seem to work:
|
||||
// it's run on main thread, tried sending the "regen" string to execute, also tried regen after every object bake, but still can't fix.
|
||||
// the objects should appear visible if you manually call the "regen" command after the operation finishes, or click on a view on the view cube which also calls regen.
|
||||
Application.DocumentManager.CurrentDocument.Editor.Regen();
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-82
@@ -1,34 +1,19 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Autocad.Bindings;
|
||||
|
||||
public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
public sealed class AutocadReceiveBinding : AutocadReceiveBaseBinding
|
||||
{
|
||||
public string Name => "receiveBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<AutocadReceiveBinding> _logger;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
private ReceiveBindingUICommands Commands { get; }
|
||||
|
||||
public AutocadReceiveBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -41,77 +26,24 @@ public sealed class AutocadReceiveBinding : IReceiveBinding
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext
|
||||
)
|
||||
{
|
||||
_store = store;
|
||||
_cancellationManager = cancellationManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
_speckleApplication = speckleApplication;
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
Commands = new ReceiveBindingUICommands(parent);
|
||||
}
|
||||
|
||||
public void CancelReceive(string modelCardId) => _cancellationManager.CancelOperation(modelCardId);
|
||||
|
||||
public async Task Receive(string modelCardId) =>
|
||||
await _threadContext.RunOnMainAsync(async () => await ReceiveInternal(modelCardId));
|
||||
|
||||
public async Task ReceiveInternal(string modelCardId)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
scope
|
||||
.ServiceProvider.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
try
|
||||
{
|
||||
// Get receiver card
|
||||
if (_store.GetModelById(modelCardId) is not ReceiverModelCard modelCard)
|
||||
{
|
||||
// Handle as GLOBAL ERROR at BrowserBridge
|
||||
throw new InvalidOperationException("No download model card was found.");
|
||||
}
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
// Disable document activation (document creation and document switch)
|
||||
// Not disabling results in DUI model card being out of sync with the active document
|
||||
// The DocumentActivated event isn't usable probably because it is pushed to back of main thread queue
|
||||
Application.DocumentManager.DocumentActivationEnabled = false;
|
||||
|
||||
// Receive host objects
|
||||
var operationResults = await scope
|
||||
.ServiceProvider.GetRequiredService<ReceiveOperation>()
|
||||
.Execute(
|
||||
modelCard.GetReceiveInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelReceiveResult(
|
||||
modelCardId,
|
||||
operationResults.BakedObjectIds,
|
||||
operationResults.ConversionResults
|
||||
);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// reenable document activation
|
||||
Application.DocumentManager.DocumentActivationEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-7
@@ -48,7 +48,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<string, byte> ChangedObjectIds { get; set; } = new();
|
||||
private ConcurrentBag<string> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
protected AutocadSendBaseBinding(
|
||||
DocumentModelStore store,
|
||||
@@ -114,21 +114,20 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
|
||||
private void OnChangeChangedObjectIds(DBObject dBObject)
|
||||
{
|
||||
ChangedObjectIds[dBObject.GetSpeckleApplicationId()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(AutocadSendBinding), async () => await RunExpirationChecks());
|
||||
ChangedObjectIds.Add(dBObject.GetSpeckleApplicationId());
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), async () => await RunExpirationChecks());
|
||||
}
|
||||
|
||||
private async Task RunExpirationChecks()
|
||||
{
|
||||
var senders = _store.GetSenders();
|
||||
string[] objectIdsList = ChangedObjectIds.Keys.ToArray();
|
||||
List<string> expiredSenderIds = new();
|
||||
|
||||
_sendConversionCache.EvictObjects(objectIdsList);
|
||||
_sendConversionCache.EvictObjects(ChangedObjectIds);
|
||||
|
||||
foreach (SenderModelCard modelCard in senders)
|
||||
{
|
||||
var intersection = modelCard.SendFilter.NotNull().RefreshObjectIds().Intersect(objectIdsList).ToList();
|
||||
var intersection = modelCard.SendFilter.NotNull().RefreshObjectIds().Intersect(ChangedObjectIds).ToList();
|
||||
bool isExpired = intersection.Count != 0;
|
||||
if (isExpired)
|
||||
{
|
||||
@@ -184,7 +183,7 @@ public abstract class AutocadSendBaseBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<AutocadRootObject>>()
|
||||
.Execute(
|
||||
autocadObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
+4
-4
@@ -83,7 +83,7 @@ public class AutocadHostObjectBuilder(
|
||||
colorBaker.ParseColors(unpackedRoot.ColorProxies, onOperationProgressed);
|
||||
}
|
||||
|
||||
// 5 - Convert atomic objects
|
||||
// 4 - Convert atomic objects
|
||||
HashSet<ReceiveConversionResult> results = new();
|
||||
HashSet<string> bakedObjectIds = new();
|
||||
Dictionary<string, IReadOnlyCollection<Entity>> applicationIdMap = new();
|
||||
@@ -116,7 +116,7 @@ public class AutocadHostObjectBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
// 6 - Convert instances
|
||||
// 5 - Convert instances
|
||||
var (createdInstanceIds, consumedObjectIds, instanceConversionResults) = instanceBaker.BakeInstances(
|
||||
instanceComponentsWithPath,
|
||||
applicationIdMap,
|
||||
@@ -129,7 +129,7 @@ public class AutocadHostObjectBuilder(
|
||||
results.RemoveWhere(result => result.ResultId != null && consumedObjectIds.Contains(result.ResultId));
|
||||
results.UnionWith(instanceConversionResults);
|
||||
|
||||
// 7 - Create groups
|
||||
// 6 - Create groups
|
||||
if (unpackedRoot.GroupProxies != null)
|
||||
{
|
||||
IReadOnlyCollection<ReceiveConversionResult> groupResults = groupBaker.CreateGroups(
|
||||
@@ -167,7 +167,7 @@ public class AutocadHostObjectBuilder(
|
||||
convertedEntities.Add(bakedEntity);
|
||||
break;
|
||||
|
||||
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx
|
||||
case List<(Entity, Base)> listConversionResult: // this is from fallback conversion for brep/brepx/subdx/extrusionx/polycurve
|
||||
var bakedFallbackEntities = BakeObjectsAsGroup(listConversionResult, obj, layerName, baseLayerNamePrefix);
|
||||
convertedEntities.UnionWith(bakedFallbackEntities);
|
||||
break;
|
||||
|
||||
+1
@@ -9,6 +9,7 @@
|
||||
<Import_RootNamespace>Speckle.Connectors.AutocadShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBaseBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSelectionBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\AutocadSendBinding.cs" />
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -304,7 +304,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -343,40 +343,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,9 +224,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -234,8 +234,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -261,7 +261,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
@@ -300,39 +300,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Autocad.Bindings;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Converters.Autocad;
|
||||
using Speckle.Converters.Civil3dShared;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Civil3dShared.Bindings;
|
||||
|
||||
public sealed class Civil3dReceiveBinding : AutocadReceiveBaseBinding
|
||||
{
|
||||
private readonly ICivil3dConversionSettingsFactory _civil3dConversionSettingsFactory;
|
||||
private readonly IAutocadConversionSettingsFactory _autocadConversionSettingsFactory;
|
||||
|
||||
public Civil3dReceiveBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
ICancellationManager cancellationManager,
|
||||
IServiceProvider serviceProvider,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
ILogger<AutocadReceiveBinding> logger,
|
||||
ICivil3dConversionSettingsFactory civil3dConversionSettingsFactory,
|
||||
IAutocadConversionSettingsFactory autocadConversionSettingsFactory,
|
||||
ISpeckleApplication speckleApplication,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
: base(
|
||||
store,
|
||||
parent,
|
||||
cancellationManager,
|
||||
serviceProvider,
|
||||
operationProgressManager,
|
||||
logger,
|
||||
speckleApplication,
|
||||
threadContext
|
||||
)
|
||||
{
|
||||
_civil3dConversionSettingsFactory = civil3dConversionSettingsFactory;
|
||||
_autocadConversionSettingsFactory = autocadConversionSettingsFactory;
|
||||
}
|
||||
|
||||
// POC: we're registering the conversion settings for autocad here because we need the autocad conversion settings to be able to use the autocad typed converters.
|
||||
// POC: We need a separate receive binding for civil3d due to using a different unit converter (needed for conversion settings construction)
|
||||
protected override void InitializeSettings(IServiceProvider serviceProvider)
|
||||
{
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<Civil3dConversionSettings>>()
|
||||
.Initialize(_civil3dConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
|
||||
serviceProvider
|
||||
.GetRequiredService<IConverterSettingsStore<AutocadConversionSettings>>()
|
||||
.Initialize(_autocadConversionSettingsFactory.Create(Application.DocumentManager.CurrentDocument));
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -6,7 +6,6 @@ using Speckle.Connectors.Civil3dShared.Bindings;
|
||||
using Speckle.Connectors.Civil3dShared.Operations.Send;
|
||||
using Speckle.Connectors.Common.Builders;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Sdk;
|
||||
|
||||
@@ -17,18 +16,20 @@ public static class Civil3dConnectorModule
|
||||
public static void AddCivil3d(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddAutocadBase();
|
||||
serviceCollection.LoadSend();
|
||||
|
||||
// register civil specific send classes
|
||||
// add send
|
||||
serviceCollection.LoadSend();
|
||||
serviceCollection.AddScoped<IRootObjectBuilder<AutocadRootObject>, Civil3dRootObjectBuilder>();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dSendBinding>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
// add receive
|
||||
serviceCollection.LoadReceive();
|
||||
serviceCollection.AddSingleton<IBinding, Civil3dReceiveBinding>();
|
||||
|
||||
// additional classes
|
||||
serviceCollection.AddScoped<PropertySetDefinitionHandler>();
|
||||
serviceCollection.AddScoped<CatchmentGroupHandler>();
|
||||
serviceCollection.AddScoped<PipeNetworkHandler>();
|
||||
|
||||
// automatically detects the Class:IClass interface pattern to register all generated interfaces
|
||||
serviceCollection.AddMatchingInterfacesAsTransient(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
||||
|
||||
-10
@@ -4,7 +4,6 @@ using Speckle.Connectors.Autocad.HostApp;
|
||||
using Speckle.Connectors.Autocad.Operations.Send;
|
||||
using Speckle.Connectors.Common.Caching;
|
||||
using Speckle.Connectors.Common.Operations;
|
||||
using Speckle.Converters.Civil3dShared.Helpers;
|
||||
using Speckle.Converters.Civil3dShared.ToSpeckle;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Logging;
|
||||
@@ -16,14 +15,10 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
private readonly AutocadLayerUnpacker _layerUnpacker;
|
||||
private readonly PropertySetDefinitionHandler _propertySetDefinitionHandler;
|
||||
private readonly CatchmentGroupHandler _catchmentGroupHandler;
|
||||
private readonly PipeNetworkHandler _pipeNetworkHandler;
|
||||
|
||||
public Civil3dRootObjectBuilder(
|
||||
AutocadLayerUnpacker layerUnpacker,
|
||||
PropertySetDefinitionHandler propertySetDefinitionHandler,
|
||||
CatchmentGroupHandler catchmentGroupHandler,
|
||||
PipeNetworkHandler pipeNetworkHandler,
|
||||
IRootToSpeckleConverter converter,
|
||||
ISendConversionCache sendConversionCache,
|
||||
AutocadInstanceUnpacker instanceObjectManager,
|
||||
@@ -46,8 +41,6 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
{
|
||||
_layerUnpacker = layerUnpacker;
|
||||
_propertySetDefinitionHandler = propertySetDefinitionHandler;
|
||||
_catchmentGroupHandler = catchmentGroupHandler;
|
||||
_pipeNetworkHandler = pipeNetworkHandler;
|
||||
}
|
||||
|
||||
public override (Collection, LayerTableRecord?) CreateObjectCollection(Entity entity, Transaction tr)
|
||||
@@ -57,11 +50,8 @@ public sealed class Civil3dRootObjectBuilder : AutocadRootObjectBaseBuilder
|
||||
return (layer, autocadLayer);
|
||||
}
|
||||
|
||||
// POC: probably will need to add Network proxies as well
|
||||
public override void AddAdditionalProxiesToRoot(Collection rootObject)
|
||||
{
|
||||
rootObject[ProxyKeys.PROPERTYSET_DEFINITIONS] = _propertySetDefinitionHandler.Definitions;
|
||||
rootObject["catchmentGroupProxies"] = _catchmentGroupHandler.CatchmentGroupProxiesCache.Values.ToList();
|
||||
rootObject["pipeNetworkProxies"] = _pipeNetworkHandler.PipeNetworkProxiesCache.Values.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,13 +9,13 @@
|
||||
<Import_RootNamespace>Speckle.Connectors.Civil3dShared</Import_RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dReceiveBinding.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)DependencyInjection\Civil3dConnectorModule.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Civil3dRootObjectBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Bindings\Civil3dSendBinding.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)DependencyInjection\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Bindings\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Operations\Send\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
+23
-6
@@ -1,4 +1,5 @@
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
@@ -11,6 +12,7 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
private readonly ISpeckleApplication _speckleApplication;
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
public string Name => "baseBinding";
|
||||
public IBrowserBridge Parent { get; }
|
||||
public BasicConnectorBindingCommands Commands { get; }
|
||||
@@ -19,9 +21,11 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
IBrowserBridge parent,
|
||||
ISpeckleApplication speckleApplication,
|
||||
DocumentModelStore store,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
_speckleApplication = speckleApplication;
|
||||
_store = store;
|
||||
@@ -31,7 +35,11 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
_store.DocumentChanged += (_, _) =>
|
||||
_topLevelExceptionHandler.FireAndForget(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
// enforce main thread
|
||||
await _threadContext.RunOnMainAsync(async () =>
|
||||
{
|
||||
await Commands.NotifyDocumentChanged();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,11 +53,20 @@ public class CsiSharedBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public DocumentModelStore GetDocumentState() => _store;
|
||||
|
||||
public void AddModel(ModelCard model) => _store.AddModel(model);
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void AddModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.AddModel(model), true));
|
||||
|
||||
public void UpdateModel(ModelCard model) => _store.UpdateModel(model);
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void UpdateModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.UpdateModel(model), true));
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
/// <remarks>Operations must run on the main thread for ETABS and SAP 2000</remarks>
|
||||
public void RemoveModel(ModelCard model) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModel(model), true));
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnThread(() => _store.RemoveModels(models), true));
|
||||
|
||||
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.CSiShared.HostApp;
|
||||
using Speckle.Connectors.CSiShared.Utils;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
@@ -12,7 +13,9 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
private bool _disposed;
|
||||
private readonly Timer _selectionTimer;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private HashSet<string> _lastSelection = new();
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
|
||||
public IBrowserBridge Parent { get; }
|
||||
public string Name => "selectionBinding";
|
||||
@@ -20,26 +23,37 @@ public class CsiSharedSelectionBinding : ISelectionBinding, IDisposable
|
||||
public CsiSharedSelectionBinding(
|
||||
IBrowserBridge parent,
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
Parent = parent;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
|
||||
_selectionTimer = new Timer(1000);
|
||||
_selectionTimer.Elapsed += (_, _) => topLevelExceptionHandler.CatchUnhandled(CheckSelectionChanged);
|
||||
_selectionTimer.Elapsed += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckSelectionChanged));
|
||||
_selectionTimer.Start();
|
||||
}
|
||||
|
||||
private void CheckSelectionChanged()
|
||||
{
|
||||
// timer callbacks are on a background thread, but CSI API calls must be on main thread
|
||||
var currentSelection = GetSelection();
|
||||
var currentIds = new HashSet<string>(currentSelection.SelectedObjectIds);
|
||||
|
||||
if (!_lastSelection.SetEquals(currentIds))
|
||||
{
|
||||
_lastSelection = currentIds;
|
||||
Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection);
|
||||
// ensure UI updates also run on main thread
|
||||
_threadContext.RunOnMain(
|
||||
() =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() => Parent.Send(SelectionBindingEvents.SET_SELECTION, currentSelection)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ public sealed class CsiSharedSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ICsiWrapper>>()
|
||||
.Execute(
|
||||
wrappers,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
@@ -16,6 +17,7 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
private readonly ILogger<CsiDocumentModelStore> _logger;
|
||||
private readonly ICsiApplicationService _csiApplicationService;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
private readonly Timer _modelCheckTimer;
|
||||
private string _lastModelFilename = string.Empty;
|
||||
private bool _disposed;
|
||||
@@ -28,10 +30,12 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
ISpeckleApplication speckleApplication,
|
||||
ILogger<CsiDocumentModelStore> logger,
|
||||
ICsiApplicationService csiApplicationService,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
_threadContext = threadContext;
|
||||
_speckleApplication = speckleApplication;
|
||||
_logger = logger;
|
||||
_csiApplicationService = csiApplicationService;
|
||||
@@ -39,7 +43,10 @@ public class CsiDocumentModelStore : DocumentModelStore, IDisposable
|
||||
|
||||
// initialize timer to check for model changes
|
||||
_modelCheckTimer = new Timer(1000);
|
||||
_modelCheckTimer.Elapsed += (_, _) => _topLevelExceptionHandler.CatchUnhandled(CheckModelChanges);
|
||||
|
||||
// timer runs on background thread but model checks must be on main thread
|
||||
_modelCheckTimer.Elapsed += (_, _) =>
|
||||
_topLevelExceptionHandler.CatchUnhandled(() => _threadContext.RunOnMain(CheckModelChanges));
|
||||
_modelCheckTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs21": {
|
||||
@@ -332,40 +332,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +215,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -225,8 +225,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -243,7 +243,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.etabs22": {
|
||||
@@ -288,39 +288,39 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2020": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2021": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2022": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2023": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -259,9 +259,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -269,8 +269,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -287,7 +287,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2024": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
@@ -265,9 +265,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -275,8 +275,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -293,7 +293,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.navisworks2025": {
|
||||
@@ -334,40 +334,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
".NETFramework,Version=v4.8/win-x64": {
|
||||
|
||||
+2
@@ -50,6 +50,8 @@ public class NavisworksBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public Task HighlightModel(string modelCardId) => Task.CompletedTask;
|
||||
|
||||
public async Task HighlightObjects(IReadOnlyList<string> objectIds) =>
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class NavisworksSelectionBinding : ISelectionBinding
|
||||
}
|
||||
|
||||
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
|
||||
_idleManager.SubscribeToIdle(nameof(NavisworksSelectionBinding), async () => await UpdateSelectionAsync());
|
||||
_idleManager.SubscribeToIdle(nameof(UpdateSelectionAsync), async () => await UpdateSelectionAsync());
|
||||
|
||||
private async Task UpdateSelectionAsync()
|
||||
{
|
||||
|
||||
+58
-25
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connector.Navisworks.Operations.Send.Filters;
|
||||
using Speckle.Connector.Navisworks.Operations.Send.Settings;
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Connectors.Common.Cancellation;
|
||||
@@ -30,7 +31,6 @@ public class NavisworksSendBinding : ISendBinding
|
||||
|
||||
private readonly DocumentModelStore _store;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly List<ISendFilter> _sendFilters;
|
||||
private readonly ICancellationManager _cancellationManager;
|
||||
private readonly IOperationProgressManager _operationProgressManager;
|
||||
private readonly ILogger<NavisworksSendBinding> _logger;
|
||||
@@ -44,7 +44,6 @@ public class NavisworksSendBinding : ISendBinding
|
||||
public NavisworksSendBinding(
|
||||
DocumentModelStore store,
|
||||
IBrowserBridge parent,
|
||||
IEnumerable<ISendFilter> sendFilters,
|
||||
IServiceProvider serviceProvider,
|
||||
ICancellationManager cancellationManager,
|
||||
IOperationProgressManager operationProgressManager,
|
||||
@@ -61,7 +60,6 @@ public class NavisworksSendBinding : ISendBinding
|
||||
Commands = new SendBindingUICommands(parent);
|
||||
_store = store;
|
||||
_serviceProvider = serviceProvider;
|
||||
_sendFilters = sendFilters.ToList();
|
||||
_cancellationManager = cancellationManager;
|
||||
_operationProgressManager = operationProgressManager;
|
||||
_logger = logger;
|
||||
@@ -76,7 +74,12 @@ public class NavisworksSendBinding : ISendBinding
|
||||
|
||||
private static void SubscribeToNavisworksEvents() { }
|
||||
|
||||
public List<ISendFilter> GetSendFilters() => _sendFilters;
|
||||
// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise, we might not be able to update list of saved sets.
|
||||
public List<ISendFilter> GetSendFilters() =>
|
||||
[
|
||||
new NavisworksSelectionFilter() { IsDefault = true },
|
||||
new NavisworksSavedSetsFilter(new ElementSelectionService())
|
||||
];
|
||||
|
||||
public List<ICardSetting> GetSendSettings() =>
|
||||
[
|
||||
@@ -84,6 +87,7 @@ public class NavisworksSendBinding : ISendBinding
|
||||
new OriginModeSetting(OriginMode.ModelOrigin),
|
||||
new IncludeInternalPropertiesSetting(false),
|
||||
new ConvertHiddenElementsSetting(false),
|
||||
new PreserveModelHierarchySetting(false),
|
||||
];
|
||||
|
||||
public async Task Send(string modelCardId) =>
|
||||
@@ -102,9 +106,21 @@ public class NavisworksSendBinding : ISendBinding
|
||||
|
||||
using var cancellationItem = _cancellationManager.GetCancellationItem(modelCardId);
|
||||
|
||||
var navisworksModelItems = GetNavisworksModelItems(modelCard);
|
||||
var progress = _operationProgressManager.CreateOperationProgressEventHandler(
|
||||
Parent,
|
||||
modelCard.ModelCardId.NotNull(),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
var sendResult = await ExecuteSendOperation(scope, modelCard, navisworksModelItems, cancellationItem.Token);
|
||||
var navisworksModelItems = await GetNavisworksModelItems(modelCard, progress);
|
||||
|
||||
var sendResult = await ExecuteSendOperation(
|
||||
scope,
|
||||
modelCard,
|
||||
navisworksModelItems,
|
||||
progress,
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
await Commands.SetModelSendResult(modelCardId, sendResult.RootObjId, sendResult.ConversionResults);
|
||||
}
|
||||
@@ -119,12 +135,16 @@ public class NavisworksSendBinding : ISendBinding
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
await Commands.SetModelError(modelCardId, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// otherwise the id of the operation persists on the cancellation manager and triggers 'Operations cancelled because of document swap!' message to UI.
|
||||
_cancellationManager.CancelOperation(modelCardId);
|
||||
}
|
||||
}
|
||||
|
||||
private SenderModelCard GetModelCard(string modelCardId) =>
|
||||
_store.GetModelById(modelCardId) is not SenderModelCard modelCard
|
||||
? throw new InvalidOperationException("No publish model card was found.")
|
||||
: modelCard;
|
||||
_store.GetModelById(modelCardId) as SenderModelCard
|
||||
?? throw new InvalidOperationException("No publish model card was found.");
|
||||
|
||||
private void InitializeConverterSettings(IServiceScope scope, SenderModelCard modelCard) =>
|
||||
scope
|
||||
@@ -134,43 +154,56 @@ public class NavisworksSendBinding : ISendBinding
|
||||
originMode: _toSpeckleSettingsManagerNavisworks.GetOriginMode(modelCard),
|
||||
visualRepresentationMode: _toSpeckleSettingsManagerNavisworks.GetVisualRepresentationMode(modelCard),
|
||||
convertHiddenElements: _toSpeckleSettingsManagerNavisworks.GetConvertHiddenElements(modelCard),
|
||||
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard)
|
||||
includeInternalProperties: _toSpeckleSettingsManagerNavisworks.GetIncludeInternalProperties(modelCard),
|
||||
preserveModelHierarchy: _toSpeckleSettingsManagerNavisworks.GetPreserveModelHierarchy(modelCard)
|
||||
)
|
||||
);
|
||||
|
||||
private List<NAV.ModelItem> GetNavisworksModelItems(SenderModelCard modelCard)
|
||||
private async Task<List<NAV.ModelItem>> GetNavisworksModelItems(
|
||||
SenderModelCard modelCard,
|
||||
IProgress<CardProgress> onOperationProgressed
|
||||
)
|
||||
{
|
||||
var selectedPaths = modelCard.SendFilter.NotNull().RefreshObjectIds();
|
||||
var convertHiddenElementsSetting =
|
||||
modelCard.Settings!.FirstOrDefault(s => s.Id == "convertHiddenElements")?.Value as bool? ?? false;
|
||||
var message = convertHiddenElementsSetting
|
||||
? "No visible objects were found to convert. Please update your publish filter!"
|
||||
: "No objects were found to convert. Please update your publish filter, or check items are visible!";
|
||||
|
||||
if (selectedPaths.Count == 0)
|
||||
{
|
||||
throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!");
|
||||
throw new SpeckleSendFilterException(message);
|
||||
}
|
||||
onOperationProgressed.Report(new CardProgress("Getting selection...", null));
|
||||
await Task.CompletedTask;
|
||||
|
||||
var modelItems = modelCard
|
||||
.SendFilter.NotNull()
|
||||
.RefreshObjectIds()
|
||||
.Select(_selectionService.GetModelItemFromPath)
|
||||
.SelectMany(_selectionService.GetGeometryNodes)
|
||||
.Where(_selectionService.IsVisible)
|
||||
.ToList();
|
||||
|
||||
return modelItems.Count == 0
|
||||
? throw new SpeckleSendFilterException("No objects were found to convert. Please update your publish filter!")
|
||||
: modelItems;
|
||||
var modelItems = new List<NAV.ModelItem>();
|
||||
double count = 0;
|
||||
foreach (var path in selectedPaths)
|
||||
{
|
||||
onOperationProgressed.Report(new CardProgress("Getting selection...", count / selectedPaths.Count));
|
||||
await Task.CompletedTask;
|
||||
var modelItem = _selectionService.GetModelItemFromPath(path);
|
||||
modelItems.AddRange(_selectionService.GetGeometryNodes(modelItem).Where(_selectionService.IsVisible));
|
||||
count++;
|
||||
}
|
||||
return modelItems.Count == 0 ? throw new SpeckleSendFilterException(message) : modelItems;
|
||||
}
|
||||
|
||||
private async Task<SendOperationResult> ExecuteSendOperation(
|
||||
IServiceScope scope,
|
||||
SenderModelCard modelCard,
|
||||
List<NAV.ModelItem> navisworksModelItems,
|
||||
IProgress<CardProgress> onOperationProgressed,
|
||||
CancellationToken token
|
||||
) =>
|
||||
await scope
|
||||
.ServiceProvider.GetRequiredService<SendOperation<NAV.ModelItem>>()
|
||||
.Execute(
|
||||
navisworksModelItems,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCard.ModelCardId.NotNull(), token),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
onOperationProgressed,
|
||||
token
|
||||
);
|
||||
|
||||
|
||||
+1
@@ -67,6 +67,7 @@ public static class NavisworksConnectorServiceRegistration
|
||||
|
||||
// register filters
|
||||
serviceCollection.AddScoped<ISendFilter, NavisworksSelectionFilter>();
|
||||
serviceCollection.AddScoped<ISendFilter, NavisworksSavedSetsFilter>();
|
||||
serviceCollection.AddScoped<IElementSelectionService, ElementSelectionService>();
|
||||
}
|
||||
}
|
||||
|
||||
+4
-11
@@ -1,15 +1,9 @@
|
||||
using static Speckle.Converter.Navisworks.Helpers.ElementSelectionHelper;
|
||||
using Speckle.InterfaceGenerator;
|
||||
using static Speckle.Converter.Navisworks.Helpers.ElementSelectionHelper;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Services;
|
||||
|
||||
public interface IElementSelectionService
|
||||
{
|
||||
string GetModelItemPath(NAV.ModelItem modelItem);
|
||||
NAV.ModelItem GetModelItemFromPath(string path);
|
||||
bool IsVisible(NAV.ModelItem modelItem);
|
||||
IReadOnlyCollection<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem);
|
||||
}
|
||||
|
||||
[GenerateAutoInterface]
|
||||
public class ElementSelectionService : IElementSelectionService
|
||||
{
|
||||
public string GetModelItemPath(NAV.ModelItem modelItem) => ResolveModelItemToIndexPath(modelItem);
|
||||
@@ -18,6 +12,5 @@ public class ElementSelectionService : IElementSelectionService
|
||||
|
||||
public bool IsVisible(NAV.ModelItem modelItem) => IsElementVisible(modelItem);
|
||||
|
||||
public IReadOnlyCollection<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem) =>
|
||||
ResolveGeometryLeafNodes(modelItem);
|
||||
public IEnumerable<NAV.ModelItem> GetGeometryNodes(NAV.ModelItem modelItem) => ResolveGeometryLeafNodes(modelItem);
|
||||
}
|
||||
|
||||
+5
-5
@@ -43,12 +43,13 @@ public class NavisworksColorUnpacker(
|
||||
Dictionary<string, ColorProxy> colorProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
foreach (var node in group.Value)
|
||||
string groupKey = group.Key;
|
||||
|
||||
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
|
||||
{
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
mergedIds[nodePath] = groupKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +57,13 @@ public class NavisworksColorUnpacker(
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip non-2D elements
|
||||
if (!Is2DElement(navisworksObject))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
@@ -77,7 +78,6 @@ public class NavisworksColorUnpacker(
|
||||
geometry.OriginalColor,
|
||||
defaultColor
|
||||
);
|
||||
|
||||
var colorId = Select(
|
||||
mode,
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
|
||||
+4
-1
@@ -77,7 +77,10 @@ public sealed class NavisworksDocumentEvents
|
||||
|
||||
_topLevelExceptionHandler.CatchUnhandled(
|
||||
() =>
|
||||
_idleManager.SubscribeToIdle(nameof(NavisworksDocumentEvents), async () => await ProcessModelStateChangeAsync())
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(ProcessModelStateChangeAsync),
|
||||
async () => await ProcessModelStateChangeAsync()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -43,12 +43,13 @@ public class NavisworksMaterialUnpacker(
|
||||
Dictionary<string, RenderMaterialProxy> renderMaterialProxies = [];
|
||||
Dictionary<string, string> mergedIds = [];
|
||||
|
||||
// Build mergedIds map once
|
||||
foreach (var group in groupedNodes)
|
||||
{
|
||||
foreach (var node in group.Value)
|
||||
string groupKey = group.Key;
|
||||
|
||||
foreach (var nodePath in group.Value.Select(selectionService.GetModelItemPath))
|
||||
{
|
||||
mergedIds[selectionService.GetModelItemPath(node)] = group.Key;
|
||||
mergedIds[nodePath] = groupKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +64,6 @@ public class NavisworksMaterialUnpacker(
|
||||
|
||||
var navisworksObjectId = selectionService.GetModelItemPath(navisworksObject);
|
||||
var finalId = mergedIds.TryGetValue(navisworksObjectId, out var mergedId) ? mergedId : navisworksObjectId;
|
||||
|
||||
var geometry = navisworksObject.Geometry;
|
||||
var mode = converterSettings.Current.User.VisualRepresentationMode;
|
||||
|
||||
@@ -76,7 +76,6 @@ public class NavisworksMaterialUnpacker(
|
||||
geometry.OriginalColor,
|
||||
defaultColor
|
||||
);
|
||||
|
||||
var renderTransparency = Select(
|
||||
mode,
|
||||
geometry.ActiveTransparency,
|
||||
@@ -84,7 +83,6 @@ public class NavisworksMaterialUnpacker(
|
||||
geometry.OriginalTransparency,
|
||||
0.0
|
||||
);
|
||||
|
||||
var renderMaterialId = Select(
|
||||
mode,
|
||||
$"{geometry.ActiveColor.GetHashCode()}_{geometry.ActiveTransparency}".GetHashCode(),
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Connectors.DUI.Exceptions;
|
||||
using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
using Speckle.Converter.Navisworks.Constants;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send.Filters;
|
||||
|
||||
public class NavisworksSavedSetsFilter : DiscriminatedObject, ISendFilterSelect
|
||||
{
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
|
||||
public NavisworksSavedSetsFilter(IElementSelectionService selectionService)
|
||||
{
|
||||
_selectionService = selectionService;
|
||||
|
||||
Items = [];
|
||||
SelectedItems = [];
|
||||
|
||||
GetSavedSets();
|
||||
}
|
||||
|
||||
public string Id { get; set; } = "navisworksSavedSets";
|
||||
public string Name { get; set; } = "Saved Sets";
|
||||
public string? Summary { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public List<string> SelectedObjectIds { get; set; } = [];
|
||||
public Dictionary<string, string>? IdMap { get; set; }
|
||||
|
||||
public bool IsMultiSelectable { get; set; } = true;
|
||||
public List<SendFilterSelectItem> SelectedItems { get; set; }
|
||||
public List<SendFilterSelectItem> Items { get; set; }
|
||||
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
List<string> objectIds = [];
|
||||
|
||||
if (SelectedItems.Count == 0)
|
||||
{
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
var selectionSets = NavisworksApp.ActiveDocument.SelectionSets;
|
||||
|
||||
foreach (var selectedSetGuid in SelectedItems)
|
||||
{
|
||||
var guid = new Guid(selectedSetGuid.Id);
|
||||
var selectionSetItem =
|
||||
selectionSets.ResolveGuid(guid)
|
||||
?? throw new SpeckleSendFilterException($"Selection set with GUID {guid} not found.");
|
||||
var selectionSet = (NAV.SelectionSet)selectionSetItem;
|
||||
if (selectionSet.HasSearch)
|
||||
{
|
||||
objectIds.AddRange(ResolveSearchSet(selectionSet.Search));
|
||||
}
|
||||
|
||||
if (selectionSet.HasExplicitModelItems)
|
||||
{
|
||||
objectIds.AddRange(ResolveSelectionSet(selectionSet.ExplicitModelItems));
|
||||
}
|
||||
}
|
||||
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
private IEnumerable<string> ResolveSelectionSet(NAV.ModelItemCollection selectionSetExplicitModelItems) =>
|
||||
selectionSetExplicitModelItems
|
||||
.Where(_selectionService.IsVisible) // Exclude hidden elements
|
||||
.Select(_selectionService.GetModelItemPath) // Resolve to index paths
|
||||
.ToList();
|
||||
|
||||
private IEnumerable<string> ResolveSearchSet(NAV.Search selectionSetSearch) =>
|
||||
selectionSetSearch
|
||||
.FindAll(NavisworksApp.ActiveDocument, false)
|
||||
.Where(_selectionService.IsVisible)
|
||||
.Select(_selectionService.GetModelItemPath)
|
||||
.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Since it is called from constructor, it is re-called whenever UI calls SendBinding.GetSendFilters() on SendFilter dialog.
|
||||
/// Do not change the behavior/scope of this class on send binding unless make sure the behavior is same. Otherwise, we might not be able to update list of saved sets.
|
||||
/// </summary>
|
||||
private void GetSavedSets()
|
||||
{
|
||||
List<NAV.SelectionSet> savedSetRecords = [];
|
||||
|
||||
CollectSavedSets(NavisworksApp.ActiveDocument.SelectionSets.RootItem, savedSetRecords);
|
||||
|
||||
Items = savedSetRecords
|
||||
.Select(setRecord =>
|
||||
{
|
||||
string hierarchicalName = BuildHierarchicalName(setRecord);
|
||||
return new SendFilterSelectItem(setRecord.Guid.ToString(), hierarchicalName);
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static void CollectSavedSets(NAV.SavedItem parentItem, List<NAV.SelectionSet> collectedSets)
|
||||
{
|
||||
if (!parentItem.IsGroup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (NAV.SavedItem item in ((NAV.FolderItem)parentItem).Children)
|
||||
{
|
||||
if (item.IsGroup)
|
||||
{
|
||||
CollectSavedSets(item, collectedSets);
|
||||
}
|
||||
else
|
||||
{
|
||||
collectedSets.Add((NAV.SelectionSet)item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildHierarchicalName(NAV.SavedItem item)
|
||||
{
|
||||
var pathParts = new List<string> { item.DisplayName };
|
||||
|
||||
var current = item.Parent;
|
||||
while (current != null && current != NavisworksApp.ActiveDocument.SelectionSets.RootItem)
|
||||
{
|
||||
pathParts.Insert(0, current.DisplayName);
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return string.Join(PathConstants.SET_SEPARATOR, pathParts);
|
||||
}
|
||||
}
|
||||
+149
-6
@@ -1,4 +1,5 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Constants;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
|
||||
@@ -7,16 +8,158 @@ namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
/// </summary>
|
||||
public static class GeometryNodeMerger
|
||||
{
|
||||
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes) =>
|
||||
nodes
|
||||
/// <summary>
|
||||
/// Groups sibling geometry nodes based on material properties for merging.
|
||||
/// Only merges nodes that share the same parent and have identical material properties.
|
||||
/// </summary>
|
||||
/// <param name="nodes">The collection of ModelItems to process</param>
|
||||
/// <returns>Dictionary mapping parent paths (with material signature suffix) to their mergeable child nodes</returns>
|
||||
public static Dictionary<string, List<NAV.ModelItem>> GroupSiblingGeometryNodes(IReadOnlyList<NAV.ModelItem> nodes)
|
||||
{
|
||||
var selectionService = new ElementSelectionService();
|
||||
|
||||
// Group nameless geometry nodes by parent path and material signature
|
||||
var mergeableGroups = nodes
|
||||
.Where(node => node.HasGeometry && string.IsNullOrEmpty(node.DisplayName)) // Only anonymous geometry nodes
|
||||
.GroupBy(node =>
|
||||
{
|
||||
var service = new ElementSelectionService();
|
||||
var path = service.GetModelItemPath(node);
|
||||
// Get parent path
|
||||
var path = selectionService.GetModelItemPath(node);
|
||||
var lastSeparatorIndex = path.LastIndexOf(PathConstants.SEPARATOR);
|
||||
return lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
|
||||
var parentPath = lastSeparatorIndex == -1 ? path : path[..lastSeparatorIndex];
|
||||
|
||||
// Generate material signature
|
||||
string signature = GenerateSignature(node);
|
||||
|
||||
// Combine parent path with signature
|
||||
return $"{parentPath}{PathConstants.MATERIAL_SEPARATOR}{signature}";
|
||||
})
|
||||
.Where(group => group.Count() > 1) // Only group multiples
|
||||
.Where(group => group.Count() > 1) // Only include groups with multiple children
|
||||
.ToDictionary(group => group.Key, group => group.ToList());
|
||||
|
||||
return mergeableGroups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a signature for a node based on material properties
|
||||
/// </summary>
|
||||
private static string GenerateSignature(NAV.ModelItem node)
|
||||
{
|
||||
var signatureProperties = new Dictionary<string, object>();
|
||||
|
||||
// We can as many signature defining methods as we want here
|
||||
AddMaterialProperties(node, signatureProperties);
|
||||
|
||||
// When we are done adding properties, we can generate the signature
|
||||
return GetSignature(signatureProperties);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds material-related properties to the properties dictionary
|
||||
/// </summary>
|
||||
private static void AddMaterialProperties(NAV.ModelItem node, Dictionary<string, object> properties)
|
||||
{
|
||||
if (!node.HasGeometry || node.Geometry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var geometry = node.Geometry;
|
||||
if (geometry.ActiveColor != null)
|
||||
{
|
||||
properties["ActiveColor"] = (geometry.ActiveColor.R, geometry.ActiveColor.G, geometry.ActiveColor.B);
|
||||
properties["ActiveTransparency"] = geometry.ActiveTransparency;
|
||||
}
|
||||
|
||||
// Add material name if available
|
||||
var materialName = GetMaterialName(node);
|
||||
if (!string.IsNullOrEmpty(materialName))
|
||||
{
|
||||
properties["MaterialName"] = materialName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a hash-based signature from a dictionary of properties.
|
||||
/// </summary>
|
||||
/// <param name="properties">Dictionary containing property name/value pairs to include in the signature</param>
|
||||
/// <param name="hashLength">Length of the returned hash string (default: 8 characters)</param>
|
||||
/// <returns>A hash string representing the combined properties</returns>
|
||||
private static string GetSignature(Dictionary<string, object> properties, int hashLength = 8)
|
||||
{
|
||||
if (properties.Count == 0)
|
||||
{
|
||||
return "empty";
|
||||
}
|
||||
|
||||
// Build a consistent string representation of all properties
|
||||
var hashInput = new System.Text.StringBuilder();
|
||||
|
||||
// Sort keys to ensure consistent order
|
||||
var sortedKeys = properties.Keys.OrderBy(k => k).ToList();
|
||||
|
||||
foreach (var key in sortedKeys)
|
||||
{
|
||||
var value = properties[key];
|
||||
switch (value)
|
||||
{
|
||||
case null:
|
||||
continue;
|
||||
// Format numbers with fixed precision to avoid floating point inconsistencies
|
||||
case double doubleValue:
|
||||
hashInput.Append($"{key}:{Math.Round(doubleValue, 6)}_");
|
||||
break;
|
||||
case float floatValue:
|
||||
hashInput.Append($"{key}:{Math.Round(floatValue, 6)}_");
|
||||
break;
|
||||
default:
|
||||
hashInput.Append($"{key}:{value.GetHashCode()}_");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hashInput.Length == 0)
|
||||
{
|
||||
return "empty";
|
||||
}
|
||||
|
||||
// Use MD5 hash with warning suppression
|
||||
#pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms
|
||||
using var md5 = System.Security.Cryptography.MD5.Create();
|
||||
var inputBytes = System.Text.Encoding.UTF8.GetBytes(hashInput.ToString());
|
||||
var hashBytes = md5.ComputeHash(inputBytes);
|
||||
#pragma warning restore CA5351
|
||||
|
||||
var fullHashString = BitConverter.ToString(hashBytes).Replace("-", "");
|
||||
return fullHashString[..Math.Min(hashLength, fullHashString.Length)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts material name from a node if available.
|
||||
/// </summary>
|
||||
private static string GetMaterialName(NAV.ModelItem node)
|
||||
{
|
||||
// Check Item category for material name
|
||||
var itemCategory = node.PropertyCategories.FindCategoryByDisplayName("Item");
|
||||
if (itemCategory != null)
|
||||
{
|
||||
var itemProperties = itemCategory.Properties;
|
||||
var itemMaterial = itemProperties.FindPropertyByDisplayName("Material");
|
||||
if (itemMaterial != null && !string.IsNullOrEmpty(itemMaterial.DisplayName))
|
||||
{
|
||||
return itemMaterial.Value.ToDisplayString();
|
||||
}
|
||||
}
|
||||
|
||||
// Check Material category for material name
|
||||
var materialPropertyCategory = node.PropertyCategories.FindCategoryByDisplayName("Material");
|
||||
if (materialPropertyCategory == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var material = materialPropertyCategory.Properties;
|
||||
var name = material.FindPropertyByDisplayName("Name");
|
||||
return name != null && !string.IsNullOrEmpty(name.DisplayName) ? name.Value.ToDisplayString() : string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
using Speckle.Connector.Navisworks.Services;
|
||||
using Speckle.Converter.Navisworks.Constants;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send;
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds the Navisworks document hierarchy from converted geometry leaves while preserving
|
||||
/// the parent-child relationships between elements in the original model structure.
|
||||
/// </summary>
|
||||
public class NavisworksHierarchyBuilder
|
||||
{
|
||||
private readonly Dictionary<string, Base?> _geometryLeaves;
|
||||
private readonly IRootToSpeckleConverter _converter;
|
||||
private readonly IElementSelectionService _selectionService;
|
||||
private readonly Dictionary<string, Base> _allNodes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the NavisworksHierarchyBuilder.
|
||||
/// </summary>
|
||||
/// <param name="geometryLeaves">Dictionary of path-indexed converted geometry elements</param>
|
||||
/// <param name="converter">Converter to transform Navisworks elements to Speckle objects</param>
|
||||
/// <param name="selectionService">Service for resolving Navisworks element paths</param>
|
||||
public NavisworksHierarchyBuilder(
|
||||
Dictionary<string, Base?> geometryLeaves,
|
||||
IRootToSpeckleConverter converter,
|
||||
IElementSelectionService selectionService
|
||||
)
|
||||
{
|
||||
_geometryLeaves = geometryLeaves;
|
||||
_converter = converter;
|
||||
_selectionService = selectionService;
|
||||
_allNodes = new Dictionary<string, Base>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a hierarchical tree of Speckle objects that mirrors the Navisworks document structure.
|
||||
/// </summary>
|
||||
/// <returns>List of root-level Speckle Base objects containing the full hierarchy</returns>
|
||||
public List<Base> BuildHierarchy()
|
||||
{
|
||||
foreach (var kvp in _geometryLeaves)
|
||||
{
|
||||
if (kvp.Value != null)
|
||||
{
|
||||
_allNodes[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// For each leaf path, traverse up the document structure converting any missing ancestors
|
||||
foreach (var nodePath in _allNodes.ToList().Select(kvp => kvp.Key))
|
||||
{
|
||||
ClimbUpToRoot(nodePath);
|
||||
}
|
||||
|
||||
var allPaths = _allNodes.Keys.ToList();
|
||||
allPaths.Sort(
|
||||
(a, b) =>
|
||||
{
|
||||
var depthA = a.Count(c => c == PathConstants.SEPARATOR);
|
||||
var depthB = b.Count(c => c == PathConstants.SEPARATOR);
|
||||
return depthB.CompareTo(depthA); // <- Sort in ascending order of path length
|
||||
}
|
||||
);
|
||||
|
||||
// Link nodes to parents and identify root nodes that have no recognized parent
|
||||
var rootCandidates = new Dictionary<string, Base>(_allNodes);
|
||||
|
||||
foreach (var nodePath in allPaths)
|
||||
{
|
||||
if (nodePath == "0")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var nodeBase = _allNodes[nodePath];
|
||||
var parentPath = GetParentPath(nodePath);
|
||||
|
||||
if (string.IsNullOrEmpty(parentPath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Navisworks API: Add child elements to parent collections
|
||||
if (!_allNodes.TryGetValue(parentPath, out var parentBase) || parentBase is not Collection parentCollection)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
parentCollection.elements.Add(nodeBase);
|
||||
rootCandidates.Remove(nodePath);
|
||||
}
|
||||
|
||||
var rootNodes = rootCandidates.Values.ToList();
|
||||
PruneEmptyCollections(rootNodes);
|
||||
|
||||
return rootNodes;
|
||||
}
|
||||
|
||||
private void ClimbUpToRoot(string currentPath)
|
||||
{
|
||||
while (!string.IsNullOrEmpty(currentPath) && currentPath != "0")
|
||||
{
|
||||
var parentPath = GetParentPath(currentPath);
|
||||
|
||||
if (string.IsNullOrEmpty(parentPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_allNodes.ContainsKey(parentPath))
|
||||
{
|
||||
currentPath = parentPath;
|
||||
continue;
|
||||
}
|
||||
|
||||
var parentModelItem = _selectionService.GetModelItemFromPath(parentPath);
|
||||
var parentConverted = _converter.Convert(parentModelItem);
|
||||
_allNodes[parentPath] = parentConverted;
|
||||
|
||||
currentPath = parentPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetParentPath(string path)
|
||||
{
|
||||
var idx = path.LastIndexOf(PathConstants.SEPARATOR);
|
||||
return idx == -1 ? string.Empty : path[..idx];
|
||||
}
|
||||
|
||||
private static void PruneEmptyCollections(List<Base> nodes)
|
||||
{
|
||||
foreach (var node in nodes.ToList())
|
||||
{
|
||||
if (node is not Collection collection)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PruneEmptyCollections(collection.elements);
|
||||
collection.elements.RemoveAll(child => child is Collection { elements.Count: 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-4
@@ -144,12 +144,27 @@ public class NavisworksRootObjectBuilder(
|
||||
Dictionary<string, List<NAV.ModelItem>> groupedNodes
|
||||
)
|
||||
{
|
||||
// First build the grouped nodes as before
|
||||
var finalElements = new List<Base>();
|
||||
var processedPaths = new HashSet<string>();
|
||||
|
||||
AddGroupedElements(finalElements, convertedBases, groupedNodes, processedPaths);
|
||||
AddRemainingElements(finalElements, convertedBases, processedPaths);
|
||||
|
||||
// If hierarchy mode is enabled, reorganize into proper nested structure
|
||||
if (converterSettings.Current.User.PreserveModelHierarchy)
|
||||
{
|
||||
var hierarchyBuilder = new NavisworksHierarchyBuilder(
|
||||
convertedBases,
|
||||
rootToSpeckleConverter,
|
||||
elementSelectionService
|
||||
);
|
||||
|
||||
var hierarchy = hierarchyBuilder.BuildHierarchy();
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
// Otherwise continue with flat mode
|
||||
AddRemainingElements(finalElements, convertedBases, processedPaths);
|
||||
return finalElements;
|
||||
}
|
||||
|
||||
@@ -221,7 +236,8 @@ public class NavisworksRootObjectBuilder(
|
||||
/// </remarks>
|
||||
private NavisworksObject CreateNavisworksObject(string groupKey, List<Base> siblingBases)
|
||||
{
|
||||
(string name, string path) = GetContext(groupKey);
|
||||
string cleanParentPath = ElementSelectionHelper.GetCleanPath(groupKey);
|
||||
(string name, string path) = GetContext(cleanParentPath);
|
||||
|
||||
return new NavisworksObject
|
||||
{
|
||||
@@ -229,7 +245,7 @@ public class NavisworksRootObjectBuilder(
|
||||
displayValue = siblingBases.SelectMany(b => b["displayValue"] as List<Base> ?? []).ToList(),
|
||||
properties = siblingBases.First()["properties"] as Dictionary<string, object?> ?? [],
|
||||
units = converterSettings.Current.Derived.SpeckleUnits,
|
||||
applicationId = groupKey,
|
||||
applicationId = groupKey, // Use the full composite key as applicationId to preserve uniqueness
|
||||
["path"] = path
|
||||
};
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
|
||||
namespace Speckle.Connector.Navisworks.Operations.Send.Settings;
|
||||
|
||||
public class PreserveModelHierarchySetting(bool value) : ICardSetting
|
||||
{
|
||||
public string? Id { get; set; } = "preserveModelHierarchy";
|
||||
public string? Title { get; set; } = "Preserve Model Hierarchy";
|
||||
public string? Type { get; set; } = "boolean";
|
||||
public List<string>? Enum { get; set; }
|
||||
public object? Value { get; set; } = value;
|
||||
}
|
||||
+18
@@ -17,6 +17,7 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
private readonly Dictionary<string, OriginMode> _originModeCache = [];
|
||||
private readonly Dictionary<string, bool?> _convertHiddenElementsCache = [];
|
||||
private readonly Dictionary<string, bool?> _includeInternalPropertiesCache = [];
|
||||
private readonly Dictionary<string, bool?> _preserveModelHierarchyCache = [];
|
||||
|
||||
public ToSpeckleSettingsManagerNavisworks(ISendConversionCache sendConversionCache)
|
||||
{
|
||||
@@ -120,6 +121,23 @@ public class ToSpeckleSettingsManagerNavisworks : IToSpeckleSettingsManagerNavis
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public bool GetPreserveModelHierarchy([NotNull] SenderModelCard modelCard)
|
||||
{
|
||||
var value = modelCard.Settings?.FirstOrDefault(s => s.Id == "preserveModelHierarchy")?.Value as bool?;
|
||||
|
||||
var returnValue = value != null && value.NotNull();
|
||||
if (_preserveModelHierarchyCache.TryGetValue(modelCard.ModelCardId.NotNull(), out var previousValue))
|
||||
{
|
||||
if (previousValue != returnValue)
|
||||
{
|
||||
EvictCacheForModelCard(modelCard);
|
||||
}
|
||||
}
|
||||
|
||||
_preserveModelHierarchyCache[modelCard.ModelCardId] = returnValue;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private void EvictCacheForModelCard(SenderModelCard modelCard)
|
||||
{
|
||||
var objectIds = modelCard.SendFilter != null ? modelCard.SendFilter.NotNull().SelectedObjectIds : [];
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Speckle.Connector.Navisworks;
|
||||
|
||||
public static class PathConstants
|
||||
{
|
||||
public const char SEPARATOR = '/';
|
||||
}
|
||||
+3
-1
@@ -21,14 +21,16 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)HostApp\NavisworksMaterialUnpacker.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\GeometryNodeMerger.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksHierarchyBuilder.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\NavisworksRootObjectBuilder.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ConvertHiddenEleementsSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\IncludeInternalPropertiesSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\OriginModeSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\PreserveModelHierarchySetting.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\ToSpeckleSettingsManagerNavisworks.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Settings\VisualRepresentationSetting.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSelectionFilter.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)PathConstants.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Operations\Send\Filters\NavisworksSavedSetsFilter.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\BrowserPane.xaml.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\DockableConnectorPane.cs"/>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\NavisworksRibbon.xaml.cs"/>
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2022": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2023": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +287,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -297,8 +297,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -308,7 +308,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2024": {
|
||||
@@ -348,16 +348,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -368,26 +368,26 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,9 +237,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -247,8 +247,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.logging": {
|
||||
@@ -258,7 +258,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.revit2025": {
|
||||
@@ -298,16 +298,16 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Revit.API": {
|
||||
@@ -318,25 +318,25 @@
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
},
|
||||
"net8.0-windows7.0/win-x64": {
|
||||
|
||||
+8
-1
@@ -82,6 +82,8 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
var model = _store.GetModelById(modelCardId);
|
||||
@@ -103,7 +105,12 @@ internal sealed class BasicConnectorBindingRevit : IBasicConnectorBinding
|
||||
var view = revitViewsFilter.GetView();
|
||||
if (view is not null)
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
await RevitTask
|
||||
.RunAsync(() =>
|
||||
{
|
||||
_revitContext.UIApplication.ActiveUIDocument.ActiveView = view;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Models.Card;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Settings;
|
||||
using Speckle.Sdk;
|
||||
@@ -98,6 +99,10 @@ internal sealed class RevitReceiveBinding : IReceiveBinding
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
}
|
||||
catch (SpeckleRevitTaskException ex)
|
||||
{
|
||||
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.ExtensibleStorage;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -16,6 +15,7 @@ using Speckle.Connectors.DUI.Models.Card.SendFilter;
|
||||
using Speckle.Connectors.DUI.Settings;
|
||||
using Speckle.Connectors.Revit.HostApp;
|
||||
using Speckle.Connectors.Revit.Operations.Send.Settings;
|
||||
using Speckle.Connectors.Revit.Plugin;
|
||||
using Speckle.Connectors.RevitShared.Operations.Send.Filters;
|
||||
using Speckle.Converters.Common;
|
||||
using Speckle.Converters.RevitShared.Helpers;
|
||||
@@ -47,7 +47,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
/// As to why a concurrent dictionary, it's because it's the cheapest/easiest way to do so.
|
||||
/// https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework
|
||||
/// </summary>
|
||||
private ConcurrentDictionary<ElementId, byte> ChangedObjectIds { get; set; } = new();
|
||||
private ConcurrentHashSet<ElementId> ChangedObjectIds { get; set; } = new();
|
||||
|
||||
public RevitSendBinding(
|
||||
IAppIdleManager idleManager,
|
||||
@@ -147,7 +147,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ElementId>>()
|
||||
.Execute(
|
||||
elementIds,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
@@ -160,6 +160,10 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
}
|
||||
catch (SpeckleRevitTaskException ex)
|
||||
{
|
||||
await SpeckleRevitTaskException.ProcessException(modelCardId, ex, _logger, Commands);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal()) // UX reasons - we will report operation exceptions as model card error. We may change this later when we have more exception documentation
|
||||
{
|
||||
_logger.LogModelCardHandledError(ex);
|
||||
@@ -236,17 +240,17 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
|
||||
foreach (ElementId elementId in addedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
ChangedObjectIds.Add(elementId);
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in deletedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
ChangedObjectIds.Add(elementId);
|
||||
}
|
||||
|
||||
foreach (ElementId elementId in modifiedElementIds)
|
||||
{
|
||||
ChangedObjectIds[elementId] = 1;
|
||||
ChangedObjectIds.Add(elementId);
|
||||
}
|
||||
|
||||
if (addedElementIds.Count > 0)
|
||||
@@ -267,7 +271,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
var selectedObjects = sender.SendFilter.NotNull().SelectedObjectIds;
|
||||
objectIds.AddRange(selectedObjects);
|
||||
}
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds.ToList());
|
||||
var unpackedObjectIds = _elementUnpacker.GetUnpackedElementIds(objectIds);
|
||||
_sendConversionCache.EvictObjects(unpackedObjectIds);
|
||||
}
|
||||
|
||||
@@ -332,9 +336,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
// }
|
||||
|
||||
if (
|
||||
ChangedObjectIds.Keys.Any(e =>
|
||||
_revitContext.UIApplication.NotNull().ActiveUIDocument.Document.GetElement(e) is View
|
||||
)
|
||||
ChangedObjectIds.Any(e => _revitContext.UIApplication.NotNull().ActiveUIDocument.Document.GetElement(e) is View)
|
||||
)
|
||||
{
|
||||
await Commands.RefreshSendFilters();
|
||||
@@ -353,7 +355,7 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
}
|
||||
|
||||
var objUniqueIds = new List<string>();
|
||||
var changedIds = ChangedObjectIds.Keys.ToList();
|
||||
var changedIds = ChangedObjectIds.ToList();
|
||||
|
||||
// Handling type changes: if an element's type is changed, we need to mark as changed all objects that have that type.
|
||||
// Step 1: get any changed types
|
||||
@@ -361,10 +363,10 @@ internal sealed class RevitSendBinding : RevitBaseBinding, ISendBinding
|
||||
.Select(e => doc.GetElement(e))
|
||||
.OfType<ElementType>()
|
||||
.Select(el => el.Id)
|
||||
.ToArray();
|
||||
.ToHashSet(); // ToHashSet() for faster Contains
|
||||
|
||||
// Step 2: Find all elements of the changed types, and add them to the changed ids list.
|
||||
if (elementTypeIdsList.Length != 0)
|
||||
if (elementTypeIdsList.Count != 0)
|
||||
{
|
||||
using var collector = new FilteredElementCollector(doc);
|
||||
var collectorElements = collector
|
||||
|
||||
@@ -35,7 +35,7 @@ internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, ID
|
||||
#else
|
||||
|
||||
_revitContext.UIApplication.NotNull().SelectionChanged += (_, _) =>
|
||||
_idleManager.SubscribeToIdle(nameof(SelectionBinding), OnSelectionChanged);
|
||||
_idleManager.SubscribeToIdle(nameof(OnSelectionChanged), OnSelectionChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -56,15 +56,16 @@ internal sealed class SelectionBinding : RevitBaseBinding, ISelectionBinding, ID
|
||||
}
|
||||
|
||||
var activeUIDoc = _revitContext.UIApplication.ActiveUIDocument.NotNull();
|
||||
var doc = activeUIDoc.Document;
|
||||
|
||||
// POC: this was also being called on shutdown
|
||||
// probably the bridge needs to be able to know if the plugin has been terminated
|
||||
// also on termination the OnSelectionChanged event needs unwinding
|
||||
var selectionIds = activeUIDoc
|
||||
.Selection.GetElementIds()
|
||||
.Select(eid => activeUIDoc.Document.GetElement(eid).UniqueId.ToString())
|
||||
.ToList();
|
||||
return new SelectionInfo(selectionIds, $"{selectionIds.Count} objects selected.");
|
||||
var selectionIds = activeUIDoc.Selection.GetElementIds();
|
||||
//reduce allocates by allocating what we need.
|
||||
var selectionUniqueIds = new List<string>(selectionIds.Count);
|
||||
selectionUniqueIds.AddRange(selectionIds.Select(eid => doc.GetElement(eid).UniqueId));
|
||||
return new SelectionInfo(selectionUniqueIds, $"{selectionIds.Count} objects selected.");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ElementUnpacker
|
||||
/// <remarks>
|
||||
/// This is used to invalidate object ids in the send conversion cache when the selected object id is only the parent element id
|
||||
/// </remarks>
|
||||
public IEnumerable<string> GetUnpackedElementIds(List<string> objectIds)
|
||||
public IEnumerable<string> GetUnpackedElementIds(IEnumerable<string> objectIds)
|
||||
{
|
||||
var doc = _revitContext.UIApplication?.ActiveUIDocument.Document!;
|
||||
var docElements = doc.GetElements(objectIds);
|
||||
|
||||
@@ -2,7 +2,7 @@ using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.DB.ExtensibleStorage;
|
||||
using Autodesk.Revit.UI;
|
||||
using Autodesk.Revit.UI.Events;
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Connectors.DUI.Bridge;
|
||||
using Speckle.Connectors.DUI.Models;
|
||||
using Speckle.Connectors.DUI.Utils;
|
||||
@@ -22,6 +22,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
private readonly DocumentModelStorageSchema _documentModelStorageSchema;
|
||||
private readonly IdStorageSchema _idStorageSchema;
|
||||
private readonly ITopLevelExceptionHandler _topLevelExceptionHandler;
|
||||
private readonly IThreadContext _threadContext;
|
||||
|
||||
public RevitDocumentStore(
|
||||
IAppIdleManager idleManager,
|
||||
@@ -29,7 +30,8 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
IJsonSerializer jsonSerializer,
|
||||
DocumentModelStorageSchema documentModelStorageSchema,
|
||||
IdStorageSchema idStorageSchema,
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler
|
||||
ITopLevelExceptionHandler topLevelExceptionHandler,
|
||||
IThreadContext threadContext
|
||||
)
|
||||
: base(jsonSerializer)
|
||||
{
|
||||
@@ -38,6 +40,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
_documentModelStorageSchema = documentModelStorageSchema;
|
||||
_idStorageSchema = idStorageSchema;
|
||||
_topLevelExceptionHandler = topLevelExceptionHandler;
|
||||
_threadContext = threadContext;
|
||||
|
||||
UIApplication uiApplication = _revitContext.UIApplication.NotNull();
|
||||
|
||||
@@ -73,7 +76,7 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
|
||||
IsDocumentInit = true;
|
||||
_idleManager.SubscribeToIdle(
|
||||
nameof(RevitDocumentStore),
|
||||
nameof(LoadState) + nameof(OnDocumentChanged),
|
||||
() =>
|
||||
{
|
||||
LoadState();
|
||||
@@ -91,23 +94,25 @@ internal sealed class RevitDocumentStore : DocumentModelStore
|
||||
return;
|
||||
}
|
||||
|
||||
RevitTask.RunAsync(() =>
|
||||
{
|
||||
using Transaction t = new(doc, "Speckle Write State");
|
||||
t.Start();
|
||||
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
|
||||
_threadContext
|
||||
.RunOnMain(() =>
|
||||
{
|
||||
using Transaction t = new(doc, "Speckle Write State");
|
||||
t.Start();
|
||||
using DataStorage ds = GetSettingsDataStorage(doc) ?? DataStorage.Create(doc);
|
||||
|
||||
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
|
||||
string serializedModels = Serialize();
|
||||
stateEntity.Set("contents", serializedModels);
|
||||
using Entity stateEntity = new(_documentModelStorageSchema.GetSchema());
|
||||
string serializedModels = Serialize();
|
||||
stateEntity.Set("contents", serializedModels);
|
||||
|
||||
using Entity idEntity = new(_idStorageSchema.GetSchema());
|
||||
idEntity.Set("Id", s_revitDocumentStoreId);
|
||||
using Entity idEntity = new(_idStorageSchema.GetSchema());
|
||||
idEntity.Set("Id", s_revitDocumentStoreId);
|
||||
|
||||
ds.SetEntity(idEntity);
|
||||
ds.SetEntity(stateEntity);
|
||||
t.Commit();
|
||||
});
|
||||
ds.SetEntity(idEntity);
|
||||
ds.SetEntity(stateEntity);
|
||||
t.Commit();
|
||||
})
|
||||
.FireAndForget();
|
||||
}
|
||||
|
||||
protected override void LoadState()
|
||||
|
||||
@@ -12,6 +12,7 @@ public class SendCollectionManager
|
||||
{
|
||||
private readonly IConverterSettingsStore<RevitConversionSettings> _converterSettings;
|
||||
private readonly Dictionary<string, Collection> _collectionCache = new();
|
||||
private readonly Dictionary<ElementId, (string name, Dictionary<string, object?> props)> _levelCache = new(); // stores level id and its properties
|
||||
|
||||
public SendCollectionManager(IConverterSettingsStore<RevitConversionSettings> converterSettings)
|
||||
{
|
||||
@@ -30,9 +31,29 @@ public class SendCollectionManager
|
||||
var doc = _converterSettings.Current.Document;
|
||||
var path = new List<string>();
|
||||
|
||||
// Step 0: get the level and its properties
|
||||
string levelName = "No Level";
|
||||
Dictionary<string, object?> levelProperties = new();
|
||||
if (element.LevelId != ElementId.InvalidElementId)
|
||||
{
|
||||
if (_levelCache.TryGetValue(element.LevelId, out var cachedLevel))
|
||||
{
|
||||
levelName = cachedLevel.name;
|
||||
levelProperties = cachedLevel.props;
|
||||
}
|
||||
else
|
||||
{
|
||||
var level = (Level)doc.GetElement(element.LevelId);
|
||||
levelName = level.Name;
|
||||
levelProperties.Add("elevation", level.Elevation);
|
||||
levelProperties.Add("units", _converterSettings.Current.SpeckleUnits);
|
||||
_levelCache.Add(element.LevelId, (levelName, levelProperties));
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1: create path components. Currently, this is
|
||||
// level > category > type
|
||||
path.Add(doc.GetElement(element.LevelId) is not Level level ? "No level" : level.Name);
|
||||
path.Add(levelName);
|
||||
path.Add(element.Category?.Name ?? "No category");
|
||||
var typeId = element.GetTypeId();
|
||||
if (typeId != ElementId.InvalidElementId)
|
||||
@@ -57,8 +78,9 @@ public class SendCollectionManager
|
||||
string flatPathName = "";
|
||||
Collection previousCollection = rootObject;
|
||||
|
||||
foreach (var pathItem in path)
|
||||
for (int i = 0; i < path.Count; i++)
|
||||
{
|
||||
var pathItem = path[i];
|
||||
flatPathName += pathItem;
|
||||
Collection childCollection;
|
||||
if (_collectionCache.TryGetValue(flatPathName, out Collection? collection))
|
||||
@@ -68,6 +90,13 @@ public class SendCollectionManager
|
||||
else
|
||||
{
|
||||
childCollection = new Collection(pathItem);
|
||||
// add props if it's the 1st path item, representing level
|
||||
// if the structure ever changes from level > category > type, this needs to be changed
|
||||
if (i == 0 && levelProperties.Count > 0)
|
||||
{
|
||||
childCollection["properties"] = levelProperties;
|
||||
}
|
||||
|
||||
previousCollection.elements.Add(childCollection);
|
||||
_collectionCache[flatPathName] = childCollection;
|
||||
}
|
||||
|
||||
+26
-12
@@ -5,7 +5,7 @@ namespace Speckle.Connectors.Revit.HostApp;
|
||||
public static class SupportedCategoriesUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters out all categories besides Model categories. This utility should be used
|
||||
/// Filters out all categories besides Model categories, and Grids in Annotation. This utility should be used
|
||||
/// to clean any elements we might want to send pre-conversion as well as in what categories
|
||||
/// to display in our category filter.
|
||||
/// </summary>
|
||||
@@ -13,18 +13,32 @@ public static class SupportedCategoriesUtils
|
||||
/// <returns></returns>
|
||||
public static bool IsSupportedCategory(Category? category)
|
||||
{
|
||||
return category is not null
|
||||
&& (
|
||||
category.CategoryType == CategoryType.Model
|
||||
// || category.CategoryType == CategoryType.AnalyticalModel
|
||||
)
|
||||
#if REVIT_2023_OR_GREATER
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines
|
||||
if (category is null || !category.IsVisibleInUI)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (category.CategoryType)
|
||||
{
|
||||
case CategoryType.Annotation:
|
||||
return
|
||||
#if REVIT2023_OR_GREATER
|
||||
category.BuiltInCategory == BuiltInCategory.OST_Grids;
|
||||
#else
|
||||
&& category.Name != "OST_AreaSchemeLines"
|
||||
&& category.Name != "OST_AreaSchemes"
|
||||
category.Name == "OST_Grids";
|
||||
#endif
|
||||
&& category.IsVisibleInUI;
|
||||
|
||||
case CategoryType.Model:
|
||||
return
|
||||
#if REVIT2023_OR_GREATER
|
||||
category.BuiltInCategory != BuiltInCategory.OST_AreaSchemes
|
||||
&& category.BuiltInCategory != BuiltInCategory.OST_AreaSchemeLines;
|
||||
#else
|
||||
category.Name != "OST_AreaSchemeLines" && category.Name != "OST_AreaSchemes";
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -40,22 +40,17 @@ public class RevitCategoriesFilter : DiscriminatedObject, ISendFilter, IRevitSen
|
||||
/// <exception cref="SpeckleSendFilterException">Whenever no view is found.</exception>
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
if (SelectedCategories is null)
|
||||
{
|
||||
return objectIds;
|
||||
return [];
|
||||
}
|
||||
|
||||
var elementIds = SelectedCategories.Select(c => ElementIdHelper.GetElementId(c)).Where(e => e is not null).ToList();
|
||||
|
||||
using var categoryFilter = new ElementMulticategoryFilter(elementIds);
|
||||
using var collector = new FilteredElementCollector(_doc);
|
||||
var elements = collector
|
||||
.WhereElementIsNotElementType()
|
||||
.WhereElementIsViewIndependent()
|
||||
.WherePasses(categoryFilter)
|
||||
.ToList();
|
||||
objectIds = elements.Select(e => e.UniqueId).ToList();
|
||||
var elements = collector.WhereElementIsNotElementType().WhereElementIsViewIndependent().WherePasses(categoryFilter);
|
||||
var objectIds = elements.Select(e => e.UniqueId).ToList();
|
||||
SelectedObjectIds = objectIds;
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
+3
-4
@@ -53,10 +53,9 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
/// <exception cref="SpeckleSendFilterException">Whenever no view is found.</exception>
|
||||
public List<string> RefreshObjectIds()
|
||||
{
|
||||
var objectIds = new List<string>();
|
||||
if (SelectedView is null)
|
||||
{
|
||||
return objectIds;
|
||||
return [];
|
||||
}
|
||||
|
||||
// Paşa Bilal wants it like this... (three dots = important meaning for ogu)
|
||||
@@ -75,8 +74,8 @@ public class RevitViewsFilter : DiscriminatedObject, ISendFilter, IRevitSendFilt
|
||||
throw new SpeckleSendFilterException("View not found, please update your model send filter.");
|
||||
}
|
||||
using var viewCollector = new FilteredElementCollector(_doc, view.Id);
|
||||
List<Element> elementsInView = viewCollector.ToElements().ToList();
|
||||
objectIds = elementsInView.Select(e => e.UniqueId).ToList();
|
||||
var elementsInView = viewCollector.ToElements();
|
||||
var objectIds = elementsInView.Select(e => e.UniqueId).ToList();
|
||||
SelectedObjectIds = objectIds;
|
||||
return objectIds;
|
||||
}
|
||||
|
||||
+3
-2
@@ -85,7 +85,7 @@ public class RevitRootObjectBuilder(
|
||||
|
||||
var countProgress = 0;
|
||||
var cacheHitCount = 0;
|
||||
|
||||
var skippedObjectCount = 0;
|
||||
foreach (Element revitElement in atomicObjects)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -105,6 +105,7 @@ public class RevitRootObjectBuilder(
|
||||
new SpeckleException($"Category {cat} is not supported.")
|
||||
)
|
||||
);
|
||||
skippedObjectCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ public class RevitRootObjectBuilder(
|
||||
onOperationProgressed.Report(new("Converting", (double)++countProgress / atomicObjects.Count));
|
||||
}
|
||||
|
||||
if (results.All(x => x.Status == Status.ERROR))
|
||||
if (results.All(x => x.Status == Status.ERROR) || skippedObjectCount == atomicObjects.Count)
|
||||
{
|
||||
throw new SpeckleException("Failed to convert all objects.");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Revit.Async;
|
||||
using Speckle.Connectors.Common.Threading;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
@@ -7,16 +8,82 @@ public class RevitThreadContext : ThreadContext
|
||||
{
|
||||
protected override Task<T> MainToWorkerAsync<T>(Func<Task<T>> action) => action();
|
||||
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) =>
|
||||
RevitTask.RunAsync(async () => await action());
|
||||
protected override Task<T> WorkerToMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
|
||||
|
||||
protected override Task<T> MainToWorker<T>(Func<T> action) => Task.FromResult(action());
|
||||
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => RevitTask.RunAsync(action);
|
||||
protected override Task<T> WorkerToMain<T>(Func<T> action) => CatchExceptions(action);
|
||||
|
||||
protected override Task RunMainAsync(Func<Task> action) => RevitTask.RunAsync(action);
|
||||
protected override Task RunMainAsync(Func<Task> action) => CatchExceptions(action);
|
||||
|
||||
protected override Task<T> RunMainAsync<T>(Func<T> action) => RevitTask.RunAsync(action);
|
||||
protected override Task<T> RunMainAsync<T>(Func<T> action) => CatchExceptions(action);
|
||||
|
||||
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => RevitTask.RunAsync(action);
|
||||
protected override Task<T> RunMainAsync<T>(Func<Task<T>> action) => CatchExceptions(action);
|
||||
|
||||
private static async Task<T> CatchExceptions<T>(Func<T> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
var ret = await RevitTask.RunAsync(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
return ret!;
|
||||
}
|
||||
|
||||
private static async Task<T> CatchExceptions<T>(Func<Task<T>> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
var ret = await RevitTask.RunAsync(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return await action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
return default;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
return ret!;
|
||||
}
|
||||
|
||||
private static async Task CatchExceptions(Func<Task> action)
|
||||
{
|
||||
Exception? ex = null;
|
||||
//force the usage of the application overload
|
||||
await RevitTask.RunAsync(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await action();
|
||||
}
|
||||
catch (Exception e) when (!e.IsFatal())
|
||||
{
|
||||
ex = e;
|
||||
}
|
||||
});
|
||||
if (ex is not null)
|
||||
{
|
||||
throw new SpeckleRevitTaskException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Speckle.Connectors.DUI.Bindings;
|
||||
using Speckle.Connectors.DUI.Logging;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
|
||||
namespace Speckle.Connectors.Revit.Plugin;
|
||||
|
||||
#pragma warning disable CA1032
|
||||
public class SpeckleRevitTaskException(Exception exception) : SpeckleException("Revit operation failed", exception)
|
||||
#pragma warning restore CA1032
|
||||
{
|
||||
public static async Task ProcessException<T>(
|
||||
string modelCardId,
|
||||
SpeckleRevitTaskException ex,
|
||||
ILogger<T> logger,
|
||||
BasicConnectorBindingCommands commands
|
||||
)
|
||||
where T : IBinding
|
||||
{
|
||||
Exception e = ex.InnerException.NotNull();
|
||||
while (e is SpeckleRevitTaskException srte)
|
||||
{
|
||||
e = srte.InnerException.NotNull();
|
||||
}
|
||||
if (e is OperationCanceledException)
|
||||
{
|
||||
// SWALLOW -> UI handles it immediately, so we do not need to handle anything for now!
|
||||
// Idea for later -> when cancel called, create promise from UI to solve it later with this catch block.
|
||||
// So have 3 state on UI -> Cancellation clicked -> Cancelling -> Cancelled
|
||||
return;
|
||||
}
|
||||
//log everything though
|
||||
logger.LogModelCardHandledError(ex);
|
||||
//always process the inner exception
|
||||
await commands.SetModelError(modelCardId, e);
|
||||
}
|
||||
}
|
||||
+1
@@ -50,5 +50,6 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitIdleManager.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitThreadContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\RevitCefPlugin.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Plugin\SpeckleRevitTaskException.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -296,7 +296,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino7": {
|
||||
@@ -342,40 +342,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -278,8 +278,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -296,7 +296,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.converters.rhino8": {
|
||||
@@ -342,40 +342,40 @@
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.1.0, )",
|
||||
"resolved": "4.0.1",
|
||||
"contentHash": "MzEQ1Im0zTja+tEsdRIk/WlPiKqb22NmTOJcR1ZKm/mz46pezyyID3/wRz6vJUELMpSLnG7LhsxBL+nxbr7V0w=="
|
||||
"resolved": "4.1.0",
|
||||
"contentHash": "20DtS+FsDRsOD9+AU3TwNFZ0qrKo5f6f7B5ZR9wStsIHHHC9k7DpjbCvuNtmnSjx54MD+TJC7wV2f5iyGVPj1A=="
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,8 @@ public sealed class RhinoBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public Task HighlightObjects(IReadOnlyList<string> objectIds)
|
||||
{
|
||||
var objects = GetObjectsFromIds(objectIds);
|
||||
|
||||
@@ -24,7 +24,7 @@ public class RhinoSelectionBinding : ISelectionBinding
|
||||
}
|
||||
|
||||
private void OnSelectionChange(object? o, EventArgs eventArgs) =>
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSelectionBinding), UpdateSelection);
|
||||
_idleManager.SubscribeToIdle(nameof(UpdateSelection), UpdateSelection);
|
||||
|
||||
private void UpdateSelection()
|
||||
{
|
||||
|
||||
@@ -113,8 +113,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[selectedObject.Id.ToString()] = 1;
|
||||
}
|
||||
_idleManager.SubscribeToIdle("a", RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,7 +143,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
});
|
||||
|
||||
RhinoDoc.DeleteRhinoObject += (_, e) =>
|
||||
@@ -156,7 +155,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
}
|
||||
|
||||
ChangedObjectIds[e.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
});
|
||||
|
||||
// NOTE: Catches an object's material change from one user defined doc material to another. Does not catch (as the top event is not triggered) swapping material sources for an object or moving to/from the default material (this is handled below)!
|
||||
@@ -171,7 +170,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
if (args is RhinoDoc.RenderMaterialAssignmentChangedEventArgs changedEventArgs)
|
||||
{
|
||||
ChangedObjectIds[changedEventArgs.ObjectId.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -187,7 +186,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
{
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
});
|
||||
|
||||
RhinoDoc.LayerTableEvent += (_, args) =>
|
||||
@@ -220,7 +219,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
ChangedObjectIdsInGroupsOrLayers[obj.Id.ToString()] = 1;
|
||||
}
|
||||
}
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
});
|
||||
|
||||
// Catches and stores changed material ids. These are then used in the expiry checks to invalidate all objects that have assigned any of those material ids.
|
||||
@@ -235,7 +234,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
if (args.EventType == MaterialTableEventType.Modified)
|
||||
{
|
||||
ChangedMaterialIndexes[args.Index] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -260,7 +259,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
)
|
||||
{
|
||||
ChangedObjectIds[e.RhinoObject.Id.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -274,7 +273,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
|
||||
ChangedObjectIds[e.NewRhinoObject.Id.ToString()] = 1;
|
||||
ChangedObjectIds[e.OldRhinoObject.Id.ToString()] = 1;
|
||||
_idleManager.SubscribeToIdle(nameof(RhinoSendBinding), RunExpirationChecks);
|
||||
_idleManager.SubscribeToIdle(nameof(RunExpirationChecks), RunExpirationChecks);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -316,7 +315,7 @@ public sealed class RhinoSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<RhinoObject>>()
|
||||
.Execute(
|
||||
rhinoObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
+13
-4
@@ -1,4 +1,6 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Speckle.Sdk;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp.Properties;
|
||||
|
||||
@@ -13,11 +15,18 @@ public class PropertiesExtractor
|
||||
var userStrings = rhObject.Attributes.GetUserStrings();
|
||||
foreach (var key in userStrings.AllKeys)
|
||||
{
|
||||
// POC: could not determine how to extract the value of a formula user string.
|
||||
// So for now we are skipping them
|
||||
if (userStrings[key].StartsWith("%<"))
|
||||
try
|
||||
{
|
||||
continue;
|
||||
if (userStrings[key].StartsWith("%<"))
|
||||
{
|
||||
var value = RhinoApp.ParseTextField(userStrings[key], rhObject, null);
|
||||
properties[key] = value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
// Shh. We can fail silently here - it's not even worth logging. I expect users will complain properties are missing.
|
||||
}
|
||||
|
||||
properties[key] = userStrings[key];
|
||||
|
||||
@@ -19,11 +19,6 @@ public class RhinoDocumentStore : DocumentModelStore
|
||||
RhinoDoc.EndOpenDocument += (_, e) =>
|
||||
topLevelExceptionHandler.CatchUnhandled(() =>
|
||||
{
|
||||
if (e.Merge)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Document == null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -13,7 +13,6 @@ using Speckle.Sdk.Common.Exceptions;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using RenderMaterial = Rhino.Render.RenderMaterial;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
@@ -129,11 +128,9 @@ public class RhinoInstanceBaker : IInstanceBaker<IReadOnlyCollection<string>>
|
||||
string instanceProxyId = instanceProxy.applicationId ?? instanceProxy.id.NotNull();
|
||||
|
||||
ObjectAttributes atts = new() { LayerIndex = layerIndex };
|
||||
if (
|
||||
_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(instanceProxyId, out RenderMaterial renderMaterial)
|
||||
)
|
||||
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(instanceProxyId, out int mIndex))
|
||||
{
|
||||
atts.RenderMaterial = renderMaterial;
|
||||
atts.MaterialIndex = mIndex;
|
||||
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Rhino;
|
||||
using Rhino.DocObjects;
|
||||
using Rhino.Render;
|
||||
using Speckle.Connectors.Common.Operations.Receive;
|
||||
using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
@@ -116,11 +115,11 @@ public class RhinoLayerBaker : TraversalContextUnpacker
|
||||
if (
|
||||
_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(
|
||||
collection.applicationId ?? collection.id.NotNull(),
|
||||
out RenderMaterial renderMaterial
|
||||
out int mIndex
|
||||
)
|
||||
)
|
||||
{
|
||||
newLayer.RenderMaterial = renderMaterial;
|
||||
newLayer.RenderMaterialIndex = mIndex;
|
||||
}
|
||||
|
||||
// set color
|
||||
|
||||
@@ -7,7 +7,6 @@ using Speckle.Sdk;
|
||||
using Speckle.Sdk.Common;
|
||||
using Speckle.Sdk.Common.Exceptions;
|
||||
using Material = Rhino.DocObjects.Material;
|
||||
using RenderMaterial = Rhino.Render.RenderMaterial;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.HostApp;
|
||||
|
||||
@@ -26,9 +25,9 @@ public class RhinoMaterialBaker
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A map keeping track of ids, <b>either layer id or object id</b>, and their render material guid. It's generated from the material proxy list as we bake materials; <see cref="BakeMaterials"/> must be called in advance for this to be populated with the correct data.
|
||||
/// A map keeping track of ids, <b>either layer id or object id</b>, and their material index. It's generated from the material proxy list as we bake materials; <see cref="BakeMaterials"/> must be called in advance for this to be populated with the correct data.
|
||||
/// </summary>
|
||||
public Dictionary<string, RenderMaterial> ObjectIdAndMaterialIndexMap { get; } = new();
|
||||
public Dictionary<string, int> ObjectIdAndMaterialIndexMap { get; } = new();
|
||||
|
||||
public void BakeMaterials(IReadOnlyCollection<RenderMaterialProxy> speckleRenderMaterialProxies, string baseLayerName)
|
||||
{
|
||||
@@ -68,23 +67,19 @@ public class RhinoMaterialBaker
|
||||
rhinoMaterial.Shine = shine;
|
||||
}
|
||||
|
||||
// We are creating a render material and adding it to the render material table because render materials have a guid independent of objects they are applied to.
|
||||
// Regular materials and the material table is populated by materials applied to objects: the same material can therefore have multiple entries in the material table if it is applied to multiple objects
|
||||
// see: https://discourse.mcneel.com/t/render-material-events/99886/5
|
||||
RenderMaterial rhinoRenderMaterial = RenderMaterial.FromMaterial(rhinoMaterial, doc);
|
||||
int matIndex = doc.Materials.Add(rhinoMaterial);
|
||||
|
||||
if (doc.RenderMaterials.Add(rhinoRenderMaterial))
|
||||
{
|
||||
// Create the object <> render material guid map
|
||||
foreach (var objectId in proxy.objects)
|
||||
{
|
||||
ObjectIdAndMaterialIndexMap[objectId] = rhinoRenderMaterial;
|
||||
}
|
||||
}
|
||||
else
|
||||
// POC: check on matIndex -1, means we haven't created anything - this is most likely an recoverable error at this stage
|
||||
if (matIndex == -1)
|
||||
{
|
||||
throw new ConversionException("Failed to add a material to the document.");
|
||||
}
|
||||
|
||||
// Create the object <> material index map
|
||||
foreach (var objectId in proxy.objects)
|
||||
{
|
||||
ObjectIdAndMaterialIndexMap[objectId] = matIndex;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
@@ -100,13 +95,18 @@ public class RhinoMaterialBaker
|
||||
public void PurgeMaterials(string namePrefix)
|
||||
{
|
||||
var currentDoc = RhinoDoc.ActiveDoc; // POC: too much right now to interface around
|
||||
// POC: looping through the render material table somehow doesn't capture all render materials!! That's why we're doing it this way.
|
||||
var materialsToDelete = currentDoc.RenderMaterials.Where(o => o.DisplayName.Contains(namePrefix)).ToList();
|
||||
foreach (RenderMaterial materialToDelete in materialsToDelete)
|
||||
foreach (Material material in currentDoc.Materials)
|
||||
{
|
||||
if (!currentDoc.RenderMaterials.Remove(materialToDelete))
|
||||
try
|
||||
{
|
||||
_logger.LogError("Failed to purge a material from the document");
|
||||
if (!material.IsDeleted && material.Name != null && material.Name.Contains(namePrefix))
|
||||
{
|
||||
currentDoc.Materials.Delete(material);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
_logger.LogError(ex, "Failed to purge a material from the document");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,17 @@ public class RhinoMaterialUnpacker
|
||||
/// Processes an object's material and adds the object id to a material proxy in <see cref="RenderMaterialProxies"/> if object color is set ByObject or ByParent.
|
||||
/// </summary>
|
||||
/// <param name="objId"></param>
|
||||
private void ProcessObjectMaterial(string objId, RenderMaterial renderMaterial, ObjectMaterialSource source)
|
||||
private void ProcessObjectMaterial(
|
||||
string objId,
|
||||
RenderMaterial? renderMaterial,
|
||||
Material? material,
|
||||
ObjectMaterialSource source
|
||||
)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case ObjectMaterialSource.MaterialFromObject:
|
||||
AddObjectIdToRenderMaterialProxy(objId, renderMaterial);
|
||||
AddObjectIdToRenderMaterialProxy(objId, renderMaterial, material);
|
||||
break;
|
||||
|
||||
// POC: skip if object material source is *not* by object. we don't support render material inheritance atm bc alex disagrees with the concept
|
||||
@@ -43,29 +48,55 @@ public class RhinoMaterialUnpacker
|
||||
}
|
||||
}
|
||||
|
||||
private void AddObjectIdToRenderMaterialProxy(string objectId, RenderMaterial renderMaterial)
|
||||
private void AddObjectIdToRenderMaterialProxy(string objectId, RenderMaterial? renderMaterial, Material? material)
|
||||
{
|
||||
string? renderMaterialId = renderMaterial.Id.ToString();
|
||||
// NOTE: material ids are not the same, even if the underlying material is. the number of materials in the mat table corresponds
|
||||
// with the number of objects, and each material will get a new id, even if it is THE SAME. shockingly, TY bob, material names
|
||||
// are unique so we use those for identity checks rather than the material's id.
|
||||
string? renderMaterialId = renderMaterial?.Name ?? material?.Name; //renderMaterial?.Id.ToString() ?? material?.Id.ToString();
|
||||
|
||||
if (RenderMaterialProxies.TryGetValue(renderMaterialId, out RenderMaterialProxy? proxy))
|
||||
if (renderMaterialId is not null)
|
||||
{
|
||||
proxy.objects.Add(objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (
|
||||
ConvertMaterialToRenderMaterialProxy(renderMaterialId, renderMaterial) is RenderMaterialProxy newRenderMaterial
|
||||
)
|
||||
if (RenderMaterialProxies.TryGetValue(renderMaterialId, out RenderMaterialProxy? proxy))
|
||||
{
|
||||
newRenderMaterial.objects.Add(objectId);
|
||||
RenderMaterialProxies[renderMaterialId] = newRenderMaterial;
|
||||
proxy.objects.Add(objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (
|
||||
ConvertMaterialToRenderMaterialProxy(renderMaterialId, renderMaterial, material)
|
||||
is RenderMaterialProxy newRenderMaterial
|
||||
)
|
||||
{
|
||||
newRenderMaterial.objects.Add(objectId);
|
||||
RenderMaterialProxies[renderMaterialId] = newRenderMaterial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RenderMaterialProxy? ConvertMaterialToRenderMaterialProxy(string materialId, RenderMaterial renderMaterial)
|
||||
private RenderMaterialProxy? ConvertMaterialToRenderMaterialProxy(
|
||||
string materialId,
|
||||
RenderMaterial? renderMaterial,
|
||||
Material? material
|
||||
)
|
||||
{
|
||||
SpeckleRenderMaterial myMaterial = ConvertRenderMaterialToSpeckle(renderMaterial);
|
||||
// TY Rhino api for being a bit confused about materials 💖
|
||||
SpeckleRenderMaterial? myMaterial = null;
|
||||
if (renderMaterial is not null)
|
||||
{
|
||||
myMaterial = ConvertRenderMaterialToSpeckle(renderMaterial);
|
||||
}
|
||||
else if (material is not null)
|
||||
{
|
||||
RenderMaterial convertedRender = ConvertMaterialToRenderMaterial(material);
|
||||
myMaterial = ConvertRenderMaterialToSpeckle(convertedRender);
|
||||
}
|
||||
|
||||
if (myMaterial is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
RenderMaterialProxy renderMaterialProxy =
|
||||
new()
|
||||
@@ -92,26 +123,23 @@ public class RhinoMaterialUnpacker
|
||||
// Stage 1: unpack materials from objects
|
||||
foreach (RhinoObject rootObj in atomicObjects)
|
||||
{
|
||||
// materials are confusing in rhino - some objects can have render materials, other may only have a material.
|
||||
// see: https://discourse.mcneel.com/t/getting-material-from-rhinoobject/114870/6
|
||||
// basically, materials (old) are created PER OBJECT if they are assigned per object. This means the same material will have diff ids when called from the material table
|
||||
// unfortunately, in the case where no rendermaterial exists, we'll have to create duplicate proxies.
|
||||
RenderMaterial? rhinoRenderMaterial = rootObj.GetRenderMaterial(true);
|
||||
if (rhinoRenderMaterial is null)
|
||||
if (rootObj.Attributes.MaterialSource == ObjectMaterialSource.MaterialFromLayer)
|
||||
{
|
||||
if (rootObj.GetMaterial(true) is Material rhinoMaterial)
|
||||
{
|
||||
rhinoRenderMaterial = RenderMaterial.FromMaterial(rhinoMaterial, currentDoc);
|
||||
}
|
||||
else // could not get rendermaterial or material
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// materials are confusing in rhino. we need both render material and material because objects can have either assigned
|
||||
RenderMaterial? rhinoRenderMaterial = rootObj.GetRenderMaterial(true);
|
||||
Material? rhinoMaterial = rootObj.GetMaterial(true);
|
||||
|
||||
try
|
||||
{
|
||||
ProcessObjectMaterial(rootObj.Id.ToString(), rhinoRenderMaterial, rootObj.Attributes.MaterialSource);
|
||||
ProcessObjectMaterial(
|
||||
rootObj.Id.ToString(),
|
||||
rhinoRenderMaterial,
|
||||
rhinoMaterial,
|
||||
rootObj.Attributes.MaterialSource
|
||||
);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
@@ -122,29 +150,19 @@ public class RhinoMaterialUnpacker
|
||||
// Stage 2: make sure we collect layer materials as well
|
||||
foreach (Layer layer in layers)
|
||||
{
|
||||
// materials are confusing in rhino - some objects can have render materials, other may only have a material.
|
||||
// see: https://discourse.mcneel.com/t/getting-material-from-rhinoobject/114870/6
|
||||
// basically, materials (old) are created PER OBJECT if they are assigned per object. This means the same material will have diff ids when called from the material table
|
||||
// unfortunately, in the case where no rendermaterial exists, we'll have to create duplicate proxies.
|
||||
// materials are confusing in rhino. we will first try to get layer render material and then material by index if null
|
||||
RenderMaterial? rhinoRenderMaterial = layer.RenderMaterial;
|
||||
if (rhinoRenderMaterial is null)
|
||||
{
|
||||
if (layer.RenderMaterialIndex == -1) // no material assigned
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
rhinoRenderMaterial = RenderMaterial.FromMaterial(
|
||||
currentDoc.Materials[layer.RenderMaterialIndex],
|
||||
currentDoc
|
||||
);
|
||||
}
|
||||
}
|
||||
Material? rhinoMaterial =
|
||||
layer.RenderMaterialIndex == -1 ? null : currentDoc.Materials[layer.RenderMaterialIndex];
|
||||
|
||||
try
|
||||
{
|
||||
ProcessObjectMaterial(layer.Id.ToString(), rhinoRenderMaterial, ObjectMaterialSource.MaterialFromObject);
|
||||
ProcessObjectMaterial(
|
||||
layer.Id.ToString(),
|
||||
rhinoRenderMaterial,
|
||||
rhinoMaterial,
|
||||
ObjectMaterialSource.MaterialFromObject
|
||||
);
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
@@ -155,6 +173,21 @@ public class RhinoMaterialUnpacker
|
||||
return RenderMaterialProxies.Values.ToList();
|
||||
}
|
||||
|
||||
// converts a rhino material to a rhino render material
|
||||
private RenderMaterial ConvertMaterialToRenderMaterial(Material material)
|
||||
{
|
||||
// get physically based render material
|
||||
Material pbMaterial = material;
|
||||
if (!material.IsPhysicallyBased)
|
||||
{
|
||||
pbMaterial = new();
|
||||
pbMaterial.CopyFrom(material);
|
||||
pbMaterial.ToPhysicallyBased();
|
||||
}
|
||||
|
||||
return RenderMaterial.FromMaterial(pbMaterial, null);
|
||||
}
|
||||
|
||||
private SpeckleRenderMaterial ConvertRenderMaterialToSpeckle(RenderMaterial renderMaterial)
|
||||
{
|
||||
PhysicallyBasedMaterial pbRenderMaterial = renderMaterial.ConvertToPhysicallyBased(
|
||||
|
||||
+10
-6
@@ -16,7 +16,6 @@ using Speckle.Sdk.Logging;
|
||||
using Speckle.Sdk.Models;
|
||||
using Speckle.Sdk.Models.Collections;
|
||||
using Speckle.Sdk.Models.Instances;
|
||||
using RenderMaterial = Rhino.Render.RenderMaterial;
|
||||
|
||||
namespace Speckle.Connectors.Rhino.Operations.Receive;
|
||||
|
||||
@@ -104,7 +103,10 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
if (unpackedRoot.RenderMaterialProxies != null)
|
||||
{
|
||||
using var _ = _activityFactory.Start("Render Materials");
|
||||
_materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseLayerName);
|
||||
_threadContext.RunOnMain(() =>
|
||||
{
|
||||
_materialBaker.BakeMaterials(unpackedRoot.RenderMaterialProxies, baseLayerName);
|
||||
});
|
||||
}
|
||||
|
||||
if (unpackedRoot.ColorProxies != null)
|
||||
@@ -301,16 +303,18 @@ public class RhinoHostObjectBuilder : IHostObjectBuilder
|
||||
{
|
||||
var objectId = originalObject.applicationId ?? originalObject.id.NotNull();
|
||||
|
||||
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(objectId, out RenderMaterial oRenderMaterial))
|
||||
if (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(objectId, out int mIndex))
|
||||
{
|
||||
atts.RenderMaterial = oRenderMaterial; // no need to set source since setting render material handles this
|
||||
atts.MaterialIndex = mIndex;
|
||||
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
|
||||
}
|
||||
else if (
|
||||
parentObjectId is not null
|
||||
&& (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(parentObjectId, out RenderMaterial pRenderMaterial))
|
||||
&& (_materialBaker.ObjectIdAndMaterialIndexMap.TryGetValue(parentObjectId, out int mIndexSpeckleObj))
|
||||
)
|
||||
{
|
||||
atts.RenderMaterial = pRenderMaterial; // no need to set source since setting render material handles this
|
||||
atts.MaterialIndex = mIndexSpeckleObj;
|
||||
atts.MaterialSource = ObjectMaterialSource.MaterialFromObject;
|
||||
}
|
||||
|
||||
if (_colorBaker.ObjectColorsIdMap.TryGetValue(objectId, out (Color, ObjectColorSource) color))
|
||||
|
||||
@@ -1,26 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<Target AfterTargets="Build" Name="AfterBuildTekla" Condition="'$(TeklaVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<Target AfterTargets="Build" Name="AfterBuildTekla" Condition="'$(TeklaVersion)' != '' And '$(ContinuousIntegrationBuild)' != 'true'">
|
||||
<ItemGroup>
|
||||
<TeklaDlls Include="$(TargetDir)\**\*.*" Exclude="$(TargetDir)*.bmp" />
|
||||
<TeklaBmp Include="$(TargetDir)\Assets\et_element_Speckle.bmp"/>
|
||||
<TeklaBmp Include="$(TargetDir)\Resources\et_element_Speckle.bmp"/>
|
||||
<TeklaSvg Include="$(TargetDir)\Resources\speckle.svg"/>
|
||||
<TeklaRibbonXml Include="$(TargetDir)\Resources\Speckle-Ribbon.xml"/>
|
||||
</ItemGroup>
|
||||
<Message Text="Tekla Version $(TeklaVersion)" Importance="high"/>
|
||||
<Copy Condition="Exists('$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0')"
|
||||
DestinationFolder="$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0\Environments\common\extensions\Speckle3TeklaStructures\%(RecursiveDir)"
|
||||
SourceFiles="@(TeklaDlls)" />
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<Copy Condition="Exists('$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0')"
|
||||
DestinationFolder="$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0\Bitmaps"
|
||||
SourceFiles="@(TeklaBmp)" />
|
||||
</ItemGroup>
|
||||
<Copy Condition="Exists('C:\TeklaStructures\2024.0')"
|
||||
DestinationFolder="C:\TeklaStructures\2024.0\Environments\common\extensions\Speckle3TeklaStructures\%(RecursiveDir)"
|
||||
SourceFiles="@(TeklaDlls)" />
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<Copy Condition="Exists('C:\TeklaStructures\2024.0')"
|
||||
DestinationFolder="$(ProgramFiles)\TeklaStructures\2024.0\bin\Env\Bitmaps"
|
||||
SourceFiles="@(TeklaBmp)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Define installation paths -->
|
||||
<PropertyGroup>
|
||||
<ProgramDataTeklaPath>$(ProgramData)\Trimble\Tekla Structures\$(TeklaVersion).0</ProgramDataTeklaPath>
|
||||
<DirectTeklaPath>C:\TeklaStructures\$(TeklaVersion).0</DirectTeklaPath>
|
||||
|
||||
<!-- Define extension and ribbon paths -->
|
||||
<ProgramDataRibbonPath>$(ProgramDataTeklaPath)\Environments\common\system\Ribbons\CustomTabs\Modeling</ProgramDataRibbonPath>
|
||||
<DirectRibbonPath>$(DirectTeklaPath)\Environments\common\system\Ribbons\CustomTabs\Modeling</DirectRibbonPath>
|
||||
|
||||
<SpeckleExtensionPath Condition="Exists('$(ProgramDataTeklaPath)')">$(ProgramDataTeklaPath)\Environments\common\extensions\Speckle3TeklaStructures</SpeckleExtensionPath>
|
||||
<SpeckleExtensionPath Condition="Exists('$(DirectTeklaPath)')">$(DirectTeklaPath)\Environments\common\extensions\Speckle3TeklaStructures</SpeckleExtensionPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Delete win-arm64 folder if it exists in the active installation path -->
|
||||
<RemoveDir
|
||||
Condition="Exists('$(SpeckleExtensionPath)\runtimes\win-arm64\native')"
|
||||
Directories="$(SpeckleExtensionPath)\runtimes\win-arm64\native" />
|
||||
|
||||
<!-- Check which installation path exists for the specific version -->
|
||||
<PropertyGroup>
|
||||
<TeklaInstallPath Condition="Exists('$(ProgramDataTeklaPath)')">$(ProgramDataTeklaPath)</TeklaInstallPath>
|
||||
<TeklaInstallPath Condition="Exists('$(DirectTeklaPath)')">$(DirectTeklaPath)</TeklaInstallPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Copy DLLs to extension folder -->
|
||||
<Copy
|
||||
Condition="'$(SpeckleExtensionPath)' != ''"
|
||||
DestinationFolder="$(SpeckleExtensionPath)\%(RecursiveDir)"
|
||||
SourceFiles="@(TeklaDlls)" />
|
||||
|
||||
<!-- Copy SVG to Resources folder -->
|
||||
<Copy
|
||||
Condition="'$(SpeckleExtensionPath)' != ''"
|
||||
DestinationFolder="$(SpeckleExtensionPath)\Resources"
|
||||
SourceFiles="@(TeklaSvg)" />
|
||||
|
||||
<!-- Copy BMP to Bitmaps folder -->
|
||||
<Copy
|
||||
Condition="'$(TeklaInstallPath)' != ''"
|
||||
DestinationFolder="$(TeklaInstallPath)\Bitmaps"
|
||||
SourceFiles="@(TeklaBmp)" />
|
||||
|
||||
<!-- Create Ribbon directories if they don't exist -->
|
||||
<MakeDir Directories="$(ProgramDataRibbonPath)"
|
||||
Condition="Exists('$(ProgramDataTeklaPath)') And !Exists('$(ProgramDataRibbonPath)')" />
|
||||
<MakeDir Directories="$(DirectRibbonPath)"
|
||||
Condition="Exists('$(DirectTeklaPath)') And !Exists('$(DirectRibbonPath)')" />
|
||||
|
||||
<!-- Copy the XML file to both possible destinations -->
|
||||
<Copy
|
||||
SourceFiles="@(TeklaRibbonXml)"
|
||||
DestinationFolder="$(ProgramDataRibbonPath)"
|
||||
Condition="Exists('$(ProgramDataTeklaPath)')" />
|
||||
<Copy
|
||||
SourceFiles="@(TeklaRibbonXml)"
|
||||
DestinationFolder="$(DirectRibbonPath)"
|
||||
Condition="Exists('$(DirectTeklaPath)')" />
|
||||
|
||||
<!-- Copy the SVG file to both possible ribbon destinations -->
|
||||
<Copy
|
||||
SourceFiles="@(TeklaSvg)"
|
||||
DestinationFolder="$(ProgramDataRibbonPath)"
|
||||
Condition="Exists('$(ProgramDataTeklaPath)')" />
|
||||
<Copy
|
||||
SourceFiles="@(TeklaSvg)"
|
||||
DestinationFolder="$(DirectRibbonPath)"
|
||||
Condition="Exists('$(DirectTeklaPath)')" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -325,9 +325,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -335,8 +335,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -362,7 +362,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"LibTessDotNet": {
|
||||
@@ -412,35 +412,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,9 +406,9 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "[2.2.0, )",
|
||||
"Speckle.Connectors.Logging": "[1.0.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )",
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui": {
|
||||
@@ -416,8 +416,8 @@
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Connectors.Common": "[1.0.0, )",
|
||||
"Speckle.Sdk": "[3.1.0-dev.255, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.0-dev.255, )"
|
||||
"Speckle.Sdk": "[3.1.4, )",
|
||||
"Speckle.Sdk.Dependencies": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"speckle.connectors.dui.webview": {
|
||||
@@ -443,7 +443,7 @@
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging.Abstractions": "[2.2.0, )",
|
||||
"Speckle.Objects": "[3.1.0-dev.255, )"
|
||||
"Speckle.Objects": "[3.1.4, )"
|
||||
}
|
||||
},
|
||||
"LibTessDotNet": {
|
||||
@@ -493,35 +493,35 @@
|
||||
},
|
||||
"Speckle.Objects": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "0S9YVdu5nx7SYS0y5Gq1nwCbxfYB2UxsUUCskaGmzRAm+QzHGqCLYHgadz7Sw5mNAF3bOTLVrOYMzyLAWFWxJA==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "3l7BaePUVvZ5LbXQoudZpSo7ntNkrXYVe5VhokKp0HsrnwPcA0A2WgDcuZC3mss204UNezu5lZUqv5lM2GXXgg==",
|
||||
"dependencies": {
|
||||
"Speckle.Sdk": "3.1.0-dev.255"
|
||||
"Speckle.Sdk": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "TsFpIv8ipvOD/r0se1XmcNPo7t5dWVadwV32Z6vUqoW3s94VIE54/ZTHNkRCEYHFhfOyTcFfbLegiei+0D13bQ==",
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "aYiItasQxpGbSIQEg3sM8jk+5SV4jt2Gk+0wKr1EBUndA/l8eB5tAi6eMInL7pGnErEHjj+En9DJU4WRzo3wdw==",
|
||||
"dependencies": {
|
||||
"GraphQL.Client": "6.0.0",
|
||||
"Microsoft.Bcl.AsyncInterfaces": "[5.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",
|
||||
"Microsoft.Data.Sqlite": "7.0.5",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "2.2.0",
|
||||
"Microsoft.Extensions.Logging": "2.2.0",
|
||||
"Speckle.DoubleNumerics": "4.1.0",
|
||||
"Speckle.Newtonsoft.Json": "13.0.2",
|
||||
"Speckle.Sdk.Dependencies": "3.1.0-dev.255"
|
||||
"Speckle.Sdk.Dependencies": "3.1.4"
|
||||
}
|
||||
},
|
||||
"Speckle.Sdk.Dependencies": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[3.1.0-dev.255, )",
|
||||
"resolved": "3.1.0-dev.255",
|
||||
"contentHash": "koFeWc/EB2XrMH2aKl2Hqwrqk/fAGYEVKgxFlFpnEAsbZf7Kk57gBQ3ViV5l6X9vqMHGWFc4dWUp24diq/XPtQ=="
|
||||
"requested": "[3.1.4, )",
|
||||
"resolved": "3.1.4",
|
||||
"contentHash": "9w6uBekthmmKZhV4bau36Fu8HRPSq4UsS4UB1I9IUsh9xF9IPHt0hVvDBpwQB1P0Gy9fVrcZQeAuP4TMRQqv0A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ public class TeklaBasicConnectorBinding : IBasicConnectorBinding
|
||||
|
||||
public void RemoveModel(ModelCard model) => _store.RemoveModel(model);
|
||||
|
||||
public void RemoveModels(List<ModelCard> models) => _store.RemoveModels(models);
|
||||
|
||||
public async Task HighlightModel(string modelCardId)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -35,7 +35,7 @@ public class TeklaSelectionBinding : ISelectionBinding
|
||||
{
|
||||
lock (_selectionEventHandlerLock)
|
||||
{
|
||||
_idleManager.SubscribeToIdle(nameof(TeklaSelectionBinding), UpdateSelection);
|
||||
_idleManager.SubscribeToIdle(nameof(UpdateSelection), UpdateSelection);
|
||||
UpdateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public sealed class TeklaSendBinding : ISendBinding
|
||||
.ServiceProvider.GetRequiredService<SendOperation<ModelObject>>()
|
||||
.Execute(
|
||||
teklaObjects,
|
||||
modelCard.GetSendInfo(_speckleApplication.Slug),
|
||||
modelCard.GetSendInfo(_speckleApplication.ApplicationAndVersion),
|
||||
_operationProgressManager.CreateOperationProgressEventHandler(Parent, modelCardId, cancellationItem.Token),
|
||||
cancellationItem.Token
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user