Hi,

I'm struggling a little with the attached program (segfaults on line 258
-- pSIA->dump(); ), which is intended to become a tutorial for the usage
of DynFieldAttachment.
Is DynFieldAttachment supposed to work at this point or simply not
complete yet ?

If it should work, then I think there is a bug related to the _localType
member, which is copy constructed from Self::_type (which does not exist
and thus is resolved to the parents _type) and hence there is never a
prototype of the DynFieldAttachment instance created, but only of the
parent class FieldContainerAttachment. I assume that this prototype
fails in some dynamic_cast or so and hence the pointer pSIA points to a
broken FC and segfaults when calling dump, or something similar.

Ideas, Comments ?

        Carsten

PS: I don't need this for anything so it is low priority for me, I'm
just curious what goes wrong ;)
// OpenSG Tutorial Example: DynamicAttachment
//
// This example shows how to use the DynamicAttachment to store information
// about a scene in its root node.
// Here we will restrict ourselves to things that are already present in the
// scene (we will collect geometries and the transformations), but
// a similar approach can be used to keep data associated to a scene that is
// not currently in use.

// Headers
#include <OSGGLUT.h>
#include <OSGConfig.h>
#include <OSGSimpleGeometry.h>
#include <OSGGLUTWindow.h>
#include <OSGSimpleSceneManager.h>
#include <OSGSceneFileHandler.h>
#include <OSGMaterial.h>
#include <OSGTransform.h>
#include <OSGDynamicAttachmentMixin.h>
#include <OSGAction.h>

// needed for traversal state object binding
#include <boost/bind.hpp>

// Activate the OpenSG namespace
OSG_USING_NAMESPACE

// SimpleSceneManager to manage simple applications
SimpleSceneManager *_mgr = NULL;

// Scene root node.
NodePtr _scene = NullFC;

// forward declaration so we can have the interesting stuff upfront
int setupGLUT(int *argc, char *argv[]);

// start by building a Descriptor for the new Attachment.
struct SceneInfoAttachmentDesc
{
    typedef FieldContainerAttachment    Parent;
    typedef FieldContainerAttachmentPtr ParentPtr;

    static const Char8 *getTypeName      (void) { return "SceneInfoAttachment"; }
    static const Char8 *getParentTypeName(void) { return "Attachment";          }
    static const Char8 *getGroupName     (void) { return "SceneInfoAttachment"; }

    static InitContainerF         getInitMethod(void) { return NULL; }

    static FieldDescriptionBase **getDesc      (void) { return NULL; }
};

// Give the Attachment and pointer a simpler name.
typedef DynFieldAttachment<SceneInfoAttachmentDesc>  SceneInfoAttachment;
typedef SceneInfoAttachment::ObjPtr                  SceneInfoAttachmentPtr;

#if 0
// ***
// I think this is not required - I don't want to have fields that hold
// SceneInfoAttachmentPtr
OSG_BEGIN_NAMESPACE
// specialize FieldTraits for SceneInfoAttachmentPtr fields.
template <>
struct FieldTraits<SceneInfoAttachmentPtr> : 
    public FieldTraitsFCPtrBase<SceneInfoAttachmentPtr>
{
    static  DataType                            _type;
    typedef FieldTraits<SceneInfoAttachmentPtr>  Self;

    enum                            { Convertible = Self::NotConvertible };

    static DataType &getType (void) { return _type;                      }

    static Char8    *getSName(void) { return "SFSceneInfoAttachmentPtr";     }
    static Char8    *getMName(void) { return "MFSceneInfoAttachmentPtr";     }
};

DataType FieldTraits<SceneInfoAttachmentPtr>::_type("SceneInfoAttachmentPtr",
                                                    "AttachmentPtr"          );

OSG_END_NAMESPACE
//
// ***
#endif

// A traversal state object
class SceneInfoCollector
{
public:
    SceneInfoCollector(SceneInfoAttachmentPtr pSIA);
    
    Action::ResultE enter(NodePtrConstArg node);
    
private:
    void addGeometry (GeometryPtr  pGeo  );
    void addTransform(TransformPtr pTrans);
    
    SceneInfoAttachmentPtr _pSIA;
};

// Constructor - just store the attachment ptr
SceneInfoCollector::SceneInfoCollector(SceneInfoAttachmentPtr pSIA)
    : _pSIA(pSIA)
{
}

// Traversal "callback" function
// If a Geometry core is found addGeometry is called
// If a Transform core is found addTransform is called
Action::ResultE
SceneInfoCollector::enter(NodePtrConstArg node)
{
    SINFO << "SceneInfoCollector::enter" << endLog;
    
    NodeCorePtr core = node->getCore();
    
    SINFO << "Core type: " << core->getType().getCName() << endLog;
    
    if(core->getType().isDerivedFrom(Geometry::getClassType()))
    {
        addGeometry(cast_dynamic<GeometryPtr>(core));
    }
    else if(core->getType().isDerivedFrom(Transform::getClassType()))
    {
        addTransform(cast_dynamic<TransformPtr>(core));
    }
    
    return Action::Continue;
}

void
SceneInfoCollector::addGeometry(GeometryPtr pGeo)
{
    SINFO << "SceneInfoCollector::addGeometry" << endLog;
    
    Field* field = _pSIA->editDynamicFieldByName("geometries");
    
    // field does not exist yet
    if(field == NULL)
    {
        FieldDescriptionBase* fDescGeometries = 
            new MFGeometryPtr::Description(
                MFGeometryPtr::getClassType(),
                "geometries",
                "List of geometries",
                0,
                0,
                reinterpret_cast<FieldIndexEditMethodSig>(
                    &SceneInfoAttachment::editDynamicField),
                reinterpret_cast<FieldIndexGetMethodSig> (
                    &SceneInfoAttachment::getDynamicField),
                false,
                Field::MFDefaultFlags);
        
        UInt32 fieldId = _pSIA->addField(*fDescGeometries);
        field          = _pSIA->editDynamicField(fieldId);
    }
    
    MFGeometryPtr* geoField = static_cast<MFGeometryPtr*>(field);
    
    if(geoField != NULL)
    {
        geoField->push_back(pGeo);
    }
    else
    {
        SWARNING << "SceneInfoCollector::addGeometry: could not add to field."
                 << endLog;
    }
}

void
SceneInfoCollector::addTransform(TransformPtr pTrans)
{
    SINFO << "SceneInfoCollector::addTransform" << endLog;
    
    Field* field = _pSIA->editDynamicFieldByName("transforms");
    
    // field does not exist yet
    if(field == NULL)
    {
        FieldDescriptionBase* fDescTransforms =
            new MFTransformPtr::Description(
                MFTransformPtr::getClassType(),
                "transforms",
                "List of transformations",
                0,
                0,
                reinterpret_cast<FieldIndexEditMethodSig>(
                    &SceneInfoAttachment::editDynamicField),
                reinterpret_cast<FieldIndexGetMethodSig> (
                    &SceneInfoAttachment::getDynamicField),
                false,
                Field::MFDefaultFlags);
        
        UInt32 fieldId = _pSIA->addField(*fDescTransforms);
        field          = _pSIA->editDynamicField(fieldId);
    }
    
    MFTransformPtr* transField = static_cast<MFTransformPtr*>(field);
    
    if(transField != NULL)
    {
        transField->push_back(pTrans);
    }
    else
    {
        SWARNING << "SceneInfoCollector::addTransform: could not add to field."
                 << endLog;
    }
}

void
printSIA(SceneInfoAttachmentPtr pSIA)
{
    if(pSIA == NullFC)
    {
        SWARNING << "printSIA: pSIA == NullFC" << endLog;
        return;
    }
    
    for(UInt32 i = 2; i <= pSIA->getType().getNumFieldDescs(); ++i)
    {
        FieldDescriptionBase *pFieldDesc = pSIA->getFieldDescription(i);
        const Field          *pField     = pSIA->getDynamicField(i);
        
        SLOG << "field: " << i
             << " name: " << pFieldDesc->getCName()
             << " type: " << pFieldDesc->getFieldType().getCName()
             << endLog;
    }
}

// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // load the given scene
    if(argc < 2)
    {
        SWARNING << "No scene file given, using a dummy scene." << endLog;

        _scene = makeTorus(.5, 2, 16, 16);
    }
    else
    {
        _scene = SceneFileHandler::the()->read(argv[1]);
    }

    // create the attachment.
    SceneInfoAttachmentPtr pSIA = SceneInfoAttachment::create();
    
    // dump to make sure the attachment is alive
    pSIA->dump();
    
    // add the attachment to the scene root
    _scene->addAttachment(pSIA);
    
    // traversal state object
    SceneInfoCollector sic(pSIA);
    
    // traverse the scene and collect info in the attachment.
    traverse(_scene, boost::bind(&SceneInfoCollector::enter, &sic, _1));
    
    // notify system of changed fields and cause update of dependent data.
    commitChanges();
    
    printSIA(pSIA);
    
    // the connection between GLUT and OpenSG
    GLUTWindowPtr gwin= GLUTWindow::create();
    gwin->setId(winid);
    gwin->init();
    
    // create the SimpleSceneManager helper
    _mgr = new SimpleSceneManager;

    // tell the manager what to manage
    _mgr->setWindow(gwin  );
    _mgr->setRoot  (_scene);

    // notify system of changed fields and cause update of dependent data.
    commitChanges();
    
    // GLUT main loop
    glutMainLoop();

    return 0;
}

//
// GLUT callback functions
//

// redraw the window
void display(void)
{
    _mgr->idle();
    _mgr->redraw();
}

// react to size changes
void reshape(int w, int h)
{
    _mgr->resize(w, h);
    glutPostRedisplay();
}

// react to mouse button presses
void mouse(int button, int state, int x, int y)
{

    if (state)
        _mgr->mouseButtonRelease(button, x, y);
    else
        _mgr->mouseButtonPress(button, x, y);
        
    glutPostRedisplay();
}

// react to mouse motions with pressed buttons
void motion(int x, int y)
{

    _mgr->mouseMove(x, y);
    glutPostRedisplay();
}

// react to keys
void keyboard(unsigned char k, int , int )
{
    switch(k)
    {
        case 27:    
        {
            OSG::osgExit();
            exit(0);
        }
        break;
        
        case 'f':
        {  
            _mgr->setNavigationMode(Navigator::FLY);
        }
        break;
        
        case 't':
        {
            _mgr->setNavigationMode(Navigator::TRACKBALL);
        }
        break;
    }
}

// setup the GLUT library which handles the windows for us
int setupGLUT(int *argc, char *argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    
    int winid = glutCreateWindow("OpenSG");
    
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    return winid;
}
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core

Reply via email to