Operate on surfaces in scripting
For complex optomechanical models it can be tedious to modify a collection of surfaces using the GUI's drag and drop capability. In such cases, however, the scripting language can be used to perform the surface modifications programmatically. In this KB article, two script implementations for identifying surfaces to be operated on will be demonstrated.
Implementation 1: Find surfaces by name
Every node on the object tree has a full name whose syntax follows the structure of the object tree itself. Consider the object tree shown below, which shows the full name for three different nodes. In this example, the "maksutov" subassembly is a "child node" of the Geometry folder and this relationship is given by the "dot" notation construction of its full name string. The construction of the node's full name string as, "Geometry.maksutov", uses the "." symbol to indicate that the "maksutov" node is a child of the "Geometry" node. Similarly, the "structure" subassembly is a child of the "maksutov" subassembly, who, in turn, is a child of the "Geometry" node. Consequently, the "structure" subassembly's full name is, "Geometry.maksutov.structure".
Note that in the construction of the full name strings above, the parent node's full name is always embedded within the child node's full name string. For example, "Geometry.maksutov.structure" is a substring within "Geometry.maksutov.structure.Prism 1". Therefore, any descendant node of the "structure" subassembly will contain the substring, "Geometry.maksutov.structure", within its own full name string. This is the critical item that will be leveraged in the first example script below.
This example script contains a Main subroutine, where the script starts its execution, and a custom function called "OperateOnNode". The purpose of this script is to identify all Surfaces that are descended from the "Geometry.maksutov.structure" subassembly and then perform some operation on those surfaces using the custom OperateOnNode function. In this example, the OperateOnNode function simply prints the name of the node passed into the function as the argument, but it could generically be made to perform any variety of tasks on the input node.
The flow of the script is the following:
- Retrieve the node number of the "structure" subassembly and store it in the variable, pNode.
- Begin looping over all nodes in the model
- For the current node, check to see if the node is a surface
- If the current node is a surface, use the BASIC "InStr" function to determine if the full name string of pNode is contained within the full name string of the current node. Recall from above that this will only be true if the current node is a descendant of pNode as a result of the construction of the full name strings.
Sub Main ClearOutputWindow() 'Parent node whose descendants we want to find Dim pNode As Long pNode = FindFullName( "Geometry.maksutov.structure" ) 'Loop over all surfaces in model Dim curEnt As Long For curEnt = 0 To GetEntityCount()-1 'Is the entity a surface? If IsSurface( curEnt ) Then 'Is the parent node's name found in the current entities full name string? If InStr( GetFullName( curEnt ), GetFullName( pNode ) )>0 Then 'This is a surface we care about. Operate on it in some way. OperateOnNode( curEnt ) End If End If Next End Sub Function OperateOnNode( ByVal in_node As Long ) As Boolean 'Custom function that operates on in_node in some way 'For example: ' SetSurfCoating ' SetSurfRaytraceCtrl ' ImpSampAddCurve ' AddSurfScatter Print GetFullName( in_node ) Return True End Function<br>
Implementation 2: Find surfaces by selection
FRED's scripting language has a command called, IsEntitySelected, which returns a True or False indicating whether the entity is currently selected on the object tree. With this command, a script can be linked to the GUI such that the script can easily isolate and operate on the nodes that are selected on the object tree.
The flow of the script is the following:
- Loop over all nodes in the model
- Determine if the node (a) is a surface, and (b) is currently selected on the tree
- If the surface meets the conditions above, increment a counter and then operate on the current node using the OperateOnNode function
- If, at the end of the script, the counter variable is 0, print a message to the output window indicating that no surfaces were selected on the tree
Sub Main ClearOutputWindow() 'Loop over all nodes in the system Dim curEnt As Long, nSelect As Long For curEnt = 0 To GetEntityCount()-1 'Is the entity a selected surface? If IsSurface( curEnt ) And IsEntitySelected( curEnt ) Then 'Counter for messaging nSelect += 1 'Operate on the selected surface in some way OperateOnNode( curEnt ) End If Next 'Did we find any selected surfaces? If not, print a message to output window. If nSelect < 1 Then Print "No surfaces were selected." End If End Sub Function OperateOnNode( ByVal in_node As Long ) As Boolean 'Custom function that operates on in_node in some way 'For example: ' SetSurfCoating ' SetSurfRaytraceCtrl ' ImpSampAddCurve ' AddSurfScatter Print GetFullName( in_node ) Return True End Function
The two scripts described above are implemented as embedded scripts in this FRED file: operateOnSurfaces.frd