NextFEM Designer can host plugins able to interact with model and viewport. Plugins must be written in any of the .NET Framework supported languages (eg. C#, VB.NET, F#, …). Recommended framework version is v4.7.1.
NextFEM gives the public interface IPlugin in NextFEMplugin.dll, that must be implemented inside the plugin you’re developing. In addition, the plugin must reference NextFEMapi.dll. Both NextFEMapi.dll and NextFEMplugin.dll can be found in the installation folder of NextFEM Designer, typically C:\Program Files\NextFEM\NextFEM Designer 64bit\ for 64bit installations.
Both references must have the Copy locally flag set to False in the Visual Studio reference properties. To be found by the plugin, please insert the following code in your app.config.
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath=".." /> </assemblyBinding> </runtime>
Implement a base class like the samples below.
Imports NextFEMplugin
Public Class plugin
Implements IPlugin
Public Sub LaunchMe(hnd As IntPtr) Implements IPlugin.LaunchMe
Dim frm As New TrussDrawer
frm.caller = Me
frm.Text = Me.PluginName
frm.Show(System.Windows.Forms.Control.FromHandle(hnd))
End Sub
Public ReadOnly Property PluginAuthor As String Implements IPlugin.PluginAuthor
Get
Return “NextFEM Support Team”
End Get
End Property
Public ReadOnly Property PluginName As String Implements IPlugin.PluginName
Get
Return “Truss Drawer”
End Get
End Property
Public ReadOnly Property iconFile As String Implements IPlugin.iconFile
Get
Return “NextFEM.ico”
End Get
End Property
Public Event updateModel(sender As Object, resize As Boolean, Vstate As ViewState) Implements IPlugin.updateModel
Friend Sub RequestScreenUpdate(sender As Object,resize As Boolean, Vstate As ViewState)
RaiseEvent updateModel(sender, resize, Vstate)
End Sub
Public Event undoCall(undoProperty As undoOps) Implements IPlugin.undoCall
Friend Sub RequestUndo(undoProperty As undoOps)
RaiseEvent undoCall(undoProperty)
End Sub
Public Property API As NextFEMapi.API Implements IPlugin.API
Public Property currentLoadcase As String Implements IPlugin.currentLoadcase
Public Property currentTime As String Implements IPlugin.currentTime
End Class
using NextFEMplugin;
public class plugin : IPlugin
{
public void LaunchMe(IntPtr hnd)
{
TrussDrawer frm = new TrussDrawer();
frm.caller = this;
frm.Text = this.PluginName;
frm.Show(System.Windows.Forms.Control.FromHandle(hnd));
}
public string PluginAuthor
{
get
{ return “NextFEM Support Team”; }
}
public string PluginName
{
get
{ return “Truss Drawer”; }
}
public string iconFile
{
get
{ return “NextFEM.ico”; }
}
public event EventHandler updateModel;
internal void RequestScreenUpdate(object sender, bool resize, ViewState Vstate)
{
updateModel(sender, resize,Vstate);
}
public event EventHandler undoCall;
internal void RequestUndo(undoOps undoProperty)
{
undoCall(undoProperty);
}
public NextFEMapi.API API {get; set;}
public string currentLoadcase {get; set;}
public string currentTime {get; set;}
}
Implementation is discussed on VB.NET code. Below all the fields of the interface are described:
- PluginName : name of the plugin as string. The same name can be used to call the plugin by starting Designer via command-line. Eg. exe –plugin “Truss Drawer”
- PluginAuthor : string for the author of the plugin;
- iconFile : it sets the filename of the image to be loaded into the Tools/Plugins menu in NextFEM Designer. This is optional, if not used please return an empty string.
- LaunchMe : procedure for starting the plugin application (eg. a form). It must initialize NextFEM API (otherwise ) and pass the current instance of the base class to the plugin application form. In the sample above, it instantiates and launches the TrussDrawer The variable caller is declared in the form as: Friend caller as plugin
As final step, this procedure launched the form, passing the handle to be treated as Designer mask:
frm.Show(System.Windows.Forms.Control.FromHandle(hnd)) - updateModel : event to be called for requesting a viewport update. Since events can be called only in the same class, the function RequestScreenUpdate is implemented and has to be called from the plugin app form.
- undoCall : it follows the same working mechanism as updateModel.
- API : an instance of NextFEM API class, retaining all the methods to operate in model and results. You don’t need to implement it in your base class.
- currentLoadCase : string indicating the loadcase showed on screen for loading or results views.
- currentTime : string indicating the time or the mode showed on screen for results view.
Plugins can operate in every way in the model. There are some good practice rules to ensure their optimal functionality:
1) to load other DLLs in your plugin, please add the following code inside the form code:
' for loading dlls in the same folder - IMPORTANT: must be Private! Private currentDomain As AppDomain = AppDomain.CurrentDomain Private Function MyResolveEventHandler(ByVal sender As Object, ByVal args As ResolveEventArgs) As System.Reflection.Assembly ' this handler is called only when the CLR tries to bind to the assembly and fails Dim strTempAssmbPath As String = "" Dim MyAssembly, objExecutingAssembly As System.Reflection.Assembly objExecutingAssembly = System.Reflection.Assembly.GetExecutingAssembly() ' seek in the same folder Dim name As String = args.Name.Substring(0, args.Name.IndexOf(",")) strTempAssmbPath = My.Application.Info.DirectoryPath & "\plugins\" & name & ".dll" If IO.File.Exists(strTempAssmbPath) = False Then Return Nothing ' load the assembly from the specified path MyAssembly = System.Reflection.Assembly.LoadFrom(strTempAssmbPath) ' return the loaded assembly Return MyAssembly End Function
In addition, a handler to this event must be added to the MyBase.Load procedure:
' use DLL loading for load assemblied from the same plugin folder (or set subfolder in MyResolveEventHandler) AddHandler currentDomain.AssemblyResolve, AddressOf MyResolveEventHandler
Remember, in MyBase.Closing, to remove the handler:
RemoveHandler currentDomain.AssemblyResolve, AddressOf MyResolveEventHandler
Complex plugins with many DLLs may use a subdirectory of “plugins” folder.
2) Every operation on the model have to be preceded by an “Undo request” to Designer.
' call undo caller.RequestUndo(NextFEMplugin.undoProps.Normal)
and followed by a request for updating screen:
' refresh the view caller.RequestScreenUpdate(caller, True, NextFEMplugin.ViewState.NoOperation)
3) to update the viewport in Designer, you may choose between a variety of commands, all put together in the ViewState enumerator.
Eg.: caller.RequestScreenUpdate(caller, False, NextFEMplugin.ViewState.NoOperation)
This line request to Designer a screen update, resize is set to false hence not “View all” operation is called, and the ViewState is set to NoOperation, that means no operation required.
Here you are a list of visual operations you can call:
ViewState enumerator | Action and remarks |
Reset | Viewport is reset to default (no results and no loading views) |
NoOperation | No operation is performed, leave viewport as it is. |
NodesVisible | Show nodes. Call Reset to disable view. |
NodesNumber | Show nodes numbers. Call Reset to disable view. |
ElementsNumber | Show elements numbers. Call Reset to disable view. |
ExtrudedView | Show extruded views. Call Reset to disable view. |
ColorElements_Uniform | Show uniform color in elements. Call Reset to disable view. |
ColorElements_BySection | Color elements by sections. Call Reset to disable view. |
ColorElements_ByMaterial | Color elements by materials. Call Reset to disable view. |
ColorElements_ByGroup | Color elements by groups. Call Reset to disable view. |
ShowLocalAxes | Show element local axes. Recall it to disable view. |
GetScreenshot | Get screenshot of the current view. Screenshot is stored in Clipboard. |
ShowAllLoads | Show all loads in mdoel. Call reset to disable view. |
ShowDisplResults | Show displacement results. Call Reset to disable view. |
HighlightSelectedNodes | Highlight selected nodes. Call ClearNodesHighlight to disable view. |
HighlightSelectedElems | Highlight selected element. Call ClearElementsHighlight to disable view. |
ClearNodesHighlight | Clear the nodes highlighting |
ClearElementsHighlight | Clear the elements highlighting |
ShowNodesCheckResults | Show nodes check results. Call Reset to disable view. |
ShowElementsCheckResults | Show elements check results. Call Reset to disable view. |
ShowFrameForcesResults | Show frame forces results. Call Reset to disable view. |
ShowReactionsResults | Show element reactions results. Recall it to disable view. |
For results and loading views, you should set also caller.currentLoadcase and, mostly for modal or non-linear analyses, also caller.currentTime.
4) prior to do any action in the model (adding nodes, element, etc.) you should request an undo operation to the Designer. Otherwise, the user cannot revert what plugin did in the model.
Eg.: caller.RequestUndo(NextFEMplugin.undoOps.Normal)
undoOps enumerator | Action and remarks |
Normal | User will be prompted to clear results, if present. |
NormalDontAsk | User will not be prompted to clear results. |
NoUndo | No operation is added to undo stack. |
Debugging a plugin
Finally, for debugging purposes, you can copy the whole NextFEM Designer installation directory (typically C:\Program Files\NextFEM\NextFEM Designer 64bit\ for 64bit installations) anywhere in your hard-disk, and target its subfolder “plugins” as output directory for your program.
IMPORTANT: remember that the “plugins” folder is not writable.
Plugins DLLs can be freely developed and distributed without including files or parts of NextFEM Designer assemblies. Always remember to distribute the DLL together with the corresponding .dll.config file (which contains the app.config copy).
Each plugin must be a DLL build on the base of the sample project below, which is a simple program to draw truss structures in Designer. You can freely use this as a base for your plugin.
Get element type
When using the method
getElementProperty(ID, "type")
to check the type of an element, you get an integer value as listed below:
unk = 0
line = 1
tria = 2
quad = 3
hexa = 4
wedge = 5
tetra = 6
user = 10
line3 = 20
quad8 = 21
hexa16 = 22
hexa20 = 23
tetra10 = 24
tria6 = 25
wedge15 = 26
spring2nodes = 40
Saving plugin data
To save plugin data you can use a custom field stored just inside the model. See API reference for the following functions. The key used to store data should be the plugin name.
addOrModifyCustomData getCustomData removeCustomData
Resources
Download VB.NET sample project
Developers’ forum (for all public enquiries)