From cd6b0fbef11da318aab4ccfd6a765f0cb21f1c10 Mon Sep 17 00:00:00 2001 From: Cirilo Bernardo Date: Fri, 5 Feb 2016 16:08:30 +1100 Subject: [PATCH] Added visualization of X3D models --- plugins/3d/vrml/CMakeLists.txt | 2 +- plugins/3d/vrml/x3d.cpp | 4 + plugins/3d/vrml/x3d/x3d_appearance.cpp | 51 ++++++++- plugins/3d/vrml/x3d/x3d_base.cpp | 1 + plugins/3d/vrml/x3d/x3d_coords.cpp | 16 ++- plugins/3d/vrml/x3d/x3d_coords.h | 2 + plugins/3d/vrml/x3d/x3d_ifaceset.cpp | 148 ++++++++++++++++++++++++- 7 files changed, 214 insertions(+), 10 deletions(-) diff --git a/plugins/3d/vrml/CMakeLists.txt b/plugins/3d/vrml/CMakeLists.txt index 4b1854b611..e7e99634c1 100644 --- a/plugins/3d/vrml/CMakeLists.txt +++ b/plugins/3d/vrml/CMakeLists.txt @@ -6,7 +6,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/x3d ) -add_definitions( -DDEBUG_VRML1=1 -DDEBUG_VRML2=1 ) +add_definitions( -DDEBUG_VRML1=1 -DDEBUG_VRML2=1 -DDEBUG_X3D=4 ) add_library( s3d_plugin_vrml MODULE ${CMAKE_SOURCE_DIR}/common/richio.cpp diff --git a/plugins/3d/vrml/x3d.cpp b/plugins/3d/vrml/x3d.cpp index 406f19b742..d5a32c42b9 100644 --- a/plugins/3d/vrml/x3d.cpp +++ b/plugins/3d/vrml/x3d.cpp @@ -81,7 +81,11 @@ SCENEGRAPH* X3DPARSER::Load( const wxString& aFileName ) SCENEGRAPH* sp = NULL; if( ok ) + { + std::cerr << "XXX: Translating ...\n"; sp = (SCENEGRAPH*) topNode->TranslateToSG( NULL ); + std::cerr << "XXX: sp = " << sp << "\n"; + } delete topNode; return sp; diff --git a/plugins/3d/vrml/x3d/x3d_appearance.cpp b/plugins/3d/vrml/x3d/x3d_appearance.cpp index 5407cdfea3..1ae6f34338 100644 --- a/plugins/3d/vrml/x3d/x3d_appearance.cpp +++ b/plugins/3d/vrml/x3d/x3d_appearance.cpp @@ -26,6 +26,7 @@ #include #include "x3d_ops.h" #include "x3d_appearance.h" +#include "plugins/3dapi/ifsg_all.h" X3DAPP::X3DAPP() : X3DNODE() @@ -231,6 +232,52 @@ bool X3DAPP::AddRefNode( X3DNODE* aNode ) SGNODE* X3DAPP::TranslateToSG( SGNODE* aParent ) { - // XXX - - return NULL; + S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); + + if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE ) + { + #ifdef DEBUG_X3D + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [BUG] Appearance does not have a Shape parent (parent ID: "; + std::cerr << ptype << ")\n"; + #endif + + return NULL; + } + + #if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 ) + std::cerr << " * [INFO] Translating Appearance with " << m_Children.size(); + std::cerr << " children, " << m_Refs.size() << " references and "; + std::cerr << m_BackPointers.size() << " backpointers\n"; + #endif + + 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_APPEARANCE matNode( aParent ); + matNode.SetEmissive( emissiveColor.x, emissiveColor.y, emissiveColor.z ); + matNode.SetSpecular( specularColor.x, specularColor.y, specularColor.z ); + matNode.SetDiffuse( diffuseColor.x, diffuseColor.y, diffuseColor.z ); + matNode.SetAmbient( ambientIntensity ); + matNode.SetShininess( shininess ); + matNode.SetTransparency( transparency ); + m_sgNode = matNode.GetRawPtr(); + + return m_sgNode; } diff --git a/plugins/3d/vrml/x3d/x3d_base.cpp b/plugins/3d/vrml/x3d/x3d_base.cpp index 6adae10acd..cfb9ac5bc1 100644 --- a/plugins/3d/vrml/x3d/x3d_base.cpp +++ b/plugins/3d/vrml/x3d/x3d_base.cpp @@ -22,6 +22,7 @@ */ +#include #include #include #include "x3d_base.h" diff --git a/plugins/3d/vrml/x3d/x3d_coords.cpp b/plugins/3d/vrml/x3d/x3d_coords.cpp index 0410c43211..5548e6c2c1 100644 --- a/plugins/3d/vrml/x3d/x3d_coords.cpp +++ b/plugins/3d/vrml/x3d/x3d_coords.cpp @@ -171,8 +171,22 @@ bool X3DCOORDS::AddRefNode( X3DNODE* aNode ) } +void X3DCOORDS::GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ) +{ + if( points.size() < 3 ) + { + aCoordList = NULL; + aListSize = 0; + return; + } + + aCoordList = &points[0]; + aListSize = points.size(); + return; +} + + SGNODE* X3DCOORDS::TranslateToSG( SGNODE* aParent ) { - // XXX - return NULL; } diff --git a/plugins/3d/vrml/x3d/x3d_coords.h b/plugins/3d/vrml/x3d/x3d_coords.h index 6dfaebf49c..1d8579fcd5 100644 --- a/plugins/3d/vrml/x3d/x3d_coords.h +++ b/plugins/3d/vrml/x3d/x3d_coords.h @@ -54,6 +54,8 @@ public: bool AddChildNode( X3DNODE* aNode ); bool AddRefNode( X3DNODE* aNode ); SGNODE* TranslateToSG( SGNODE* aParent ); + + void GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ); }; #endif // X3D_COORDS_H diff --git a/plugins/3d/vrml/x3d/x3d_ifaceset.cpp b/plugins/3d/vrml/x3d/x3d_ifaceset.cpp index e029b6bf98..d059f212bd 100644 --- a/plugins/3d/vrml/x3d/x3d_ifaceset.cpp +++ b/plugins/3d/vrml/x3d/x3d_ifaceset.cpp @@ -28,11 +28,15 @@ #include #include "x3d_ops.h" #include "x3d_ifaceset.h" +#include "x3d_coords.h" +#include "plugins/3dapi/ifsg_all.h" +#include "wrlfacet.h" X3DIFACESET::X3DIFACESET() : X3DNODE() { m_Type = X3D_INDEXED_FACE_SET; + coord = NULL; init(); return; @@ -42,6 +46,7 @@ X3DIFACESET::X3DIFACESET() : X3DNODE() X3DIFACESET::X3DIFACESET( X3DNODE* aParent ) : X3DNODE() { m_Type = X3D_INDEXED_FACE_SET; + coord = NULL; init(); if( NULL != aParent ) @@ -155,8 +160,6 @@ bool X3DIFACESET::Read( wxXmlNode* aNode, X3DNODE* aTopNode, X3D_DICT& aDict ) if( !SetParent( aTopNode ) ) return false; - std::cerr << "XXX: Got " << coordIndex.size() << " indices\n"; - return true; } @@ -188,18 +191,151 @@ bool X3DIFACESET::SetParent( X3DNODE* aParent, bool doUnlink ) bool X3DIFACESET::AddChildNode( X3DNODE* aNode ) { - return false; + if( NULL == aNode ) + return false; + + if( aNode->GetNodeType() != X3D_COORDINATE ) + return false; + + if( aNode == coord ) + return true; + + if( NULL != coord ) + return false; + + m_Children.push_back( aNode ); + coord = aNode; + + if( aNode->GetParent() != this ) + aNode->SetParent( this ); + + return true; } bool X3DIFACESET::AddRefNode( X3DNODE* aNode ) { - return false; + if( NULL == aNode ) + return false; + + if( aNode->GetNodeType() != X3D_COORDINATE ) + return false; + + if( aNode == coord ) + return true; + + if( NULL != coord ) + return false; + + m_Refs.push_back( aNode ); + coord = aNode; + return true; } SGNODE* X3DIFACESET::TranslateToSG( SGNODE* aParent ) { - // XXX - - return NULL; + S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); + + if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE ) + { + #ifdef DEBUG_X3D + std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; + std::cerr << " * [BUG] IndexedFaceSet does not have a Shape parent (parent ID: "; + std::cerr << ptype << ")\n"; + #endif + + return NULL; + } + + #if defined( DEBUG_X3D ) && ( DEBUG_X3D > 2 ) + std::cerr << " * [INFO] Translating IndexedFaceSet with " << m_Children.size(); + std::cerr << " children, " << m_Refs.size() << " references, "; + std::cerr << m_BackPointers.size() << " backpointers and "; + std::cerr << coordIndex.size() << " coord indices\n"; + #endif + + 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; + } + + size_t vsize = coordIndex.size(); + + if( NULL == coord || vsize < 3 ) + return NULL; + + WRLVEC3F* pcoords; + size_t coordsize; + ((X3DCOORDS*) coord)->GetCoords( pcoords, coordsize ); + + if( coordsize < 3 ) + return NULL; + + // check that all indices are valid + for( size_t idx = 0; idx < vsize; ++idx ) + { + if( coordIndex[idx] < 0 ) + continue; + + if( coordIndex[idx] >= (int)coordsize ) + return NULL; + } + + SHAPE lShape; + FACET* fp = NULL; + size_t iCoord; + int idx; // coordinate index + + // no per-vertex colors; we can save a few CPU cycles + for( iCoord = 0; iCoord < vsize; ++iCoord ) + { + idx = coordIndex[iCoord]; + + if( idx < 0 ) + { + if( NULL != fp ) + { + if( fp->HasMinPoints() ) + fp = NULL; + else + fp->Init(); + } + + continue; + } + + // if the coordinate is bad then skip it + if( idx >= (int)coordsize ) + continue; + + if( NULL == fp ) + fp = lShape.NewFacet(); + + // push the vertex value and index + fp->AddVertex( pcoords[idx], idx ); + } + + SGNODE* np = NULL; + + if( ccw ) + np = lShape.CalcShape( aParent, NULL, ORD_CCW, creaseLimit, true ); + else + np = lShape.CalcShape( aParent, NULL, ORD_CLOCKWISE, creaseLimit, true ); + + return np; }