Hi All,
I'm attaching the updated code where you can see the problem: even if I call 
dirty() for primitive sets and dirtyBounds() on the related geometry, the 
graphics is not updated.

Cheers,
Gianni

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=68671#68671



#include "stdafx.h"

#include <QTimer>
#include <QApplication>
#include <QGridLayout>

#include <osg/Geometry>
#include <osg/Geode>
#include <osg/MatrixTransform>
#include <osg/PolygonOffset>

#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/MultiTouchTrackballManipulator>

#include <osgDB/ReadFile>

#include <osgQt/GraphicsWindowQt>

#include <iostream>

const osg::Vec4 selectedColor(1.0f, 1.0f, 1.0f, 0.5f);
const osg::Vec4 color1(1.0f, 0.0f, 0.0f, 1.0f);
const osg::Vec4 color2(0.0f, 1.0f, 0.0f, 1.0f);
const osg::Vec4 color3(0.0f, 0.0f, 1.0f, 1.0f);
const osg::Vec4 color4(1.0f, 0.0f, 1.0f, 1.0f);

class SelectModelHandler : public osgGA::GUIEventHandler
{
public:
    SelectModelHandler() : _selector(0), currentPrimitiveIndex(0) {}
    
    osg::Geode* createFaceSelector()
    {
        osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
        (*colors)[0] = selectedColor;
        
        _selector = new osg::Geometry;
        _selector->setDataVariance( osg::Object::DYNAMIC );
        _selector->setUseDisplayList( false );
        _selector->setUseVertexBufferObjects( true );
        _selector->setVertexArray( new osg::Vec3Array(3) );
        _selector->setColorArray( colors.get() );
        _selector->setColorBinding( osg::Geometry::BIND_OVERALL );
        _selector->addPrimitiveSet( new osg::DrawArrays(GL_TRIANGLES, 0, 3) );
        
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->addDrawable( _selector.get() );
        geode->getOrCreateStateSet()->setMode( GL_LIGHTING, 
osg::StateAttribute::OFF );
        geode->getOrCreateStateSet()->setMode( GL_BLEND, 
osg::StateAttribute::ON );
        geode->getOrCreateStateSet()->setRenderingHint( 
osg::StateSet::TRANSPARENT_BIN );
        geode->getOrCreateStateSet()->setAttributeAndModes(new 
osg::PolygonOffset(-1.0f, -1.0f));
        return geode.release();
    }

    virtual bool handle( const osgGA::GUIEventAdapter& ea, 
osgGA::GUIActionAdapter& aa )
    {
       if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE &&
            ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
       {
          _selector->setVertexArray( new osg::Vec3Array(3) );
       }
        if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE &&
            ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON &&
            ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL)
        {
           osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
           if ( viewer )
           {
               osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new 
osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), 
ea.getY());
               osgUtil::IntersectionVisitor iv(intersector.get());
               osg::Camera* camera = viewer->getCamera();
               camera->accept( iv );
            
               if ( intersector->containsIntersections() )
               {
                   osgUtil::LineSegmentIntersector::Intersection result = 
*(intersector->getIntersections().begin());
                   doUserOperations( result );
               }
           }
        }
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1) {
           currentPrimitiveIndex = 0;
        }
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2) {
           currentPrimitiveIndex = 1;
        }
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3) {
           currentPrimitiveIndex = 2;
        }
        if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4) {
           currentPrimitiveIndex = 3;
        }
        return false;
    }

    virtual void doUserOperations( 
osgUtil::LineSegmentIntersector::Intersection& result )
    {
        osg::Geometry* geom = dynamic_cast<osg::Geometry*>( 
result.drawable.get() );
        if ( !geom || !_selector || geom==_selector ) return;
        
        osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>( 
geom->getVertexArray() );
        osg::Vec3Array* selVertices = dynamic_cast<osg::Vec3Array*>( 
_selector->getVertexArray() );
        if ( !vertices || !selVertices ) return;
        
        osg::Geode* geode = 
dynamic_cast<osg::Geode*>(result.nodePath[result.nodePath.size()-1]);
        unsigned int primitiveIndex = 
getPrimitiveIndex(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), 
result.primitiveIndex);
        unsigned int indexInsidePrimitive = 
getIndexInsidePrimitive(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), 
result.primitiveIndex);
        std::cout << "primitiveIndex = " << result.primitiveIndex << std::endl;
        std::cout << primitiveIndex << " - " << indexInsidePrimitive << 
std::endl;
        move(dynamic_cast<osg::Geometry*>(geode->getDrawable(0)), 
primitiveIndex, indexInsidePrimitive, currentPrimitiveIndex);

        osg::Matrix matrix = osg::computeLocalToWorld( result.nodePath );
        const std::vector<unsigned int>& selIndices = result.indexList;
        for ( unsigned int i=0; i<3 && i<selIndices.size(); ++i )
        {
            unsigned int pos = selIndices[i];
            (*selVertices)[i] = (*vertices)[pos] * matrix;
        }
        selVertices->dirty();
        _selector->dirtyBound();
    }

    unsigned int getPrimitiveIndex(osg::Geometry* geometry, unsigned int 
globalIndex)
    {
       unsigned int numPrimitives = geometry->getNumPrimitiveSets();
       unsigned int currentPrimitive = numPrimitives;
       unsigned int globalCount = 0;
       for (int i=0; i<numPrimitives; ++i) {
          osg::PrimitiveSet* primitiveSet = geometry->getPrimitiveSet(i);
          unsigned int count = primitiveSet->getNumPrimitives();
          if (globalCount <= globalIndex && globalIndex < globalCount+count) {
             currentPrimitive = i;
             break;
          } else {
             globalCount += count;
          }
       }
       return currentPrimitive;
    }
    
    unsigned int getIndexInsidePrimitive(osg::Geometry* geometry, unsigned int 
globalIndex)
    {
       unsigned int numPrimitives = geometry->getNumPrimitiveSets();
       unsigned int index = 0;
       unsigned int globalCount = 0;
       for (int i=0; i<numPrimitives; ++i) {
          osg::PrimitiveSet* primitiveSet = geometry->getPrimitiveSet(i);
          unsigned int count = primitiveSet->getNumPrimitives();
          if (globalCount <= globalIndex && globalIndex < globalCount+count) {
             index = globalIndex - globalCount;
             break;
          } else {
             globalCount += count;
          }
       }
       return index;
    }

    void move(osg::Geometry* geometry, unsigned int sourcePrimitiveSetIndex, 
unsigned int elementIndex, unsigned int destinationPrimitiveIndex)
    {
       osg::DrawElementsUInt* sourcePrimitiveSet = 
dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(sourcePrimitiveSetIndex));
       osg::DrawElementsUInt* destinationPrimitiveSet = 
dynamic_cast<osg::DrawElementsUInt*>(geometry->getPrimitiveSet(destinationPrimitiveIndex));
       
destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3));
       
destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3+1));
       
destinationPrimitiveSet->push_back(sourcePrimitiveSet->at(elementIndex*3+2));
       sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3);
       sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3);
       sourcePrimitiveSet->erase(sourcePrimitiveSet->begin()+elementIndex*3);

       sourcePrimitiveSet->dirty();
       destinationPrimitiveSet->dirty();
       geometry->dirtyBound();
    }

protected:
    osg::ref_ptr<osg::Geometry> _selector;
    unsigned int currentPrimitiveIndex;
};

osg::Vec3Array* buildVertices() {
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(0,0,0));
vertices->push_back(osg::Vec3(10,0,0));
vertices->push_back(osg::Vec3(10,10,0));
vertices->push_back(osg::Vec3(0,10,0));
vertices->push_back(osg::Vec3(20,0,0));
vertices->push_back(osg::Vec3(20,10,0));
vertices->push_back(osg::Vec3(20,20,0));
vertices->push_back(osg::Vec3(10,20,0));
vertices->push_back(osg::Vec3(0,20,0));
return vertices;
}

osg::DrawElementsUInt* buildElement1() {
   osg::DrawElementsUInt* element = new 
osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
   element->push_back(0);
   element->push_back(1);
   element->push_back(2);
   element->push_back(0);
   element->push_back(2);
   element->push_back(3);
   return element;
}

osg::DrawElementsUInt* buildElement2() {
   osg::DrawElementsUInt* element = new 
osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
   element->push_back(1);
   element->push_back(4);
   element->push_back(5);
   element->push_back(1);
   element->push_back(5);
   element->push_back(2);
   return element;
}

osg::DrawElementsUInt* buildElement3() {
   osg::DrawElementsUInt* element = new 
osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
   element->push_back(2);
   element->push_back(5);
   element->push_back(6);
   element->push_back(2);
   element->push_back(6);
   element->push_back(7);
   return element;
}

osg::DrawElementsUInt* buildElement4() {
   osg::DrawElementsUInt* element = new 
osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
   element->push_back(3);
   element->push_back(2);
   element->push_back(7);
   element->push_back(3);
   element->push_back(7);
   element->push_back(8);
   return element;
}

osg::Vec4Array* buildColors() {
   osg::Vec4Array* colors = new osg::Vec4Array;
   colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
   colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
   colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
   colors->push_back(osg::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
   return colors;
}

osg::Geometry* buildGeometry() {
   osg::Geometry* geometry = new osg::Geometry;
   geometry->setDataVariance(osg::Object::DYNAMIC);
   geometry->setVertexArray(buildVertices());
   geometry->setColorArray(buildColors(), osg::Array::BIND_PER_PRIMITIVE_SET);

   geometry->addPrimitiveSet(buildElement1());
   geometry->addPrimitiveSet(buildElement2());
   geometry->addPrimitiveSet(buildElement3());
   geometry->addPrimitiveSet(buildElement4());

   return geometry;
}

osg::Node* createScene() {
   osg::Geode* geode = new osg::Geode;
   geode->addDrawable(buildGeometry());
   return geode;
}

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments(&argc, argv);

    osgViewer::Viewer viewer(arguments);

    osg::ref_ptr<osg::Group> root = new osg::Group;
    root->addChild(createScene());
    osg::ref_ptr<SelectModelHandler> selector = new SelectModelHandler;
    root->addChild(selector->createFaceSelector());
    viewer.setSceneData(root);
    viewer.addEventHandler(selector.get());
    viewer.setCameraManipulator( new osgGA::TrackballManipulator );
    
    // add the window size toggle handler
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    viewer.run();
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to