Third Party SDK - Analysis Data Model
Updated: 2023-01-16
The third party SDK ADM is a wrapper that has been built on top of the third party SDK which enables users to work with the third party SDK while utilizing our internal ADM and its services.
In its current state, the ADM wrapper does not yet support all functionality exposed in the third party SDK
Requirements
- .NET Framework 4.8
- Usage of the new UI in SCIA Engineer (run SCIA Engineer using SciaEngineer.exe instead of esa.exe)
- Knowledge of how to work with ADM and its services
- Latest language version enabled for your project (Some of the snippets use some of the latest C# language features) - See C# language versioning - C# Guide | Microsoft Docs
Functionality
The ADM layer exposes the following functionality:
GetAnalysisModelFromSciaEngineer()
Retrieving data from SCIA Engineer and provide it to your application in the ADM format
SendAnalysisModelToSciaEngineer(AnalysisModel)
Send data in the ADM format to SCIA Engineer so the active model can be updated with the data
There are two ways you can go about using this layer:
Simple
The simple method is meant for users that do not have a lot of programming knowledge and only want to get some data out of SCIA Engineer, modify the data and send it back.
ThirdPartySdkAnalysisDataModelWrapper wrapper = new ThirdPartySdkAnalysisDataModelWrapper();
// Retrieve the current active project from SCIA Engineer
AnalysisModel model = wrapper.GetAnalysisModelFromSciaEngineer();
// Do some modifications on model
// Send the modified model back to SCIA Engineer
bool isUpdated = wrapper.SendAnalysisModelToSciaEngineer(model);
Advanced
The advanced method will allow you to utilize some additional functionality, which has been hidden away on the simpler wrapper.
// Argument value provided by SCIA Engineer when starting your application
string pathToSdkConfiguration = args[0];
// Create a new configuration. Feel free to explore the available settings on this object
ThirdPartySdkAdmConfiguration configuration = new ThirdPartySdkAdmConfiguration(pathToSdkConfiguration);
// Create a new bootstrapper, which will bootstrap the ADM layer and all its services
using(ThirdPartySdkAdmBootstrapper bootstrapper = new ThirdPartySdkAdmBootstrapper())
{
// Retrieve the service from the bootstrapper, using the configuration to configu
IThirdPartySdkAnalysisModelService service = bootstrapper.GetService(configuration);
// Subscribe to log events, so you can see what's going on. Useful for debugging purposes
service.OnLogEvent += (sender, logEvent) => Console.WriteLine(logEvent.Message);
AnalysisModel model = service.GetAnalysisModelFromSciaEngineer();
// Do some modifications on model
bool isUpdated = service.SendAnalysisModelToSciaEngineer(model);
How does it work
SCIA Engineer has a command called Custom check
When you execute this command, SCIA Engineer will read a JSON configuration file located in the 3rdparty subfolder to know which application to start.
SCIA Engineer will then proceed to launch the executable defined inside that configuration file and pass it a single argument, which is the path to another JSON configuration file which is to be used when initializing the third party SDK.
Once your application is started and it has initialized the third party SDK (which is done automatically when using the ADM wrapper), it can start sending commands to SCIA Engineer.
Please note that the first command should always be retrieving the model from SCIA Engineer.
Immediately sending an ADM to SCIA Engineer will fail.
The intermediate format used during data exchange with SCIA Engineer is the Structural Analysis Format, or SAF.
When exporting data from SCIA Engineer, it will create a SAF file on disk containing the current model data. Then in the third party SDK ADM, we will read this SAF file and convert it to ADM.
The opposite is true for sending data to SCIA Engineer.
The third party SDK ADM will create a SAF file on disk from the ADM and then lets SCIA Engineer know that it needs to import that SAF file.
Getting started
Using NuGet
Install the Scia.StructuralToolkit.ThirdPartySdk.ADM NuGet package into your project.
This will make sure that all other dependencies are added to your project and automatically referenced.
If you do not have access to our NuGet packages, your only option is to go with the manual method below.
Manually referencing dlls
Locate your SCIA Engineer installation folder.
(e.g. C:\Program Files\SCIA\Engineer21.1)
Inside that folder, there’s a folder called dll_calatrava.
In this folder, your application can find all the dlls it needs.
Add the following dlls from the dll_calatrava folder as a reference to your project:
- SciaTools.ThirdParty.SDK.ADM.dll
- ModelExchanger.AnalysisDataModel.dll
- ModelExchanger.AnalysisDataModel.Contracts.dll
- ModelExchanger.AnalysisDataModel.Integration.Bootstrapper.dll
- ModelExchanger.Shared.Models.dll
- CSInfrastructure.dll
- UnitsNet.dll
Configuring SCIA Engineer
SCIA Engineer needs to be configured so it knows which executable to start.
In your SCIA Engineer’s installation folder (e.g C:\Program Files\SCIA\Engineer21.1) there should be a folder called 3rdparty
Inside that folder you’ll find a file called user_third_party_link.json
Edit this JSON file with a text editor and update the value of the exe-full-path property to point to your executable:
"exe-full-path": "C:\\path\\to\\your\\executable.exe"
Make sure that you escape any backslashes with another backslash:
\
becomes \\
Configuring third party SDK
Please note that this is only available when utilizing the advanced interface
You may configure the third party SDK with an instance of
ThirdPartySdkAdmConfiguration
when retrieving the service from the bootstrapper.
ThirdPartySdkAdmConfiguration
Name | Type | Description |
---|---|---|
ThirdPartyConfigurationFile | string | Path to the configuration file, provided by SCIA Engineer when starting your application. |
Import | ThirdPartySdkImportConfiguration | Contains settings that control how data is sent to SCIA Engineer |
Export | ThirdPartySdkExportConfiguration | Contains settings that control how data is retrieved from SCIA Engineer |
ThirdPartySdkImportConfiguration
Name | Type | Description |
---|---|---|
- | - | - |
At this point, there’s nothing available yet to configure the import into SCIA Engineer
ThirdPartySdkExportConfiguration
Name | Type | Description |
---|---|---|
ResultsToInclude | ThirdPartySdkAdmResultsExport | Flag enumeration that controls which kind of results should be included (if any). |
Further reading
For more information regarding ADM:
Snippets
Visual Studio project snippet
The following snippet can be copy pasted into your csproj file and will handle adding the required dlls as references to your project:
Note: this is not needed if you are using the NuGet package
<PropertyGroup>
<!-- The full path to the dll_calatrava folder from your SCIA Engineer installation. Adjust this value if required -->
<LibFolder>C:\Program Files\SCIA\Engineer 21.1\dll_calatrava</LibFolder>
</PropertyGroup>
<ItemGroup>
<Reference Include="SciaTools.ThirdParty.SDK.ADM">
<HintPath>$(LibFolder)\SciaTools.ThirdParty.SDK.ADM.dll</HintPath>
</Reference>
<Reference Include="ModelExchanger.AnalysisDataModel">
<HintPath>$(LibFolder)\ModelExchanger.AnalysisDataModel.dll</HintPath>
</Reference>
</ItemGroup>
Assembly resolver
The following code snippet can also be copy-pasted into your application.
It hooks into the assembly resolve event, which is triggered if your application is unable to resolve an assembly (dll) from it’s own folder.
Instead of having to make sure you have all the required dlls besides your application’s executable, we can use the assembly resolve event to allow the application to load assemblies directly from the dll_calatrava folder:
// The full path to the dll_calatrava folder from your SCIA Engineer installation. Adjust this value if required
string assembliesFolder = "C:\\Program Files\\SCIA\\Engineer 21.1\\dll_calatrava";
// Hook into the AssemblyResolve event
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
/// <summary>
/// Method that gets triggered whenever the application is unable to resolve an assembly from its own folder
/// </summary>
Assembly? CurrentDomain_AssemblyResolve(object? sender, ResolveEventArgs args)
{
string assemblyFilename = $"{args.Name.Substring(0, args.Name.IndexOf(","))}.dll";
if (File.Exists($"{assembliesFolder}\\{assemblyFilename}"))
{
return Assembly.LoadFrom($"{assembliesFolder}\\{assemblyFilename}");
}
return null;
}
Note: You may get a compiler error concerning the Assembly?
return value of the CurrentDomain_AssemblyResolve
function. If this is the case, you’re probably not using the latest langversion setting.
One possible way to resolve this is by removing the method and let visual studio regenerate it for you
Examples
Simple
Read/write
using ModelExchanger.AnalysisDataModel.Models;
using SciaTools.ThirdParty.SDK.ADM;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
ThirdPartySdkAnalysisDataModelWrapper wrapper = new ThirdPartySdkAnalysisDataModelWrapper();
// Retrieve the current active project from SCIA Engineer
AnalysisModel model = wrapper.GetAnalysisModelFromSciaEngineer();
// Do some modifications on model
// Send the modified model back to SCIA Engineer
bool isUpdated = wrapper.SendAnalysisModelToSciaEngineer(model);
Console.WriteLine($"Model has been updated in SCIA Engineer: {isUpdated}");
Console.ReadLine();
}
}
}
Modification
<MadCap:keyword term="node" xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" />using CSInfrastructure.IOC;
using ModelExchanger.AnalysisDataModel.Models;
using ModelExchanger.AnalysisDataModel.Contracts;
using ModelExchanger.AnalysisDataModel.StructuralElements;
using ModelExchanger.AnalysisDataModel.Integration.Bootstrapper;
using SciaTools.ThirdParty.SDK.ADM;
using UnitsNet;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
ThirdPartySdkAnalysisDataModelWrapper wrapper = new ThirdPartySdkAnalysisDataModelWrapper();
// Retrieve the current active project from SCIA Engineer
AnalysisModel model = wrapper.GetAnalysisModelFromSciaEngineer();
// Do some modifications on model
ModifyModel(model);
// Send the modified model back to SCIA Engineer
bool isUpdated = wrapper.SendAnalysisModelToSciaEngineer(model);
Console.WriteLine($"Model has been updated in SCIA Engineer: {isUpdated}");
Console.ReadLine();
}
private static void ModifyModel(AnalysisModel model)
{
using(IBootstrapper bootstrapper = new AnalysisDataModelBootstrapper())
using(IScopedServiceProvider scope = bootstrapper.CreateThreadedScope())
{
IAnalysisModelService service = scope.GetService<IAnalysisModelService>();
// Lets move the entire structure up by 2 meters
foreach(StructuralPointConnection node in model.OfType<StructuralPointConnection>())
{
node.Z += Length.FromMeters(2);
}
service.ValidateModel(model);
}
}
}
}