Added support for FreeCAD VRML files
This commit is contained in:
parent
97d4c33a9f
commit
c798f8b545
|
@ -486,3 +486,23 @@ bool S3D::AddSGNodeRef( SGNODE* aParent, SGNODE* aChild )
|
|||
|
||||
return aParent->AddRefNode( aChild );
|
||||
}
|
||||
|
||||
|
||||
bool S3D::AddSGNodeChild( SGNODE* aParent, SGNODE* aChild )
|
||||
{
|
||||
if( NULL == aParent || NULL == aChild )
|
||||
return false;
|
||||
|
||||
return aParent->AddChildNode( aChild );
|
||||
}
|
||||
|
||||
|
||||
void S3D::AssociateSGNodeWrapper( SGNODE* aObject, SGNODE** aRefPtr )
|
||||
{
|
||||
if( NULL == aObject || NULL == aRefPtr || aObject != *aRefPtr )
|
||||
return;
|
||||
|
||||
aObject->AssociateWrapper( aRefPtr );
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ namespace S3D
|
|||
SGLIB_API S3D::SGTYPES GetSGNodeType( SGNODE* aNode );
|
||||
SGLIB_API SGNODE* GetSGNodeParent( SGNODE* aNode );
|
||||
SGLIB_API bool AddSGNodeRef( SGNODE* aParent, SGNODE* aChild );
|
||||
SGLIB_API bool AddSGNodeChild( SGNODE* aParent, SGNODE* aChild );
|
||||
SGLIB_API void AssociateSGNodeWrapper( SGNODE* aObject, SGNODE** aRefPtr );
|
||||
|
||||
/**
|
||||
* Function CalcTriNorm
|
||||
|
|
|
@ -19,6 +19,7 @@ add_library( s3d_plugin_vrml MODULE
|
|||
v2/vrml2_norms.cpp
|
||||
v2/vrml2_color.cpp
|
||||
v2/vrml2_box.cpp
|
||||
v2/vrml2_switch.cpp
|
||||
)
|
||||
|
||||
target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} )
|
||||
|
|
|
@ -369,10 +369,18 @@ SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -33,11 +33,13 @@
|
|||
#include "vrml2_norms.h"
|
||||
#include "vrml2_color.h"
|
||||
#include "vrml2_box.h"
|
||||
#include "vrml2_switch.h"
|
||||
#include "plugins/3dapi/ifsg_all.h"
|
||||
|
||||
|
||||
WRL2BASE::WRL2BASE() : WRL2NODE()
|
||||
{
|
||||
m_useInline = false;
|
||||
m_Type = WRL2_BASE;
|
||||
return;
|
||||
}
|
||||
|
@ -61,6 +63,44 @@ bool WRL2BASE::SetParent( WRL2NODE* aParent )
|
|||
}
|
||||
|
||||
|
||||
void WRL2BASE::SetEnableInline( bool enable )
|
||||
{
|
||||
m_useInline = enable;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool WRL2BASE::GetEnableInline( void )
|
||||
{
|
||||
return m_useInline;
|
||||
}
|
||||
|
||||
|
||||
SGNODE* WRL2BASE::AddInlineData( const std::string& aName, WRL2INLINE* aObject )
|
||||
{
|
||||
std::map< std::string, WRL2INLINE* >::iterator dp = m_inlineModels.find( aName );
|
||||
// XXX;
|
||||
// qwerty;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SGNODE* WRL2BASE::GetInlineData( const std::string& aName, WRL2INLINE* aObject )
|
||||
{
|
||||
// XXX;
|
||||
// qwerty;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void WRL2BASE::DelInlineData( const std::string& aName, WRL2INLINE* aObject )
|
||||
{
|
||||
// XXX;
|
||||
// qwerty;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string WRL2BASE::GetName( void )
|
||||
{
|
||||
#ifdef DEBUG_VRML2
|
||||
|
@ -508,6 +548,13 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
|
|||
|
||||
break;
|
||||
|
||||
case WRL2_SWITCH:
|
||||
|
||||
if( !readSwitch( proc, aParent, aNode ) )
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
case WRL2_TRANSFORM:
|
||||
case WRL2_GROUP:
|
||||
|
||||
|
@ -549,7 +596,6 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
|
|||
case WRL2_SOUND:
|
||||
case WRL2_SPHERESENSOR:
|
||||
case WRL2_SPOTLIGHT:
|
||||
case WRL2_SWITCH:
|
||||
case WRL2_TEXT:
|
||||
case WRL2_TEXTURECOORDINATE:
|
||||
case WRL2_TEXTURETRANSFORM:
|
||||
|
@ -775,13 +821,62 @@ bool WRL2BASE::readBox( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
|
|||
}
|
||||
|
||||
|
||||
bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
|
||||
{
|
||||
if( NULL != aNode )
|
||||
*aNode = NULL;
|
||||
|
||||
WRL2SWITCH* np = new WRL2SWITCH( aParent );
|
||||
|
||||
if( !np->Read( proc, this ) )
|
||||
{
|
||||
delete np;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( NULL != aNode )
|
||||
*aNode = (WRL2NODE*) np;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||
{
|
||||
if( m_Children.empty() )
|
||||
return NULL;
|
||||
|
||||
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
||||
|
||||
if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
|
||||
{
|
||||
#ifdef DEBUG_VRML2
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [BUG] WRL2BASE 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 topNode( aParent );
|
||||
|
||||
|
@ -815,6 +910,7 @@ SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
break;
|
||||
|
||||
case WRL2_TRANSFORM:
|
||||
case WRL2_SWITCH:
|
||||
|
||||
if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr(), calcNormals ) )
|
||||
test = true;
|
||||
|
|
|
@ -45,9 +45,12 @@
|
|||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "vrml2_node.h"
|
||||
|
||||
class SGNODE;
|
||||
class WRL2INLINE;
|
||||
|
||||
/**
|
||||
* Class WRL2BASE
|
||||
|
@ -56,6 +59,8 @@
|
|||
class WRL2BASE : public WRL2NODE
|
||||
{
|
||||
private:
|
||||
bool m_useInline;
|
||||
|
||||
// handle cases of USE / DEF
|
||||
bool implementUse( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
bool implementDef( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
|
@ -69,6 +74,9 @@ private:
|
|||
bool readNorms( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
bool readColor( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
bool readBox( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
bool readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
|
||||
|
||||
std::map< std::string, WRL2INLINE* > m_inlineModels;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -79,6 +87,15 @@ public:
|
|||
WRL2BASE();
|
||||
virtual ~WRL2BASE();
|
||||
|
||||
// function to enable/disable Inline{} expansion
|
||||
void SetEnableInline( bool enable );
|
||||
bool GetEnableInline( void );
|
||||
|
||||
// functions to manipulate Inline{} objects
|
||||
SGNODE* AddInlineData( const std::string& aName, WRL2INLINE* aObject );
|
||||
SGNODE* GetInlineData( const std::string& aName, WRL2INLINE* aObject );
|
||||
void DelInlineData( const std::string& aName, WRL2INLINE* aObject );
|
||||
|
||||
// function to read entire VRML file
|
||||
bool Read( WRLPROC& proc );
|
||||
|
||||
|
|
|
@ -228,10 +228,18 @@ SGNODE* WRL2BOX::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -578,10 +578,18 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -305,10 +305,18 @@ SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -235,10 +235,11 @@ bool WRL2NODE::SetName( const std::string& aName )
|
|||
return false;
|
||||
}
|
||||
|
||||
// XXX: NOTE: in VRML2 the '-' is invalid; however there are some bad models which contain '-' in
|
||||
// a name and many VRML parsers seem to accept them. In VRML1 the '-' is allowed.
|
||||
// The characters '+' and '-' are not allowed in names as per the VRML2 specification;
|
||||
// however many parsers accept them and many bad generators use them so the rules
|
||||
// have been relaxed here.
|
||||
// #define BAD_CHARS1 "\"\'#+,-.\\[]{}\x00\x01\x02\x03\x04\x05\x06\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
||||
#define BAD_CHARS1 "\"\'#+,.\\[]{}\x00\x01\x02\x03\x04\x05\x06\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
||||
#define BAD_CHARS1 "\"\'#,.\\[]{}\x00\x01\x02\x03\x04\x05\x06\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
||||
#define BAD_CHARS2 "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
|
||||
|
||||
if( std::string::npos != aName.find_first_of( BAD_CHARS1 )
|
||||
|
@ -396,6 +397,8 @@ bool WRL2NODE::AddRefNode( WRL2NODE* aNode )
|
|||
{
|
||||
if( *sR == aNode )
|
||||
return false;
|
||||
|
||||
++sR;
|
||||
}
|
||||
|
||||
m_Refs.push_back( aNode );
|
||||
|
|
|
@ -65,9 +65,13 @@ WRL2SHAPE::~WRL2SHAPE()
|
|||
|
||||
bool WRL2SHAPE::isDangling( void )
|
||||
{
|
||||
// this node is dangling unless it has a parent of type WRL2_TRANSFORM
|
||||
// this node is dangling unless it has a parent of type:
|
||||
// WRL2_TRANSFORM
|
||||
// WRL2_SWITCH
|
||||
|
||||
if( NULL == m_Parent || m_Parent->GetNodeType() != WRL2_TRANSFORM )
|
||||
if( NULL == m_Parent
|
||||
|| ( m_Parent->GetNodeType() != WRL2_TRANSFORM
|
||||
&& m_Parent->GetNodeType() != WRL2_SWITCH ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -332,10 +336,18 @@ SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* 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
|
||||
* 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 "vrml2_base.h"
|
||||
#include "vrml2_switch.h"
|
||||
#include "plugins/3dapi/ifsg_all.h"
|
||||
|
||||
|
||||
WRL2SWITCH::WRL2SWITCH() : WRL2NODE()
|
||||
{
|
||||
m_Type = WRL2_SWITCH;
|
||||
whichChoice = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WRL2SWITCH::WRL2SWITCH( WRL2NODE* aParent ) : WRL2NODE()
|
||||
{
|
||||
m_Type = WRL2_SWITCH;
|
||||
m_Parent = aParent;
|
||||
whichChoice = -1;
|
||||
|
||||
if( NULL != m_Parent )
|
||||
m_Parent->AddChildNode( this );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WRL2SWITCH::~WRL2SWITCH()
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 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;
|
||||
}
|
||||
|
||||
|
||||
bool WRL2SWITCH::isDangling( void )
|
||||
{
|
||||
// a Switch node is never dangling
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// functions inherited from WRL2NODE
|
||||
bool WRL2SWITCH::Read( WRLPROC& proc, WRL2BASE* aTopNode )
|
||||
{
|
||||
/*
|
||||
* Structure of a Switch node (p.113):
|
||||
*
|
||||
* Switch {
|
||||
* exposedField MFNode choice []
|
||||
* exposedField SFInt32 whichChoice -1
|
||||
* }
|
||||
*/
|
||||
|
||||
if( NULL == aTopNode )
|
||||
{
|
||||
#ifdef DEBUG_VRML2
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [BUG] aTopNode is NULL\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t line, column;
|
||||
proc.GetFilePosData( line, column );
|
||||
|
||||
char tok = proc.Peek();
|
||||
|
||||
if( proc.eof() )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] bad file format; unexpected eof at line ";
|
||||
std::cerr << line << ", column " << column << "\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if( '{' != tok )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << proc.GetError() << "\n";
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] bad file format; expecting '{' but got '" << tok;
|
||||
std::cerr << "' at line " << line << ", column " << column << "\n";
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
proc.Pop();
|
||||
std::string glob;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( proc.Peek() == '}' )
|
||||
{
|
||||
proc.Pop();
|
||||
break;
|
||||
}
|
||||
|
||||
if( !proc.ReadName( glob ) )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << proc.GetError() << "\n";
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// expecting one of:
|
||||
// choice
|
||||
// whichChoice
|
||||
|
||||
proc.GetFilePosData( line, column );
|
||||
|
||||
if( !glob.compare( "whichChoice" ) )
|
||||
{
|
||||
if( !proc.ReadSFInt( whichChoice ) )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] invalid whichChoice at line " << line << ", column ";
|
||||
std::cerr << column << "\n";
|
||||
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
|
||||
std::cerr << " * [INFO] message: '" << proc.GetError() << "'\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if( !glob.compare( "choice" ) )
|
||||
{
|
||||
if( !readChildren( proc, aTopNode ) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] bad Switch at line " << line << ", column ";
|
||||
std::cerr << column << "\n";
|
||||
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
} // while( true ) -- reading contents of Switch{}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WRL2SWITCH::AddRefNode( WRL2NODE* aNode )
|
||||
{
|
||||
if( NULL == aNode )
|
||||
{
|
||||
#ifdef DEBUG_VRML2
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [BUG] NULL passed as node pointer\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !WRL2NODE::AddRefNode( aNode ) )
|
||||
return false;
|
||||
|
||||
// take possession if the node is dangling WRL2_SHAPE
|
||||
|
||||
if( WRL2_SHAPE == aNode->GetNodeType() && aNode->isDangling() )
|
||||
{
|
||||
WRL2NODE* np = aNode->GetParent();
|
||||
|
||||
if( NULL != np )
|
||||
aNode->SetParent( this );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool WRL2SWITCH::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
|
||||
{
|
||||
size_t line, column;
|
||||
proc.GetFilePosData( line, column );
|
||||
|
||||
char tok = proc.Peek();
|
||||
|
||||
if( proc.eof() )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
|
||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||
std::cerr << " * [INFO] bad file format; unexpected eof at line ";
|
||||
std::cerr << line << ", column " << column << "\n";
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
WRL2NODE* child = NULL;
|
||||
|
||||
if( '[' != tok )
|
||||
{
|
||||
// since there are no delimeters we expect a single child
|
||||
if( !aTopNode->ReadNode( proc, this, &child ) )
|
||||
return false;
|
||||
|
||||
if( NULL != child )
|
||||
choices.push_back( child );
|
||||
|
||||
if( proc.Peek() == ',' )
|
||||
proc.Pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
proc.Pop();
|
||||
std::string glob;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( proc.Peek() == ']' )
|
||||
{
|
||||
proc.Pop();
|
||||
break;
|
||||
}
|
||||
|
||||
if( !aTopNode->ReadNode( proc, this, &child ) )
|
||||
return false;
|
||||
|
||||
if( NULL != child )
|
||||
choices.push_back( child );
|
||||
|
||||
if( proc.Peek() == ',' )
|
||||
proc.Pop();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
|
||||
std::cerr << " * [INFO] Translating Switch with " << m_Children.size();
|
||||
std::cerr << " children, " << m_Refs.size() << " references and ";
|
||||
std::cerr << m_BackPointers.size() << " backpointers\n";
|
||||
#endif
|
||||
|
||||
if( choices.empty() )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
|
||||
std::cerr << " * [INFO] Switch translation: no choices\n";
|
||||
#endif
|
||||
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( whichChoice < 0 || whichChoice >= (int)choices.size() )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
|
||||
std::cerr << " * [INFO] Switch translation: no choice (choices = ";
|
||||
std::cerr << choices.size() << "), whichChoice = " << whichChoice << "\n";
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WRL2NODES type = choices[whichChoice]->GetNodeType();
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case WRL2_SHAPE:
|
||||
case WRL2_SWITCH:
|
||||
case WRL2_INLINE:
|
||||
case WRL2_TRANSFORM:
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return choices[whichChoice]->TranslateToSG( aParent, calcNormals );
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* 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
|
||||
* 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 vrml2_switch.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VRML2_SWITCH_H
|
||||
#define VRML2_SWITCH_H
|
||||
|
||||
#include "vrml2_node.h"
|
||||
|
||||
class WRL2BASE;
|
||||
class SGNODE;
|
||||
|
||||
/**
|
||||
* Class WRL2SWITCH
|
||||
*/
|
||||
class WRL2SWITCH : public WRL2NODE
|
||||
{
|
||||
private:
|
||||
int whichChoice;
|
||||
std::vector< WRL2NODE* > choices;
|
||||
|
||||
bool readChildren( WRLPROC& proc, WRL2BASE* aTopNode );
|
||||
|
||||
public:
|
||||
|
||||
// functions inherited from WRL2NODE
|
||||
bool isDangling( void );
|
||||
|
||||
public:
|
||||
WRL2SWITCH();
|
||||
WRL2SWITCH( WRL2NODE* aNode );
|
||||
virtual ~WRL2SWITCH();
|
||||
|
||||
// functions inherited from WRL2NODE
|
||||
bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
|
||||
bool AddRefNode( WRL2NODE* aNode );
|
||||
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
||||
};
|
||||
|
||||
#endif // VRML2_SWITCH_H
|
|
@ -314,6 +314,9 @@ bool WRL2TRANSFORM::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
|
|||
if( !aTopNode->ReadNode( proc, this, NULL ) )
|
||||
return false;
|
||||
|
||||
if( proc.Peek() == ',' )
|
||||
proc.Pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -330,6 +333,10 @@ bool WRL2TRANSFORM::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
|
|||
|
||||
if( !aTopNode->ReadNode( proc, this, NULL ) )
|
||||
return false;
|
||||
|
||||
if( proc.Peek() == ',' )
|
||||
proc.Pop();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -338,6 +345,12 @@ bool WRL2TRANSFORM::readChildren( WRLPROC& proc, WRL2BASE* aTopNode )
|
|||
|
||||
SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||
{
|
||||
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 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;
|
||||
|
||||
|
@ -356,10 +369,18 @@ SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
|
||||
if( m_sgNode )
|
||||
{
|
||||
if( NULL != aParent && aParent != S3D::GetSGNodeParent( m_sgNode )
|
||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||
if( NULL != aParent )
|
||||
{
|
||||
return NULL;
|
||||
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;
|
||||
|
@ -371,7 +392,11 @@ SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
std::list< WRL2NODE* >::iterator eC = m_Children.end();
|
||||
WRL2NODES type;
|
||||
|
||||
// Include only Shape and Transform nodes in a Transform node
|
||||
// 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 )
|
||||
|
@ -383,6 +408,8 @@ SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
|||
switch( type )
|
||||
{
|
||||
case WRL2_SHAPE:
|
||||
case WRL2_SWITCH:
|
||||
case WRL2_INLINE:
|
||||
case WRL2_TRANSFORM:
|
||||
|
||||
if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr(), calcNormals ) )
|
||||
|
|
|
@ -197,6 +197,9 @@ SCENEGRAPH* Load( char const* aFileName )
|
|||
#endif
|
||||
WRL2BASE* bp = new WRL2BASE;
|
||||
|
||||
// allow Inline{} files to be included
|
||||
bp->SetEnableInline( true );
|
||||
|
||||
if( !bp->Read( proc ) )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -113,9 +113,10 @@ bool WRLPROC::Open( const std::string& aFileName )
|
|||
// backslash
|
||||
// XXX: NOTE: badchars should include '-' but due to my bad model naming scheme
|
||||
// in the VRML model generator, I have allowed '-'. Other VRML parsers seem to
|
||||
// accept '-'.
|
||||
// accept '-'. FreeCAD produces names with '+' in them so '+' has been allowed
|
||||
// as well; '+' is not even valid for VRML1.
|
||||
//m_badchars = "'\"#,.+-[]\\{}";
|
||||
m_badchars = "'\"#,.+[]\\{}";
|
||||
m_badchars = "'\"#,.[]\\{}";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -305,7 +306,8 @@ bool WRLPROC::ReadName( std::string& aName )
|
|||
while( m_buf[m_linepos] > 0x20 && m_linepos < ssize )
|
||||
{
|
||||
if( '[' == m_buf[m_linepos] || '{' == m_buf[m_linepos]
|
||||
|| '.' == m_buf[m_linepos] || '#' == m_buf[m_linepos] )
|
||||
|| '.' == m_buf[m_linepos] || '#' == m_buf[m_linepos]
|
||||
|| ',' == m_buf[m_linepos] )
|
||||
{
|
||||
if( !aName.empty() )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue