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