No announcement yet.

Changing color of selected points in PoinSet

  • Filter
  • Time
  • Show
Clear All
new posts

  • Changing color of selected points in PoinSet


    I am really new to Open Inventor and working on my first project. At the moment I am rendering a colored PointSet.

        int PointArrayLength = 100;
        SoSeparator* Scan = new SoSeparator();
        SbVec3f* coords = ...; // Array of coordinates
        SbColor* vertexColor = ...; // Array of colors
        // Add colors to vertices
        SoMaterial* colors = new SoMaterial();
        colors->diffuseColor.setValues(0, PointArrayLength, vertexColor);
        SoVertexProperty* pVProp = new SoVertexProperty();
        pVProp->vertex.setValues(0, PointArrayLength, coords);
        SoMaterialBinding *matBind = new SoMaterialBinding;
        matBind->value = SoMaterialBinding::PER_VERTEX;
        SoPointSet* pointSet = new SoPointSet();
        pointSet->vertexProperty = pVProp;
    Now I try to change the color of a subset of the PointSet. To do this I added a SoExtSelection Node to select the points. Now I want to set a new color to the selected points.
    Can anybody give me a hint how to proceed?

    Thanks in advance for your help.

  • #2
    Unfortunately, the first problem is that SoExtSelection is only designed to select shape nodes. It can tell you if some part of the PointSet is inside the "lasso", but it cannot currently tell you which individual points in the set were inside the lasso. It is possible to do this using other Open Inventor classes. Although it's straightforward for a PointSet, it's not quite trivial. :-)
    1. Create an SoScreenDrawer, for example SoRectangleScreenDrawer, to allow the user select a region in the window.
      See example code fragment in SoPolylineScreenDrawer.
      When the user has selected a region (screen drawer's onFinish callback is called)...
    2. Get the screen space coordinates of the selected region from the screen drawer.
      Note - These coordinates are in normalized -1 to 1 space.
    3. Get a path (SoPath) to the SoPointSet node.
      Not strictly necessary. If there are no other PointSet shapes in the scene graph, you can apply the action to the whole scene graph.
    4. Get an SbViewVolume object from the Camera node (be sure to use the current aspect ratio of the viewer).
      We can use this to transform vertices into screen space.
    5. Create an SoCallbackAction.
      Set a "point" callback (see addPointCallback method).
      Declare a counter, e.g.: int pointIndex = 0;
      Declare collection, e.g.: std::vector<int> selectedPoints;
      Apply the action to the path (or to the root of the scene graph if no other shapes).
    6. The point callback function will be called for each point in the PointSet.
      • Get the 3D coordinate of the point by calling the SoPrimitiveVertex method getPoint().
      • Call the SbViewVolume method projectToScreen() to convert the 3D coordinate to normalized screen space.
        NOTE: The result of calling projectToScreen() is a coordinate in normalized 0 to 1 space.
        Your selection region is in -1 to 1 space. Sorry, it's inconvenient but can't be changed without breaking compatibility.
      • If the screen space coordinate is inside the selected region, then save the index, e.g.
        selectedPoint.push_back( pointIndex );
      • Increment the point index:
    7. After the CallbackAction returns, 'selectedPoints' will contain a list of the indices of selected points (if any).
      Use those indices to modify the color values in the VertexProperty.
    Good luck!