Work in progress: VRML2 parser

This commit is contained in:
Cirilo Bernardo 2015-12-20 23:37:04 +11:00
parent e13dade517
commit 735137a26a
8 changed files with 285 additions and 83 deletions

View File

@ -3,8 +3,8 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/v2 )
add_library( s3d_plugin_vrml MODULE add_library( s3d_plugin_vrml MODULE
vrml.cpp vrml.cpp
v2/wrlproc.cpp v2/wrlproc.cpp
# v2/vrml2_node.cpp v2/vrml2_node.cpp
# v2/vrml2_base.cpp v2/vrml2_base.cpp
) )
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} ) target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )

View File

@ -27,9 +27,9 @@
#include "vrml2_helpers.h" #include "vrml2_helpers.h"
WRL2BASE::WRL2BASE( WRL2NODE* aParent ) : WRL2NODE() WRL2BASE::WRL2BASE() : WRL2NODE()
{ {
m_Type = V2_BASE; m_Type = WRL2_BASE;
return; return;
} }
@ -46,7 +46,7 @@ WRL2BASE::~WRL2BASE()
++sC; ++sC;
} }
sC.clear(); m_Children.clear();
return; return;
} }
@ -56,8 +56,10 @@ bool WRL2BASE::SetParent( WRL2NODE* aParent )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] attempting to extract name from virtual base node\n"; std::cerr << " * [BUG] attempting to set parent on WRL2BASE node\n";
#endif #endif
return false;
} }
@ -134,6 +136,37 @@ bool WRL2BASE::SetName(const char *aName)
} }
void WRL2BASE::unlinkChildNode( const WRL2NODE* aNode )
{
std::list< WRL2NODE* >::iterator sL = m_Children.begin();
std::list< WRL2NODE* >::iterator eL = m_Children.end();
while( sL != eL )
{
if( *sL == aNode )
{
m_Children.erase( sL );
return;
}
++sL;
}
return;
}
void WRL2BASE::unlinkRefNode( const WRL2NODE* aNode )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] WRL2BASE was invoked to unlink a referenced node\n";
#endif
return;
}
bool WRL2BASE::Read( WRLPROC& proc ) bool WRL2BASE::Read( WRLPROC& proc )
{ {
if( proc.GetVRMLType() != VRML_V2 ) if( proc.GetVRMLType() != VRML_V2 )
@ -146,15 +179,148 @@ bool WRL2BASE::Read( WRLPROC& proc )
} }
std::string glob; std::string glob;
bool hasComma = false;
WRL2NODES ntype;
while( proc.ReadGlob( glob ) ) while( proc.ReadName( glob ) )
{ {
// XXX - Process node name // Process node name:
// the names encountered at this point should be one of the
// built-in node names or one of:
// DEF, USE
// PROTO, EXTERNPROTO
// ROUTE
// any PROTO or EXTERNPROTO defined name
// since we do not support PROTO or EXTERNPROTO, any unmatched names are
// assumed to be defined via PROTO/EXTERNPROTO and deleted according to
// a typical pattern.
if( !glob.compare( "USE" ) )
{
// XXX - implement
}
if( !glob.compare( "DEF" ) )
{
// XXX - implement
}
xxx; if( !glob.compare( "PROTO" ) )
} while( !glob.empty() ); {
// XXX - implement
}
if( !glob.compare( "EXTERNPROTO" ) )
{
// XXX - implement
}
if( !glob.compare( "ROUTE" ) )
{
// XXX - implement
}
ntype = getNodeTypeID( glob );
switch( ntype )
{
//
// items to be implemented:
//
case WRL2_APPEARANCE:
// note:
break;
case WRL2_BOX:
break;
case WRL2_COLOR:
break;
case WRL2_CONE:
break;
case WRL2_COORDINATE:
break;
case WRL2_CYLINDER:
break;
case WRL2_ELEVATIONGRID:
break;
case WRL2_EXTRUSION:
break;
case WRL2_INDEXEDFACESET:
break;
case WRL2_MATERIAL:
break;
case WRL2_NORMAL:
break;
case WRL2_SHAPE:
break;
case WRL2_SPHERE:
break;
case WRL2_TRANSFORM:
case WRL2_GROUP:
break;
//
// items not implemented or for optional future implementation:
//
case WRL2_ANCHOR:
case WRL2_AUDIOCLIP:
case WRL2_BACKGROUND:
case WRL2_BILLBOARD:
case WRL2_COLLISION:
case WRL2_COLORINTERPOLATOR:
case WRL2_COORDINATEINTERPOLATOR:
case WRL2_CYLINDERSENSOR:
case WRL2_DIRECTIONALLIGHT:
case WRL2_FOG:
case WRL2_FONTSTYLE:
case WRL2_IMAGETEXTURE:
case WRL2_INDEXEDLINESET:
case WRL2_INLINE:
case WRL2_LOD:
case WRL2_MOVIETEXTURE:
case WRL2_NAVIGATIONINFO:
case WRL2_NORMALINTERPOLATOR:
case WRL2_ORIENTATIONINTERPOLATOR:
case WRL2_PIXELTEXTURE:
case WRL2_PLANESENSOR:
case WRL2_POINTLIGHT:
case WRL2_POINTSET:
case WRL2_POSITIONINTERPOLATOR:
case WRL2_PROXIMITYSENSOR:
case WRL2_SCALARINTERPOLATOR:
case WRL2_SCRIPT:
case WRL2_SOUND:
case WRL2_SPHERESENSOR:
case WRL2_SPOTLIGHT:
case WRL2_SWITCH:
case WRL2_TEXT:
case WRL2_TEXTURECOORDINATE:
case WRL2_TEXTURETRANSFORM:
case WRL2_TIMESENSOR:
case WRL2_TOUCHSENSOR:
case WRL2_VIEWPOINT:
case WRL2_VISIBILITYSENSOR:
case WRL2_WORLDINFO:
case WRL2_INVALID:
default: // any nodes which may have been defined via PROTO/EXTERNPROTO
break;
}
//xxx;
};
// XXX - determine why ReadName failed
// XXX - // XXX -
#warning TO BE IMPLEMENTED #warning TO BE IMPLEMENTED

View File

@ -48,6 +48,11 @@
#include "vrml2_node.h" #include "vrml2_node.h"
// BUG: there are no referenced nodes; however it is indeed
// possible for the BASE node to have reference nodes, for example:
// DEF BLAH Transform{}
// USE BLAH
// The code must be adjusted to respond to unlink requests and addNodeRef requests
/** /**
* Class WRL2BASE * Class WRL2BASE

View File

@ -32,12 +32,12 @@
// Function to find a node object given a (non-unique) node name // Function to find a node object given a (non-unique) node name
#define FIND_NODE( aName, aNodeList, aCallingNode ) do { \ #define FIND_NODE( aName, aNodeList, aCallingNode ) do { \
std::vector< aType* >::iterator sLA = aNodeList.begin(); \ std::list< WRL2NODE* >::iterator sLA = aNodeList.begin(); \
std::vector< aType* >::iterator eLA = aNodeList.end(); \ std::list< WRL2NODE* >::iterator eLA = aNodeList.end(); \
WRL2NODE* psg = NULL; \ WRL2NODE* psg = NULL; \
while( sLA != eLA ) { \ while( sLA != eLA ) { \
if( (WRL2NODE*)*sLA != aCallingNode ) { \ if( (WRL2NODE*)*sLA != aCallingNode ) { \
psg = (WRL2NODE*) (*sLA)->FindNode( aName, this ); \ psg = (*sLA)->FindNode( aName, this ); \
if( NULL != psg) \ if( NULL != psg) \
return psg; \ return psg; \
} \ } \

View File

@ -25,22 +25,25 @@
#include <set> #include <set>
#include <map> #include <map>
#include <utility> #include <utility>
#include <iterator>
#include <cctype> #include <cctype>
#include <iostream>
#include <algorithm>
#include "vrml2_node.h" #include "vrml2_node.h"
static std::set< std::string > badNames; static std::set< std::string > badNames;
typedef std::pair< std::string, WRLNODES > NODEITEM; typedef std::pair< std::string, WRL2NODES > NODEITEM;
typedef std::map< std::string, WRLNODES > NODEMAP; typedef std::map< std::string, WRL2NODES > NODEMAP;
static NODEMAP nodenames; static NODEMAP nodenames;
WRL2NODE::WRL2NODE() WRL2NODE::WRL2NODE()
{ {
m_Parent = NULL; m_Parent = NULL;
m_Type = V2_END; m_Type = WRL2_END;
if( badNames.empty() ) if( badNames.empty() )
{ {
@ -62,60 +65,60 @@ WRL2NODE::WRL2NODE()
if( nodenames.empty() ) if( nodenames.empty() )
{ {
node_names.insert( NODEITEM( "Anchor", WRL2_ANCHOR ) ); nodenames.insert( NODEITEM( "Anchor", WRL2_ANCHOR ) );
node_names.insert( NODEITEM( "Appearance", WRL2_APPEARANCE ) ); nodenames.insert( NODEITEM( "Appearance", WRL2_APPEARANCE ) );
node_names.insert( NODEITEM( "Audioclip", WRL2_AUDIOCLIP ); nodenames.insert( NODEITEM( "Audioclip", WRL2_AUDIOCLIP ) );
node_names.insert( NODEITEM( "Background", WRL2_BACKGROUND ) ); nodenames.insert( NODEITEM( "Background", WRL2_BACKGROUND ) );
node_names.insert( NODEITEM( "Billboard", WRL2_BILLBOARD ) ); nodenames.insert( NODEITEM( "Billboard", WRL2_BILLBOARD ) );
node_names.insert( NODEITEM( "Box", WRL2_BOX ) ); nodenames.insert( NODEITEM( "Box", WRL2_BOX ) );
node_names.insert( NODEITEM( "Collision", WRL2_COLLISION ) ); nodenames.insert( NODEITEM( "Collision", WRL2_COLLISION ) );
node_names.insert( NODEITEM( "Color", WRL2_COLOR ) ); nodenames.insert( NODEITEM( "Color", WRL2_COLOR ) );
node_names.insert( NODEITEM( "ColorInterpolator", WRL2_COLORINTERPOLATOR ) ); nodenames.insert( NODEITEM( "ColorInterpolator", WRL2_COLORINTERPOLATOR ) );
node_names.insert( NODEITEM( "Cone", WRL2_CONE ) ); nodenames.insert( NODEITEM( "Cone", WRL2_CONE ) );
node_names.insert( NODEITEM( "Coordinate", WRL2_COORDINATE ) ); nodenames.insert( NODEITEM( "Coordinate", WRL2_COORDINATE ) );
node_names.insert( NODEITEM( "CoordinateInterpolator", WRL2_COORDINATEINTERPOLATOR ) ); nodenames.insert( NODEITEM( "CoordinateInterpolator", WRL2_COORDINATEINTERPOLATOR ) );
node_names.insert( NODEITEM( "Cylinder", WRL2_CYLINDER ) ); nodenames.insert( NODEITEM( "Cylinder", WRL2_CYLINDER ) );
node_names.insert( NODEITEM( "CylinderSensor", WRL2_CYLINDERSENSOR ) ); nodenames.insert( NODEITEM( "CylinderSensor", WRL2_CYLINDERSENSOR ) );
node_names.insert( NODEITEM( "DirectionalLight", WRL2_DIRECTIONALLIGHT ) ); nodenames.insert( NODEITEM( "DirectionalLight", WRL2_DIRECTIONALLIGHT ) );
node_names.insert( NODEITEM( "ElevationGrid", WRL2_ELEVATIONGRID ) ); nodenames.insert( NODEITEM( "ElevationGrid", WRL2_ELEVATIONGRID ) );
node_names.insert( NODEITEM( "Extrusion", WRL2_EXTRUSION ) ); nodenames.insert( NODEITEM( "Extrusion", WRL2_EXTRUSION ) );
node_names.insert( NODEITEM( "Fog", WRL2_FOG ) ); nodenames.insert( NODEITEM( "Fog", WRL2_FOG ) );
node_names.insert( NODEITEM( "FontStyle", WRL2_FONTSTYLE ) ); nodenames.insert( NODEITEM( "FontStyle", WRL2_FONTSTYLE ) );
node_names.insert( NODEITEM( "Group", WRL2_GROUP ) ); nodenames.insert( NODEITEM( "Group", WRL2_GROUP ) );
node_names.insert( NODEITEM( "ImageTexture", WRL2_IMAGETEXTURE ) ); nodenames.insert( NODEITEM( "ImageTexture", WRL2_IMAGETEXTURE ) );
node_names.insert( NODEITEM( "IndexedFaceSet", WRL2_INDEXEDFACESET ) ); nodenames.insert( NODEITEM( "IndexedFaceSet", WRL2_INDEXEDFACESET ) );
node_names.insert( NODEITEM( "IndexedLineSet", WRL2_INDEXEDLINESET ) ); nodenames.insert( NODEITEM( "IndexedLineSet", WRL2_INDEXEDLINESET ) );
node_names.insert( NODEITEM( "Inline", WRL2_INLINE ) ); nodenames.insert( NODEITEM( "Inline", WRL2_INLINE ) );
node_names.insert( NODEITEM( "LOD", WRL2_LOD ) ); nodenames.insert( NODEITEM( "LOD", WRL2_LOD ) );
node_names.insert( NODEITEM( "Material", WRL2_MATERIAL ) ); nodenames.insert( NODEITEM( "Material", WRL2_MATERIAL ) );
node_names.insert( NODEITEM( "MovieTexture", WRL2_MOVIETEXTURE ) ); nodenames.insert( NODEITEM( "MovieTexture", WRL2_MOVIETEXTURE ) );
node_names.insert( NODEITEM( "NavigationInfo", WRL2_NAVIGATIONINFO ) ); nodenames.insert( NODEITEM( "NavigationInfo", WRL2_NAVIGATIONINFO ) );
node_names.insert( NODEITEM( "Normal", WRL2_NORMAL ) ); nodenames.insert( NODEITEM( "Normal", WRL2_NORMAL ) );
node_names.insert( NODEITEM( "NormalInterpolator", WRL2_NORMALINTERPOLATOR ) ); nodenames.insert( NODEITEM( "NormalInterpolator", WRL2_NORMALINTERPOLATOR ) );
node_names.insert( NODEITEM( "OrientationInterpolator", WRL2_ORIENTATIONINTERPOLATOR ) ); nodenames.insert( NODEITEM( "OrientationInterpolator", WRL2_ORIENTATIONINTERPOLATOR ) );
node_names.insert( NODEITEM( "PixelTexture", WRL2_PIXELTEXTURE ) ); nodenames.insert( NODEITEM( "PixelTexture", WRL2_PIXELTEXTURE ) );
node_names.insert( NODEITEM( "PlaneSensor", WRL2_PLANESENSOR ) ); nodenames.insert( NODEITEM( "PlaneSensor", WRL2_PLANESENSOR ) );
node_names.insert( NODEITEM( "PointLight", WRL2_POINTLIGHT ) ); nodenames.insert( NODEITEM( "PointLight", WRL2_POINTLIGHT ) );
node_names.insert( NODEITEM( "PointSet", WRL2_POINTSET ) ); nodenames.insert( NODEITEM( "PointSet", WRL2_POINTSET ) );
node_names.insert( NODEITEM( "PositionInterpolator", WRL2_POSITIONINTERPOLATOR ) ); nodenames.insert( NODEITEM( "PositionInterpolator", WRL2_POSITIONINTERPOLATOR ) );
node_names.insert( NODEITEM( "ProximitySensor", WRL2_PROXIMITYSENSOR ) ); nodenames.insert( NODEITEM( "ProximitySensor", WRL2_PROXIMITYSENSOR ) );
node_names.insert( NODEITEM( "ScalarInterpolator", WRL2_SCALARINTERPOLATOR ) ); nodenames.insert( NODEITEM( "ScalarInterpolator", WRL2_SCALARINTERPOLATOR ) );
node_names.insert( NODEITEM( "Script", WRL2_SCRIPT ) ); nodenames.insert( NODEITEM( "Script", WRL2_SCRIPT ) );
node_names.insert( NODEITEM( "Shape", WRL2_SHAPE ) ); nodenames.insert( NODEITEM( "Shape", WRL2_SHAPE ) );
node_names.insert( NODEITEM( "Sound", WRL2_SOUND ) ); nodenames.insert( NODEITEM( "Sound", WRL2_SOUND ) );
node_names.insert( NODEITEM( "Sphere", WRL2_SPHERE ) ); nodenames.insert( NODEITEM( "Sphere", WRL2_SPHERE ) );
node_names.insert( NODEITEM( "SphereSensor", WRL2_SPHERESENSOR ) ); nodenames.insert( NODEITEM( "SphereSensor", WRL2_SPHERESENSOR ) );
node_names.insert( NODEITEM( "SpotLight", WRL2_SPOTLIGHT ) ); nodenames.insert( NODEITEM( "SpotLight", WRL2_SPOTLIGHT ) );
node_names.insert( NODEITEM( "Switch", WRL2_SWITCH ) ); nodenames.insert( NODEITEM( "Switch", WRL2_SWITCH ) );
node_names.insert( NODEITEM( "Text", WRL2_TEXT ) ); nodenames.insert( NODEITEM( "Text", WRL2_TEXT ) );
node_names.insert( NODEITEM( "TextureCoordinate", WRL2_TEXTURECOORDINATE ) ); nodenames.insert( NODEITEM( "TextureCoordinate", WRL2_TEXTURECOORDINATE ) );
node_names.insert( NODEITEM( "TextureTransform", WRL2_TEXTURETRANSFORM ) ); nodenames.insert( NODEITEM( "TextureTransform", WRL2_TEXTURETRANSFORM ) );
node_names.insert( NODEITEM( "TimeSensor", WRL2_TIMESENSOR ) ); nodenames.insert( NODEITEM( "TimeSensor", WRL2_TIMESENSOR ) );
node_names.insert( NODEITEM( "TouchSensor", WRL2_TOUCHSENSOR ) ); nodenames.insert( NODEITEM( "TouchSensor", WRL2_TOUCHSENSOR ) );
node_names.insert( NODEITEM( "Transform", WRL2_TRANSFORM ) ); nodenames.insert( NODEITEM( "Transform", WRL2_TRANSFORM ) );
node_names.insert( NODEITEM( "ViewPoint", WRL2_VIEWPOINT ) ); nodenames.insert( NODEITEM( "ViewPoint", WRL2_VIEWPOINT ) );
node_names.insert( NODEITEM( "VisibilitySensor", WRL2_VISIBILITYSENSOR ) ); nodenames.insert( NODEITEM( "VisibilitySensor", WRL2_VISIBILITYSENSOR ) );
node_names.insert( NODEITEM( "WorldInfo", WRL2_WORLDINFO ) ); nodenames.insert( NODEITEM( "WorldInfo", WRL2_WORLDINFO ) );
} }
return; return;
@ -124,10 +127,6 @@ WRL2NODE::WRL2NODE()
WRL2NODE::~WRL2NODE() WRL2NODE::~WRL2NODE()
{ {
std::list< WRL2NODE* > m_BackPointers; // nodes which hold a reference to this
std::list< WRL2NODE* > m_Children; // nodes owned by this node
std::list< WRL2NODE* > m_References; // nodes not owned but referenced by this node
if( m_Parent ) if( m_Parent )
m_Parent->unlinkChildNode( this ); m_Parent->unlinkChildNode( this );
@ -178,7 +177,7 @@ void WRL2NODE::delNodeRef( WRL2NODE* aNode )
} }
WRL2TYPES WRL2NODE::GetNodeType( void ) const WRL2NODES WRL2NODE::GetNodeType( void ) const
{ {
return m_Type; return m_Type;
} }
@ -192,7 +191,7 @@ WRL2NODE* WRL2NODE::GetParent( void )
const char* WRL2NODE::GetName( void ) const char* WRL2NODE::GetName( void )
{ {
return m_Name; return m_Name.c_str();
} }
@ -246,10 +245,24 @@ bool WRL2NODE::SetName(const char *aName)
} }
const char* WRL2NODE::GetNodeTypeName( WRL::V2TYPES aNodeType ) const const char* WRL2NODE::GetNodeTypeName( WRL2NODES aNodeType ) const
{ {
if( aNodeType < WRL2_BEGIN || aNodeType >= WRL2_END ) if( aNodeType < WRL2_BEGIN || aNodeType >= WRL2_END )
return NULL; return NULL;
return nodenames[aNodeType]->first.c_str(); NODEMAP::iterator it = nodenames.begin();
advance( it, aNodeType );
return it->first.c_str();
}
WRL2NODES WRL2NODE::getNodeTypeID( const std::string aNodeName )
{
NODEMAP::iterator it = nodenames.find( aNodeName );
if( nodenames.end() != it )
return it->second;
return WRL2_INVALID;
} }

View File

@ -57,12 +57,20 @@ class WRL2NODE
{ {
protected: protected:
WRL2NODE* m_Parent; // pointer to parent node; may be NULL for top level node WRL2NODE* m_Parent; // pointer to parent node; may be NULL for top level node
WRL2TYPES m_Type; // type of VRML node WRL2NODES m_Type; // type of VRML node
std::string m_Name; // name to use for referencing the node by name std::string m_Name; // name to use for referencing the node by name
std::list< WRL2NODE* > m_BackPointers; // nodes which hold a reference to this std::list< WRL2NODE* > m_BackPointers; // nodes which hold a reference to this
public: public:
/**
* Function getNodeTypeID
* returns the ID based on the given aNodeName or WRL2_INVALID (WRL2_END)
* if no such node name exists
*/
WRL2NODES getNodeTypeID( const std::string aNodeName );
/** /**
* Function unlinkChild * Function unlinkChild
* removes references to an owned child; it is invoked by the child upon destruction * removes references to an owned child; it is invoked by the child upon destruction
@ -110,7 +118,7 @@ public:
* Function GetNodeType * Function GetNodeType
* returns the type of this node instance * returns the type of this node instance
*/ */
WRL2TYPES GetNodeType( void ) const; WRL2NODES GetNodeType( void ) const;
/** /**
* Function GetParent * Function GetParent
@ -133,7 +141,7 @@ public:
virtual const char* GetName( void ); virtual const char* GetName( void );
virtual bool SetName(const char *aName); virtual bool SetName(const char *aName);
const char * GetNodeTypeName( WRL::V2TYPES aNodeType ) const; const char* GetNodeTypeName( WRL2NODES aNodeType ) const;
/** /**
* Function FindNode searches the tree of linked nodes and returns a * Function FindNode searches the tree of linked nodes and returns a

View File

@ -826,6 +826,15 @@ bool WRLPROC::ReadSFInt( int& aSFInt32, bool* hasComma )
return false; return false;
} }
if( std::string::npos != tmp.find( "0x" ) )
{
#warning TO BE IMPLEMENTED
// XXX - handle the case of a hex value.
// Rules: "0x" + "0-9, A-F" - pay attention to capitalization;
// if we encounter defective hex values (using 'a-f') we may
// consider relaxing the requirements.
}
std::istringstream istr; std::istringstream istr;
istr.str( tmp ); istr.str( tmp );

View File

@ -44,7 +44,7 @@ enum WRLVERSION
// These are used to look up node names and to quickly // These are used to look up node names and to quickly
// determine what routine to invoke to read a section of // determine what routine to invoke to read a section of
// a file. // a file.
enum WRLNODES enum WRL2NODES
{ {
WRL2_BASE = 0, // not really a VRML node but we need a top level virtual node WRL2_BASE = 0, // not really a VRML node but we need a top level virtual node
WRL2_BEGIN, WRL2_BEGIN,
@ -102,7 +102,8 @@ enum WRLNODES
WRL2_VIEWPOINT, WRL2_VIEWPOINT,
WRL2_VISIBILITYSENSOR, WRL2_VISIBILITYSENSOR,
WRL2_WORLDINFO, WRL2_WORLDINFO,
WRL2_END WRL2_INVALID,
WRL2_END = WRL2_INVALID
}; };