├── .github
└── workflows
│ └── contrast_security_app.yaml
├── .gitignore
├── CreatingAndAnalyzingModel
├── BeamDeflectionResults.cs
├── ColumnResults.cs
├── CreateLoading.cs
├── CreateModelObjects.cs
├── CreatingAndAnalyzingModel.csproj
├── MidSpanResults.cs
├── Program.cs
└── ResultsOutput.cs
├── ExportingFireCheckDataToUDA
├── Commands.cs
├── DataApplier.cs
├── DataCollector.cs
├── ExportingFireCheckDataToUDA.csproj
├── Extensions
│ ├── CalculationsNodeExtensions.cs
│ ├── ReadOnlyPropertyExtensions.cs
│ └── ReportTableExtensions.cs
├── FireCheckData.cs
├── Orchestrator.cs
├── Program.cs
└── ProgressIndicator.cs
├── Extracting1DElementData
├── App.config
├── ApplicationPage.Designer.cs
├── ApplicationPage.cs
├── ApplicationPage.resx
├── ConnectionForm.Designer.cs
├── ConnectionForm.cs
├── ConnectionForm.resx
├── Exporters
│ └── Element1dExporter.cs
├── Extracting1DElementData.csproj
├── MainForm.Designer.cs
├── MainForm.cs
├── MainForm.resx
├── Program.cs
└── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── ExtractingModelData
├── DataOutputFileCreator.cs
├── ExtractingModelData.csproj
├── OutputConnectionData.cs
├── OutputMemberData.cs
├── OutputSlabData.cs
├── OutputWallData.cs
└── Program.cs
├── ExtractingResultsTableItem
├── ExtractingResultsTableItem.csproj
├── Program.cs
└── ResultsValuesOutputter.cs
├── ExtractingSteelBeamData
├── ExtractingSteelBeamData.csproj
└── ExtractingSteelBeamDataExample.cs
├── LICENSE
├── PythonNetExperiment
├── Program.cs
├── PythonNetExperiment.csproj
├── PythonNetExperiment.py
├── PythonNetExperiment.sln
└── TsdApiPythonGuide.md
├── README.md
├── ReactingToSelection
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── Helpers
│ ├── ListWithNotify.cs
│ ├── ReadOnlyPropertyExtensions.cs
│ ├── RelayCommand.cs
│ ├── TaskExtensions.cs
│ ├── UiHelpers.cs
│ └── ViewModelBase.cs
├── Models
│ ├── ConnectionFetcher.cs
│ ├── MemberSpanFetcher.cs
│ └── Model.cs
├── ReactingToSelection.csproj
├── ViewModels
│ ├── AnchorPlate.cs
│ ├── BasePlate.cs
│ ├── BasePlateAsymmetricBoltLayout.cs
│ ├── BasePlateBoltData.cs
│ ├── BasePlateBoltLayout.cs
│ ├── BasePlateConcreteData.cs
│ ├── BasePlateFourBoltLayout.cs
│ ├── BasePlateProperties.cs
│ ├── BasePlateSymmetricBoltLayout.cs
│ ├── BasePlateWelds.cs
│ ├── Bolt.cs
│ ├── BoltEc.cs
│ ├── BoltUs.cs
│ ├── ConnectedMember.cs
│ ├── Connection.cs
│ ├── ConnectionDetails.cs
│ ├── MainWindowViewModel.cs
│ ├── SpanReleases.cs
│ ├── SupportReaction.cs
│ └── WeldedWasher.cs
└── Views
│ ├── AnchorPlate.xaml
│ ├── AnchorPlate.xaml.cs
│ ├── BasePlate.xaml
│ ├── BasePlate.xaml.cs
│ ├── BasePlateAsymmetricBoltLayout.xaml
│ ├── BasePlateAsymmetricBoltLayout.xaml.cs
│ ├── BasePlateBoltData.xaml
│ ├── BasePlateBoltData.xaml.cs
│ ├── BasePlateBoltLayout.xaml
│ ├── BasePlateBoltLayout.xaml.cs
│ ├── BasePlateConcreteData.xaml
│ ├── BasePlateConcreteData.xaml.cs
│ ├── BasePlateFourBoltLayout.xaml
│ ├── BasePlateFourBoltLayout.xaml.cs
│ ├── BasePlateProperties.xaml
│ ├── BasePlateProperties.xaml.cs
│ ├── BasePlateSymmetricBoltLayout.xaml
│ ├── BasePlateSymmetricBoltLayout.xaml.cs
│ ├── BasePlateWelds.xaml
│ ├── BasePlateWelds.xaml.cs
│ ├── Bolt.xaml
│ ├── Bolt.xaml.cs
│ ├── BoltEc.xaml
│ ├── BoltEc.xaml.cs
│ ├── BoltUs.xaml
│ ├── BoltUs.xaml.cs
│ ├── ConnectedMember.xaml
│ ├── ConnectedMember.xaml.cs
│ ├── Connection.xaml
│ ├── Connection.xaml.cs
│ ├── ConnectionDetails.xaml
│ ├── ConnectionDetails.xaml.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ ├── SpanReleases.xaml
│ ├── SpanReleases.xaml.cs
│ ├── SupportReaction.xaml
│ ├── SupportReaction.xaml.cs
│ ├── WeldedWasher.xaml
│ └── WeldedWasher.xaml.cs
├── ReleaseNotes
├── 2023.md
├── 2024.md
└── 2025.md
└── RemotingAPIExamples.sln
/.github/workflows/contrast_security_app.yaml:
--------------------------------------------------------------------------------
1 | # DISCLAIMER: This workflow file has been auto-generated and committed to the repo by the GitHub App from Contrast Security.
2 | # Manual edits to this file could cause the integration to produce unexpected behavior or break.
3 | # Version: 1.0.0
4 | # Last updated: 2024-02-13T15:58:18.544081668Z
5 | name: Contrast Security App Workflow
6 | on:
7 | workflow_dispatch:
8 | push:
9 | branches:
10 | - master
11 | pull_request:
12 | types: [opened, synchronize, reopened]
13 | branches:
14 | - master
15 | jobs:
16 | fingerprint_repo:
17 | if: ${{ github.actor != 'dependabot[bot]' }}
18 | runs-on: ubuntu-22.04
19 | steps:
20 | - name: Clone repository
21 | uses: actions/checkout@v3
22 | - name: Run Contrast SCA Fingerprint
23 | id: fingerprint
24 | uses: 'Contrast-Security-OSS/contrast-sca-action@v2'
25 | with:
26 | apiKey: ${{ secrets.CONTRAST_GITHUB_APP_API_KEY }}
27 | authHeader: ${{ secrets.CONTRAST_GITHUB_APP_AUTH_HEADER }}
28 | orgId: ${{ vars.CONTRAST_GITHUB_APP_ORG_ID }}
29 | apiUrl: ${{ vars.CONTRAST_GITHUB_APP_TS_URL }}
30 | repoUrl: ${{ github.server_url }}/${{ github.repository }}
31 | repoName: ${{ github.repository }}
32 | externalId: ${{ vars.CONTRAST_GITHUB_APP_ID }}
33 | command: fingerprint
34 | outputs:
35 | fingerprint: ${{ steps.fingerprint.outputs.fingerprint }}
36 | analyze_dependencies:
37 | if: ${{ needs.fingerprint_repo.outputs.fingerprint != '' }}
38 | needs: fingerprint_repo
39 | runs-on: ubuntu-22.04
40 | strategy:
41 | fail-fast: false
42 | matrix:
43 | manifest:
44 | - ${{ fromJson(needs.fingerprint_repo.outputs.fingerprint) }}
45 | steps:
46 | - name: Clone repository
47 | uses: actions/checkout@v3
48 | - name: Run Contrast SCA Audit
49 | uses: 'Contrast-Security-OSS/contrast-sca-action@v2'
50 | with:
51 | apiKey: ${{ secrets.CONTRAST_GITHUB_APP_API_KEY }}
52 | authHeader: ${{ secrets.CONTRAST_GITHUB_APP_AUTH_HEADER }}
53 | orgId: ${{ vars.CONTRAST_GITHUB_APP_ORG_ID }}
54 | apiUrl: ${{ vars.CONTRAST_GITHUB_APP_TS_URL }}
55 | filePath: ${{ matrix.manifest.filePath }}
56 | repositoryId: ${{ matrix.manifest.repositoryId }}
57 | projectGroupId: ${{ matrix.manifest.projectGroupId }}
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #Ignore thumbnails created by Windows
2 | Thumbs.db
3 | #Ignore files built by Visual Studio
4 | *.obj
5 | *.exe
6 | *.pdb
7 | *.user
8 | *.aps
9 | *.pch
10 | *.vspscc
11 | *_i.c
12 | *_p.c
13 | *.ncb
14 | *.suo
15 | *.tlb
16 | *.tlh
17 | *.bak
18 | *.cache
19 | *.ilk
20 | *.log
21 | [Bb]in
22 | [Dd]ebug/
23 | *.lib
24 | *.sbr
25 | obj/
26 | [Rr]elease/
27 | _ReSharper*/
28 | [Tt]est[Rr]esult*
29 | .vs/
30 | #Nuget packages folder
31 | packages/
32 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/BeamDeflectionResults.cs:
--------------------------------------------------------------------------------
1 | namespace CreatingAndAnalyzingModel
2 | {
3 | ///
4 | /// Stores the results required for identifying and reporting critical beam deflection
5 | ///
6 | public class BeamDeflectionResults
7 | {
8 | #region Properties
9 |
10 | ///
11 | /// Gets or sets the member name
12 | ///
13 | public string MemberName { get; set; }
14 |
15 | ///
16 | /// Gets or sets the members total length (includes all spans) (in [mm])
17 | ///
18 | public double MemberTotalLength { get; set; }
19 |
20 | ///
21 | /// Gets or sets the name of the critical combination
22 | ///
23 | public string CriticalCombinationName { get; set; }
24 |
25 | ///
26 | /// Gets or sets the value of the maximum deflection (in [mm])
27 | ///
28 | public double MaximumDeflectionValue { get; set; }
29 |
30 | ///
31 | /// Gets or sets the span index at which the maximum deflection occurs
32 | ///
33 | public int MaximumDeflectionSpanIndex { get; set; }
34 |
35 | ///
36 | /// Gets or sets the position at which the maximum deflection occurs, relative to the appropriate span (in [mm])
37 | ///
38 | public double MaximumDeflectionPosition { get; set; }
39 |
40 | ///
41 | /// Gets or sets the value of the maximum moment (in [Nmm])
42 | ///
43 | public double MaximumMomentValue { get; set; }
44 |
45 | ///
46 | /// Gets or sets the span index at which the maximum moment occurs
47 | ///
48 | public int MaximumMomentSpanIndex { get; set; }
49 |
50 | ///
51 | /// Gets or sets the position at which the maximum moment occurs, relative to the appropriate span (in [mm])
52 | ///
53 | public double MaximumMomentPosition { get; set; }
54 |
55 | #endregion
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/ColumnResults.cs:
--------------------------------------------------------------------------------
1 | namespace CreatingAndAnalyzingModel
2 | {
3 | ///
4 | /// Stores the results required for identifying and reporting critical column forces
5 | ///
6 | public class ColumnResults
7 | {
8 | #region Properties
9 |
10 | ///
11 | /// Gets or sets the member name
12 | ///
13 | public string MemberName { get; set; }
14 |
15 | ///
16 | /// Gets or sets the span number
17 | ///
18 | public int SpanNumber { get; set; }
19 |
20 | ///
21 | /// Gets or sets the span length (in [mm])
22 | ///
23 | public double SpanLength { get; set; }
24 |
25 | ///
26 | /// Gets or sets the name of the critical combination for major moment
27 | ///
28 | public string CriticalMajorMomentCombinationName { get; set; }
29 |
30 | ///
31 | /// Gets or sets the name of the critical combination for minor moment
32 | ///
33 | public string CriticalMinorMomentCombinationName { get; set; }
34 |
35 | ///
36 | /// Gets or sets the name of the critical combination for axial force
37 | ///
38 | public string CriticalAxialForceCombinationName { get; set; }
39 |
40 | ///
41 | /// Gets or sets the value of the maximum major moment (in [Nmm])
42 | ///
43 | public double MaximumMajorMomentValue { get; set; }
44 |
45 | ///
46 | /// Gets or sets the value of the maximum minor moment (in [Nmm])
47 | ///
48 | public double MaximumMinorMomentValue { get; set; }
49 |
50 | ///
51 | /// Gets or sets the value of the maximum axial force (in [N])
52 | ///
53 | public double MaximumAxialForceValue { get; set; }
54 |
55 | #endregion
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/CreateLoading.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using TSD.API.Remoting.Common;
6 | using TSD.API.Remoting.Loading;
7 | using TSD.API.Remoting.Loading.Create;
8 | using TSD.API.Remoting.Structure;
9 |
10 | namespace CreatingAndAnalyzingModel
11 | {
12 | ///
13 | /// Contains methods to create the model loading
14 | ///
15 | public class CreateLoading
16 | {
17 | #region Methods
18 |
19 | public async Task Create( IModel model )
20 | {
21 | await CreateLoads( model );
22 |
23 | await CreateCombinations( model );
24 |
25 | Console.WriteLine( "Loading created" );
26 | }
27 |
28 | private static async Task CreateLoads( IModel model )
29 | {
30 | var loadcases = (await model.GetLoadcasesAsync()).ToList();
31 |
32 | var createLoadParams = new List();
33 |
34 | var levels = (await model.GetLevelsAsync()).ToList();
35 |
36 | // Create some level loading for each loadcase
37 | foreach( var loadcase in loadcases )
38 | {
39 | var load = 0.0;
40 |
41 | if( loadcase.Name.Contains( "Dead" ) )
42 | {
43 | load = 0.004; // 0.004 N/mm^2 = 4kN/m^2
44 | }
45 | else if( loadcase.Name.Contains( "Services" ) )
46 | {
47 | load = 0.003; // 0.003 N/mm^2 = 3kN/m^2
48 | }
49 | else if( loadcase.Name.Contains( "Imposed" ) )
50 | {
51 | load = 0.005; // 0.005 N/mm^2 = 5kN/m^2
52 | }
53 | else
54 | {
55 | continue;
56 | }
57 |
58 | foreach( var level in levels.Where( l => l.Level.Value > 0.001 ) ) // ignore base level
59 | {
60 | var planeLoad = ConstructionPlaneLoadParams.AlongPlaneNormal( level, load );
61 | createLoadParams.Add( planeLoad );
62 | }
63 |
64 | await loadcase.CreateLoadAsync( createLoadParams );
65 | createLoadParams.Clear();
66 | }
67 |
68 | // Create a lateral load on the structure for the imposed load case
69 | var imposedLoadcase = loadcases.First( l => l.Type.Value == LoadcaseType.Imposed );
70 |
71 | var members = await model.GetMembersAsync();
72 | var constructionPoints = await model.GetConstructionPointsAsync();
73 |
74 | // Find edge beam points where X co-ordinate is 0 at first floor
75 | var edgeBeamPoints = constructionPoints.Where( c => Math.Abs( c.Coordinates.Value.X ) < 0.001 && Math.Abs( c.Coordinates.Value.Z - 3000.0 ) < 0.001 );
76 |
77 | foreach( var member in members.Where( m => m.Data.Value.MemberType.Value == MemberType.Beam ) )
78 | {
79 | foreach( var span in await member.GetSpanAsync( new[] { 0, member.SpanCount.Value - 1 } ) )
80 | {
81 | if( edgeBeamPoints.Select( p => p.Index ).ToList().Contains( span.EndMemberNode.ConstructionPointIndex.Value ) )
82 | {
83 | var memberSpanInfo = new MemberSpanInfo( member.Id, span.Id );
84 | var memberLateralLoad = MemberFullUniformlyDistributedLoadParams.Local( memberSpanInfo, 10.0, MemberLoadParams.LoadDirectionLocal.Y );
85 | createLoadParams.Add( memberLateralLoad );
86 | }
87 | }
88 | }
89 |
90 | await imposedLoadcase.CreateLoadAsync( createLoadParams );
91 |
92 | createLoadParams.Clear();
93 |
94 | // Create a snow load
95 | var loadcaseParams = new List()
96 | {
97 | LoadcaseParams.Create(),
98 | };
99 |
100 | await model.CreateEntityAsync( loadcaseParams );
101 |
102 | var snowLoadcase = (await model.GetLoadcasesAsync()).Last();
103 |
104 | await snowLoadcase.UserName.SetValueAndUpdateAsync( "Snow" );
105 | await snowLoadcase.Type.SetValueAndUpdateAsync( LoadcaseType.Snow );
106 |
107 | var roofSlab = (await model.GetSlabsAsync()).Last();
108 | var slabSnowLoad = SlabLoadParams.AlongSlabNormal( roofSlab, 0.00063 );
109 | createLoadParams.Add( slabSnowLoad );
110 | await snowLoadcase.CreateLoadAsync( createLoadParams );
111 | }
112 |
113 | private static async Task CreateCombinations( IModel model )
114 | {
115 | var loadcases = (await model.GetLoadcasesAsync()).ToList();
116 |
117 | var cbParams = new List()
118 | {
119 | CombinationParams.Create(),
120 | };
121 |
122 | // Create 4 combinations
123 | for( int i = 0; i < 4; i++ )
124 | {
125 | await model.CreateEntityAsync( cbParams );
126 | }
127 |
128 | var combinations = (await model.GetCombinationsAsync()).ToList();
129 |
130 | foreach( var combination in combinations )
131 | {
132 | switch( combination.Index )
133 | {
134 | case 1:
135 | await combination.UserName.SetValueAndUpdateAsync( "Dead + Imposed" );
136 |
137 | break;
138 |
139 | case 2:
140 | await combination.UserName.SetValueAndUpdateAsync( "Dead only" );
141 |
142 | break;
143 |
144 | case 3:
145 | await combination.UserName.SetValueAndUpdateAsync( "Imposed only" );
146 |
147 | break;
148 |
149 | case 4:
150 | await combination.UserName.SetValueAndUpdateAsync( "Dead + Imposed + Snow" );
151 |
152 | break;
153 | }
154 |
155 | // Add each loadcase to the combination
156 | foreach( var loadcase in loadcases )
157 | {
158 | if( AddLoadcaseToCombination( combination.Index, loadcase.Type.Value ) )
159 | await combination.AddLoadcaseAsync( loadcase );
160 | }
161 | }
162 |
163 | // Create an envelope of all combinations
164 | var envParams = new List()
165 | {
166 | EnvelopeParams.Create(),
167 | };
168 |
169 | await model.CreateEntityAsync( envParams );
170 |
171 | var envelope = (await model.GetEnvelopesAsync()).ToList().FirstOrDefault();
172 |
173 | if( envelope == null )
174 | return;
175 |
176 | foreach( var combination in combinations )
177 | {
178 | await envelope.AddCombinationAsync( combination );
179 | }
180 |
181 | bool AddLoadcaseToCombination( int combinationIndex, LoadcaseType loadcaseType )
182 | {
183 | if( combinationIndex == 1 && (loadcaseType == LoadcaseType.Dead || loadcaseType == LoadcaseType.Imposed) )
184 | return true;
185 |
186 | if( combinationIndex == 2 && loadcaseType is LoadcaseType.Dead )
187 | return true;
188 |
189 | if( combinationIndex == 3 && loadcaseType is LoadcaseType.Imposed )
190 | return true;
191 |
192 | if( combinationIndex == 4 && (loadcaseType == LoadcaseType.Dead || loadcaseType == LoadcaseType.Imposed || loadcaseType == LoadcaseType.Snow) )
193 | return true;
194 |
195 | return false;
196 | }
197 | }
198 |
199 | #endregion
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/CreatingAndAnalyzingModel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | 7.3
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/MidSpanResults.cs:
--------------------------------------------------------------------------------
1 | namespace CreatingAndAnalyzingModel
2 | {
3 | ///
4 | /// Stores the results required for identifying and reporting mid span forces
5 | ///
6 | public class MidSpanResults
7 | {
8 | #region Properties
9 |
10 | ///
11 | /// Gets or sets the member name
12 | ///
13 | public string MemberName { get; set; }
14 |
15 | ///
16 | /// Gets or sets the span index
17 | ///
18 | public int SpanIndex { get; set; }
19 |
20 | ///
21 | /// Gets or sets the position of the mid span (in [mm])
22 | ///
23 | public double MidSpanPosition { get; set; }
24 |
25 | ///
26 | /// Gets or sets the name of the combination
27 | ///
28 | public string CombinationName { get; set; }
29 |
30 | ///
31 | /// Gets or sets the value of the major moment at the mid span (in [Nmm])
32 | ///
33 | public double MidSpanMajorMomentValue { get; set; }
34 |
35 | ///
36 | /// Gets or sets the value of the major shear at the mid span (in [N])
37 | ///
38 | public double MidSpanMajorShearValue { get; set; }
39 |
40 | ///
41 | /// Gets or sets the value of the axial force at the mid span (in [N])
42 | ///
43 | public double MidSpanAxialValue { get; set; }
44 |
45 | ///
46 | /// Gets or sets the value of the torsion at the mid span (in [Nmm])
47 | ///
48 | public double MidSpanTorsionValue { get; set; }
49 |
50 | ///
51 | /// Gets or sets the value of the deflection at the mid span (in [mm])
52 | ///
53 | public double MidSpanDeflectionValue { get; set; }
54 |
55 | #endregion
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/CreatingAndAnalyzingModel/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using TSD.API.Remoting;
6 | using TSD.API.Remoting.Solver;
7 |
8 | namespace CreatingAndAnalyzingModel
9 | {
10 | class Program
11 | {
12 | public static async Task Main()
13 | {
14 | // Get the first running TSD instance found
15 | using( var tsdInstance = await ApplicationFactory.GetFirstRunningApplicationAsync() )
16 | {
17 | if( tsdInstance == null )
18 | {
19 | Console.WriteLine( "No running instances of TSD found!" );
20 |
21 | return;
22 | }
23 |
24 | // Output the version number of TSD
25 | Console.WriteLine( await tsdInstance.GetVersionStringAsync() );
26 |
27 | // Get the active document from the running instance of TSD
28 | var document = await tsdInstance.GetDocumentAsync();
29 |
30 | if( document == null )
31 | {
32 | Console.WriteLine( "No document was found in the TSD instance!" );
33 |
34 | return;
35 | }
36 |
37 | // Get the model from the document
38 | var model = await document.GetModelAsync();
39 |
40 | if( model == null )
41 | {
42 | Console.WriteLine( "No model was found in the document!" );
43 |
44 | return;
45 | }
46 |
47 | var createModelObjects = new CreateModelObjects();
48 | await createModelObjects.Create( model );
49 |
50 | var createLoading = new CreateLoading();
51 | await createLoading.Create( model );
52 |
53 | await RunValidation( model );
54 |
55 | var requestedAnalysisType = AnalysisType.FirstOrderLinear;
56 |
57 | var solvedLoading = await RunAnalysis( model, requestedAnalysisType );
58 |
59 | var resultsOutput = new ResultsOutput();
60 | await resultsOutput.OutputResults( model, solvedLoading, requestedAnalysisType );
61 | }
62 | }
63 |
64 | private static async Task RunValidation( TSD.API.Remoting.Structure.IModel model )
65 | {
66 | await model.ValidateAsync();
67 |
68 | var validationData = await model.GetValidationDataAsync();
69 |
70 | Console.WriteLine( validationData.OverallStatus.Value.ToString() );
71 | }
72 |
73 | private static async Task> RunAnalysis( TSD.API.Remoting.Structure.IModel model, AnalysisType requestedAnalysisType )
74 | {
75 | var analysedLoading = await model.RunAnalysisAsync( requestedAnalysisType );
76 |
77 | Console.WriteLine( requestedAnalysisType.ToString() + " analysis complete" );
78 |
79 | return analysedLoading;
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Commands.cs:
--------------------------------------------------------------------------------
1 | using System.CommandLine;
2 |
3 | namespace ExportingFireCheckDataToUDA;
4 |
5 | ///
6 | /// Contains command line commands
7 | ///
8 | internal static class Commands
9 | {
10 | #region Fields
11 |
12 | ///
13 | /// The option for API port
14 | ///
15 | private static readonly Option _apiPortOption = new( "--api-port", "The port TSD API is listening on." );
16 |
17 | #endregion
18 |
19 | #region Properties
20 |
21 | ///
22 | /// Gets the root command
23 | ///
24 | public static RootCommand RootCommand
25 | {
26 | get
27 | {
28 | var command = new RootCommand
29 | {
30 | _apiPortOption,
31 | };
32 |
33 | command.SetHandler( Orchestrator.ExportDataToUdaAsync, _apiPortOption );
34 |
35 | return command;
36 | }
37 | }
38 |
39 | #endregion
40 | }
41 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/ExportingFireCheckDataToUDA.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | 12.0
7 | enable
8 | enable
9 | false
10 |
11 |
12 |
13 | bin\publish
14 | en-US
15 | false
16 | true
17 |
18 |
19 |
20 |
21 |
22 | $(AllowedReferenceRelatedFileExtensions.Replace('.pdb;','').Replace('.xml;',''))
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Extensions/CalculationsNodeExtensions.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Report;
2 |
3 | namespace ExportingFireCheckDataToUDA.Extensions;
4 |
5 | ///
6 | /// Contains extension methods for
7 | ///
8 | internal static class CalculationsNodeExtensions
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Returns a child node of the given node with the specified name
14 | ///
15 | /// The node to query the child nodes of
16 | /// The name of the node to look for
17 | /// Returns a child node of the given node with the specified name (or if no such exists)
18 | public static ICalculationsNode? GetChildNode( this ICalculationsNode node, string name )
19 | => node.Nodes.SingleOrDefault( n => n.Name.Equals( name, StringComparison.InvariantCultureIgnoreCase ) );
20 |
21 | ///
22 | /// Returns a child node of the given node that matches the predicate
23 | ///
24 | /// The node to query the child nodes of
25 | /// The predicate to use to look for the child node
26 | /// Returns a child node of the given node that matches the predicate (or if no such exists)
27 | public static ICalculationsNode? GetChildNode( this ICalculationsNode node, Func predicate )
28 | => node.Nodes.SingleOrDefault( predicate );
29 |
30 | #endregion
31 | }
32 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Extensions/ReadOnlyPropertyExtensions.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Common.Properties;
2 |
3 | namespace ExportingFireCheckDataToUDA.Extensions;
4 |
5 | ///
6 | /// Contains extension methods for the interface
7 | ///
8 | internal static class ReadOnlyPropertyExtensions
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Returns the value of this property or the given default value in case the property is not applicable
14 | ///
15 | /// The property to get value of
16 | /// The default value to use in case the property is not applicable
17 | /// The type of value stored in the property
18 | public static TValue? GetValueOrDefault( this IReadOnlyProperty property, TValue? defaultValue = default )
19 | => property is { IsApplicable: true } ? property.Value : defaultValue;
20 |
21 | #endregion
22 | }
23 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Extensions/ReportTableExtensions.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Report;
2 |
3 | namespace ExportingFireCheckDataToUDA.Extensions;
4 |
5 | ///
6 | /// Contains extension methods for
7 | ///
8 | internal static class ReportTableExtensions
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Returns a value associated with item with the given name from the specified table
14 | ///
15 | /// The table to retrieve value from
16 | /// The name of the item to retrieve value of
17 | public static double? GetValue( this IReportTable table, string name )
18 | {
19 | if( table.GetLine( name ) is not { } line )
20 | return null;
21 |
22 | var itemWithValue = line.Items
23 | .OfType()
24 | .FirstOrDefault();
25 |
26 | return itemWithValue is { Value: var value } ? value : null;
27 | }
28 |
29 | ///
30 | /// Returns a line containing an item with the given name from the specified table
31 | ///
32 | /// The table to retrieve line from
33 | /// The name of the item to retrieve the associated line
34 | public static IReportTableLine? GetLine( this IReportTable table, string name )
35 | => table.Lines.FirstOrDefault( l => l.Items.OfType().Any( i => i.Text.Equals( name ) ) );
36 |
37 | #endregion
38 | }
39 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/FireCheckData.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Structure;
2 |
3 | namespace ExportingFireCheckDataToUDA;
4 |
5 | ///
6 | /// Contains the fire check data
7 | ///
8 | /// The owning member of the span the fire check data belong to
9 | /// The member span the fire check data belong to
10 | /// The fire exposure of the member span
11 | /// The time of fire exposure of the member span
12 | /// The critical temperature for the member span
13 | /// The ambient utilization ratio for the member span
14 | /// The load reduction factor for the member span
15 | /// The reference index of the combination
16 | internal readonly record struct FireCheckData(
17 | IMember Member,
18 | IMemberSpan MemberSpan,
19 | ExposedSides? Exposure,
20 | TimeOfFireExposure? NominalFireExposure,
21 | double? CriticalTemperature,
22 | double? AmbientUtilizationRatio,
23 | double? LoadReductionFactor,
24 | int? CombinationReferenceIndex
25 | );
26 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Orchestrator.cs:
--------------------------------------------------------------------------------
1 | using ExportingFireCheckDataToUDA.Extensions;
2 | using TSD.API.Remoting;
3 | using TSD.API.Remoting.Materials;
4 | using TSD.API.Remoting.Structure;
5 |
6 | namespace ExportingFireCheckDataToUDA;
7 |
8 | ///
9 | /// Orchestrates the whole export process
10 | ///
11 | internal static class Orchestrator
12 | {
13 | #region Methods
14 |
15 | ///
16 | /// Exports the fire check data to UDA
17 | ///
18 | /// The port TSD API is listening on (if the first running application will be used)
19 | public static async Task ExportDataToUdaAsync( int? apiPort )
20 | {
21 | var model = await GetModelAsync( apiPort );
22 |
23 | var eligibleMembers = (await model.GetMembersAsync())
24 | .Where( IsEligible )
25 | .ToList();
26 |
27 | Console.WriteLine( $"Found {eligibleMembers.Count} eligible members" );
28 |
29 | var spans = new System.Collections.Concurrent.ConcurrentBag<(IMember Member, IEnumerable Spans)>();
30 |
31 | await Task.Run( () => Parallel.ForEachAsync( eligibleMembers, async ( m, cancellationToken ) =>
32 | {
33 | spans.Add( (Member: m, await m.GetSpanAsync( cancellationToken: cancellationToken )) );
34 | } ) );
35 |
36 | var fireCheckData = spans
37 | .SelectMany( tuple => tuple.Spans.Select( s => GetFireCheckData( tuple.Member, s ) ) )
38 | .ToList();
39 |
40 | Console.WriteLine( $"Found {fireCheckData.Count} eligible member spans" );
41 |
42 | var dataList = await DataCollector.PopulateFireCheckDataAsync( fireCheckData );
43 |
44 | await DataApplier.ApplyFireCheckDataAsync( model, dataList );
45 | }
46 |
47 | ///
48 | /// Returns a value indicating whether the given member is eligible for the fire check
49 | ///
50 | /// The member to check
51 | private static bool IsEligible( IMember member )
52 | {
53 | if( member.Data.GetValueOrDefault() is not { } memberData )
54 | return false;
55 |
56 | if( memberData.MaterialType.GetValueOrDefault() is not MaterialType.Steel and not MaterialType.ColdFormed )
57 | return false;
58 |
59 | return true;
60 | }
61 |
62 | ///
63 | /// Returns a fire check data associated with the given member span
64 | ///
65 | /// The owning member of the span to check
66 | /// The member span to check
67 | /// Returns a fire check data associated with the given member span (or in case the member span is not eligible)
68 | private static FireCheckData GetFireCheckData( IMember member, IMemberSpan memberSpan )
69 | {
70 | var fireCheckData = memberSpan.FireCheckData.GetValueOrDefault();
71 |
72 | return new FireCheckData
73 | {
74 | Member = member,
75 | MemberSpan = memberSpan,
76 | Exposure = fireCheckData?.ExposedSides.IsApplicable is true ? fireCheckData.ExposedSides.Value : null,
77 | NominalFireExposure = fireCheckData?.TimeOfFireExposure.IsApplicable is true ? fireCheckData.TimeOfFireExposure.Value : null,
78 | };
79 | }
80 |
81 | ///
82 | /// Returns the currently active model
83 | ///
84 | /// The port TSD API is listening on (if the first running application will be used)
85 | private static async Task GetModelAsync( int? apiPort )
86 | {
87 | var application = await ConnectAsync( apiPort );
88 |
89 | if( await application.GetDocumentAsync() is not { } document )
90 | throw new InvalidOperationException( "Could not obtain document!" );
91 |
92 | if( await document.GetModelAsync() is not { } model )
93 | throw new InvalidOperationException( "Could not obtain model!" );
94 |
95 | return model;
96 | }
97 |
98 | ///
99 | /// Connects to TSD
100 | ///
101 | /// The port TSD API is listening on (if the first running application will be used)
102 | /// The connected application
103 | private static async Task ConnectAsync( int? apiPort )
104 | {
105 | if( apiPort is { } specifiedPort )
106 | {
107 | if( await ApplicationFactory.ConnectToRunningApplicationAsync( specifiedPort ) is not { } application )
108 | throw new InvalidOperationException( $"Could not connect to TSD API at port {specifiedPort}!" );
109 |
110 | return application;
111 | }
112 | else
113 | {
114 | if( await ApplicationFactory.GetFirstRunningApplicationAsync() is not { } application )
115 | throw new InvalidOperationException( "Could not connect to TSD API!" );
116 |
117 | return application;
118 | }
119 | }
120 |
121 | #endregion
122 | }
123 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/Program.cs:
--------------------------------------------------------------------------------
1 | using System.CommandLine;
2 |
3 | namespace ExportingFireCheckDataToUDA;
4 |
5 | ///
6 | /// Contains entry point of the application
7 | ///
8 | internal static class Program
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Executes the application logic
14 | ///
15 | /// The command line arguments
16 | /// The exit code indicating how the application terminated
17 | private static int Main( string[] args ) => Commands.RootCommand.Invoke( args );
18 |
19 | #endregion
20 | }
21 |
--------------------------------------------------------------------------------
/ExportingFireCheckDataToUDA/ProgressIndicator.cs:
--------------------------------------------------------------------------------
1 | namespace ExportingFireCheckDataToUDA;
2 |
3 | ///
4 | /// Contains methods for indicating progress
5 | ///
6 | internal static class ProgressIndicator
7 | {
8 | #region Methods
9 |
10 | ///
11 | /// Returns the text indicating the current progress
12 | ///
13 | /// The number of decimal places of the total number of data chunks
14 | /// The index of the currently processed data chunk
15 | /// The total number of data chunks
16 | public static string GetText( int decimalPlaces, int currentChunkIndex, int totalChunkCount )
17 | => $"{(currentChunkIndex + 1).ToString().PadLeft( decimalPlaces )}/{totalChunkCount}";
18 |
19 | #endregion
20 | }
21 |
--------------------------------------------------------------------------------
/Extracting1DElementData/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Extracting1DElementData/ApplicationPage.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | False
122 |
123 |
124 | False
125 |
126 |
127 | False
128 |
129 |
130 | False
131 |
132 |
133 | False
134 |
135 |
136 | False
137 |
138 |
--------------------------------------------------------------------------------
/Extracting1DElementData/ConnectionForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Extracting1DElementData
2 | {
3 | partial class ConnectionForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose( bool disposing )
15 | {
16 | if( disposing && (components != null) )
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose( disposing );
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.Windows.Forms.Label label1;
32 | System.Windows.Forms.Label label2;
33 | this._address = new System.Windows.Forms.TextBox();
34 | this._port = new System.Windows.Forms.TextBox();
35 | this._cancel = new System.Windows.Forms.Button();
36 | this._ok = new System.Windows.Forms.Button();
37 | label1 = new System.Windows.Forms.Label();
38 | label2 = new System.Windows.Forms.Label();
39 | this.SuspendLayout();
40 | //
41 | // label1
42 | //
43 | label1.AutoSize = true;
44 | label1.Location = new System.Drawing.Point(12, 9);
45 | label1.Name = "label1";
46 | label1.Size = new System.Drawing.Size(51, 13);
47 | label1.TabIndex = 0;
48 | label1.Text = "Address :";
49 | //
50 | // label2
51 | //
52 | label2.AutoSize = true;
53 | label2.Location = new System.Drawing.Point(12, 35);
54 | label2.Name = "label2";
55 | label2.Size = new System.Drawing.Size(32, 13);
56 | label2.TabIndex = 1;
57 | label2.Text = "Port :";
58 | //
59 | // _address
60 | //
61 | this._address.Location = new System.Drawing.Point(68, 6);
62 | this._address.Name = "_address";
63 | this._address.Size = new System.Drawing.Size(112, 20);
64 | this._address.TabIndex = 1;
65 | this._address.Text = "localhost";
66 | //
67 | // _port
68 | //
69 | this._port.Location = new System.Drawing.Point(68, 32);
70 | this._port.Name = "_port";
71 | this._port.Size = new System.Drawing.Size(112, 20);
72 | this._port.TabIndex = 0;
73 | this._port.TextChanged += new System.EventHandler(this.OnPortTextChanged);
74 | //
75 | // _cancel
76 | //
77 | this._cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
78 | this._cancel.Location = new System.Drawing.Point(15, 58);
79 | this._cancel.Name = "_cancel";
80 | this._cancel.Size = new System.Drawing.Size(75, 23);
81 | this._cancel.TabIndex = 3;
82 | this._cancel.Text = "Cancel";
83 | this._cancel.UseVisualStyleBackColor = true;
84 | //
85 | // _ok
86 | //
87 | this._ok.DialogResult = System.Windows.Forms.DialogResult.OK;
88 | this._ok.Location = new System.Drawing.Point(105, 58);
89 | this._ok.Name = "_ok";
90 | this._ok.Size = new System.Drawing.Size(75, 23);
91 | this._ok.TabIndex = 2;
92 | this._ok.Text = "OK";
93 | this._ok.UseVisualStyleBackColor = true;
94 | //
95 | // ConnectionForm
96 | //
97 | this.AcceptButton = this._ok;
98 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
99 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
100 | this.CancelButton = this._cancel;
101 | this.ClientSize = new System.Drawing.Size(194, 93);
102 | this.ControlBox = false;
103 | this.Controls.Add(this._ok);
104 | this.Controls.Add(this._cancel);
105 | this.Controls.Add(this._port);
106 | this.Controls.Add(this._address);
107 | this.Controls.Add(label2);
108 | this.Controls.Add(label1);
109 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
110 | this.Name = "ConnectionForm";
111 | this.ShowInTaskbar = false;
112 | this.Text = "Connect to...";
113 | this.ResumeLayout(false);
114 | this.PerformLayout();
115 |
116 | }
117 |
118 | #endregion
119 |
120 | private System.Windows.Forms.TextBox _address;
121 | private System.Windows.Forms.TextBox _port;
122 | private System.Windows.Forms.Button _cancel;
123 | private System.Windows.Forms.Button _ok;
124 | }
125 | }
--------------------------------------------------------------------------------
/Extracting1DElementData/ConnectionForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Extracting1DElementData
5 | {
6 | public partial class ConnectionForm : Form
7 | {
8 | public ConnectionForm()
9 | {
10 | InitializeComponent();
11 | }
12 |
13 | private void OnPortTextChanged( object sender, EventArgs e )
14 | {
15 | _ok.Enabled = _port.Text.Length > 0 && int.TryParse( _port.Text, out _ );
16 | }
17 |
18 | public string Host => _address.Text;
19 |
20 | public int Port => int.Parse( _port.Text );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Extracting1DElementData/ConnectionForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | False
122 |
123 |
124 | False
125 |
126 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Extracting1DElementData.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-windows
5 | WinExe
6 | Copyright © 2022
7 | 1.0.0.0
8 | true
9 | 7.3
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Extracting1DElementData/MainForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace Extracting1DElementData
2 | {
3 | partial class MainForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose( bool disposing )
15 | {
16 | if( disposing && (components != null) )
17 | {
18 | Clear();
19 | components.Dispose();
20 | }
21 | base.Dispose( disposing );
22 | }
23 |
24 | #region Windows Form Designer generated code
25 |
26 | ///
27 | /// Required method for Designer support - do not modify
28 | /// the contents of this method with the code editor.
29 | ///
30 | private void InitializeComponent()
31 | {
32 | this._refreshButton = new System.Windows.Forms.Button();
33 | this._statusLabel = new System.Windows.Forms.Label();
34 | this._table = new System.Windows.Forms.TableLayoutPanel();
35 | this._directConnect = new System.Windows.Forms.Button();
36 | this.SuspendLayout();
37 | //
38 | // _refreshButton
39 | //
40 | this._refreshButton.Location = new System.Drawing.Point(12, 12);
41 | this._refreshButton.Name = "_refreshButton";
42 | this._refreshButton.Size = new System.Drawing.Size(75, 23);
43 | this._refreshButton.TabIndex = 1;
44 | this._refreshButton.Text = "Refresh";
45 | this._refreshButton.UseVisualStyleBackColor = true;
46 | this._refreshButton.Click += new System.EventHandler(this.OnRefreshButtonClick);
47 | //
48 | // _statusLabel
49 | //
50 | this._statusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
51 | | System.Windows.Forms.AnchorStyles.Right)));
52 | this._statusLabel.AutoSize = true;
53 | this._statusLabel.Location = new System.Drawing.Point(218, 17);
54 | this._statusLabel.Name = "_statusLabel";
55 | this._statusLabel.Size = new System.Drawing.Size(35, 13);
56 | this._statusLabel.TabIndex = 2;
57 | this._statusLabel.Text = "label1";
58 | //
59 | // _table
60 | //
61 | this._table.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
62 | | System.Windows.Forms.AnchorStyles.Left)
63 | | System.Windows.Forms.AnchorStyles.Right)));
64 | this._table.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.InsetDouble;
65 | this._table.ColumnCount = 2;
66 | this._table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
67 | this._table.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
68 | this._table.Location = new System.Drawing.Point(12, 41);
69 | this._table.Name = "_table";
70 | this._table.RowCount = 2;
71 | this._table.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
72 | this._table.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
73 | this._table.Size = new System.Drawing.Size(733, 427);
74 | this._table.TabIndex = 3;
75 | //
76 | // _directConnect
77 | //
78 | this._directConnect.Location = new System.Drawing.Point(93, 12);
79 | this._directConnect.Name = "_directConnect";
80 | this._directConnect.Size = new System.Drawing.Size(119, 23);
81 | this._directConnect.TabIndex = 4;
82 | this._directConnect.Text = "Direct connection...";
83 | this._directConnect.UseVisualStyleBackColor = true;
84 | this._directConnect.Click += new System.EventHandler(this.OnDirectConnectClick);
85 | //
86 | // MainForm
87 | //
88 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
89 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
90 | this.ClientSize = new System.Drawing.Size(757, 480);
91 | this.Controls.Add(this._directConnect);
92 | this.Controls.Add(this._table);
93 | this.Controls.Add(this._statusLabel);
94 | this.Controls.Add(this._refreshButton);
95 | this.Name = "MainForm";
96 | this.Text = "TSD API 2 Sample Application";
97 | this.ResumeLayout(false);
98 | this.PerformLayout();
99 |
100 | }
101 |
102 | #endregion
103 | private System.Windows.Forms.Button _refreshButton;
104 | private System.Windows.Forms.Label _statusLabel;
105 | private System.Windows.Forms.TableLayoutPanel _table;
106 | private System.Windows.Forms.Button _directConnect;
107 | }
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/Extracting1DElementData/MainForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 | using TSD.API.Remoting;
7 |
8 | namespace Extracting1DElementData
9 | {
10 | public partial class MainForm : Form
11 | {
12 | #region Fields
13 |
14 | private List _pages = new List();
15 |
16 | #endregion
17 |
18 | #region Constructors
19 |
20 | public MainForm()
21 | {
22 | InitializeComponent();
23 | UpdateStatus();
24 | }
25 |
26 | #endregion
27 |
28 | #region Overrides
29 |
30 | protected override void OnLoad( EventArgs e )
31 | {
32 | Clear();
33 | base.OnLoad( e );
34 | }
35 |
36 | #endregion
37 |
38 | #region Methods
39 |
40 | private void Clear()
41 | {
42 | foreach( var page in _pages.ToArray() )
43 | {
44 | RemovePage( page );
45 | }
46 |
47 | _pages.Clear();
48 | _table.RowCount = 0;
49 | _table.ColumnCount = 0;
50 | }
51 |
52 | private void UpdateStatus()
53 | {
54 | _statusLabel.Text = $"Found {_pages.Count} running TSD applications";
55 | }
56 |
57 | ///
58 | /// Enumerates running TSD instances and for each one adds application page
59 | ///
60 | ///
61 | private async Task FindApplicationsAsync()
62 | {
63 | foreach( var page in (await ApplicationFactory.GetRunningApplicationsAsync()).Select( app => new ApplicationPage( app ) ) )
64 | AddPage( page );
65 |
66 | UpdateStatus();
67 | }
68 |
69 | private void AddPage( ApplicationPage page )
70 | {
71 | _pages.Add( page );
72 | FillTable();
73 | page.Show();
74 | page.Disconnected += OnPageDisconnected;
75 | }
76 |
77 | private void RemovePage( ApplicationPage page )
78 | {
79 | page.Disconnected -= OnPageDisconnected;
80 | page.Dispose();
81 | _pages.Remove( page );
82 | FillTable();
83 | }
84 |
85 | private void FillTable()
86 | {
87 | _table.SuspendLayout();
88 | _table.ResumeLayout();
89 |
90 | int toPlace = Math.Min( 8, _pages.Count );
91 | _table.RowCount = toPlace > 2 ? 2 : 1;
92 | _table.ColumnCount = (int) Math.Ceiling( (double) toPlace / _table.RowCount );
93 |
94 | _table.Controls.Clear();
95 |
96 | for( int i = 0; i < toPlace; i++ )
97 | _table.Controls.Add( _pages[i] );
98 |
99 | _table.PerformLayout();
100 | }
101 |
102 | #endregion
103 |
104 | #region Event Handlers
105 |
106 | private async void OnRefreshButtonClick( object sender, EventArgs e )
107 | {
108 | _refreshButton.Enabled = false;
109 |
110 | Clear();
111 | await FindApplicationsAsync();
112 |
113 | _refreshButton.Enabled = true;
114 | }
115 |
116 | private async void OnDirectConnectClick( object sender, EventArgs e )
117 | {
118 | _directConnect.Enabled = false;
119 |
120 | using( var form = new ConnectionForm() )
121 | {
122 | if( form.ShowDialog() == DialogResult.OK )
123 | {
124 | var app = await ApplicationFactory.ConnectToRunningApplicationAsync( form.Host, form.Port );
125 |
126 | if( app != null )
127 | {
128 | AddPage( new ApplicationPage( app ) );
129 | UpdateStatus();
130 | }
131 | }
132 | }
133 |
134 | _directConnect.Enabled = true;
135 | }
136 |
137 | ///
138 | /// Removes disconnected page
139 | ///
140 | private void OnPageDisconnected( object sender, EventArgs e )
141 | {
142 | RemovePage( (ApplicationPage) sender );
143 | UpdateStatus();
144 | }
145 |
146 | #endregion
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/Extracting1DElementData/MainForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace Extracting1DElementData
5 | {
6 | static class Program
7 | {
8 | ///
9 | /// The main entry point for the application.
10 | ///
11 | [STAThread]
12 | static void Main()
13 | {
14 | Application.EnableVisualStyles();
15 | Application.SetCompatibleTextRenderingDefault( false );
16 | Application.Run( new MainForm() );
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | [assembly: ComVisible( false )]
4 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Extracting1DElementData.Properties {
12 | ///
13 | /// A strongly-typed resource class, for looking up localized strings, etc.
14 | ///
15 | // This class was auto-generated by the StronglyTypedResourceBuilder
16 | // class via a tool like ResGen or Visual Studio.
17 | // To add or remove a member, edit your .ResX file then rerun ResGen
18 | // with the /str option, or rebuild your VS project.
19 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
20 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
21 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
22 | internal class Resources {
23 |
24 | private static global::System.Resources.ResourceManager resourceMan;
25 |
26 | private static global::System.Globalization.CultureInfo resourceCulture;
27 |
28 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
29 | internal Resources() {
30 | }
31 |
32 | ///
33 | /// Returns the cached ResourceManager instance used by this class.
34 | ///
35 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
36 | internal static global::System.Resources.ResourceManager ResourceManager {
37 | get {
38 | if (object.ReferenceEquals(resourceMan, null)) {
39 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TsdApiRemotingSample.Properties.Resources", typeof(Resources).Assembly);
40 | resourceMan = temp;
41 | }
42 | return resourceMan;
43 | }
44 | }
45 |
46 | ///
47 | /// Overrides the current thread's CurrentUICulture property for all
48 | /// resource lookups using this strongly typed resource class.
49 | ///
50 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
51 | internal static global::System.Globalization.CultureInfo Culture {
52 | get {
53 | return resourceCulture;
54 | }
55 | set {
56 | resourceCulture = value;
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace TsdApiRemotingSample.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Extracting1DElementData/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ExtractingModelData/DataOutputFileCreator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace ExtractingModelData
7 | {
8 | internal static class DataOutputFileCreator
9 | {
10 | #region Constants
11 |
12 | internal const string OutputFileName = "TsdRemotingApiModelDataOutput.csv";
13 |
14 | #endregion
15 |
16 | #region Methods
17 |
18 | public static async Task OutputDataAsync( StringBuilder stringBuilder )
19 | {
20 | // Write the .csv file with the output data
21 | await File.WriteAllTextAsync( Path.Combine( Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments ), OutputFileName ), stringBuilder.ToString() );
22 |
23 | Console.WriteLine( "Results output complete" );
24 | }
25 |
26 | #endregion
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ExtractingModelData/ExtractingModelData.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | 7.3
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ExtractingModelData/OutputConnectionData.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Text;
3 | using System.Threading.Tasks;
4 | using TSD.API.Remoting.Structure;
5 |
6 | namespace ExtractingModelData
7 | {
8 | internal class OutputConnectionData
9 | {
10 | #region Methods
11 |
12 | public static async Task CreateConnectionDataOutputAsync( IModel model, StringBuilder stringBuilder )
13 | {
14 | stringBuilder.AppendLine(
15 | "Connection name," +
16 | "Connection type," +
17 | "X (mm)," +
18 | "Y (mm)," +
19 | "Z (mm)," +
20 | "Connected members," );
21 |
22 | var constructionPoints = (await model.GetConstructionPointsAsync()).ToList();
23 | var connections = await model.GetConnectionsAsync();
24 |
25 | foreach( var connection in connections )
26 | {
27 | var constructionPoint = constructionPoints.FirstOrDefault( c => c.Index == connection.ConstructionPointIndex.Value );
28 | var connectedMembers = await connection.GetConnectedMembersAsync();
29 |
30 | stringBuilder.AppendLine(
31 | $"{connection.Name}," +
32 | $"{connection.ConnectionType.Value}," +
33 | $"{constructionPoint?.Coordinates.Value.X}," +
34 | $"{constructionPoint?.Coordinates.Value.Y}," +
35 | $"{constructionPoint?.Coordinates.Value.Z}," +
36 | $"{string.Join( ", ", connectedMembers.Select( m => m.Name ) )}," );
37 | }
38 |
39 | stringBuilder.AppendLine( "" );
40 | }
41 |
42 | #endregion
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ExtractingModelData/OutputMemberData.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using TSD.API.Remoting.Common;
6 | using TSD.API.Remoting.Materials;
7 | using TSD.API.Remoting.Sections;
8 | using TSD.API.Remoting.Structure;
9 |
10 | namespace ExtractingModelData
11 | {
12 | internal class OutputMemberData
13 | {
14 | #region Methods
15 |
16 | public static async Task CreateMemberDataOutputAsync( IModel model, StringBuilder stringBuilder )
17 | {
18 | var members = (await model.GetMembersAsync()).ToList();
19 |
20 | await OutputMemberDataForMaterialAsync( model, members, stringBuilder, MaterialType.Steel );
21 | await OutputMemberDataForMaterialAsync( model, members, stringBuilder, MaterialType.Concrete );
22 | await OutputMemberDataForMaterialAsync( model, members, stringBuilder, MaterialType.Timber );
23 | }
24 |
25 | public static async Task OutputMemberDataForMaterialAsync( IModel model, IEnumerable members, StringBuilder stringBuilder, MaterialType materialType )
26 | {
27 | stringBuilder.AppendLine( $"{materialType} members" );
28 |
29 | stringBuilder.AppendLine(
30 | "Span name," +
31 | "Section," +
32 | "Material," +
33 | "Start X (mm)," +
34 | "Start Y (mm)," +
35 | "Start Z (mm)," +
36 | "End X (mm)," +
37 | "End Y (mm)," +
38 | "End Z (mm)," +
39 | "Ratio (Static)," +
40 | "Status (Static)," );
41 |
42 | var constructionPoints = (await model.GetConstructionPointsAsync()).ToList();
43 |
44 | var membersToReport = members.Where( m => m.Data.Value.MaterialType.Value == materialType && IsOutputMemberType( m.Data.Value.MemberType.Value ) );
45 |
46 | foreach( var member in membersToReport )
47 | {
48 | foreach( var span in await member.GetSpanAsync( new[] { 0, member.SpanCount.Value - 1 } ) )
49 | {
50 | var section = span.ElementSection.Value as IMemberSection;
51 | var startPoint = constructionPoints.First( c => c.Index == span.StartMemberNode.ConstructionPointIndex.Value );
52 | var endPoint = constructionPoints.First( c => c.Index == span.EndMemberNode.ConstructionPointIndex.Value );
53 |
54 | stringBuilder.AppendLine(
55 | $"{span.Name}," +
56 | $"{section?.PhysicalSection.Value.LongName}," +
57 | $"{span.Material.Value.Name}," +
58 | $"{startPoint.Coordinates.Value.X}," +
59 | $"{startPoint.Coordinates.Value.Y}," +
60 | $"{startPoint.Coordinates.Value.Z}," +
61 | $"{endPoint.Coordinates.Value.X}," +
62 | $"{endPoint.Coordinates.Value.Y}," +
63 | $"{endPoint.Coordinates.Value.Z}," +
64 | $"{span.CheckResults[CheckResultType.Static].Value.UtilizationRatio.Value}," +
65 | $"{span.CheckResults[CheckResultType.Static].Value.CheckStatus.Value}," );
66 | }
67 | }
68 |
69 | stringBuilder.AppendLine( string.Empty );
70 | }
71 |
72 | public static bool IsOutputMemberType( MemberType memberType ) => memberType != MemberType.WallBeamElement
73 | && memberType != MemberType.WallColumnElement
74 | && memberType != MemberType.WallMeshBeamElement
75 | && memberType != MemberType.BearingWallBeam
76 | && memberType != MemberType.BearingWallColumn;
77 |
78 | #endregion
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/ExtractingModelData/OutputSlabData.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Threading.Tasks;
3 | using TSD.API.Remoting.Structure;
4 |
5 | namespace ExtractingModelData
6 | {
7 | internal class OutputSlabData
8 | {
9 | #region Methods
10 |
11 | public static async Task CreateSlabDataOutputAsync( IModel model, StringBuilder stringBuilder )
12 | {
13 | var slabs = await model.GetSlabsAsync();
14 | var slabItems = await model.GetSlabItemsAsync();
15 |
16 | stringBuilder.AppendLine(
17 | "Slab name," +
18 | "Slab type," +
19 | "Material," );
20 |
21 | foreach( var slab in slabs )
22 | {
23 | stringBuilder.AppendLine(
24 | $"{slab.Name}," +
25 | $"{slab.SlabData.Value.SlabType.Value}," +
26 | $"{slab.SlabData.Value.Material.Value.Name}," );
27 | }
28 |
29 | stringBuilder.AppendLine();
30 |
31 | stringBuilder.AppendLine(
32 | "Slab item name," +
33 | "Slab depth (mm)," );
34 |
35 | foreach( var slabItem in slabItems )
36 | {
37 | stringBuilder.AppendLine(
38 | $"{slabItem.Name}," +
39 | $"{slabItem.SlabItemData.Value.Depth.Value}," );
40 | }
41 |
42 | stringBuilder.AppendLine();
43 | }
44 |
45 | #endregion
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ExtractingModelData/OutputWallData.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Threading.Tasks;
3 | using TSD.API.Remoting.Common;
4 | using TSD.API.Remoting.Structure;
5 |
6 | namespace ExtractingModelData
7 | {
8 | internal static class OutputWallData
9 | {
10 | #region Methods
11 |
12 | public static async Task CreateWallDataOutputAsync( IModel model, StringBuilder stringBuilder )
13 | {
14 | var walls = await model.GetStructuralWallsAsync();
15 |
16 | foreach( var wall in walls )
17 | {
18 | stringBuilder.AppendLine( $"Wall name:, {wall.Name}," );
19 |
20 | stringBuilder.AppendLine(
21 | "Panel number," +
22 | "Thickness (mm)," +
23 | "Material," +
24 | "Ratio (Static)," +
25 | "Status (Static)," );
26 |
27 | var panels = await wall.GetSpanAsync();
28 |
29 | foreach( var panel in panels )
30 | {
31 | stringBuilder.AppendLine(
32 | $"{panel.Index + 1}," +
33 | $"{panel.WallPanelData.Value.Thickness.Value}," +
34 | $"{panel.WallPanelData.Value.Material.Value.Name}," +
35 | $"{panel.CheckResults[CheckResultType.Static].Value.UtilizationRatio.Value}," +
36 | $"{panel.CheckResults[CheckResultType.Static].Value.CheckStatus.Value}," );
37 | }
38 |
39 | stringBuilder.AppendLine();
40 | }
41 | }
42 |
43 | #endregion
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ExtractingModelData/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Threading.Tasks;
4 | using TSD.API.Remoting;
5 |
6 | namespace ExtractingModelData
7 | {
8 | internal static class Program
9 | {
10 | public static async Task Main()
11 | {
12 | using( var tsdInstance = await ApplicationFactory.GetFirstRunningApplicationAsync() )
13 | {
14 | if( tsdInstance == null )
15 | {
16 | Console.WriteLine( "No running instances of TSD found!" );
17 |
18 | return;
19 | }
20 |
21 | Console.WriteLine( await tsdInstance.GetVersionStringAsync() );
22 |
23 | var document = await tsdInstance.GetDocumentAsync();
24 |
25 | if( document == null )
26 | {
27 | Console.WriteLine( "No document was found in the TSD instance!" );
28 |
29 | return;
30 | }
31 |
32 | var model = await document.GetModelAsync();
33 |
34 | var stringBuilder = new StringBuilder();
35 |
36 | await OutputMemberData.CreateMemberDataOutputAsync( model, stringBuilder );
37 | await OutputWallData.CreateWallDataOutputAsync( model, stringBuilder );
38 | await OutputSlabData.CreateSlabDataOutputAsync( model, stringBuilder );
39 | await OutputConnectionData.CreateConnectionDataOutputAsync( model, stringBuilder );
40 | await DataOutputFileCreator.OutputDataAsync( stringBuilder );
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/ExtractingResultsTableItem/ExtractingResultsTableItem.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | 7.3
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ExtractingResultsTableItem/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using TSD.API.Remoting;
5 | using TSD.API.Remoting.Structure;
6 |
7 | namespace ExtractingResultsTableItem
8 | {
9 | static class Program
10 | {
11 | [STAThread]
12 | public static async Task Main()
13 | {
14 | // Get the first running TSD instance found
15 | using( var tsdInstance = await ApplicationFactory.GetFirstRunningApplicationAsync() )
16 | {
17 | if( tsdInstance == null )
18 | {
19 | Console.WriteLine( "No running instances of TSD found!" );
20 |
21 | return;
22 | }
23 |
24 | // Output the version number of TSD
25 | Console.WriteLine( await tsdInstance.GetVersionStringAsync() );
26 |
27 | // Get the active document from the running instance of TSD
28 | var document = await tsdInstance.GetDocumentAsync();
29 |
30 | if( document == null )
31 | {
32 | Console.WriteLine( "No document was found in the TSD instance!" );
33 |
34 | return;
35 | }
36 |
37 | // Get the model from the document
38 | var model = await document.GetModelAsync();
39 |
40 | if( model == null )
41 | {
42 | Console.WriteLine( "No model was found in the document!" );
43 |
44 | return;
45 | }
46 |
47 | var member = await GetMemberForOutput( model );
48 |
49 | if( member == null )
50 | {
51 | Console.WriteLine( "No member found." );
52 |
53 | return;
54 | }
55 |
56 | var lineItemString = GetLineItemStringFromUserInput();
57 |
58 | var resultValuesOutputter = new ResultsValuesOutputter( member, lineItemString, tsdInstance );
59 | await resultValuesOutputter.Output();
60 |
61 | Console.ReadLine();
62 | }
63 | }
64 |
65 | private static async Task GetMemberForOutput( IModel model )
66 | {
67 | var members = await model.GetMembersAsync();
68 |
69 | IMember member = null;
70 |
71 | do
72 | {
73 | Console.WriteLine( "Enter member reference:" );
74 |
75 | string memberName = Console.ReadLine();
76 |
77 | member = members.FirstOrDefault( m => m.Name == memberName );
78 |
79 | if( member == null )
80 | {
81 | Console.WriteLine( "Member named " + memberName + " not found" );
82 | }
83 | } while( member == null );
84 |
85 | return member;
86 | }
87 |
88 | private static string GetLineItemStringFromUserInput()
89 | {
90 | string lineItemString;
91 |
92 | do
93 | {
94 | Console.WriteLine( "Enter string to use for results table search:" );
95 | lineItemString = Console.ReadLine();
96 | } while( lineItemString.Length == 0 );
97 |
98 | return lineItemString;
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/ExtractingResultsTableItem/ResultsValuesOutputter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using TSD.API.Remoting;
6 | using TSD.API.Remoting.Common;
7 | using TSD.API.Remoting.Report;
8 | using TSD.API.Remoting.Structure;
9 | using TSD.API.Remoting.Units;
10 |
11 | namespace ExtractingResultsTableItem
12 | {
13 | public class ResultsValuesOutputter
14 | {
15 | #region Constructors
16 |
17 | public ResultsValuesOutputter( IMember member, string lineItemString, IApplication tsdInstance )
18 | {
19 | LineItemString = lineItemString;
20 | Member = member;
21 | UnitConverter = tsdInstance.UnitConverter;
22 | }
23 |
24 | #endregion
25 |
26 | #region Properties
27 |
28 | private string LineItemString { get; }
29 |
30 | private IMember Member { get; }
31 |
32 | private IUnitConverter UnitConverter { get; }
33 |
34 | #endregion
35 |
36 | #region Methods
37 |
38 | public async Task Output()
39 | {
40 | var results = await Member.GetCalculationsAsync( CheckResultType.Static );
41 |
42 | await ProcessCalculationsNodeList( results.Nodes, "" );
43 | await ProcessItems( results.Items, "" );
44 | }
45 |
46 | private async Task ProcessCalculationsNodeList( IReadOnlyList nodes, string hierarchyString )
47 | {
48 | if( !nodes.Any() )
49 | {
50 | return;
51 | }
52 |
53 | foreach( var node in nodes )
54 | {
55 | string hierarchyStringNode = hierarchyString + " > " + node.Name;
56 |
57 | await ProcessCalculationsNodeList( node.Nodes, hierarchyStringNode );
58 | await ProcessItems( node.Items, hierarchyStringNode );
59 | }
60 | }
61 |
62 | private async Task ProcessItems( IReadOnlyList items, string hierarchyString )
63 | {
64 | if( !items.Any() )
65 | return;
66 |
67 | foreach( var item in items )
68 | {
69 | await ProcessItem( item, hierarchyString );
70 | }
71 | }
72 |
73 | private async Task ProcessItem( IReportItem item, string hierarchyString )
74 | {
75 | if( item is IReportTable table )
76 | {
77 | await ProcessTable( table, hierarchyString );
78 | }
79 | }
80 |
81 | private async Task ProcessTable( IReportTable table, string hierarchyString )
82 | {
83 | foreach( var line in table.Lines )
84 | {
85 | await ProcessLine( line, hierarchyString );
86 | }
87 | }
88 |
89 | private async Task ProcessLine( IReportTableLine line, string hierarchyString )
90 | {
91 | if( line.Table != null )
92 | {
93 | await ProcessTable( line.Table, hierarchyString );
94 | }
95 |
96 | var item = line.Items.FirstOrDefault( i => i is IReportTableLineItemText || i is IReportTableLineItemCombined );
97 |
98 | if( item != null )
99 | {
100 | string text = "";
101 |
102 | if( item is IReportTableLineItemText textItem )
103 | text = textItem.Text;
104 | else if( item is IReportTableLineItemCombined combinedItem )
105 | text = combinedItem.Text;
106 |
107 | if( !text.Contains( LineItemString ) )
108 | {
109 | return;
110 | }
111 |
112 | // Text matches that being searched for! Output the result value.
113 | await OutputResultValue( line, hierarchyString );
114 | }
115 | }
116 |
117 | private async Task OutputResultValue( IReportTableLine line, string hierarchyString )
118 | {
119 | // Assume we are looking for a line that contains just one value and one quantity
120 | double value = 0.0;
121 | Quantity quantity = Quantity.Unknown;
122 | string text = "";
123 | bool textFound, valueFound, quantityFound;
124 | textFound = valueFound = quantityFound = false;
125 | foreach( var item in line.Items )
126 | {
127 | if( !textFound )
128 | {
129 | if( item is IReportTableLineItemCombined combinedItem )
130 | {
131 | text = combinedItem.Text;
132 | textFound = true;
133 | }
134 | else if( item is IReportTableLineItemText textItem )
135 | {
136 | text = textItem.Text;
137 | textFound = true;
138 | }
139 | }
140 |
141 | if( !valueFound )
142 | {
143 | if( item is IReportTableLineItemCombined combinedItem )
144 | {
145 | value = combinedItem.Value;
146 | valueFound = true;
147 | }
148 | else if( item is IReportTableLineItemDoubleValue doubleItem )
149 | {
150 | value = doubleItem.Value;
151 | valueFound = true;
152 | }
153 | else if( item is IReportTableLineItemLongValue longItem )
154 | {
155 | value = longItem.Value;
156 | valueFound = true;
157 | }
158 | }
159 |
160 | if( !quantityFound )
161 | {
162 | if( item is IReportTableLineItemCombined combinedItem )
163 | {
164 | quantity = combinedItem.Quantity;
165 | quantityFound = true;
166 | }
167 | else if( item is IReportTableLineItemQuantity quantityItem )
168 | {
169 | quantity = quantityItem.Quantity;
170 | quantityFound = true;
171 | }
172 | }
173 | }
174 |
175 | if( !valueFound || !quantityFound )
176 | {
177 | // Not a valid value to output
178 | return;
179 | }
180 |
181 | var units = await UnitConverter.GetUnitsAsync( quantity, SystemType.Metric );
182 | var unit = units.First();
183 |
184 | if( unit != null )
185 | {
186 | Console.WriteLine( hierarchyString );
187 |
188 | Console.WriteLine( $"\t{text} {(await UnitConverter.FromBaseAsync( new[] { value }, unit )).First()} [{unit.Name}]" );
189 | }
190 | }
191 |
192 | #endregion
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/ExtractingSteelBeamData/ExtractingSteelBeamData.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net6.0
6 | 7.3
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, Trimble Solutions Corporation
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/PythonNetExperiment/Program.cs:
--------------------------------------------------------------------------------
1 | Console.WriteLine( "Hello, from donor C# executable project!" );
2 | Console.WriteLine( "This is here to provide resolution of nuget dependencies and obtain assemblies for the Python project." );
3 |
--------------------------------------------------------------------------------
/PythonNetExperiment/PythonNetExperiment.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net8.0
6 | enable
7 | enable
8 | PythonNugetFetcher
9 | latestmajor
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PythonNetExperiment/PythonNetExperiment.py:
--------------------------------------------------------------------------------
1 | from pythonnet import load
2 | load("coreclr")
3 |
4 | import clr
5 | import sys
6 | import time
7 |
8 | # Add the directory where your DLLs are located
9 | project_dir = r'.\bin\Debug\net8.0' # Adjust as needed
10 | sys.path.append(project_dir)
11 |
12 | # Load the .NET assembly
13 | clr.AddReference("System")
14 | clr.AddReference("TSD.API.Remoting")
15 |
16 | # Import the .NET namespace and types
17 | import TSD.API.Remoting as TSD
18 | from System.Collections.Generic import List
19 |
20 | # Connect to TSD instance and start interacting with API to get the model
21 | instance = TSD.ApplicationFactory.GetFirstRunningApplicationAsync().Result
22 | isConnected = instance.Connected
23 | document = instance.GetDocumentAsync().Result
24 | model = document.GetModelAsync().Result
25 |
26 | # Get the name of the entity based on the entity type and index
27 | def get_entity_name(entity_type, index):
28 | index_dotnet_list = List[int]()
29 | index_dotnet_list.Add(index)
30 |
31 | switcher = {
32 | TSD.Common.EntityType.Connection: model.GetConnectionsAsync(index_dotnet_list).Result,
33 | TSD.Common.EntityType.Member: model.GetMembersAsync(index_dotnet_list).Result,
34 | }
35 |
36 | response = switcher.get(entity_type, None)
37 |
38 | if response is None:
39 | return f"Entity type {entity_type} is not supported"
40 |
41 | return list(response)[0].Name
42 |
43 | # Define event handler for selection change event in TSD
44 | def selection_event_handler(sender, event_args):
45 | selection = model.GetSelectedEntitiesAsync().Result
46 |
47 | filtered = []
48 | filtered.extend(filter( (lambda item: hasattr(item, 'Entity') ), selection ))
49 |
50 | for item in filtered:
51 | itemName = get_entity_name(item.Entity.Type, item.Entity.Index)
52 | print(f'Selected item: {item.Entity.Type}, Index: {item.Entity.Index}, Name: {itemName}')
53 |
54 | instance.SelectionChanged += selection_event_handler
55 |
56 | # Print the TSD data
57 | print('Is Connected: ', isConnected)
58 | print('TSD version: ', instance.GetVersionStringAsync().Result)
59 | print('Model Id: ', document.ModelId)
60 |
61 | while True:
62 | time.sleep(1)
63 | # read terminal input if "exit" then close
64 | if input() == "exit":
65 | break
66 |
--------------------------------------------------------------------------------
/PythonNetExperiment/PythonNetExperiment.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.002.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PythonNetExperiment", "PythonNetExperiment.csproj", "{D1851BA4-212D-4D32-BCAB-BC2F81BB5777}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {D1851BA4-212D-4D32-BCAB-BC2F81BB5777}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {D1851BA4-212D-4D32-BCAB-BC2F81BB5777}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {D1851BA4-212D-4D32-BCAB-BC2F81BB5777}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {D1851BA4-212D-4D32-BCAB-BC2F81BB5777}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {43A602FA-083F-43F5-B1A0-E90D51E49CC8}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/PythonNetExperiment/TsdApiPythonGuide.md:
--------------------------------------------------------------------------------
1 | # Tekla Structural Designer API from Python
2 |
3 | This is a short guide for an experiment using TSD API from Python.
4 | The goal is to connect to running TSD Application and demonstrate we can retrieve some data from it.
5 | The focus here is on all the path finding and dependencies needed in order to get this working.
6 | The author of this guide has a very limited knowledge of Python.
7 |
8 | ## Introduction
9 |
10 | Tekla Structural Designer (TSD) provides a nuget package TeklaStructuralDesigner.RemotingAPI which is intended to be used from a .NET environment.
11 | In order to use this from Python, we need to use a .NET bridge. This means we will need .NET SDK to download the TeklaStructuralDesigner.RemotingAPI nuget package
12 | and its dependencies and then use the bridge to access the API from Python. To demonstrate this is possible I've prepared a simple example this mixed PythonNetExample project.
13 |
14 | ## Prerequisites
15 | - Tekla Structural Designer installed
16 | - Visual Studio Code
17 | - .NET SDK 8.0 or later
18 | - Python 3
19 |
20 | ## Steps
21 |
22 | 1. Install .NET SDK
23 | 2. Install PythonNet
24 | 3. Build the C# donor project
25 | 4. Run TSD open a model and run the Python script
26 |
27 | ### Install .NET SDK
28 | This can be done in Visual Studio Code via the **.NET Install Tool** extension. Just search for it in the extensions and install it.
29 |
30 | ### Install PythonNet
31 | This can be done via pip:
32 | ```bash
33 | pip install pythonnet
34 | ```
35 |
36 | ### Build the C# donor project
37 | This can be done from command line just navigate to the directory where the PythonNetExperiment project is extracted and run:
38 |
39 | ```bash
40 | dotnet build
41 | ```
42 | This will download the TeklaStructuralDesigner.RemotingAPI nuget package and its dependencies. You will be able to find all the dlls in the project target subfolder.
43 | This is from where pythonnet will load the .NET assemblies. You can see that when the script sets `project_dir` variable.
44 |
45 | ```bash
46 | \PythonNetExperiment\bin\Debug\net8.0
47 | ```
48 |
49 | ### Run TSD open a model and run the Python script
50 | Open Tekla Structural Designer and open any model. Then run the Python script from the extracted location. This will connect to the running TSD application and retrieve some data from it.
51 |
52 | ```bash
53 | python PythonNetExperiment.py
54 | ```
55 | The expected output looks similar to this one, given some selection in the TSD 3D view was made by the user:
56 |
57 | ```bash
58 | $ python PythonNetExperiment.py
59 |
60 | Event listening start!
61 | Is Connected: True
62 | TSD version: 24.2.0.29
63 | Model Id: 890404f0-3646-4ddc-b8b9-3712ebc99997
64 | Selected item: Member, Index: 94, Name: SB Level 2/10/19-Level 2/10/20
65 | Selected item: Connection, Index: 48, Name: SCC 10/19
66 | Selected item: Member, Index: 77, Name: SGP 10/19
67 | Selected item: ConstructionHelper, Index: 16, Name: Entity type ConstructionHelper is not supported
68 |
69 | exit
70 | ```
71 |
72 | ## Conclusion
73 | This proves that it is possible to access the TSD API from Python using PythonNet. This is a simple example and there are many more possibilities to explore.
74 | The current example blocks and waits synchronously for TSD API to finish its work. This example also does not build any conversions between .NET and Python collections it copies the values explicitly.
75 |
76 | It is important to take away that a C# project referencing the TeklaStructuralDesigner.RemotingAPI nuget package is needed to act as a donor for the Python script.
77 | The C# project can otherwise be left empty.
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TSDRemotingAPIExamples
2 | Tekla Structural Designer Remoting API Examples
3 |
4 | ## Examples
5 |
6 | * **ExtractingSteelBeamData**
7 | This project shows how to use TSD Remoting API from a command line application to export steel beam data to a .csv file.
8 | * **Extracting1DElementData**
9 | This project shows how to use TSD Remoting API from a WinForms application to export 1D element data to an excel file.
10 | * **CreatingAndAnalyzingModel**
11 | This project shows how to use TSD Remoting API from a command line application to create a multi-material model, add loading, run analysis, and extract analysis results to a .csv file.
12 | The example is designed to work with an empty model set to an EC regional code, as it sets materials in entities to EC materials.
13 | * **ExtractingDesignResults**
14 | This project shows how to use TSD Remoting API from a command line application to find values from the results tables for a given member by inputting text that will be used to search for lines in the results tables where that text appears.
15 | * **ExtractingModelData**
16 | This project shows how to use TSD Remoting API from a command line application to export data for members, walls, slabs and connections to a .csv file.
17 | * **ReactingToSelection**
18 | This project shows how to use TSD Remoting API from a WPF application that reacts to seletion in TSD displaying details about selected connections.
19 | * **PythonNetExperiment**
20 | This experimental project shows how to use TSD Remoting API from a Python application. It uses PythonNet to access the API.
21 | * **ExportingFireCheckDataToUDA**
22 | This project shows how to use TSD Remoting API from a command line application to export fire check data and set them as User Defined Attributes (UDA) for steel beams and columns.
23 |
24 | ## Compatibility
25 |
26 | These examples use TeklaStructuralDesigner.RemotingAPI version 25.0.1 and are compatible with Tekla Structural Designer 2025 Service Pack 1.
27 |
--------------------------------------------------------------------------------
/ReactingToSelection/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/ReactingToSelection/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection;
2 |
3 | ///
4 | /// Represents the entry point of the application
5 | ///
6 | public partial class App;
7 |
--------------------------------------------------------------------------------
/ReactingToSelection/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/ListWithNotify.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Specialized;
2 | using System.Windows.Threading;
3 |
4 | namespace ReactingToSelection.Helpers;
5 |
6 | ///
7 | /// Represents collection based on with rudimentary implementation
8 | ///
9 | /// The type of collection item
10 | public class ListWithNotify : List
11 | , INotifyCollectionChanged
12 | {
13 | #region Nested Types
14 |
15 | public enum NotificationType
16 | {
17 | None,
18 | Asynchronous,
19 | Synchronous,
20 | }
21 |
22 | #endregion
23 |
24 | #region Fields
25 |
26 | ///
27 | /// The dispatcher to use
28 | ///
29 | private readonly Dispatcher? _dispatcher = Dispatcher.FromThread( Thread.CurrentThread );
30 |
31 | #endregion
32 |
33 | #region Constructors
34 |
35 | ///
36 | /// Creates a new instance of class
37 | ///
38 | public ListWithNotify()
39 | {
40 | // Intentionally left blank
41 | }
42 |
43 | ///
44 | /// Creates a new instance of class
45 | ///
46 | /// The items to fill the list with
47 | public ListWithNotify( IEnumerable items )
48 | : base( items )
49 | {
50 | // Intentionally left blank
51 | }
52 |
53 | #endregion
54 |
55 | #region Methods
56 |
57 | ///
58 | /// Raises the event
59 | ///
60 | /// Value indicating how the notification should be raised
61 | private void RaiseCollectionChanged( NotificationType notificationType )
62 | {
63 | switch( notificationType )
64 | {
65 | case NotificationType.Asynchronous:
66 | (_dispatcher ?? System.Windows.Application.Current.Dispatcher).InvokeAsync( () => RaiseCollectionChanged( NotificationType.Synchronous ) );
67 |
68 | break;
69 |
70 | case NotificationType.Synchronous:
71 | CollectionChanged?.Invoke( this, new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset ) );
72 |
73 | break;
74 |
75 | case NotificationType.None:
76 | break;
77 |
78 | default:
79 | throw new InvalidOperationException( "Unsupported notification type" );
80 | }
81 | }
82 |
83 | ///
84 | /// Replaces all items in collection with the provided items and raises event
85 | ///
86 | /// Collection of items to replace the content of this collection
87 | /// Value indicating how the notification should be raised
88 | public void ReplaceContentAndNotify( IEnumerable newContent, NotificationType notificationType = NotificationType.Asynchronous )
89 | {
90 | Clear();
91 | AddRange( newContent );
92 |
93 | RaiseCollectionChanged( notificationType );
94 | }
95 |
96 | #endregion
97 |
98 | #region INotifyCollectionChanged
99 |
100 | public event NotifyCollectionChangedEventHandler? CollectionChanged;
101 |
102 | #endregion
103 | }
104 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/ReadOnlyPropertyExtensions.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Common.Properties;
2 |
3 | namespace ReactingToSelection.Helpers;
4 |
5 | ///
6 | /// Contains extension methods for the interface
7 | ///
8 | public static class ReadOnlyPropertyExtensions
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Returns the value of this property or the given default value in case the property is not applicable
14 | ///
15 | /// The property to get value of
16 | /// The default value to use in case the property is not applicable
17 | /// The type of value stored in the property
18 | public static TValue? GetValueOrDefault( this IReadOnlyProperty? property, TValue? defaultValue = default )
19 | => property is { IsApplicable: true } ? property.Value : defaultValue;
20 |
21 | #endregion
22 | }
23 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/RelayCommand.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Input;
2 |
3 | namespace ReactingToSelection.Helpers;
4 |
5 | ///
6 | /// Represents a command
7 | ///
8 | /// The action to invoke
9 | internal class RelayCommand( Action action ) : ICommand
10 | {
11 | #region ICommand
12 |
13 | public bool CanExecute( object? parameter ) => true;
14 |
15 | public void Execute( object? parameter )
16 | {
17 | action();
18 | }
19 |
20 | event EventHandler? ICommand.CanExecuteChanged
21 | {
22 | add
23 | {
24 | // Intentionally left blank
25 | }
26 | remove
27 | {
28 | // Intentionally left blank
29 | }
30 | }
31 |
32 | #endregion
33 | }
34 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/TaskExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Helpers;
2 |
3 | ///
4 | /// Contains extension methods for the class
5 | ///
6 | public static class TaskExtensions
7 | {
8 | #region Methods
9 |
10 | ///
11 | /// Provides a safe way to call asynchronous method without waiting for it's result
12 | ///
13 | /// The task to be run
14 | public static async void FireAndForgetSafeAsync( this Task task )
15 | {
16 | try
17 | {
18 | await task;
19 | }
20 | catch( Exception )
21 | {
22 | // Intentionally ignored
23 | }
24 | }
25 |
26 | #endregion
27 | }
28 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/UiHelpers.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Common;
2 | using TSD.API.Remoting.Common.Properties;
3 |
4 | namespace ReactingToSelection.Helpers;
5 |
6 | ///
7 | /// Contains helper methods for UI
8 | ///
9 | internal static class UiHelpers
10 | {
11 | #region Methods
12 |
13 | ///
14 | /// Returns the display string for the given property
15 | ///
16 | /// The property to get display string of.
17 | /// The type of the property value
18 | /// The display string for the given property
19 | internal static string GetDisplayString( this IReadOnlyProperty? property )
20 | {
21 | if( property is not { IsApplicable: true } )
22 | return "-";
23 |
24 | return property.Value switch
25 | {
26 | int integer => integer.ToString(),
27 | double number => GetDisplayString( number ),
28 | string text => text,
29 | IHaveName namedObject => namedObject.Name,
30 | _ => property.Value?.ToString() ?? "null"
31 | };
32 | }
33 |
34 | ///
35 | /// Returns the display string for the given double value
36 | ///
37 | /// The value to get display string of
38 | /// The display string for the given double value
39 | public static string GetDisplayString( double? value ) => value?.ToString( "F2" ) ?? string.Empty;
40 |
41 | #endregion
42 | }
43 |
--------------------------------------------------------------------------------
/ReactingToSelection/Helpers/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace ReactingToSelection.Helpers;
4 |
5 | ///
6 | /// Contains the base implementation of the interface
7 | ///
8 | public abstract class ViewModelBase : INotifyPropertyChanged
9 | {
10 | #region Methods
11 |
12 | ///
13 | /// Sets the property value and raises event (if the new value differs from the old one)
14 | ///
15 | /// The type of the property
16 | /// The name of the property to raise the notification event for
17 | /// The backing field for the property
18 | /// The new value to set
19 | /// An optional action to perform after raising the notification event
20 | /// when was different from the
21 | protected void SetProperty( string name, ref T field, T newValue, Action? action = null )
22 | => SetPropertyInternal( name, ref field, newValue, OnPropertyChanged, action );
23 |
24 | ///
25 | /// Sets the property value and raises event (if the new value differs from the old one)
26 | ///
27 | /// The type of the property
28 | /// The name of the property to raise the notification event for
29 | /// The backing field for the property
30 | /// The new value to set
31 | /// The action to use for raising the event
32 | /// An optional action to perform after raising the notification event
33 | /// when was different from the
34 | private static void SetPropertyInternal( string name, ref T field, T newValue, Action propertyChangedNotifier, Action? action = null )
35 | {
36 | if( Equals( field, newValue ) )
37 | return;
38 |
39 | field = newValue;
40 |
41 | propertyChangedNotifier.Invoke( name );
42 |
43 | action?.Invoke();
44 | }
45 |
46 | ///
47 | /// Reacts to change of given property
48 | ///
49 | /// The name of the property that was changed
50 | protected void OnPropertyChanged( string name )
51 | {
52 | PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( name ) );
53 | }
54 |
55 | #endregion
56 |
57 | #region INotifyPropertyChanged
58 |
59 | public event PropertyChangedEventHandler? PropertyChanged;
60 |
61 | #endregion
62 | }
63 |
--------------------------------------------------------------------------------
/ReactingToSelection/Models/ConnectionFetcher.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Common;
2 | using TSD.API.Remoting.Common.Interfaces;
3 | using TSD.API.Remoting.Connections;
4 | using TSD.API.Remoting.Loading;
5 | using TSD.API.Remoting.Solver;
6 | using TSD.API.Remoting.Structure;
7 |
8 | namespace ReactingToSelection.Models;
9 |
10 | ///
11 | /// Represents a class that fetches connection details
12 | ///
13 | public static class ConnectionFetcher
14 | {
15 | #region Methods
16 |
17 | ///
18 | /// Returns the selected connections
19 | ///
20 | public static async Task> GetSelectedConnectionsAsync()
21 | {
22 | var selection = await Model.Instance.GetSelectedEntitiesAsync();
23 |
24 | var connectionIndices = selection
25 | .OfType()
26 | .Where( x => x.Entity.Type == EntityType.Connection )
27 | .Select( e => e.Entity.Index )
28 | .ToList();
29 |
30 | if( connectionIndices.Count == 0 )
31 | return Enumerable.Empty();
32 |
33 | return await Model.Instance.GetConnectionsAsync( connectionIndices );
34 | }
35 |
36 | ///
37 | /// Returns the connected members of the connection
38 | ///
39 | /// The connection to fetch connected members of
40 | public static Task> GetConnectedMembersAsync( IConnection connection ) => connection.GetConnectedMembersAsync();
41 |
42 | ///
43 | /// Returns the support reaction of the connection
44 | ///
45 | /// The connection to fetch support reaction of
46 | public static async Task GetSupportReactionAsync( IConnection connection )
47 | {
48 | var combination = (await Model.Instance.GetCombinationsAsync()).First();
49 | var constructionPoint = (await Model.Instance.GetConstructionPointsAsync( [connection.ConstructionPointIndex.Value] )).First();
50 | int solverNodeIndex = (await Model.Instance.GetConstructionPointGroupsAsync( [constructionPoint.GroupIndex.Value] )).First().SolverNodeIndex.Value;
51 | var solverNode = (await (await Model.Instance.GetSolverModelsAsync( [AnalysisType.FirstOrderLinear] )).First().GetNodesAsync( [solverNodeIndex] )).First();
52 |
53 | return await solverNode.GetSupportReactionAsync( combination.Id, reduceAxialLoad: false );
54 | }
55 |
56 | #endregion
57 | }
58 |
--------------------------------------------------------------------------------
/ReactingToSelection/Models/MemberSpanFetcher.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Connections;
2 | using TSD.API.Remoting.Loading;
3 | using TSD.API.Remoting.Solver;
4 | using TSD.API.Remoting.Structure;
5 |
6 | namespace ReactingToSelection.Models;
7 |
8 | ///
9 | /// Represents a class that fetches member span details
10 | ///
11 | public static class MemberSpanFetcher
12 | {
13 | #region Methods
14 |
15 | ///
16 | /// Returns the connected member details
17 | ///
18 | /// The connection to fetch connected member details of
19 | /// The member to fetch connected member details of
20 | /// The loading case to fetch connected member details of
21 | /// The analysis type to fetch connected member details of
22 | public static async Task<(ISpanReleases Releases, IForce3DLocal? EndForce)?> GetConnectedMemberDetailsAsync( IConnection connection, IMember member,
23 | ILoadingCase loadingCase, AnalysisType analysisType )
24 | {
25 | int connectionConstructionPointIndex = connection.ConstructionPointIndex.Value;
26 | var spans = await member.GetSpanAsync();
27 |
28 | foreach( var span in spans )
29 | {
30 | int startConstructionPointIndex = span.StartMemberNode.ConstructionPointIndex.Value;
31 | int endConstructionPointIndex = span.EndMemberNode.ConstructionPointIndex.Value;
32 |
33 | if( connectionConstructionPointIndex == startConstructionPointIndex )
34 | return (span.StartReleases.Value, await span.GetEndForceAsync( 0, analysisType, loadingCase.Id, LoadingResultType.Base ));
35 |
36 | if( connectionConstructionPointIndex == endConstructionPointIndex )
37 | return (span.EndReleases.Value, await span.GetEndForceAsync( 1, analysisType, loadingCase.Id, LoadingResultType.Base ));
38 |
39 | var constructionPoints = await Model.Instance.GetConstructionPointsAsync( [connectionConstructionPointIndex, startConstructionPointIndex, endConstructionPointIndex] );
40 | var groupIndices = constructionPoints.Select( cp => cp.GroupIndex ).ToList();
41 |
42 | if( groupIndices[0].Value == groupIndices[1].Value )
43 | return (span.StartReleases.Value, await span.GetEndForceAsync( 0, analysisType, loadingCase.Id, LoadingResultType.Base ));
44 |
45 | if( groupIndices[0].Value == groupIndices[2].Value )
46 | return (span.EndReleases.Value, await span.GetEndForceAsync( 1, analysisType, loadingCase.Id, LoadingResultType.Base ));
47 | }
48 |
49 | return null;
50 | }
51 |
52 | #endregion
53 | }
54 |
--------------------------------------------------------------------------------
/ReactingToSelection/Models/Model.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Structure;
2 |
3 | namespace ReactingToSelection.Models;
4 |
5 | ///
6 | /// Represents a class that holds reference to the currently active model
7 | ///
8 | public static class Model
9 | {
10 | #region Fields
11 |
12 | ///
13 | /// The currently active model
14 | ///
15 | private static IModel? _instance;
16 |
17 | #endregion
18 |
19 | #region Properties
20 |
21 | ///
22 | /// Gets the currently active model
23 | ///
24 | /// Throws in case the model is not fetched
25 | public static IModel Instance => _instance ?? throw new InvalidOperationException( "There is no active model!" );
26 |
27 | #endregion
28 |
29 | #region Methods
30 |
31 | ///
32 | /// Fetches the currently opened model of given document
33 | ///
34 | /// The document to fetch currently opened model of
35 | public static async Task FetchModelAsync( TSD.API.Remoting.Document.IDocument document )
36 | {
37 | var model = await document.GetModelAsync();
38 |
39 | _instance = model;
40 | }
41 |
42 | #endregion
43 | }
44 |
--------------------------------------------------------------------------------
/ReactingToSelection/ReactingToSelection.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net7.0-windows
6 | latest
7 | enable
8 | enable
9 | true
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/AnchorPlate.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class AnchorPlate( IAnchorPlate? anchorPlate ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public string PlateType { get; } = (anchorPlate?.Type).GetDisplayString();
11 |
12 | public string Width { get; } = (anchorPlate?.Width).GetDisplayString();
13 |
14 | public string Thickness { get; } = (anchorPlate?.Thickness).GetDisplayString();
15 |
16 | public string Length { get; } = (anchorPlate?.Length).GetDisplayString();
17 |
18 | public string EdgeDistance { get; } = (anchorPlate?.EdgeDistance).GetDisplayString();
19 |
20 | #endregion
21 | }
22 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlate.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 | using TSD.API.Remoting.Loading;
4 |
5 | namespace ReactingToSelection.ViewModels;
6 |
7 | public class BasePlate( IBasePlate basePlate, IForce3DGlobal supportReaction ) : ConnectionDetails
8 | {
9 | #region Properties
10 |
11 | public BasePlateProperties Properties { get; } = new( basePlate );
12 |
13 | public BasePlateConcreteData ConcreteData { get; } = new( basePlate.ConcreteData.GetValueOrDefault() );
14 |
15 | public BasePlateBoltData BoltData { get; } = new( basePlate.BoltData.GetValueOrDefault() );
16 |
17 | public BasePlateBoltLayout? BoltLayout { get; } = BasePlateBoltLayout.Create( basePlate.BoltLayout.GetValueOrDefault() );
18 |
19 | public BasePlateWelds Welds { get; } = new( basePlate.Welds.GetValueOrDefault() );
20 |
21 | public WeldedWasher WeldedWasher { get; } = new( basePlate.WeldedWasher.GetValueOrDefault() );
22 |
23 | public SupportReaction SupportReaction { get; } = new( supportReaction );
24 |
25 | #endregion
26 | }
27 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateAsymmetricBoltLayout.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateAsymmetricBoltLayout( IBasePlateAsymmetricBoltLayout layout ) : BasePlateBoltLayout
7 | {
8 | #region Properties
9 |
10 | public BasePlateBoltLayout? FlangeA { get; } = Create( layout.FlangeA.GetValueOrDefault() );
11 |
12 | public BasePlateBoltLayout? FlangeC { get; } = Create( layout.FlangeC.GetValueOrDefault() );
13 |
14 | #endregion
15 | }
16 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateBoltData.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateBoltData( IBasePlateBoltData? data ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public Bolt? Bolt { get; } = Bolt.Create( data?.Bolt.GetValueOrDefault() );
11 |
12 | public string BoltGrade { get; } = (data?.Grade).GetDisplayString();
13 |
14 | public string Length { get; } = (data?.Length).GetDisplayString();
15 |
16 | public string ProjectionAbovePlate { get; } = (data?.ProjectionAbovePlate).GetDisplayString();
17 |
18 | public string EmbeddedDepth { get; } = (data?.EmbeddedDepth).GetDisplayString();
19 |
20 | public AnchorPlate AnchorPlate { get; } = new( data?.AnchorPlate.GetValueOrDefault() );
21 |
22 | #endregion
23 | }
24 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateBoltLayout.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public abstract class BasePlateBoltLayout : ViewModelBase
7 | {
8 | #region Methods
9 |
10 | public static BasePlateBoltLayout? Create( IBasePlateBoltLayout? layout ) => layout switch
11 | {
12 | IBasePlateFourBoltLayout fourBoltLayout => new BasePlateFourBoltLayout( fourBoltLayout ),
13 | IBasePlateSymmetricBoltLayout symmetricBoltLayout => new BasePlateSymmetricBoltLayout( symmetricBoltLayout ),
14 | IBasePlateAsymmetricBoltLayout asymmetricBoltLayout => new BasePlateAsymmetricBoltLayout( asymmetricBoltLayout ),
15 | null => null,
16 | _ => throw new InvalidOperationException( $"Unexpected type of base plate bolt layout {layout.GetType().Name} encountered!" )
17 | };
18 |
19 | #endregion
20 | }
21 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateConcreteData.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateConcreteData( IBasePlateConcreteData? data ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public string Width { get; } = (data?.Width).GetDisplayString();
11 |
12 | public string Length { get; } = (data?.Length).GetDisplayString();
13 |
14 | public string Depth { get; } = (data?.Depth).GetDisplayString();
15 |
16 | public string Material { get; } = (data?.Material).GetDisplayString();
17 |
18 | public string GroutSpace { get; } = (data?.GroutSpace).GetDisplayString();
19 |
20 | #endregion
21 | }
22 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateFourBoltLayout.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateFourBoltLayout( IBasePlateFourBoltLayout layout ) : BasePlateBoltLayout
7 | {
8 | #region Properties
9 |
10 | public string EdgeDistance { get; } = layout.EdgeDistance.GetDisplayString();
11 |
12 | public string EndDistance { get; } = layout.EndDistance.GetDisplayString();
13 |
14 | #endregion
15 | }
16 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateProperties.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateProperties( IBasePlate basePlate ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public string Length { get; } = basePlate.Length.GetDisplayString();
11 |
12 | public string Width { get; } = basePlate.Width.GetDisplayString();
13 |
14 | public string Thickness { get; } = basePlate.Thickness.GetDisplayString();
15 |
16 | public string Steel { get; } = basePlate.Steel.GetDisplayString();
17 |
18 | #endregion
19 | }
20 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateSymmetricBoltLayout.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BasePlateSymmetricBoltLayout( IBasePlateSymmetricBoltLayout layout ) : BasePlateBoltLayout
7 | {
8 | #region Properties
9 |
10 | public bool Row2Enabled { get; } = layout.Row2Enabled.GetValueOrDefault();
11 |
12 | public string BoltCountRow1 { get; } = layout.BoltCountRow1.GetDisplayString();
13 |
14 | public string BoltCountRow2 { get; } = layout.BoltCountRow2.GetDisplayString();
15 |
16 | public string EndDistance { get; } = layout.EndDistance.GetDisplayString();
17 |
18 | public string FixedDistance { get; } = layout.FixedDistance.GetDisplayString();
19 |
20 | public string EdgeDistance { get; } = layout.EdgeDistance.GetDisplayString();
21 |
22 | public string EdgeDistanceRow1 { get; } = layout.EdgeDistanceRow1.GetDisplayString();
23 |
24 | public string EdgeDistanceRow2 { get; } = layout.EdgeDistanceRow2.GetDisplayString();
25 |
26 | public string Pitch { get; } = layout.Pitch.GetDisplayString();
27 |
28 | public string PitchRow1 { get; } = layout.PitchRow1.GetDisplayString();
29 |
30 | public string PitchRow2 { get; } = layout.PitchRow2.GetDisplayString();
31 |
32 | public string Gauge { get; } = layout.Gauge.GetDisplayString();
33 |
34 | #endregion
35 | }
36 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BasePlateWelds.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Common.Properties;
3 | using TSD.API.Remoting.Connections;
4 |
5 | namespace ReactingToSelection.ViewModels;
6 |
7 | public class BasePlateWelds : ViewModelBase
8 | {
9 | #region Nested Types
10 |
11 | public class WeldData( BasePlateWeldLocation location, IBasePlateWeldData? data ) : ViewModelBase
12 | {
13 | #region Properties
14 |
15 | public string Location { get; } = location.ToString();
16 |
17 | public string WeldType { get; } = (data?.Type).GetDisplayString();
18 |
19 | public string LegLength { get; } = (data?.LegLength).GetDisplayString();
20 |
21 | public bool IsFullLength { get; } = (data?.IsFullLength).GetValueOrDefault();
22 |
23 | public string PartialLength { get; } = (data?.PartialLength).GetDisplayString();
24 |
25 | #endregion
26 | }
27 |
28 | #endregion
29 |
30 | #region Constructors
31 |
32 | public BasePlateWelds( IEnumerable>>? weldData )
33 | {
34 | Data = new ListWithNotify( weldData?.Select( kvp => new WeldData( kvp.Key, kvp.Value.GetValueOrDefault() ) ) ?? [] );
35 | }
36 |
37 | #endregion
38 |
39 | #region Properties
40 |
41 | public ListWithNotify Data { get; }
42 |
43 | #endregion
44 | }
45 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/Bolt.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 | using static ReactingToSelection.Helpers.UiHelpers;
4 |
5 | namespace ReactingToSelection.ViewModels;
6 |
7 | public abstract class Bolt( IBolt bolt ) : ViewModelBase
8 | {
9 | #region Properties
10 |
11 | public string HeadCode { get; } = bolt.HeadCode.ToString();
12 |
13 | public string SystemType { get; } = bolt.SystemType.ToString();
14 |
15 | public string Grade { get; } = bolt.Grade;
16 |
17 | public string Diameter { get; } = GetDisplayString( bolt.Diameter );
18 |
19 | public string TensileStrength { get; } = GetDisplayString( bolt.TensileStrength );
20 |
21 | public string WidthAcrossNutFlats { get; } = GetDisplayString( bolt.WidthAcrossNutFlats );
22 |
23 | public string WidthAcrossNutPoints { get; } = GetDisplayString( bolt.WidthAcrossNutPoints );
24 |
25 | public string NutThickness { get; } = GetDisplayString( bolt.NutThickness );
26 |
27 | public string WasherOutsideDiameter { get; } = GetDisplayString( bolt.WasherOutsideDiameter );
28 |
29 | public string WasherThickness { get; } = GetDisplayString( bolt.WasherThickness );
30 |
31 | #endregion
32 |
33 | #region Methods
34 |
35 | public static Bolt? Create( IBolt? bolt ) => bolt switch
36 | {
37 | IBoltEc ecBolt => new BoltEc( ecBolt ),
38 | IBoltUs usBolt => new BoltUs( usBolt ),
39 | null => null,
40 | _ => throw new InvalidOperationException( $"Unexpected type of bolt {bolt.GetType().Name} encountered!" )
41 | };
42 |
43 | #endregion
44 | }
45 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BoltEc.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Connections;
2 | using static ReactingToSelection.Helpers.UiHelpers;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BoltEc( IBoltEc bolt ) : Bolt( bolt )
7 | {
8 | #region Properties
9 |
10 | public string TensileStressArea { get; } = GetDisplayString( bolt.TensileStressArea );
11 |
12 | public string YieldStrength { get; } = GetDisplayString( bolt.YieldStrength );
13 |
14 | public string HeadThickness { get; } = GetDisplayString( bolt.HeadThickness );
15 |
16 | #endregion
17 | }
18 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/BoltUs.cs:
--------------------------------------------------------------------------------
1 | using TSD.API.Remoting.Connections;
2 | using static ReactingToSelection.Helpers.UiHelpers;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class BoltUs( IBoltUs bolt ) : Bolt( bolt )
7 | {
8 | #region Properties
9 |
10 | public string Area { get; } = GetDisplayString( bolt.Area );
11 |
12 | public string BearingArea { get; } = GetDisplayString( bolt.BearingArea );
13 |
14 | #endregion
15 | }
16 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/ConnectedMember.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 | using ReactingToSelection.Helpers;
3 | using ReactingToSelection.Models;
4 | using TSD.API.Remoting.Connections;
5 | using TSD.API.Remoting.Loading;
6 | using TSD.API.Remoting.Solver;
7 | using TSD.API.Remoting.Structure;
8 |
9 | namespace ReactingToSelection.ViewModels;
10 |
11 | public class ConnectedMember : ViewModelBase
12 | {
13 | #region Fields
14 |
15 | private IMember _member;
16 | private IConnection _connection;
17 | private SpanReleases? _spanReleases;
18 | private IForce3DLocal? _endForce;
19 | private AnalysisType _analysisType;
20 | private ICombination? _selectedCombination;
21 |
22 | #endregion
23 |
24 | #region Constructors
25 |
26 | public ConnectedMember( IMember member, IConnection connection )
27 | {
28 | SetSelectedMember( member, connection );
29 |
30 | AnalysisType = AnalysisTypes.First();
31 |
32 | GetCombinationsAsync().FireAndForgetSafeAsync();
33 | }
34 |
35 | #endregion
36 |
37 | #region Properties
38 |
39 | public string Name => _member.Name;
40 |
41 | public SpanReleases? SpanReleases
42 | {
43 | get => _spanReleases;
44 | set => SetProperty( nameof( SpanReleases ), ref _spanReleases, value );
45 | }
46 |
47 | public IForce3DLocal? EndForce
48 | {
49 | get => _endForce;
50 | set => SetProperty( nameof( EndForce ), ref _endForce, value );
51 | }
52 |
53 | public ICombination? SelectedCombination
54 | {
55 | get => _selectedCombination;
56 | set => SetProperty( nameof( SelectedCombination ), ref _selectedCombination, value, () => GetForceAndReleasesAsync().FireAndForgetSafeAsync() );
57 | }
58 |
59 | public ListWithNotify Combinations { get; } = [];
60 |
61 | public AnalysisType AnalysisType
62 | {
63 | get => _analysisType;
64 | set => SetProperty( nameof( AnalysisType ), ref _analysisType, value, () => GetForceAndReleasesAsync().FireAndForgetSafeAsync() );
65 | }
66 |
67 | public static AnalysisType[] AnalysisTypes => Enum.GetValues().Skip( 1 ).ToArray();
68 |
69 | #endregion
70 |
71 | #region Methods
72 |
73 | [MemberNotNull( nameof( _member ))]
74 | [MemberNotNull( nameof( _connection ) )]
75 | public void SetSelectedMember( IMember member, IConnection connection )
76 | {
77 | _member = member;
78 | _connection = connection;
79 |
80 | OnPropertyChanged( nameof( Name ) );
81 | GetForceAndReleasesAsync().FireAndForgetSafeAsync();
82 | }
83 |
84 | private async Task GetForceAndReleasesAsync()
85 | {
86 | if( SelectedCombination is null )
87 | {
88 | EndForce = null;
89 | SpanReleases = null;
90 |
91 | return;
92 | }
93 |
94 | var details = await MemberSpanFetcher.GetConnectedMemberDetailsAsync( _connection, _member, SelectedCombination, AnalysisType );
95 |
96 | if( details is null )
97 | {
98 | EndForce = null;
99 | SpanReleases = null;
100 |
101 | return;
102 | }
103 |
104 | EndForce = details.Value.EndForce;
105 | SpanReleases = new SpanReleases( details.Value.Releases );
106 | }
107 |
108 | private async Task GetCombinationsAsync()
109 | {
110 | var combinations = (await Model.Instance.GetCombinationsAsync()).ToList();
111 |
112 | Combinations.ReplaceContentAndNotify( combinations );
113 |
114 | SelectedCombination = combinations.FirstOrDefault();
115 | }
116 |
117 | #endregion
118 | }
119 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/Connection.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using ReactingToSelection.Models;
3 | using TSD.API.Remoting.Common;
4 | using TSD.API.Remoting.Common.Properties;
5 | using TSD.API.Remoting.Connections;
6 | using TSD.API.Remoting.Structure;
7 |
8 | namespace ReactingToSelection.ViewModels;
9 |
10 | public class Connection : ViewModelBase
11 | {
12 | #region Fields
13 |
14 | private IConnection? _connection;
15 | private ConnectionDetails? _connectionDetails;
16 | private IMember? _selectedConnectedMember;
17 | private ConnectedMember? _connectedMember;
18 |
19 | #endregion
20 |
21 | #region Constructors
22 |
23 | public Connection( IConnection? connection )
24 | {
25 | SetSelectedConnection( connection );
26 |
27 | FetchConnectedMembersAsync().FireAndForgetSafeAsync();
28 | FetchConnectionDetailsAsync().FireAndForgetSafeAsync();
29 | }
30 |
31 | #endregion
32 |
33 | #region Properties
34 |
35 | public string Name => _connection?.Name ?? string.Empty;
36 |
37 | public string ConnectionType => _connection?.ConnectionType.Value.ToString() ?? string.Empty;
38 |
39 | public string ConstructionPointIndex => _connection?.ConstructionPointIndex.Value.ToString() ?? string.Empty;
40 |
41 | public IProperty? UtilizationRatio => _connection?.UtilizationRatio;
42 |
43 | public IPropertyWithValidValues? CheckStatus => _connection?.CheckStatus;
44 |
45 | public ListWithNotify ConnectedMembers { get; } = [];
46 |
47 | public ConnectionDetails? ConnectionDetails
48 | {
49 | get => _connectionDetails;
50 | private set => SetProperty( nameof( ConnectionDetails ), ref _connectionDetails, value );
51 | }
52 |
53 | public IMember? SelectedConnectedMember
54 | {
55 | get => _selectedConnectedMember;
56 | set
57 | {
58 | if( _selectedConnectedMember?.Name == value?.Name )
59 | return;
60 |
61 | SetProperty( nameof( SelectedConnectedMember ), ref _selectedConnectedMember, value );
62 |
63 | if( _selectedConnectedMember is not { } selectedConnectedMember )
64 | return;
65 |
66 | if( _connection is not { } connection )
67 | return;
68 |
69 | ConnectedMember ??= new ConnectedMember( selectedConnectedMember, connection );
70 | ConnectedMember.SetSelectedMember( selectedConnectedMember, connection );
71 | }
72 | }
73 |
74 | public ConnectedMember? ConnectedMember
75 | {
76 | get => _connectedMember;
77 | private set => SetProperty( nameof( ConnectedMember ), ref _connectedMember, value );
78 | }
79 |
80 | #endregion
81 |
82 | #region Methods
83 |
84 | private void SetSelectedConnection( IConnection? connection )
85 | {
86 | if( connection == _connection )
87 | return;
88 |
89 | _connection = connection;
90 |
91 | OnPropertyChanged( nameof( Name ) );
92 | OnPropertyChanged( nameof( ConnectionType ) );
93 | OnPropertyChanged( nameof( ConstructionPointIndex ) );
94 | OnPropertyChanged( nameof( UtilizationRatio ) );
95 | OnPropertyChanged( nameof( CheckStatus ) );
96 | }
97 |
98 | private async Task FetchConnectedMembersAsync()
99 | {
100 | if( _connection is null )
101 | return;
102 |
103 | var connectedMembers = (await ConnectionFetcher.GetConnectedMembersAsync( _connection )).ToList();
104 |
105 | ConnectedMembers.ReplaceContentAndNotify( connectedMembers );
106 |
107 | SelectedConnectedMember = connectedMembers.FirstOrDefault();
108 | }
109 |
110 | private async Task FetchConnectionDetailsAsync()
111 | {
112 | if( _connection is null )
113 | return;
114 |
115 | var supportReaction = await ConnectionFetcher.GetSupportReactionAsync( _connection );
116 |
117 | ConnectionDetails = ConnectionDetails.Create( _connection, supportReaction );
118 | }
119 |
120 | #endregion
121 | }
122 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/ConnectionDetails.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 | using TSD.API.Remoting.Loading;
4 |
5 | namespace ReactingToSelection.ViewModels;
6 |
7 | public abstract class ConnectionDetails : ViewModelBase
8 | {
9 | #region Methods
10 |
11 | public static ConnectionDetails? Create( IConnection? connection, IForce3DGlobal supportReaction ) => connection switch
12 | {
13 | IBasePlate basePlate => new BasePlate( basePlate, supportReaction ),
14 | _ => null
15 | };
16 |
17 | #endregion
18 | }
19 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/MainWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Input;
2 | using ReactingToSelection.Helpers;
3 | using ReactingToSelection.Models;
4 | using TSD.API.Remoting;
5 | using TSD.API.Remoting.Connections;
6 |
7 | namespace ReactingToSelection.ViewModels;
8 |
9 | public class MainWindowViewModel : ViewModelBase
10 | {
11 | #region Fields
12 |
13 | private IApplication? _application;
14 | private Connection? _connection;
15 | private IConnection? _selectedConnection;
16 |
17 | #endregion
18 |
19 | #region Constructors
20 |
21 | public MainWindowViewModel()
22 | {
23 | RefreshCommand = new RelayCommand( RefreshAsync );
24 |
25 | async void RefreshAsync()
26 | {
27 | if( _application is not null )
28 | {
29 | _application.SelectionChanged -= OnSelectionChanged;
30 | }
31 |
32 | _application = (await ApplicationFactory.GetRunningApplicationsAsync()).FirstOrDefault();
33 |
34 | if( _application is null )
35 | return;
36 |
37 | _application.SelectionChanged += OnSelectionChanged;
38 |
39 | if( await _application.GetDocumentAsync() is not { } document )
40 | return;
41 |
42 | await Model.FetchModelAsync( document );
43 |
44 | OnSelectionChanged( null, EventArgs.Empty );
45 | }
46 | }
47 |
48 | #endregion
49 |
50 | #region Properties
51 |
52 | public Connection? Connection
53 | {
54 | get => _connection;
55 | set => SetProperty( nameof( Connection ), ref _connection, value );
56 | }
57 |
58 | public ListWithNotify Connections { get; } = [];
59 |
60 | public IConnection? SelectedConnection
61 | {
62 | get => _selectedConnection;
63 | set => SetProperty( nameof( SelectedConnection ), ref _selectedConnection, value, () => Connection = new Connection( value ?? Connections.FirstOrDefault() ) );
64 | }
65 |
66 | public ICommand RefreshCommand { get; }
67 |
68 | #endregion
69 |
70 | #region Event Handlers
71 |
72 | private void OnSelectionChanged( object? sender, EventArgs e )
73 | {
74 | GetConnectionDetailsForSelectionAsync().FireAndForgetSafeAsync();
75 |
76 | async Task GetConnectionDetailsForSelectionAsync()
77 | {
78 | Connections.ReplaceContentAndNotify( await ConnectionFetcher.GetSelectedConnectionsAsync() );
79 |
80 | SelectedConnection = Connections.FirstOrDefault();
81 | }
82 | }
83 |
84 | #endregion
85 | }
86 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/SpanReleases.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Structure;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class SpanReleases( ISpanReleases? spanReleases ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public string DegreeOfFreedom => (spanReleases?.DegreeOfFreedom).GetDisplayString();
11 |
12 | public string Cantilever => (spanReleases?.Cantilever).GetDisplayString();
13 |
14 | public string AxialRelease => (spanReleases?.AxialRelease).GetDisplayString();
15 |
16 | public string TorsionalRelease => (spanReleases?.TorsionalRelease).GetDisplayString();
17 |
18 | #endregion
19 | }
20 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/SupportReaction.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Loading;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class SupportReaction( IForce3DGlobal? supportReaction ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public string Fx { get; } = UiHelpers.GetDisplayString( supportReaction?.Fx );
11 |
12 | public string Fy { get; } = UiHelpers.GetDisplayString( supportReaction?.Fy );
13 |
14 | public string Fz { get; } = UiHelpers.GetDisplayString( supportReaction?.Fz );
15 |
16 | public string Mx { get; } = UiHelpers.GetDisplayString( supportReaction?.Mx );
17 |
18 | public string My { get; } = UiHelpers.GetDisplayString( supportReaction?.My );
19 |
20 | public string Mz { get; } = UiHelpers.GetDisplayString( supportReaction?.Mz );
21 |
22 | #endregion
23 | }
24 |
--------------------------------------------------------------------------------
/ReactingToSelection/ViewModels/WeldedWasher.cs:
--------------------------------------------------------------------------------
1 | using ReactingToSelection.Helpers;
2 | using TSD.API.Remoting.Connections;
3 |
4 | namespace ReactingToSelection.ViewModels;
5 |
6 | public class WeldedWasher( IWeldedWasher? weldedWasher ) : ViewModelBase
7 | {
8 | #region Properties
9 |
10 | public bool UseWeldedWashers { get; } = (weldedWasher?.UseWeldedWashers).GetValueOrDefault();
11 |
12 | public string SideLength { get; } = (weldedWasher?.SideLength).GetDisplayString();
13 |
14 | public string HoleDiameter { get; } = (weldedWasher?.HoleDiameter).GetDisplayString();
15 |
16 | public string Thickness { get; } = (weldedWasher?.Thickness).GetDisplayString();
17 |
18 | public string Steel { get; } = weldedWasher?.Steel.GetValueOrDefault()?.Name ?? string.Empty;
19 |
20 | #endregion
21 | }
22 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/AnchorPlate.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
30 |
34 |
38 |
42 |
46 |
50 |
54 |
58 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/AnchorPlate.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class AnchorPlate
4 | {
5 | #region Constructors
6 |
7 | public AnchorPlate()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlate.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlate.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlate
4 | {
5 | #region Constructors
6 |
7 | public BasePlate()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateAsymmetricBoltLayout.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateAsymmetricBoltLayout.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateAsymmetricBoltLayout
4 | {
5 | #region Constructors
6 |
7 | public BasePlateAsymmetricBoltLayout()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateBoltData.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
37 |
41 |
45 |
49 |
53 |
57 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateBoltData.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateBoltData
4 | {
5 | #region Constructors
6 |
7 | public BasePlateBoltData()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateBoltLayout.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateBoltLayout.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateBoltLayout
4 | {
5 | #region Constructors
6 |
7 | public BasePlateBoltLayout()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateConcreteData.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
31 |
35 |
39 |
43 |
47 |
51 |
55 |
59 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateConcreteData.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateConcreteData
4 | {
5 | #region Constructors
6 |
7 | public BasePlateConcreteData()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateFourBoltLayout.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
23 |
27 |
31 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateFourBoltLayout.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateFourBoltLayout
4 | {
5 | #region Constructors
6 |
7 | public BasePlateFourBoltLayout()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateProperties.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
30 |
34 |
38 |
42 |
46 |
50 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateProperties.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateProperties
4 | {
5 | #region Constructors
6 |
7 | public BasePlateProperties()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateSymmetricBoltLayout.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
38 |
42 |
46 |
50 |
54 |
58 |
62 |
66 |
70 |
74 |
78 |
82 |
86 |
90 |
94 |
98 |
102 |
106 |
110 |
114 |
118 |
122 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateSymmetricBoltLayout.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateSymmetricBoltLayout
4 | {
5 | #region Constructors
6 |
7 | public BasePlateSymmetricBoltLayout()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateWelds.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BasePlateWelds.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BasePlateWelds
4 | {
5 | #region Constructors
6 |
7 | public BasePlateWelds()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/Bolt.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/Bolt.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class Bolt
4 | {
5 | #region Constructors
6 |
7 | public Bolt()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BoltEc.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
38 |
42 |
46 |
50 |
54 |
58 |
62 |
66 |
70 |
74 |
78 |
82 |
86 |
90 |
94 |
98 |
102 |
106 |
110 |
114 |
118 |
122 |
126 |
130 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BoltEc.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BoltEc
4 | {
5 | #region Constructors
6 |
7 | public BoltEc()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BoltUs.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
37 |
41 |
45 |
49 |
53 |
57 |
61 |
65 |
69 |
73 |
77 |
81 |
85 |
89 |
93 |
97 |
101 |
105 |
109 |
113 |
117 |
121 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/BoltUs.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class BoltUs
4 | {
5 | #region Constructors
6 |
7 | public BoltUs()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/ConnectedMember.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/ConnectedMember.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class ConnectedMember
4 | {
5 | #region Constructors
6 |
7 | public ConnectedMember()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/Connection.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
61 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/Connection.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class Connection
4 | {
5 | #region Constructors
6 |
7 | public Connection()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/ConnectionDetails.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/ConnectionDetails.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class ConnectionDetails
4 | {
5 | #region Constructors
6 |
7 | public ConnectionDetails()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
31 |
38 |
46 |
47 |
48 |
49 |
50 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Controls;
2 | using ReactingToSelection.ViewModels;
3 |
4 | namespace ReactingToSelection.Views;
5 |
6 | public partial class MainWindow
7 | {
8 | #region Constructors
9 |
10 | public MainWindow()
11 | {
12 | InitializeComponent();
13 |
14 | DataContext = new MainWindowViewModel();
15 | }
16 |
17 | #endregion
18 |
19 | #region Event Handlers
20 |
21 | private void OnDataGridAutoGeneratingColumn( object sender, DataGridAutoGeneratingColumnEventArgs e )
22 | {
23 | e.Column = new DataGridTextColumn
24 | {
25 | Header = ConvertPropertyNameToHeader( e.PropertyName ),
26 | Binding = new System.Windows.Data.Binding( $"{e.PropertyName}.Value" )
27 | };
28 |
29 | static string ConvertPropertyNameToHeader( string propertyName ) => System.Text.RegularExpressions.Regex.Replace( propertyName, "([a-z])([A-Z])", "$1 $2" );
30 | }
31 |
32 | #endregion
33 | }
34 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/SpanReleases.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
29 |
33 |
37 |
41 |
45 |
49 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/SpanReleases.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class SpanReleases
4 | {
5 | #region Constructors
6 |
7 | public SpanReleases()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/SupportReaction.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
30 |
34 |
38 |
42 |
46 |
50 |
54 |
58 |
62 |
66 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/SupportReaction.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class SupportReaction
4 | {
5 | #region Constructors
6 |
7 | public SupportReaction()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/WeldedWasher.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
26 |
31 |
35 |
39 |
43 |
47 |
51 |
55 |
59 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/ReactingToSelection/Views/WeldedWasher.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ReactingToSelection.Views;
2 |
3 | public partial class WeldedWasher
4 | {
5 | #region Constructors
6 |
7 | public WeldedWasher()
8 | {
9 | InitializeComponent();
10 | }
11 |
12 | #endregion
13 | }
14 |
--------------------------------------------------------------------------------
/ReleaseNotes/2023.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | This document contains the notes for individual releases of the _TeklaStructuralDesigner.RemotingAPI_ NuGet package for major version 23.
4 |
5 | ## Version 23.4.0
6 |
7 | * A bug preventing connection to the API when using trial version of TSD has been fixed.
8 |
9 | ## Version 23.3.0
10 |
11 | * The ability to access connections via `Structure.IModel` interface has been added.
12 | * The ability to access floor analysis models via `Structure.IModel` interface has been added.
13 | * The floor analysis results (vibration modes and mode shapes by node) can be now accessed via solver model of floor analysis model (`GetVibrationModesAsync` and `GetModeShapesByNodeAsync` respectively).
14 | * The ability to access base plate data via `IBasePlate` interface has been added.
15 | * The property `GlobalRotationAngle` has been added to `IMemberSpan`.
16 | * The property `CombinationSpeciality` has been added to `ICombination`.
17 | * There is now an option to close an instance of Tekla Structural Designer application by calling `IApplication.StopAsync()`. This is only allowed for instances that were started via the API and the stop action can only be done from the client that started the instance.
18 | * A bug preventing access to concrete sections with circular holes has been fixed.
19 | * A bug preventing access to user-defined attributes has been fixed.
20 |
21 | ## Version 23.2.0
22 |
23 | * There is now a new way to peek at running instances of Tekla Structural Designer at the local machine instead of having to connect to them right away (`ApplicationFactory.GetRunningApplicationInfosAsync`). The provided `IApplicationInfo` then can be used to connect to the associated instance of Tekla Structural Designer using a new overload of method (`ApplicationFactory.ConnectToRunningApplicationAsync`).
24 | * The ability to access calculations of an object has been added (see `IHaveCalculations`).
25 | * A bug causing crash when accessing `DepthToThicknessRatio`, `BucklingParameter` and/or `TorsionalIndex` properties of `IPlatedISection` has been fixed. The properties now return `double.NaN` instead and a new interface `IPlatedISectionV2` has been added that has these properties as nullable (with `null` value instead of `double.NaN`). The old interface (`IPlatedISection`) has been made obsolete.
26 | * The ability to query units and convert values has been added (`IUnitConverter` in `IApplication`).
27 | * The ability to access current selection has been added (see `ISelectionItem`).
28 |
29 | ## Version 23.1.0
30 |
31 | * The ability to run the _"Analyze All"_ and _"Design All"_ commands has been added.
32 | * Westok web openings have been exposed via API.
33 | * The following properties of `IWebOpening` interface can now be accessed via the `Stiffener` property and were therefore made obsolete:
34 | * `Stiffening`
35 | * `StiffenerDepth`
36 | * `StiffenerThickness`
37 | * `StiffenerLength`
38 | * `EdgeToStiffenerCenter`
39 | * All these obsolete properties will be removed in version 25.0.0.
40 | * The stiffeners of web openings can be now added (resp. removed) via dedicated `Add` and `Remove` methods.
41 | * Property `IsStiffened` can therefore no longer have its value set and will be changed to `IReadOnlyProperty` in version 25.0.0.
42 | * The property `FilletWeldLegLength` of simple web opening stiffener has been exposed.
43 | * The following properties related to splices have been added to `ISteelColumnStackData`
44 | * `HasSplice`
45 | * `SpliceOffset`
46 | * The settings related to export of continuous objects have been exposed via API (under `IModelSettings.BimSettings`).
47 |
48 | ## Version 23.0.0
49 |
50 | This is the first public version of the NuGet package.
51 |
52 | The aim of the API is to allow its users to interact with the Tekla Structural Designer from within code. The following functionality is provided by the API:
53 | * Control of Tekla Structural Designer instances
54 | * Start a new instance of Tekla Structural Designer
55 | * Get currently running instances of Tekla Structural Designer
56 | * Connect to/disconnect from an instance of Tekla Structural Designer
57 | * Control of document within Tekla Structural Designer
58 | * Create a new document
59 | * Open existing document (from file or stream)
60 | * Save current document
61 | * Close current document
62 | * Access to information about sessions
63 | * Access to project details
64 | * Access to the structure model
65 | * Access to model entities and the ability to create/modify them
66 | * Architectural grid
67 | * Architectural grid lines
68 | * Construction points
69 | * Construction point groups
70 | * Construction planes (horizontal, vertical, sloped)
71 | * Foundations
72 | * Pad bases
73 | * Pile caps
74 | * Piles
75 | * Members
76 | * Beams
77 | * Braces
78 | * Columns
79 | * Portal frames
80 | * Members
81 | * Member spans
82 | * Rafters
83 | * Supports
84 | * Valleys
85 | * Roofs
86 | * Slabs
87 | * Slab items
88 | * Slab openings
89 | * Slab patches
90 | * Strips
91 | * Structural walls
92 | * Structural wall openings
93 | * Supports
94 | * Web openings
95 | * Wind walls
96 | * Access to loading and the ability to create/modify it
97 | * Loads
98 | * Load cases
99 | * Combinations
100 | * Envelopes
101 | * Access to material properties of model entities
102 | * Sections
103 | * Materials
104 | * Reinforcement
105 | * Profiles
106 | * Gauges
107 | * Access to solver model
108 | * Analysis results
109 | * Displacements
110 | * Forces
111 | * Nodal forces
112 | * Nodal mesh forces
113 | * Element end forces
114 | * Mesh forces
115 | * Result line forces
116 | * Wall line forces
117 | * Wall line station forces
118 | * Objects
119 | * Nodes
120 | * Supports
121 | * 1D elements
122 | * 2D elements
123 | * Panels
124 | * Diaphragms
125 | * Result lines
126 | * Stations
127 | * Wall lines
128 | * Access to user-defined attributes
129 | * Simple attributes
130 | * Embedded files
131 | * Access to information about embodied carbon in model entities
132 | * Control of validation
133 | * Access to the latest validation status
134 | * Means to run validation
135 | * Control of design
136 | * Access to the latest design status
137 | * Means to run design
138 |
--------------------------------------------------------------------------------
/ReleaseNotes/2024.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | This document contains the notes for individual releases of the _TeklaStructuralDesigner.RemotingAPI_ NuGet package for major version 24.
4 |
5 | ## Version 24.4.0
6 | * A new interface `IHaveUserName` has been added and implemented by most model entities
7 | * The property `Ec3FormulaType` has been added to `ICombination`.
8 | * The ability to access calculations of a structural wall (`IStructuralWall`) has been added (see `IHaveCalculations`).
9 |
10 | ## Version 24.3.0
11 |
12 | * A new value `SquareBar` has been added to the `SectionType` enumeration
13 | * A new interface `IBar` has been added which represents both square and flat bars
14 | * The interface `IFlatBar` has been made obsolete and will be removed in version 26.0.0
15 | * New `ColumnBrace`, `BeamBrace` and `XBrace` connection types have been added.
16 | * A new reinforcement geometry `Wire` and associated `IReinforcementWireSize` interface has been added.
17 |
18 | ## Version 24.2.0
19 |
20 | * The property `MinorAxisElasticSectionModulus` of `IColdRolledSectionBase` has been made optional. It will return `double.NaN` in case it is not available and its type will change to `double?` in version 26.0.0.
21 | * A new value `Mexico` has been added to the `Country` enumeration.
22 |
23 | ## Version 24.1.0
24 |
25 | * A new overload for `IModel.CreateMemberAttributeSetAsync` method has been added that allows users to specify the type of created member.
26 | * This change also allows users to set the section of created members.
27 | * The original overload is therefore redundant, has been marked obsolete and will be removed in version 26.0.0.
28 | * The property `IsWindward` has been added to `ISnowLoadDataDrift`.
29 | * The property `DistanceToRidge` has been added to `ISnowLoadDataRainOnSnow`.
30 |
31 | ## Version 24.0.0
32 |
33 | * A dedicated combination class for staged construction has been added.
34 | * A dedicated set of staged construction analysis types has been added.
35 | * The ability to access analysis types used in element design has been added (see `GetAnalysisTypesForElementDesignAsync` in `Structure.IModel`).
36 | * A new masonry material type has been added (see `IMasonry`).
37 | * Unfortunately, this _breaks the backwards compatibility_ so in order to work with TSD of version 24.0 and later, the API of at least version 24.0 needs to be used.
38 |
--------------------------------------------------------------------------------
/ReleaseNotes/2025.md:
--------------------------------------------------------------------------------
1 | # Release notes
2 |
3 | This document contains the notes for individual releases of the _TeklaStructuralDesigner.RemotingAPI_ NuGet package for major version 25.
4 |
5 | ## Version 25.1.0
6 |
7 | * A new interface `IForce3d` has been extracted. The existing `IForce3DLocal` and `IForce3DGlobal` interfaces are now extending it.
8 | * A new interface `IErrorFamily` has been added.
9 | * A new method `Structure.IModel.GetSolverErrorsAsync` has been added that allows users to obtain solver errors for the given analysis types.
10 | * A new namespace `TSD.API.Remoting.Filtering` has been added that provides objects for filtering entities.
11 | * A new property `TabularResultsAccessor` has been added to the `Structure.IModel` interface. It allows the access to various tabular results.
12 | * A new property `BimSource` has been added to the `IBimData` interface.
13 | * A new method `Structure.IModel.GetSelectedAnalysisTypeAsync` has been added that allows users to obtain the currently selected analysis type.
14 | * A new method `GetResult` has been added to the `IDesignCondition` interface that allows users to obtain the overall design result.
15 | * A new property `MasonryReinforcement` has been added to the `IStructuralWallPanel` interface.
16 | * A new method `Structure.IModel.GetStructuralWallPatchesAsync` has been added that allows users to obtain the patches in structural walls.
17 |
18 | ## Version 25.0.1
19 |
20 | * The following obsolete properties of `IWebOpening` interface have been removed:
21 | * `Stiffening`
22 | * `StiffenerDepth`
23 | * `StiffenerThickness`
24 | * `StiffenerLength`
25 | * `EdgeToStiffenerCenter`
26 | * The type of the property `IWebOpening.IsStiffened` has been changed to `IReadOnlyProperty`.
27 | * The obsolete `IPlatedISection` interface has been removed.
28 | * A new set of properties related to floor vibration has been added to `ISteelBeamSpanData` interface.
29 | * A new method `ISectionFactory.GetSectionGroupsAsync` has been added that allows users to obtain section groups compatible with the given head code and geometry.
30 | * New properties `GaugeFactory`, `ProfileFactory` and `MaterialFactory` have been added to `IModel` interface.
31 | * A new property `UnitSettings` has been added to `IModelSettings` interface.
32 |
--------------------------------------------------------------------------------
/RemotingAPIExamples.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32516.85
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExtractingSteelBeamData", "ExtractingSteelBeamData\ExtractingSteelBeamData.csproj", "{38984DD1-D052-4B17-B2E0-8C96E04EF353}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Extracting1DElementData", "Extracting1DElementData\Extracting1DElementData.csproj", "{642C6C7B-DBDF-4865-91FD-56609D661E71}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CreatingAndAnalyzingModel", "CreatingAndAnalyzingModel\CreatingAndAnalyzingModel.csproj", "{3EC3F9B8-94DF-4BD5-8074-7B39A6834DA4}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtractingResultsTableItem", "ExtractingResultsTableItem\ExtractingResultsTableItem.csproj", "{36DA71E5-9802-4A27-91C7-0B484DB33790}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtractingModelData", "ExtractingModelData\ExtractingModelData.csproj", "{372E7664-E1DE-4002-A9C5-B9EAE50B6ACC}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactingToSelection", "ReactingToSelection\ReactingToSelection.csproj", "{3EA249F1-12C3-45EB-813F-C18DFBEECE6A}"
17 | EndProject
18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportingFireCheckDataToUDA", "ExportingFireCheckDataToUDA\ExportingFireCheckDataToUDA.csproj", "{B8D97D9C-45A5-4ABE-ABAC-B36320E48DCF}"
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Release|Any CPU = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {38984DD1-D052-4B17-B2E0-8C96E04EF353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {38984DD1-D052-4B17-B2E0-8C96E04EF353}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {38984DD1-D052-4B17-B2E0-8C96E04EF353}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {38984DD1-D052-4B17-B2E0-8C96E04EF353}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {642C6C7B-DBDF-4865-91FD-56609D661E71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {642C6C7B-DBDF-4865-91FD-56609D661E71}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {642C6C7B-DBDF-4865-91FD-56609D661E71}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {642C6C7B-DBDF-4865-91FD-56609D661E71}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {3EC3F9B8-94DF-4BD5-8074-7B39A6834DA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {3EC3F9B8-94DF-4BD5-8074-7B39A6834DA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {3EC3F9B8-94DF-4BD5-8074-7B39A6834DA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {3EC3F9B8-94DF-4BD5-8074-7B39A6834DA4}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {36DA71E5-9802-4A27-91C7-0B484DB33790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {36DA71E5-9802-4A27-91C7-0B484DB33790}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {36DA71E5-9802-4A27-91C7-0B484DB33790}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {36DA71E5-9802-4A27-91C7-0B484DB33790}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {372E7664-E1DE-4002-A9C5-B9EAE50B6ACC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43 | {372E7664-E1DE-4002-A9C5-B9EAE50B6ACC}.Debug|Any CPU.Build.0 = Debug|Any CPU
44 | {372E7664-E1DE-4002-A9C5-B9EAE50B6ACC}.Release|Any CPU.ActiveCfg = Release|Any CPU
45 | {372E7664-E1DE-4002-A9C5-B9EAE50B6ACC}.Release|Any CPU.Build.0 = Release|Any CPU
46 | {3EA249F1-12C3-45EB-813F-C18DFBEECE6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 | {3EA249F1-12C3-45EB-813F-C18DFBEECE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 | {3EA249F1-12C3-45EB-813F-C18DFBEECE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
49 | {3EA249F1-12C3-45EB-813F-C18DFBEECE6A}.Release|Any CPU.Build.0 = Release|Any CPU
50 | {B8D97D9C-45A5-4ABE-ABAC-B36320E48DCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51 | {B8D97D9C-45A5-4ABE-ABAC-B36320E48DCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
52 | {B8D97D9C-45A5-4ABE-ABAC-B36320E48DCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
53 | {B8D97D9C-45A5-4ABE-ABAC-B36320E48DCF}.Release|Any CPU.Build.0 = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | GlobalSection(ExtensibilityGlobals) = postSolution
59 | SolutionGuid = {E88C85FC-48A6-4805-A86B-CD7F7F2B1934}
60 | EndGlobalSection
61 | EndGlobal
62 |
--------------------------------------------------------------------------------