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
vrml.cpp
v2/wrlproc.cpp
# v2/vrml2_node.cpp
# v2/vrml2_base.cpp
v2/vrml2_node.cpp
v2/vrml2_base.cpp
)
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )

View File

@ -27,9 +27,9 @@
#include "vrml2_helpers.h"
WRL2BASE::WRL2BASE( WRL2NODE* aParent ) : WRL2NODE()
WRL2BASE::WRL2BASE() : WRL2NODE()
{
m_Type = V2_BASE;
m_Type = WRL2_BASE;
return;
}
@ -46,7 +46,7 @@ WRL2BASE::~WRL2BASE()
++sC;
}
sC.clear();
m_Children.clear();
return;
}
@ -56,8 +56,10 @@ bool WRL2BASE::SetParent( WRL2NODE* aParent )
{
#ifdef DEBUG
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
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 )
{
if( proc.GetVRMLType() != VRML_V2 )
@ -146,15 +179,148 @@ bool WRL2BASE::Read( WRLPROC& proc )
}
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;
} while( !glob.empty() );
if( !glob.compare( "PROTO" ) )
{
// 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 -
#warning TO BE IMPLEMENTED

View File

@ -48,6 +48,11 @@
#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

View File

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

View File

@ -25,22 +25,25 @@
#include <set>
#include <map>
#include <utility>
#include <iterator>
#include <cctype>
#include <iostream>
#include <algorithm>
#include "vrml2_node.h"
static std::set< std::string > badNames;
typedef std::pair< std::string, WRLNODES > NODEITEM;
typedef std::map< std::string, WRLNODES > NODEMAP;
typedef std::pair< std::string, WRL2NODES > NODEITEM;
typedef std::map< std::string, WRL2NODES > NODEMAP;
static NODEMAP nodenames;
WRL2NODE::WRL2NODE()
{
m_Parent = NULL;
m_Type = V2_END;
m_Type = WRL2_END;
if( badNames.empty() )
{
@ -62,60 +65,60 @@ WRL2NODE::WRL2NODE()
if( nodenames.empty() )
{
node_names.insert( NODEITEM( "Anchor", WRL2_ANCHOR ) );
node_names.insert( NODEITEM( "Appearance", WRL2_APPEARANCE ) );
node_names.insert( NODEITEM( "Audioclip", WRL2_AUDIOCLIP );
node_names.insert( NODEITEM( "Background", WRL2_BACKGROUND ) );
node_names.insert( NODEITEM( "Billboard", WRL2_BILLBOARD ) );
node_names.insert( NODEITEM( "Box", WRL2_BOX ) );
node_names.insert( NODEITEM( "Collision", WRL2_COLLISION ) );
node_names.insert( NODEITEM( "Color", WRL2_COLOR ) );
node_names.insert( NODEITEM( "ColorInterpolator", WRL2_COLORINTERPOLATOR ) );
node_names.insert( NODEITEM( "Cone", WRL2_CONE ) );
node_names.insert( NODEITEM( "Coordinate", WRL2_COORDINATE ) );
node_names.insert( NODEITEM( "CoordinateInterpolator", WRL2_COORDINATEINTERPOLATOR ) );
node_names.insert( NODEITEM( "Cylinder", WRL2_CYLINDER ) );
node_names.insert( NODEITEM( "CylinderSensor", WRL2_CYLINDERSENSOR ) );
node_names.insert( NODEITEM( "DirectionalLight", WRL2_DIRECTIONALLIGHT ) );
node_names.insert( NODEITEM( "ElevationGrid", WRL2_ELEVATIONGRID ) );
node_names.insert( NODEITEM( "Extrusion", WRL2_EXTRUSION ) );
node_names.insert( NODEITEM( "Fog", WRL2_FOG ) );
node_names.insert( NODEITEM( "FontStyle", WRL2_FONTSTYLE ) );
node_names.insert( NODEITEM( "Group", WRL2_GROUP ) );
node_names.insert( NODEITEM( "ImageTexture", WRL2_IMAGETEXTURE ) );
node_names.insert( NODEITEM( "IndexedFaceSet", WRL2_INDEXEDFACESET ) );
node_names.insert( NODEITEM( "IndexedLineSet", WRL2_INDEXEDLINESET ) );
node_names.insert( NODEITEM( "Inline", WRL2_INLINE ) );
node_names.insert( NODEITEM( "LOD", WRL2_LOD ) );
node_names.insert( NODEITEM( "Material", WRL2_MATERIAL ) );
node_names.insert( NODEITEM( "MovieTexture", WRL2_MOVIETEXTURE ) );
node_names.insert( NODEITEM( "NavigationInfo", WRL2_NAVIGATIONINFO ) );
node_names.insert( NODEITEM( "Normal", WRL2_NORMAL ) );
node_names.insert( NODEITEM( "NormalInterpolator", WRL2_NORMALINTERPOLATOR ) );
node_names.insert( NODEITEM( "OrientationInterpolator", WRL2_ORIENTATIONINTERPOLATOR ) );
node_names.insert( NODEITEM( "PixelTexture", WRL2_PIXELTEXTURE ) );
node_names.insert( NODEITEM( "PlaneSensor", WRL2_PLANESENSOR ) );
node_names.insert( NODEITEM( "PointLight", WRL2_POINTLIGHT ) );
node_names.insert( NODEITEM( "PointSet", WRL2_POINTSET ) );
node_names.insert( NODEITEM( "PositionInterpolator", WRL2_POSITIONINTERPOLATOR ) );
node_names.insert( NODEITEM( "ProximitySensor", WRL2_PROXIMITYSENSOR ) );
node_names.insert( NODEITEM( "ScalarInterpolator", WRL2_SCALARINTERPOLATOR ) );
node_names.insert( NODEITEM( "Script", WRL2_SCRIPT ) );
node_names.insert( NODEITEM( "Shape", WRL2_SHAPE ) );
node_names.insert( NODEITEM( "Sound", WRL2_SOUND ) );
node_names.insert( NODEITEM( "Sphere", WRL2_SPHERE ) );
node_names.insert( NODEITEM( "SphereSensor", WRL2_SPHERESENSOR ) );
node_names.insert( NODEITEM( "SpotLight", WRL2_SPOTLIGHT ) );
node_names.insert( NODEITEM( "Switch", WRL2_SWITCH ) );
node_names.insert( NODEITEM( "Text", WRL2_TEXT ) );
node_names.insert( NODEITEM( "TextureCoordinate", WRL2_TEXTURECOORDINATE ) );
node_names.insert( NODEITEM( "TextureTransform", WRL2_TEXTURETRANSFORM ) );
node_names.insert( NODEITEM( "TimeSensor", WRL2_TIMESENSOR ) );
node_names.insert( NODEITEM( "TouchSensor", WRL2_TOUCHSENSOR ) );
node_names.insert( NODEITEM( "Transform", WRL2_TRANSFORM ) );
node_names.insert( NODEITEM( "ViewPoint", WRL2_VIEWPOINT ) );
node_names.insert( NODEITEM( "VisibilitySensor", WRL2_VISIBILITYSENSOR ) );
node_names.insert( NODEITEM( "WorldInfo", WRL2_WORLDINFO ) );
nodenames.insert( NODEITEM( "Anchor", WRL2_ANCHOR ) );
nodenames.insert( NODEITEM( "Appearance", WRL2_APPEARANCE ) );
nodenames.insert( NODEITEM( "Audioclip", WRL2_AUDIOCLIP ) );
nodenames.insert( NODEITEM( "Background", WRL2_BACKGROUND ) );
nodenames.insert( NODEITEM( "Billboard", WRL2_BILLBOARD ) );
nodenames.insert( NODEITEM( "Box", WRL2_BOX ) );
nodenames.insert( NODEITEM( "Collision", WRL2_COLLISION ) );
nodenames.insert( NODEITEM( "Color", WRL2_COLOR ) );
nodenames.insert( NODEITEM( "ColorInterpolator", WRL2_COLORINTERPOLATOR ) );
nodenames.insert( NODEITEM( "Cone", WRL2_CONE ) );
nodenames.insert( NODEITEM( "Coordinate", WRL2_COORDINATE ) );
nodenames.insert( NODEITEM( "CoordinateInterpolator", WRL2_COORDINATEINTERPOLATOR ) );
nodenames.insert( NODEITEM( "Cylinder", WRL2_CYLINDER ) );
nodenames.insert( NODEITEM( "CylinderSensor", WRL2_CYLINDERSENSOR ) );
nodenames.insert( NODEITEM( "DirectionalLight", WRL2_DIRECTIONALLIGHT ) );
nodenames.insert( NODEITEM( "ElevationGrid", WRL2_ELEVATIONGRID ) );
nodenames.insert( NODEITEM( "Extrusion", WRL2_EXTRUSION ) );
nodenames.insert( NODEITEM( "Fog", WRL2_FOG ) );
nodenames.insert( NODEITEM( "FontStyle", WRL2_FONTSTYLE ) );
nodenames.insert( NODEITEM( "Group", WRL2_GROUP ) );
nodenames.insert( NODEITEM( "ImageTexture", WRL2_IMAGETEXTURE ) );
nodenames.insert( NODEITEM( "IndexedFaceSet", WRL2_INDEXEDFACESET ) );
nodenames.insert( NODEITEM( "IndexedLineSet", WRL2_INDEXEDLINESET ) );
nodenames.insert( NODEITEM( "Inline", WRL2_INLINE ) );
nodenames.insert( NODEITEM( "LOD", WRL2_LOD ) );
nodenames.insert( NODEITEM( "Material", WRL2_MATERIAL ) );
nodenames.insert( NODEITEM( "MovieTexture", WRL2_MOVIETEXTURE ) );
nodenames.insert( NODEITEM( "NavigationInfo", WRL2_NAVIGATIONINFO ) );
nodenames.insert( NODEITEM( "Normal", WRL2_NORMAL ) );
nodenames.insert( NODEITEM( "NormalInterpolator", WRL2_NORMALINTERPOLATOR ) );
nodenames.insert( NODEITEM( "OrientationInterpolator", WRL2_ORIENTATIONINTERPOLATOR ) );
nodenames.insert( NODEITEM( "PixelTexture", WRL2_PIXELTEXTURE ) );
nodenames.insert( NODEITEM( "PlaneSensor", WRL2_PLANESENSOR ) );
nodenames.insert( NODEITEM( "PointLight", WRL2_POINTLIGHT ) );
nodenames.insert( NODEITEM( "PointSet", WRL2_POINTSET ) );
nodenames.insert( NODEITEM( "PositionInterpolator", WRL2_POSITIONINTERPOLATOR ) );
nodenames.insert( NODEITEM( "ProximitySensor", WRL2_PROXIMITYSENSOR ) );
nodenames.insert( NODEITEM( "ScalarInterpolator", WRL2_SCALARINTERPOLATOR ) );
nodenames.insert( NODEITEM( "Script", WRL2_SCRIPT ) );
nodenames.insert( NODEITEM( "Shape", WRL2_SHAPE ) );
nodenames.insert( NODEITEM( "Sound", WRL2_SOUND ) );
nodenames.insert( NODEITEM( "Sphere", WRL2_SPHERE ) );
nodenames.insert( NODEITEM( "SphereSensor", WRL2_SPHERESENSOR ) );
nodenames.insert( NODEITEM( "SpotLight", WRL2_SPOTLIGHT ) );
nodenames.insert( NODEITEM( "Switch", WRL2_SWITCH ) );
nodenames.insert( NODEITEM( "Text", WRL2_TEXT ) );
nodenames.insert( NODEITEM( "TextureCoordinate", WRL2_TEXTURECOORDINATE ) );
nodenames.insert( NODEITEM( "TextureTransform", WRL2_TEXTURETRANSFORM ) );
nodenames.insert( NODEITEM( "TimeSensor", WRL2_TIMESENSOR ) );
nodenames.insert( NODEITEM( "TouchSensor", WRL2_TOUCHSENSOR ) );
nodenames.insert( NODEITEM( "Transform", WRL2_TRANSFORM ) );
nodenames.insert( NODEITEM( "ViewPoint", WRL2_VIEWPOINT ) );
nodenames.insert( NODEITEM( "VisibilitySensor", WRL2_VISIBILITYSENSOR ) );
nodenames.insert( NODEITEM( "WorldInfo", WRL2_WORLDINFO ) );
}
return;
@ -124,10 +127,6 @@ 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 )
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;
}
@ -192,7 +191,7 @@ WRL2NODE* WRL2NODE::GetParent( 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 )
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:
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::list< WRL2NODE* > m_BackPointers; // nodes which hold a reference to this
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
* removes references to an owned child; it is invoked by the child upon destruction
@ -110,7 +118,7 @@ public:
* Function GetNodeType
* returns the type of this node instance
*/
WRL2TYPES GetNodeType( void ) const;
WRL2NODES GetNodeType( void ) const;
/**
* Function GetParent
@ -133,7 +141,7 @@ public:
virtual const char* GetName( void );
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

View File

@ -826,6 +826,15 @@ bool WRLPROC::ReadSFInt( int& aSFInt32, bool* hasComma )
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;
istr.str( tmp );

View File

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