10.3. Programming the Python Script

  1. If not yet existing, create the Python file. For this, select FileNew in the MATE menu bar and save the new file as ApplicatorMacro.py in the same folder as the other module files.

  2. [Note]Note

    In your code, you may need to import some of the global classes like MLAB, MLABFileDialog or MLABFileManager from the "mevis" module (e.g. from mevis import MLAB) to get access to some convenience functions. See the scripting reference for a list of all available helper functions.

    Then we need to add two functions, one for each scripting command

    def AdjustLength():
        pass
    
    def AdjustDiameter():
        pass
    [Note]Note

    In Python, block structure is defined by indentation. Therefore, it is important to indent the lines as shown in the code examples. In the MATE editor, this will happen automatically.

  3. Let us have a look at the diameter adjustment. The diameter is given by the diameter field. This is written as follows:

    def AdjustDiameter():
        diameter = ctx.field("diameter").value

    To have both an effect on shaft and tip likewise, the diameter parameter of both must be set to the value of the diameter field. A look at the automatic panels of SoCone and SoCylinder shows that both modules offer a radius parameter.

    Figure 10.13. Parameters for Diameter Setting

    Parameters for Diameter Setting

    These radius parameters need to be set to diameter:

        ctx.field("SoCone.bottomRadius").value = diameter
        ctx.field("SoCylinder.radius").value = diameter

    As the radius is half the diameter, a correcting factor of 0.5 has to be added to the diameter equation.

    def AdjustDiameter():
        diameter = ctx.field("diameter").value * 0.5
    
        ctx.field("SoCone.bottomRadius").value = diameter
        ctx.field("SoCylinder.radius").value = diameter
  4. To test if the diameter adjusting works, add a SceneInspector module to the network and connect its input to the output of your ApplicatorMacro module. Double-click the SceneInspector to open its viewer. When you change the diameter setting of the macro, the diameter of the applicator is changed accordingly.

    Figure 10.14. Changing the Diameter of the Applicator

    Changing the Diameter of the Applicator

  5. Adjusting the length is a bit more complicated. The length change should have the following effects:

    • The length parameter gives the overall length.

    • Only the shaft should be extended, not the tip.

    • The adjustment should be done in a way that the point of the tip is not translated, that is that the tip points to the same position as before. Therefore, we need to increase the applicator length in the direction away from the tip.

    We can define an overall length, a tip length and a shaft length. They can be calculated as follows:

    def AdjustLength():
        overallLength = ctx.field("length").value
        tipLength = ctx.field("SoCone.height").value
    
        shaftLength = overallLength - tipLength

    The original translation factor for the tip (which is the relevant factor) was given by half the shaft length (“10”) plus half the tip length (“1.5”). This can be written in a general way.

      tipTranslation = shaftLength*0.5 + tipLength*0.5

    The shaftLength defines the height of the SoCylinder cone to

      ctx.field("SoCylinder.height").value = shaftLength

    The resulting code lines for the length adjustment look as follows:

    def AdjustLength():
        overallLength = ctx.field("length").value
        tipLength = ctx.field("SoCone.height").value
    
        shaftLength = overallLength - tipLength
        tipTranslation = shaftLength * 0.5 + tipLength * 0.5
    
        ctx.field ("SoCylinder.height").value = shaftLength

    Add this code to the Python script, save, and reload the definition. A test shows a funny effect: the shaft length is changed independently of the tip.

    Figure 10.15. Strange Behavior of the ApplicatorMacro

    Strange Behavior of the ApplicatorMacro

    This is due to not having connected the calculated tipTranslation with the TranslationTip module yet.

  6. To solve this problem, add the SoComposeVec3f module to the internal network of the macro and assign to its translation in y direction the calculated value tipTranslation. Since SoComposeVec3f supports an arbitrary number of elements on x,y,z, we have to use setListValue.

      ctx.field("SoComposeVec3f.y").setListValue([tipTranslation])
  7. In a last step, this translation needs to be connected to the tip's SoTranslation module via a parameter connection in the network.

    Figure 10.16. Adding the Correct Tip Translation

    Adding the Correct Tip Translation

Here the network and complete Python script of the ApplicatorMacro example:

Figure 10.17. Complete ApplicatorMacro

Complete ApplicatorMacro

def AdjustDiameter():
    diameter = ctx.field("diameter").value * 0.5

    ctx.field("SoCone.bottomRadius").value = diameter
    ctx.field("SoCylinder.radius").value = diameter


def AdjustLength():
    overallLength  = ctx.field("length").value
    tipLength = ctx.field("SoCone.height").value

    shaftLength = overallLength - tipLength
    tipTranslation = shaftLength*0.5 + tipLength*0.5

    ctx.field("SoCylinder.height").value = shaftLength
    ctx.field("SoComposeVec3f.y").setListValue([tipTranslation])