Added preliminary X3D parser with no visualization data

This commit is contained in:
Cirilo Bernardo 2016-02-05 15:32:52 +11:00
parent 68dde1f16f
commit ffa0775074
18 changed files with 2635 additions and 23 deletions

View File

@ -3,6 +3,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/v1
${CMAKE_CURRENT_SOURCE_DIR}/v2
${CMAKE_CURRENT_SOURCE_DIR}/x3d
)
add_definitions( -DDEBUG_VRML1=1 -DDEBUG_VRML2=1 )
@ -10,6 +11,7 @@ add_definitions( -DDEBUG_VRML1=1 -DDEBUG_VRML2=1 )
add_library( s3d_plugin_vrml MODULE
${CMAKE_SOURCE_DIR}/common/richio.cpp
vrml.cpp
x3d.cpp
wrlproc.cpp
wrlfacet.cpp
v2/vrml2_node.cpp
@ -37,6 +39,13 @@ add_library( s3d_plugin_vrml MODULE
v1/vrml1_faceset.cpp
v1/vrml1_transform.cpp
v1/vrml1_shapehints.cpp
x3d/x3d_appearance.cpp
x3d/x3d_base.cpp
x3d/x3d_coords.cpp
x3d/x3d_ifaceset.cpp
x3d/x3d_ops.cpp
x3d/x3d_shape.cpp
x3d/x3d_transform.cpp
)
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,9 +23,9 @@
/*
* Description:
* This plugin implements the legacy kicad VRML1/VRML2 parsers.
* This VRML plugin will invoke a VRML1 or VRML2 parser depending
* on the identifying information in the file header:
* This plugin implements the legacy kicad VRML1/VRML2 and X3D parsers
* The plugin will invoke a VRML1 or VRML2 parser depending on the
* identifying information in the file header:
*
* #VRML V1.0 ascii
* #VRML V2.0 utf8
@ -44,10 +44,11 @@
#include "wrlproc.h"
#include "vrml1_base.h"
#include "vrml2_base.h"
#include "x3d.h"
#define PLUGIN_VRML_MAJOR 1
#define PLUGIN_VRML_MINOR 1
#define PLUGIN_VRML_MINOR 2
#define PLUGIN_VRML_PATCH 0
#define PLUGIN_VRML_REVNO 0
@ -78,21 +79,25 @@ void GetPluginVersion( unsigned char* Major,
// number of extensions supported
#ifdef _WIN32
#define NEXTS 1
#else
#define NEXTS 2
#else
#define NEXTS 4
#endif
// number of filter sets supported
#define NFILS 1
#define NFILS 2
static char ext0[] = "wrl";
static char ext1[] = "x3d";
#ifdef _WIN32
static char fil0[] = "VRML 1.0/2.0 (*.wrl)|*.wrl";
static char fil1[] = "X3D (*.x3d)|*.x3d";
#else
static char ext1[] = "WRL";
static char ext2[] = "WRL";
static char ext3[] = "X3D";
static char fil0[] = "VRML 1.0/2.0 (*.wrl;*.WRL)|*.wrl;*.WRL";
static char fil1[] = "X3D (*.x3d;*.X3D)|*.x3d;*.X3D";
#endif
static struct FILE_DATA
@ -103,10 +108,13 @@ static struct FILE_DATA
FILE_DATA()
{
extensions[0] = ext0;
extensions[1] = ext1;
filters[0] = fil0;
filters[1] = fil1;
#ifndef _WIN32
extensions[1] = ext1;
extensions[2] = ext2;
extensions[3] = ext3;
#endif
return;
@ -167,26 +175,16 @@ public:
};
SCENEGRAPH* Load( char const* aFileName )
SCENEGRAPH* LoadVRML( const wxString& aFileName )
{
if( NULL == aFileName )
return NULL;
wxString fname = wxString::FromUTF8Unchecked( aFileName );
if( !wxFileName::FileExists( fname ) )
return NULL;
LOCALESWITCH switcher;
SCENEGRAPH* scene = NULL;
FILE_LINE_READER* modelFile = NULL;
SCENEGRAPH* scene = NULL;
try
{
// set the max char limit to 8MB; if a VRML file contains
// longer lines then perhaps it shouldn't be used
modelFile = new FILE_LINE_READER( fname, 0, 8388608 );
modelFile = new FILE_LINE_READER( aFileName, 0, 8388608 );
}
catch( IO_ERROR &e )
{
@ -282,3 +280,37 @@ SCENEGRAPH* Load( char const* aFileName )
return scene;
}
SCENEGRAPH* LoadX3D( const wxString& aFileName )
{
SCENEGRAPH* scene = NULL;
X3DPARSER model;
scene = model.Load( aFileName );
return scene;
}
SCENEGRAPH* Load( char const* aFileName )
{
if( NULL == aFileName )
return NULL;
wxString fname = wxString::FromUTF8Unchecked( aFileName );
if( !wxFileName::FileExists( fname ) )
return NULL;
LOCALESWITCH switcher;
SCENEGRAPH* scene = NULL;
wxString ext = wxFileName( fname ).GetExt();
if( ext == "x3d" || ext == "X3D" )
scene = LoadX3D( fname );
else
scene = LoadVRML( fname );
return scene;
}

124
plugins/3d/vrml/x3d.cpp Normal file
View File

@ -0,0 +1,124 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 2013 Tuomas Vaherkoski <tuomasvaherkoski@gmail.com>
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* Description:
* This plugin implements the legacy kicad X3D parser.
* Due to the rare use of X3D models, this plugin is a simple
* reimplementation of the legacy x3dmodelparser.cpp and is not
* intended to be a compliant X3D implementation.
*/
#include <vector>
#include <wx/tokenzr.h>
#include <iostream>
#include "x3d.h"
#include "x3d_ops.h"
#include "x3d_transform.h"
#include "plugins/3dapi/ifsg_all.h"
SCENEGRAPH* X3DPARSER::Load( const wxString& aFileName )
{
wxXmlDocument doc;
if( !doc.Load( aFileName ) )
return NULL;
if( doc.GetRoot()->GetName() != wxT( "X3D" ) )
return NULL;
NODE_LIST children; // VRML Grouping Nodes at top level
if( !getGroupingNodes( doc.GetRoot(), children ) )
return NULL;
X3D_DICT dictionary; // dictionary for USE/DEF implementation
X3DNODE* topNode = new X3DTRANSFORM;
bool ok = false;
for( NODE_LIST::iterator node_it = children.begin();
node_it != children.end();
node_it++ )
{
wxXmlNode* node = *node_it;
wxString name = node->GetName();
if( name == "Transform" || name == "Group" )
{
// Read a Transform / Group
ok |= X3D::ReadTransform( node, topNode, dictionary );
}
else if( name == "Switch" )
{
ok |= X3D::ReadSwitch( node, topNode, dictionary );
}
}
SCENEGRAPH* sp = NULL;
if( ok )
sp = (SCENEGRAPH*) topNode->TranslateToSG( NULL );
delete topNode;
return sp;
}
bool X3DPARSER::getGroupingNodes( wxXmlNode* aNode, std::vector<wxXmlNode*>& aResult )
{
aResult.clear();
wxXmlNode* scene = NULL;
for( wxXmlNode* child = aNode->GetChildren();
child != NULL;
child = child->GetNext() )
{
if( child->GetName() == "Scene" )
{
scene = child;
break;
}
}
if( NULL == scene )
return false;
for( wxXmlNode* child = scene->GetChildren();
child != NULL;
child = child->GetNext() )
{
wxString name = child->GetName();
if( name == "Transform" || name == "Switch" || name == "Group" )
aResult.push_back( child );
}
if( aResult.empty() )
return false;
return true;
}

49
plugins/3d/vrml/x3d.h Normal file
View File

@ -0,0 +1,49 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef S3D_X3D_H
#define S3D_X3D_H
#include <map>
#include <wx/string.h>
#include <wx/xml/xml.h>
class SCENEGRAPH;
class SGNODE;
class X3DPARSER
{
private:
/**
* Function getGroupingNodes
* retrieves all permissible top-level nodes in an X3D/VRML file
*/
bool getGroupingNodes( wxXmlNode* aNode, std::vector<wxXmlNode*>& aResult );
public:
SCENEGRAPH* Load( const wxString& aFileName );
};
#endif // S3D_X3D_H

View File

@ -0,0 +1,236 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <iostream>
#include <wx/xml/xml.h>
#include "x3d_ops.h"
#include "x3d_appearance.h"
X3DAPP::X3DAPP() : X3DNODE()
{
m_Type = X3D_APPEARANCE;
init();
return;
}
X3DAPP::X3DAPP( X3DNODE* aParent ) : X3DNODE()
{
m_Type = X3D_APPEARANCE;
init();
if( NULL != aParent )
{
X3DNODES ptype = aParent->GetNodeType();
if( X3D_SHAPE == ptype )
m_Parent = aParent;
}
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
X3DAPP::~X3DAPP()
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Destroying Appearance\n";
#endif
if( !m_MatName.empty() && m_Dict )
m_Dict->DelName( m_MatName, this );
return;
}
void X3DAPP::init()
{
// default material values as per VRML2 spec
diffuseColor.x = 0.8;
diffuseColor.y = 0.8;
diffuseColor.z = 0.8;
emissiveColor.x = 0.0;
emissiveColor.y = 0.0;
emissiveColor.z = 0.0;
specularColor = emissiveColor;
ambientIntensity = 0.2;
shininess = 0.2;
transparency = 0.0;
return;
}
void X3DAPP::readFields( wxXmlNode* aNode )
{
// DEF
// diffuseColor
// emissiveColor
// specularColor
// ambientIntensity
// shininess
// transparency
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_MatName = prop->GetValue();
m_Dict->AddName( m_MatName, this );
}
if( pname == "USE" )
{
X3DNODE* np = m_Dict->FindName( prop->GetValue() );
if( np->GetNodeType() == X3D_APPEARANCE )
{
X3DAPP* ap = (X3DAPP*) np;
diffuseColor = ap->diffuseColor;
emissiveColor = ap->emissiveColor;
specularColor = ap->specularColor;
ambientIntensity = ap->ambientIntensity;
shininess = ap->shininess;
transparency = ap->transparency;
}
}
else if( pname == "diffuseColor" )
X3D::ParseSFVec3( prop->GetValue(), diffuseColor );
else if( pname == "emissiveColor" )
X3D::ParseSFVec3( prop->GetValue(), emissiveColor );
else if( pname == "specularColor" )
X3D::ParseSFVec3( prop->GetValue(), specularColor );
else if( pname == "ambientIntensity" )
X3D::ParseSFFloat( prop->GetValue(), ambientIntensity );
else if( pname == "shininess" )
X3D::ParseSFFloat( prop->GetValue(), shininess );
else if( pname == "transparency" )
X3D::ParseSFFloat( prop->GetValue(), transparency );
}
return;
}
bool X3DAPP::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
{
if( NULL == aTopNode || NULL == aNode )
return false;
m_Dict = &aDict;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_Name = prop->GetValue();
m_Dict->AddName( m_Name, this );
}
}
wxXmlNode* pmat = NULL;
for( wxXmlNode* child = aNode->GetChildren();
child != NULL;
child = child->GetNext() )
{
if( child->GetName() == "Material" )
pmat = child;
}
if( NULL == pmat )
return false;
readFields( pmat );
if( !SetParent( aTopNode ) )
return false;
return true;
}
bool X3DAPP::SetParent( X3DNODE* aParent, bool doUnlink )
{
if( aParent == m_Parent )
return true;
if( NULL != aParent )
{
X3DNODES nt = aParent->GetNodeType();
if( nt != X3D_SHAPE )
return false;
}
if( NULL != m_Parent && doUnlink )
m_Parent->unlinkChildNode( this );
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return true;
}
bool X3DAPP::AddChildNode( X3DNODE* aNode )
{
return false;
}
bool X3DAPP::AddRefNode( X3DNODE* aNode )
{
return false;
}
SGNODE* X3DAPP::TranslateToSG( SGNODE* aParent )
{
// XXX -
return NULL;
}

View File

@ -0,0 +1,69 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_appearance.h
*/
#ifndef X3D_APPEARANCE_H
#define X3D_APPEARANCE_H
#include <vector>
#include "wrltypes.h"
#include "x3d_shape.h"
/**
* Class X3DAPP
*/
class X3DAPP : public X3DNODE
{
private:
void init();
void readFields( wxXmlNode* aNode );
wxString m_MatName; // material name
protected:
WRLVEC3F diffuseColor;
WRLVEC3F emissiveColor;
WRLVEC3F specularColor;
float ambientIntensity;
float shininess;
float transparency;
public:
X3DAPP();
X3DAPP( X3DNODE* aParent );
virtual ~X3DAPP();
// functions inherited from X3DNODE
bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict );
bool SetParent( X3DNODE* aParent, bool doUnlink = true );
bool AddChildNode( X3DNODE* aNode );
bool AddRefNode( X3DNODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent );
};
#endif // X3D_APPEARANCE_H

View File

@ -0,0 +1,200 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <utility>
#include <algorithm>
#include "x3d_base.h"
bool X3D_DICT::AddName( const wxString& aName, X3DNODE* aNode )
{
if( aName.empty() )
return false;
std::map< wxString, X3DNODE* >::iterator ir = reg.find( aName );
if( ir != reg.end() )
reg.erase( ir );
reg.insert( std::pair< wxString, X3DNODE* >( aName, aNode ) );
return true;
}
bool X3D_DICT::DelName( const wxString& aName, X3DNODE* aNode )
{
if( aName.empty() )
return false;
std::map< wxString, X3DNODE* >::iterator ir = reg.find( aName );
if( ir != reg.end() && ir->second == aNode )
{
reg.erase( ir );
return true;
}
return false;
}
X3DNODE* X3D_DICT::FindName( const wxString& aName )
{
if( aName.empty() )
return NULL;
std::map< wxString, X3DNODE* >::iterator ir = reg.find( aName );
if( ir != reg.end() )
return ir->second;
return NULL;
}
X3DNODE::X3DNODE()
{
m_Parent = NULL;
m_sgNode = NULL;
m_Dict = NULL;
return;
}
X3DNODE::~X3DNODE()
{
if( !m_Name.empty() && NULL != m_Dict )
m_Dict->DelName( m_Name, this );
return;
}
void X3DNODE::unlinkChildNode( const X3DNODE* aNode )
{
std::list< X3DNODE* >::iterator sL = m_Children.begin();
std::list< X3DNODE* >::iterator eL = m_Children.end();
while( sL != eL )
{
if( *sL == aNode )
{
m_Children.erase( sL );
return;
}
++sL;
}
return;
}
void X3DNODE::unlinkRefNode( const X3DNODE* aNode )
{
std::list< X3DNODE* >::iterator sL = m_Refs.begin();
std::list< X3DNODE* >::iterator eL = m_Refs.end();
while( sL != eL )
{
if( *sL == aNode )
{
m_Refs.erase( sL );
return;
}
++sL;
}
return;
}
void X3DNODE::addNodeRef( X3DNODE* aNode )
{
// the parent node must never be added as a backpointer
if( aNode == m_Parent )
return;
std::list< X3DNODE* >::iterator sR = m_BackPointers.begin();
std::list< X3DNODE* >::iterator eR = m_BackPointers.end();
while( sR != eR )
{
if( *sR == aNode )
return;
++sR;
}
m_BackPointers.push_back( aNode );
return;
}
void X3DNODE::delNodeRef( X3DNODE* aNode )
{
std::list< X3DNODE* >::iterator np =
std::find( m_BackPointers.begin(), m_BackPointers.end(), aNode );
if( np != m_BackPointers.end() )
{
m_BackPointers.erase( np );
return;
}
#ifdef DEBUG_X3D
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] delNodeRef() did not find its target\n";
#endif
return;
}
X3DNODES X3DNODE::GetNodeType( void ) const
{
return m_Type;
}
X3DNODE* X3DNODE::GetParent( void ) const
{
return m_Parent;
}
wxString X3DNODE::GetName( void ) const
{
return m_Name;
}
std::string X3DNODE::GetError( void )
{
return m_error;
}

View File

@ -0,0 +1,183 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_base.h
* declares base class of X3D tree
*/
#ifndef X3D_BASE_H
#define X3D_BASE_H
#include <list>
#include <map>
#include <string>
#include <vector>
#include <wx/string.h>
class X3DNODE;
class SGNODE;
class wxXmlNode;
typedef std::vector< wxXmlNode* > NODE_LIST;
// a class to hold the dictionary of node DEFs
class X3D_DICT
{
private:
std::map< wxString, X3DNODE* > reg;
public:
bool AddName( const wxString& aName, X3DNODE* aNode );
bool DelName( const wxString& aName, X3DNODE* aNode );
X3DNODE* FindName( const wxString& aName );
};
enum X3DNODES
{
X3D_TRANSFORM = 0, // Transform or Group node
X3D_SWITCH,
X3D_SHAPE,
X3D_APPEARANCE,
X3D_INDEXED_FACE_SET,
X3D_COORDINATE,
X3D_INVALID,
X3D_END = X3D_INVALID
};
/**
* Class X3DNODE
* represents the base class of all X3D nodes
*/
class X3DNODE
{
protected:
X3DNODE* m_Parent; // pointer to parent node; may be NULL for top level node
X3DNODES m_Type; // type of node
X3D_DICT* m_Dict; // reference to dictionary
std::list< X3DNODE* > m_BackPointers; // nodes which hold a reference to this
std::list< X3DNODE* > m_Children; // nodes owned by this node
std::list< X3DNODE* > m_Refs; // nodes referenced by this node
std::string m_error;
wxString m_Name; // name to use for referencing the node by name
SGNODE* m_sgNode; // the SGNODE representation of the display data
public:
/**
* Function unlinkChild
* removes references to an owned child; it is invoked by the child upon destruction
* to ensure that the parent has no invalid references.
*
* @param aNode is the child which is being deleted
*/
virtual void unlinkChildNode( const X3DNODE* aNode );
/**
* Function unlinkRef
* removes pointers to a referenced node; it is invoked by the referenced node
* upon destruction to ensure that the referring node has no invalid references.
*
* @param aNode is the node which is being deleted
*/
virtual void unlinkRefNode( const X3DNODE* aNode );
/**
* Function addNodeRef
* adds a pointer to a node which references, but does not own, this node.
* Such back-pointers are required to ensure that invalidated references
* are removed when a node is deleted
*
* @param aNode is the node holding a reference to this object
*/
void addNodeRef( X3DNODE* aNode );
/**
* Function delNodeRef
* removes a pointer to a node which references, but does not own, this node.
*
* @param aNode is the node holding a reference to this object
*/
void delNodeRef( X3DNODE* aNode );
public:
X3DNODE();
virtual ~X3DNODE();
// read data and return TRUE on success
virtual bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict ) = 0;
/**
* Function GetNodeType
* returns the type of this node instance
*/
X3DNODES GetNodeType( void ) const;
/**
* Function GetParent
* returns a pointer to the parent node of this object
* or NULL if the object has no parent (ie. top level transform)
*/
X3DNODE* GetParent( void ) const;
/**
* Function GetName
* returns the name of this object
*/
wxString GetName( void ) const;
/**
* Function SetParent
* sets the parent X3DNODE of this object.
*
* @param aParent [in] is the desired parent node
* @param doUnlink indicates that the child must be unlinked from the parent
* @return true if the operation succeeds; false if
* the given node is not allowed to be a parent to
* the derived object.
*/
virtual bool SetParent( X3DNODE* aParent, bool doUnlink = true ) = 0;
virtual bool AddChildNode( X3DNODE* aNode ) = 0;
virtual bool AddRefNode( X3DNODE* aNode ) = 0;
std::string GetError( void );
/**
* Function TranslateToSG
* produces a representation of the data using the intermediate
* scenegraph structures of the kicad_3dsg library.
*
* @param aParent is a pointer to the parent SG node
* @return is non-NULL on success
*/
virtual SGNODE* TranslateToSG( SGNODE* aParent ) = 0;
};
#endif // X3D_BASE_H

View File

@ -0,0 +1,178 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <iostream>
#include <wx/xml/xml.h>
#include <wx/tokenzr.h>
#include "x3d_ops.h"
#include "x3d_coords.h"
X3DCOORDS::X3DCOORDS() : X3DNODE()
{
m_Type = X3D_COORDINATE;
return;
}
X3DCOORDS::X3DCOORDS( X3DNODE* aParent ) : X3DNODE()
{
m_Type = X3D_COORDINATE;
if( NULL != aParent )
{
X3DNODES ptype = aParent->GetNodeType();
if( X3D_INDEXED_FACE_SET == ptype )
m_Parent = aParent;
}
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
X3DCOORDS::~X3DCOORDS()
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Destroying Coordinate\n";
#endif
return;
}
bool X3DCOORDS::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
{
if( NULL == aTopNode || NULL == aNode )
return false;
m_Dict = &aDict;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_Name = prop->GetValue();
m_Dict->AddName( m_Name, this );
}
else if( pname == "point" )
{
// Save points to vector as doubles
wxStringTokenizer plist( prop->GetValue() );
double point = 0.0;
WRLVEC3F pt;
int i = 0;
while( plist.HasMoreTokens() )
{
if( plist.GetNextToken().ToDouble( &point ) )
{
switch( i % 3 )
{
case 0:
pt.x = point;
break;
case 1:
pt.y = point;
break;
case 2:
pt.z = point;
points.push_back( pt );
break;
}
}
else
{
return false;
}
++i;
}
}
}
if( points.size() < 3 )
return false;
if( !SetParent( aTopNode ) )
return false;
return true;
}
bool X3DCOORDS::SetParent( X3DNODE* aParent, bool doUnlink )
{
if( aParent == m_Parent )
return true;
if( NULL != aParent )
{
X3DNODES nt = aParent->GetNodeType();
if( nt != X3D_INDEXED_FACE_SET )
return false;
}
if( NULL != m_Parent && doUnlink )
m_Parent->unlinkChildNode( this );
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return true;
}
bool X3DCOORDS::AddChildNode( X3DNODE* aNode )
{
return false;
}
bool X3DCOORDS::AddRefNode( X3DNODE* aNode )
{
return false;
}
SGNODE* X3DCOORDS::TranslateToSG( SGNODE* aParent )
{
// XXX -
return NULL;
}

View File

@ -0,0 +1,59 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_coords.h
*/
#ifndef X3D_COORDS_H
#define X3D_COORDS_H
#include <vector>
#include "wrltypes.h"
#include "x3d_ifaceset.h"
/**
* Class X3DCOORDS
*/
class X3DCOORDS : public X3DNODE
{
private:
std::vector< WRLVEC3F > points;
public:
X3DCOORDS();
X3DCOORDS( X3DNODE* aParent );
virtual ~X3DCOORDS();
// functions inherited from X3DNODE
bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict );
bool SetParent( X3DNODE* aParent, bool doUnlink = true );
bool AddChildNode( X3DNODE* aNode );
bool AddRefNode( X3DNODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent );
};
#endif // X3D_COORDS_H

View File

@ -0,0 +1,205 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <iostream>
#include <cmath>
#include <wx/xml/xml.h>
#include <wx/tokenzr.h>
#include "x3d_ops.h"
#include "x3d_ifaceset.h"
X3DIFACESET::X3DIFACESET() : X3DNODE()
{
m_Type = X3D_INDEXED_FACE_SET;
init();
return;
}
X3DIFACESET::X3DIFACESET( X3DNODE* aParent ) : X3DNODE()
{
m_Type = X3D_INDEXED_FACE_SET;
init();
if( NULL != aParent )
{
X3DNODES ptype = aParent->GetNodeType();
if( X3D_SHAPE == ptype )
m_Parent = aParent;
}
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
X3DIFACESET::~X3DIFACESET()
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Destroying IndexedFaceSet\n";
#endif
return;
}
void X3DIFACESET::init()
{
coord = NULL;
ccw = true;
creaseAngle = 0.5;
creaseLimit = 0.878; // approx cos( 0.5 )
return;
}
void X3DIFACESET::readFields( wxXmlNode* aNode )
{
// DEF
// ccw
// creaseAngle
// coordIndex
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_Name = prop->GetValue();
m_Dict->AddName( m_Name, this );
}
else if( pname == "ccw" )
X3D::ParseSFBool( prop->GetValue(), ccw );
else if( pname == "creaseAngle" )
{
X3D::ParseSFFloat( prop->GetValue(), creaseAngle );
if( creaseAngle < 0.0f )
creaseAngle = 0.0f;
else if( creaseAngle > M_PI * 0.34 )
creaseAngle = M_PI / 3.0;
creaseLimit = cosf( creaseAngle );
}
else if( pname == "coordIndex" )
{
wxStringTokenizer indices( prop->GetValue() );
while( indices.HasMoreTokens() )
{
long index = 0;
indices.GetNextToken().ToLong( &index );
coordIndex.push_back( (int) index );
}
}
}
return;
}
bool X3DIFACESET::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
{
if( NULL == aTopNode || NULL == aNode )
return false;
m_Dict = &aDict;
readFields( aNode );
bool ok = false;
for( wxXmlNode* child = aNode->GetChildren();
child != NULL;
child = child->GetNext() )
{
if( child->GetName() == "Coordinate" )
ok = X3D::ReadCoordinates( child, this, aDict );
}
if( false == ok )
return false;
if( !SetParent( aTopNode ) )
return false;
std::cerr << "XXX: Got " << coordIndex.size() << " indices\n";
return true;
}
bool X3DIFACESET::SetParent( X3DNODE* aParent, bool doUnlink )
{
if( aParent == m_Parent )
return true;
if( NULL != aParent )
{
X3DNODES nt = aParent->GetNodeType();
if( nt != X3D_SHAPE )
return false;
}
if( NULL != m_Parent && doUnlink )
m_Parent->unlinkChildNode( this );
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return true;
}
bool X3DIFACESET::AddChildNode( X3DNODE* aNode )
{
return false;
}
bool X3DIFACESET::AddRefNode( X3DNODE* aNode )
{
return false;
}
SGNODE* X3DIFACESET::TranslateToSG( SGNODE* aParent )
{
// XXX -
return NULL;
}

View File

@ -0,0 +1,67 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_ifaceset.h
*/
#ifndef X3D_IFACESET_H
#define X3D_IFACESET_H
#include <vector>
#include "wrltypes.h"
#include "x3d_shape.h"
/**
* Class X3DIFACESET
*/
class X3DIFACESET : public X3DNODE
{
private:
X3DNODE* coord;
bool ccw;
float creaseAngle;
float creaseLimit;
std::vector< int > coordIndex;
void init();
void readFields( wxXmlNode* aNode );
public:
X3DIFACESET();
X3DIFACESET( X3DNODE* aParent );
virtual ~X3DIFACESET();
// functions inherited from X3DNODE
bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict );
bool SetParent( X3DNODE* aParent, bool doUnlink = true );
bool AddChildNode( X3DNODE* aNode );
bool AddRefNode( X3DNODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent );
};
#endif // X3D_IFACESET_H

View File

@ -0,0 +1,316 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/tokenzr.h>
#include <wx/xml/xml.h>
#include <iostream>
#include "x3d_appearance.h"
#include "x3d_coords.h"
#include "x3d_ifaceset.h"
#include "x3d_ops.h"
#include "x3d_shape.h"
#include "x3d_transform.h"
bool X3D::ReadTransform( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// note: we must have a parent or else we will have a memory leak
if( NULL == aParent || NULL == aNode )
return false;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "USE" )
{
X3DNODE* np = aDict.FindName( prop->GetValue() );
if( NULL == np )
return false;
if( !aParent->AddRefNode( np ) )
return false;
return true;
}
}
X3DNODE* node = new X3DTRANSFORM;
if( !node->Read( aNode, aParent, aDict ) )
{
delete node;
return false;
}
return true;
}
bool X3D::ReadSwitch( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// XXX - TO BE IMPLEMENTED
return false;
}
bool X3D::ReadShape( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// note: we must have a parent or else we will have a memory leak
if( NULL == aParent || NULL == aNode )
return false;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "USE" )
{
X3DNODE* np = aDict.FindName( prop->GetValue() );
if( NULL == np )
return false;
if( !aParent->AddRefNode( np ) )
return false;
return true;
}
}
X3DNODE* node = new X3DSHAPE;
if( !node->Read( aNode, aParent, aDict ) )
{
delete node;
return false;
}
return true;
}
bool X3D::ReadAppearance( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// note: we must have a parent or else we will have a memory leak
if( NULL == aParent || NULL == aNode )
return false;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "USE" )
{
X3DNODE* np = aDict.FindName( prop->GetValue() );
if( NULL == np )
return false;
if( !aParent->AddRefNode( np ) )
return false;
return true;
}
}
X3DNODE* node = new X3DAPP;
if( !node->Read( aNode, aParent, aDict ) )
{
delete node;
return false;
}
return true;
}
bool X3D::ReadIndexedFaceSet( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// note: we must have a parent or else we will have a memory leak
if( NULL == aParent || NULL == aNode )
return false;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "USE" )
{
X3DNODE* np = aDict.FindName( prop->GetValue() );
if( NULL == np )
return false;
if( !aParent->AddRefNode( np ) )
return false;
return true;
}
}
X3DNODE* node = new X3DIFACESET;
if( !node->Read( aNode, aParent, aDict ) )
{
delete node;
return false;
}
return true;
}
bool X3D::ReadCoordinates( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict )
{
// note: we must have a parent or else we will have a memory leak
if( NULL == aParent || NULL == aNode )
return false;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "USE" )
{
X3DNODE* np = aDict.FindName( prop->GetValue() );
if( NULL == np )
return false;
if( !aParent->AddRefNode( np ) )
return false;
return true;
}
}
X3DNODE* node = new X3DCOORDS;
if( !node->Read( aNode, aParent, aDict ) )
{
delete node;
return false;
}
return true;
}
bool X3D::ParseSFBool( const wxString& aSource, bool& aResult )
{
wxStringTokenizer tokens( aSource );
wxString val = tokens.GetNextToken();
if( val == "TRUE" || val == "1" )
{
aResult = true;
return true;
}
if( val == "FALSE" || val == "0" )
{
aResult = false;
return true;
}
return false;
}
bool X3D::ParseSFFloat( const wxString& aSource, float& aResult )
{
wxStringTokenizer tokens( aSource );
double x = 0;
bool ret = tokens.GetNextToken().ToDouble( &x );
aResult = x;
return ret;
}
bool X3D::ParseSFVec3( const wxString& aSource, WRLVEC3F& aResult )
{
wxStringTokenizer tokens( aSource );
double x = 0;
double y = 0;
double z = 0;
bool ret = tokens.GetNextToken().ToDouble( &x )
&& tokens.GetNextToken().ToDouble( &y )
&& tokens.GetNextToken().ToDouble( &z );
aResult.x = x;
aResult.y = y;
aResult.z = z;
return ret;
}
bool X3D::ParseSFRotation( const wxString& aSource, WRLROTATION& aResult )
{
wxStringTokenizer tokens( aSource );
double x = 0;
double y = 0;
double z = 0;
double w = 0;
bool ret = tokens.GetNextToken().ToDouble( &x )
&& tokens.GetNextToken().ToDouble( &y )
&& tokens.GetNextToken().ToDouble( &z )
&& tokens.GetNextToken().ToDouble( &w );
aResult.x = x;
aResult.y = y;
aResult.z = z;
aResult.w = w;
return ret;
}

View File

@ -0,0 +1,54 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_ops.h
*/
#ifndef X3D_OPS_H
#define X3D_OPS_H
#include "x3d_base.h"
#include "wrltypes.h"
namespace X3D
{
/* Functions to create and read X3D Nodes */
bool ReadTransform( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ReadSwitch( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ReadShape( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ReadAppearance( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ReadIndexedFaceSet( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ReadCoordinates( wxXmlNode* aNode, X3DNODE* aParent, X3D_DICT& aDict );
bool ParseSFBool( const wxString& aSource, bool& aResult );
bool ParseSFFloat( const wxString& aSource, float& aResult );
bool ParseSFVec3( const wxString& aSource, WRLVEC3F& aResult );
bool ParseSFRotation( const wxString& aSource, WRLROTATION& aResult );
};
#endif // X3D_OPS_H

View File

@ -0,0 +1,344 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <iostream>
#include <wx/xml/xml.h>
#include "x3d_ops.h"
#include "x3d_shape.h"
#include "plugins/3dapi/ifsg_all.h"
X3DSHAPE::X3DSHAPE() : X3DNODE()
{
m_Type = X3D_SHAPE;
appearance = NULL;
geometry = NULL;
return;
}
X3DSHAPE::X3DSHAPE( X3DNODE* aParent ) : X3DNODE()
{
m_Type = X3D_SHAPE;
appearance = NULL;
geometry = NULL;
if( NULL != aParent )
{
X3DNODES ptype = aParent->GetNodeType();
if( X3D_TRANSFORM == ptype || X3D_SWITCH == ptype )
m_Parent = aParent;
}
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
X3DSHAPE::~X3DSHAPE()
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Destroying Shape with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
return;
}
bool X3DSHAPE::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
{
if( NULL == aTopNode || NULL == aNode )
return false;
if( NULL != appearance || NULL != geometry )
return false;
m_Dict = &aDict;
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_Name = prop->GetValue();
m_Dict->AddName( m_Name, this );
}
}
for( wxXmlNode* child = aNode->GetChildren();
child != NULL;
child = child->GetNext() )
{
wxString name = child->GetName();
if( name == "Appearance" && NULL == appearance )
X3D::ReadAppearance( child, this, aDict );
else if( name == "IndexedFaceSet" && NULL == geometry )
X3D::ReadIndexedFaceSet( child, this, aDict );
}
if( NULL == appearance || NULL == geometry )
return false;
if( !SetParent( aTopNode ) )
return false;
return true;
}
bool X3DSHAPE::SetParent( X3DNODE* aParent, bool doUnlink )
{
if( aParent == m_Parent )
return true;
if( NULL != aParent )
{
X3DNODES nt = aParent->GetNodeType();
if( nt != X3D_SWITCH && nt != X3D_TRANSFORM )
return false;
}
if( NULL != m_Parent && doUnlink )
m_Parent->unlinkChildNode( this );
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return true;
}
bool X3DSHAPE::AddChildNode( X3DNODE* aNode )
{
if( NULL == aNode )
return false;
X3DNODES tchild = aNode->GetNodeType();
if( X3D_APPEARANCE != tchild && X3D_INDEXED_FACE_SET != tchild )
return false;
std::list< X3DNODE* >::iterator sC = m_Children.begin();
std::list< X3DNODE* >::iterator eC = m_Children.end();
while( sC != eC )
{
if( *sC == aNode )
return false;
++sC;
}
if( X3D_APPEARANCE == tchild )
{
if( NULL == appearance )
{
m_Children.push_back( aNode );
appearance = aNode;
}
else
return false;
}
else
{
if( NULL == geometry )
{
m_Children.push_back( aNode );
geometry = aNode;
}
else
return false;
}
if( aNode->GetParent() != this )
aNode->SetParent( this );
return true;
}
bool X3DSHAPE::AddRefNode( X3DNODE* aNode )
{
if( NULL == aNode )
return false;
X3DNODES tchild = aNode->GetNodeType();
if( X3D_APPEARANCE != tchild && X3D_INDEXED_FACE_SET != tchild )
return false;
std::list< X3DNODE* >::iterator sR = m_Refs.begin();
std::list< X3DNODE* >::iterator eR = m_Refs.end();
while( sR != eR )
{
if( *sR == aNode )
return false;
++sR;
}
if( X3D_APPEARANCE == tchild )
{
if( NULL == appearance )
{
m_Refs.push_back( aNode );
appearance = aNode;
}
else
return false;
}
else
{
if( NULL == geometry )
{
m_Refs.push_back( aNode );
geometry = aNode;
}
else
return false;
}
return true;
}
SGNODE* X3DSHAPE::TranslateToSG( SGNODE* aParent )
{
if( NULL == geometry || NULL == appearance )
return NULL;
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Translating Shape with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
{
#ifdef DEBUG_X3D
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] Shape does not have a Transform parent (parent ID: ";
std::cerr << ptype << ")\n";
#endif
return NULL;
}
if( m_sgNode )
{
if( NULL != aParent )
{
if( NULL == S3D::GetSGNodeParent( m_sgNode )
&& !S3D::AddSGNodeChild( aParent, m_sgNode ) )
{
return NULL;
}
else if( aParent != S3D::GetSGNodeParent( m_sgNode )
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
{
return NULL;
}
}
return m_sgNode;
}
IFSG_SHAPE shNode( aParent );
SGNODE* pShape = shNode.GetRawPtr();
SGNODE* pGeom = geometry->TranslateToSG( pShape );
SGNODE* pApp = appearance->TranslateToSG( pShape );
if( NULL == pApp || NULL == pGeom )
{
if( pGeom )
{
IFSG_FACESET tmp( false );
tmp.Attach( pGeom );
tmp.Destroy();
}
if( pApp )
{
IFSG_APPEARANCE tmp( false );
tmp.Attach( pApp );
tmp.Destroy();
}
shNode.Destroy();
return NULL;
}
m_sgNode = shNode.GetRawPtr();
return m_sgNode;
}
void X3DSHAPE::unlinkChildNode( const X3DNODE* aNode )
{
if( NULL == aNode )
return;
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
X3DNODE::unlinkChildNode( aNode );
return;
}
void X3DSHAPE::unlinkRefNode( const X3DNODE* aNode )
{
if( NULL == aNode )
return;
if( aNode == appearance )
appearance = NULL;
else if( aNode == geometry )
geometry = NULL;
X3DNODE::unlinkRefNode( aNode );
return;
}

View File

@ -0,0 +1,64 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_shape.h
*/
#ifndef X3D_SHAPE_H
#define X3D_SHAPE_H
#include <vector>
#include "x3d_base.h"
#include "wrltypes.h"
/**
* Class X3DSHAPE
*/
class X3DSHAPE : public X3DNODE
{
private:
X3DNODE* appearance;
X3DNODE* geometry;
public:
X3DSHAPE();
X3DSHAPE( X3DNODE* aParent );
virtual ~X3DSHAPE();
// functions inherited from X3DNODE
bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict );
bool SetParent( X3DNODE* aParent, bool doUnlink = true );
bool AddChildNode( X3DNODE* aNode );
bool AddRefNode( X3DNODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent );
// overrides
virtual void unlinkChildNode( const X3DNODE* aNode );
virtual void unlinkRefNode( const X3DNODE* aNode );
};
#endif // X3D_SHAPE_H

View File

@ -0,0 +1,355 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <iostream>
#include <wx/xml/xml.h>
#include "x3d_ops.h"
#include "x3d_transform.h"
#include "plugins/3dapi/ifsg_all.h"
X3DTRANSFORM::X3DTRANSFORM() : X3DNODE()
{
m_Type = X3D_TRANSFORM;
init();
return;
}
X3DTRANSFORM::X3DTRANSFORM( X3DNODE* aParent ) : X3DNODE()
{
m_Type = X3D_TRANSFORM;
init();
if( NULL != aParent )
{
X3DNODES ptype = aParent->GetNodeType();
if( X3D_TRANSFORM == ptype || X3D_SWITCH == ptype )
m_Parent = aParent;
}
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
X3DTRANSFORM::~X3DTRANSFORM()
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Destroying Transform with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
return;
}
void X3DTRANSFORM::init()
{
center.x = 0.0;
center.y = 0.0;
center.z = 0.0;
scale.x = 1.0;
scale.y = 1.0;
scale.z = 1.0;
translation = center;
rotation.x = 0.0;
rotation.y = 0.0;
rotation.z = 1.0;
scaleOrientation = rotation;
bboxCenter = center;
bboxSize = center;
return;
}
void X3DTRANSFORM::readFields( wxXmlNode* aNode )
{
// DEF
// center
// scale
// translation
// rotation
// scaleOrientation
// bboxCenter (ignored)
// bboxSize (ignored)
wxXmlAttribute* prop;
for( prop = aNode->GetAttributes();
prop != NULL;
prop = prop->GetNext() )
{
wxString pname = prop->GetName();
if( pname == "DEF" )
{
m_Name = prop->GetValue();
m_Dict->AddName( m_Name, this );
}
else if( pname == "center" )
X3D::ParseSFVec3( prop->GetValue(), center );
else if( pname == "scale" )
X3D::ParseSFVec3( prop->GetValue(), scale );
else if( pname == "translation" )
X3D::ParseSFVec3( prop->GetValue(), translation );
else if( pname == "rotation" )
X3D::ParseSFRotation( prop->GetValue(), rotation );
else if( pname == "scaleOrientation" )
X3D::ParseSFRotation( prop->GetValue(), scaleOrientation );
}
return;
}
bool X3DTRANSFORM::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict )
{
if( NULL == aTopNode || NULL == aNode )
return false;
std::cerr << "XXX: Reading Transform\n";
m_Dict = &aDict;
readFields( aNode );
bool ok = false;
for( wxXmlNode* child = aNode->GetChildren();
child != NULL;
child = child->GetNext() )
{
wxString name = child->GetName();
if( name == "Transform" || name == "Group" )
ok |= X3D::ReadTransform( child, this, aDict );
else if( name == "Switch" )
ok |= X3D::ReadSwitch( child, this, aDict );
else if( name == "Shape" )
ok |= X3D::ReadShape( child, this, aDict );
}
if( !ok )
return false;
if( !SetParent( aTopNode ) )
return false;
return true;
}
bool X3DTRANSFORM::SetParent( X3DNODE* aParent, bool doUnlink )
{
if( aParent == m_Parent )
return true;
if( NULL != aParent )
{
X3DNODES nt = aParent->GetNodeType();
if( nt != X3D_SWITCH && nt != X3D_TRANSFORM )
return false;
}
if( NULL != m_Parent && doUnlink )
m_Parent->unlinkChildNode( this );
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return true;
}
bool X3DTRANSFORM::AddChildNode( X3DNODE* aNode )
{
if( NULL == aNode )
return false;
X3DNODES tchild = aNode->GetNodeType();
if( X3D_SWITCH != tchild && X3D_TRANSFORM != tchild && X3D_SHAPE != tchild )
return false;
std::list< X3DNODE* >::iterator sC = m_Children.begin();
std::list< X3DNODE* >::iterator eC = m_Children.end();
while( sC != eC )
{
if( *sC == aNode )
return false;
++sC;
}
m_Children.push_back( aNode );
if( aNode->GetParent() != this )
aNode->SetParent( this );
return true;
}
bool X3DTRANSFORM::AddRefNode( X3DNODE* aNode )
{
if( NULL == aNode )
return false;
X3DNODES tchild = aNode->GetNodeType();
if( X3D_SWITCH != tchild && X3D_TRANSFORM != tchild && X3D_SHAPE != tchild )
return false;
std::list< X3DNODE* >::iterator sR = m_Refs.begin();
std::list< X3DNODE* >::iterator eR = m_Refs.end();
while( sR != eR )
{
if( *sR == aNode )
return true;
++sR;
}
m_Refs.push_back( aNode );
return true;
}
SGNODE* X3DTRANSFORM::TranslateToSG( SGNODE* aParent )
{
#if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 )
std::cerr << " * [INFO] Translating Transform with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
if( m_Children.empty() && m_Refs.empty() )
return NULL;
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
{
#ifdef DEBUG_VRML2
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] Transform does not have a Transform parent (parent ID: ";
std::cerr << ptype << ")\n";
#endif
return NULL;
}
if( m_sgNode )
{
if( NULL != aParent )
{
if( NULL == S3D::GetSGNodeParent( m_sgNode )
&& !S3D::AddSGNodeChild( aParent, m_sgNode ) )
{
return NULL;
}
else if( aParent != S3D::GetSGNodeParent( m_sgNode )
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
{
return NULL;
}
}
return m_sgNode;
}
IFSG_TRANSFORM txNode( aParent );
std::list< X3DNODE* >::iterator sC = m_Children.begin();
std::list< X3DNODE* >::iterator eC = m_Children.end();
X3DNODES type;
// Include only the following in a Transform node:
// Shape
// Switch
// Transform
// Inline
bool test = false; // set to true if there are any subnodes for display
for( int i = 0; i < 2; ++i )
{
while( sC != eC )
{
type = (*sC)->GetNodeType();
switch( type )
{
case X3D_SHAPE:
case X3D_SWITCH:
case X3D_TRANSFORM:
if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr() ) )
test = true;
break;
default:
break;
}
++ sC;
}
sC = m_Refs.begin();
eC = m_Refs.end();
}
if( false == test )
{
txNode.Destroy();
return NULL;
}
txNode.SetScale( SGPOINT( scale.x, scale.y, scale.z ) );
txNode.SetCenter( SGPOINT( center.x, center.y, center.z ) );
txNode.SetTranslation( SGPOINT( translation.x, translation.y, translation.z ) );
txNode.SetScaleOrientation( SGVECTOR( scaleOrientation.x, scaleOrientation.y,
scaleOrientation.z ), scaleOrientation.w );
txNode.SetRotation( SGVECTOR( rotation.x, rotation.y, rotation.z), rotation.w );
m_sgNode = txNode.GetRawPtr();
return m_sgNode;
}

View File

@ -0,0 +1,68 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file x3d_transform.h
*/
#ifndef X3D_TRANSFORM_H
#define X3D_TRANSFORM_H
#include <vector>
#include "x3d_base.h"
#include "wrltypes.h"
/**
* Class X3DTRANSFORM
*/
class X3DTRANSFORM : public X3DNODE
{
private:
WRLVEC3F center;
WRLVEC3F scale;
WRLVEC3F translation;
WRLROTATION rotation;
WRLROTATION scaleOrientation;
WRLVEC3F bboxCenter;
WRLVEC3F bboxSize;
void init();
void readFields( wxXmlNode* aNode );
public:
X3DTRANSFORM();
X3DTRANSFORM( X3DNODE* aParent );
virtual ~X3DTRANSFORM();
// functions inherited from X3DNODE
bool Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict );
bool SetParent( X3DNODE* aParent, bool doUnlink = true );
bool AddChildNode( X3DNODE* aNode );
bool AddRefNode( X3DNODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent );
};
#endif // X3D_TRANSFORM_H