diff --git a/plugins/3d/vrml/CMakeLists.txt b/plugins/3d/vrml/CMakeLists.txt index 30779dcc1a..892b858d66 100644 --- a/plugins/3d/vrml/CMakeLists.txt +++ b/plugins/3d/vrml/CMakeLists.txt @@ -26,6 +26,7 @@ add_library( s3d_plugin_vrml MODULE v1/vrml1_separator.cpp v1/vrml1_material.cpp v1/vrml1_matbinding.cpp + v1/vrml1_coords.cpp ) target_link_libraries( s3d_plugin_vrml kicad_3dsg ${OPENGL_LIBRARIES} ${wxWidgets_LIBRARIES} ) diff --git a/plugins/3d/vrml/v1/vrml1_base.cpp b/plugins/3d/vrml/v1/vrml1_base.cpp index 2773e10595..2ddc2ea5d8 100644 --- a/plugins/3d/vrml/v1/vrml1_base.cpp +++ b/plugins/3d/vrml/v1/vrml1_base.cpp @@ -27,6 +27,7 @@ #include "vrml1_separator.h" #include "vrml1_material.h" #include "vrml1_matbinding.h" +#include "vrml1_coords.h" #include "plugins/3dapi/ifsg_all.h" @@ -436,6 +437,13 @@ bool WRL1BASE::ReadNode( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ) break; + case WRL1_COORDINATE3: + + if( !readCoords( proc, aParent, aNode ) ) + return false; + + break; + // // items not implemented or for optional future implementation: // @@ -560,6 +568,26 @@ bool WRL1BASE::readMatBinding( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNod } +bool WRL1BASE::readCoords( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ) +{ + if( NULL != aNode ) + *aNode = NULL; + + WRL1COORDS* np = new WRL1COORDS( m_dictionary, aParent ); + + if( !np->Read( proc, this ) ) + { + delete np; + return false; + } + + if( NULL != aNode ) + *aNode = (WRL1NODE*) np; + + return true; +} + + SGNODE* WRL1BASE::TranslateToSG( SGNODE* aParent, bool calcNormals ) { #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 ) diff --git a/plugins/3d/vrml/v1/vrml1_base.h b/plugins/3d/vrml/v1/vrml1_base.h index 1ede1fac5b..d9f6b1ec90 100644 --- a/plugins/3d/vrml/v1/vrml1_base.h +++ b/plugins/3d/vrml/v1/vrml1_base.h @@ -55,6 +55,7 @@ private: bool readSwitch( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ); bool readMaterial( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ); bool readMatBinding( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ); + bool readCoords( WRLPROC& proc, WRL1NODE* aParent, WRL1NODE** aNode ); std::map< std::string, WRL1INLINE* > m_inlineModels; diff --git a/plugins/3d/vrml/v1/vrml1_coords.cpp b/plugins/3d/vrml/v1/vrml1_coords.cpp new file mode 100644 index 0000000000..2cf3e7e4ef --- /dev/null +++ b/plugins/3d/vrml/v1/vrml1_coords.cpp @@ -0,0 +1,209 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2016 Cirilo Bernardo + * + * 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 + +#include "vrml1_base.h" +#include "vrml1_coords.h" + + +WRL1COORDS::WRL1COORDS( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary ) +{ + m_Type = WRL1_COORDINATE3; + return; +} + + +WRL1COORDS::WRL1COORDS( NAMEREGISTER* aDictionary, WRL1NODE* aParent ) : + WRL1NODE( aDictionary ) +{ + m_Type = WRL1_COORDINATE3; + m_Parent = aParent; + + if( NULL != m_Parent ) + m_Parent->AddChildNode( this ); + + return; +} + + +WRL1COORDS::~WRL1COORDS() +{ + #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 ) + std::cerr << " * [INFO] Destroying Coordinate3 node\n"; + #endif + return; +} + + +bool WRL1COORDS::AddRefNode( WRL1NODE* aNode ) +{ + // this node may not own or reference any other node + + #ifdef DEBUG_VRML2 + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [BUG] AddRefNode is not applicable\n"; + #endif + + return false; +} + + +bool WRL1COORDS::AddChildNode( WRL1NODE* aNode ) +{ + // this node may not own or reference any other node + + #ifdef DEBUG_VRML2 + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [BUG] AddChildNode is not applicable\n"; + #endif + + return false; +} + + +bool WRL1COORDS::Read( WRLPROC& proc, WRL1BASE* 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; + } + + 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; + + if( proc.Peek() == '}' ) + { + proc.Pop(); + return true; + } + + 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; + } + + proc.GetFilePosData( line, column ); + + // expecting 'point' + if( !glob.compare( "point" ) ) + { + if( !proc.ReadMFVec3f( points ) ) + { + #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 ) + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [INFO] invalid point set 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 defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 ) + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [INFO] bad Coordinate at line " << line << ", column "; + std::cerr << column << "\n"; + std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n"; + #endif + + return false; + } + + if( proc.Peek() == '}' ) + { + proc.Pop(); + return true; + } + + proc.GetFilePosData( line, column ); + + #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 ) + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [INFO] bad Coordinate at line " << line << ", column "; + std::cerr << column << " (no closing brace)\n"; + std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n"; + #endif + + return false; +} + + +void WRL1COORDS::GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ) +{ + if( points.size() < 3 ) + { + aCoordList = NULL; + aListSize = 0; + return; + } + + aCoordList = &points[0]; + aListSize = points.size(); + return; +} + + +SGNODE* WRL1COORDS::TranslateToSG( SGNODE* aParent, bool calcNormals ) +{ + if( m_Parent ) + { + WRL1STATUS* cp = m_Parent->GetCurrentSettings(); + + if( NULL != cp ) + cp->coord = this; + + } + + return NULL; +} diff --git a/plugins/3d/vrml/v1/vrml1_coords.h b/plugins/3d/vrml/v1/vrml1_coords.h new file mode 100644 index 0000000000..d3ed5882d8 --- /dev/null +++ b/plugins/3d/vrml/v1/vrml1_coords.h @@ -0,0 +1,61 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2016 Cirilo Bernardo + * + * 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 vrml1_coords.h + */ + + +#ifndef VRML1_COORDS_H +#define VRML1_COORDS_H + +#include + +#include "vrml1_node.h" + +class WRL1BASE; +class SGNODE; + +/** + * Class WRL1COORDS + */ +class WRL1COORDS : public WRL1NODE +{ +private: + std::vector< WRLVEC3F > points; + +public: + WRL1COORDS( NAMEREGISTER* aDictionary ); + WRL1COORDS( NAMEREGISTER* aDictionary, WRL1NODE* aParent ); + virtual ~WRL1COORDS(); + + // functions inherited from WRL1NODE + bool Read( WRLPROC& proc, WRL1BASE* aTopNode ); + bool AddRefNode( WRL1NODE* aNode ); + bool AddChildNode( WRL1NODE* aNode ); + SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + + void GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ); +}; + +#endif // VRML1_COORDS_H diff --git a/plugins/3d/vrml/v1/vrml1_matbinding.cpp b/plugins/3d/vrml/v1/vrml1_matbinding.cpp index 1c87fdc7de..484a77e32d 100644 --- a/plugins/3d/vrml/v1/vrml1_matbinding.cpp +++ b/plugins/3d/vrml/v1/vrml1_matbinding.cpp @@ -146,6 +146,28 @@ bool WRL1MATBINDING::Read( WRLPROC& proc, WRL1BASE* aTopNode ) return false; } + if( glob.compare( "value" ) ) + { + #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 ) + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [INFO] bad MaterialBinding at line " << line << ", column "; + std::cerr << column << " (did not find keyword 'value')\n"; + std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n"; + #endif + + return false; + } + + if( !proc.ReadName( glob ) ) + { + #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 ) + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << proc.GetError() << "\n"; + #endif + + return false; + } + // expecting one of: // DEFAULT // OVERALL @@ -194,7 +216,7 @@ bool WRL1MATBINDING::Read( WRLPROC& proc, WRL1BASE* aTopNode ) { #if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 ) std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; - std::cerr << " * [INFO] bad Material at line " << line << ", column "; + std::cerr << " * [INFO] bad MaterialBinding at line " << line << ", column "; std::cerr << column << "\n"; std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n"; #endif diff --git a/plugins/3d/vrml/v1/vrml1_node.h b/plugins/3d/vrml/v1/vrml1_node.h index 16222f4c82..f893d6a817 100644 --- a/plugins/3d/vrml/v1/vrml1_node.h +++ b/plugins/3d/vrml/v1/vrml1_node.h @@ -58,6 +58,7 @@ public: class WRL1BASE; class WRL1MATERIAL; +class WRL1COORDS; class SGNODE; @@ -70,7 +71,7 @@ struct WRL1STATUS // normals WRL1NODE* norm; // coordinate3 - WRL1NODE* coord; + WRL1COORDS* coord; // material binding WRL1_BINDING matbind; // normal binding