No announcement yet.

Override existing Override-Drawstyle

  • Filter
  • Time
  • Show
Clear All
new posts

  • Override existing Override-Drawstyle

    Hello Open-Inventor Community,

    I have a question regarding the Drawstyle override-feature. I am developing an application in which the user can load an existing complex scene-graph. The user can manipulate the appearance over the UI. For example one can change globally the color of all objects to blue. To do so, I am inserting a SoDrawstyle with ->setOverride(TRUE) near the top of the scene graph.
    Everything works as expected. Unfortunately I am in the situation that I have to break the overall global blue Drawstyle for the children of several Groups. For example every object is blue, but the Objects of the oxygen group should become yellow (see attached picture).
    I though, I could just insert another Override-DrawStyle and override the existing Override. Unfortunately this is not working and the objects are still drawn blue.

    To better explain my problem, I have modified a picture from the inventor mentor book (see attachement).


    Is there a possibility to break/reset an existing override DrawStyle?

    Thanks in advance and best regards

  • #2
    Thank you for your question mecanum,

    If I understand correctly, you are talking about the SoMaterial node and not SoDrawStyle but the explanation remains the same.
    As mentioned in the SoNode documentation:
    The override flag is a powerful mechanism typically used (sparingly) near the top of a scene graph. When this flag is set, any nodes of the same type encountered later in the graph are ignored even if they also have their own override flag set. Normally, the override flag is not used within a scene graph for modeling. Use it in applications where you need to specify a temporary change to the whole graph.
    Some more comments that could be helpful:
    1. A common mechanism to discard a node already in a scene graph is to have it into a SoSwitch. Simply switch the SoSwitch to SO_SWITCH_NONE so the children, in your case SoMaterial, can be ignored.
    2. I would recommend to keep a list of the materials in your scene and modify the ones you need to modify.
    Last edited by Benjamin; November 4, 2020, 02:20 PM.


    • #3
      Hello Benjamin,

      thanks a lot for your reply. Because the loaded scene graph is extremely complex, I hoped that I could just use the override feature and do not need to search for all SoMaterials in the scene graph.

      Thanks for your comments, I will try the "SO_SWITCH_NODE" feature


      • #4
        As Benjamin indicated, there is no "trivial" way to disable the 'override' setting lower in the scene graph.
        But... just in case it's useful, note that it is possible using an SoCallback node.
        What makes this possible is that the 'override' flags, like most properties, are stored in the Open Inventor traversal state using an SoElement. In this case, the SoOverrideElement class.
        Note that the override() method is per-node, but many of the override flags are per-field. In this case there are separate override flags for ambient color, diffuse color, etc.

        Create an SoCallback node and insert it before the SoMaterial node lower in the scene graph. When the SoCallback node is traversed, the override flag for diffuseColor will be cleared. As a result, the diffuse color set by the following SoMaterial node will take effect.

        This solution does require inserting two nodes at the lower level (SoCallback and SoMaterial). But you could make it more elegant by creating a simple custom node, for example using Composite pattern, create a custom node that automatically creates an SoCallback and an SoMaterial as children.

        Insert callback node (the same callback node could be inserted multiple places).
          auto callbackNode = new SoCallback();
        The callback function should look like this:
        void myCallback(void* data, SoAction* action)
          // Only handle specific actions
          if (action->isOfType(SoGLRenderAction::getClassTypeId())) {
            // Disable 'override' flag for diffuseColor
            auto state = action->getState();
            SoOverrideElement::setDiffuseColorOverride(state, (SoNode*)data, FALSE);