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

Functionality

The ADM layer exposes the following functionality:

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.

Copy
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.

Copy
// 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:

 

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
Copy
<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:

Copy
// 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

Copy
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

Copy
<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);
            }
        }
    }
}