Fixed various bugs in VRML2 and VRML1 code

This commit is contained in:
Cirilo Bernardo 2016-01-07 11:24:11 +11:00
parent 29d7829909
commit 8a9eb3bbe8
17 changed files with 1131 additions and 104 deletions

View File

@ -32,16 +32,12 @@
#include <GL/glew.h>
#include <GL/gl.h>
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
# include <GL/glu.h>
#include <GL/gl.h>
#include <GL/glu.h>
#endif

View File

@ -4,7 +4,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/v2
)
#add_definitions( -DDEBUG_VRML1=2 )
add_definitions( -DDEBUG_VRML1=2 -DDEBUG_VRML2=2 )
add_library( s3d_plugin_vrml MODULE
vrml.cpp
@ -16,6 +16,8 @@ add_library( s3d_plugin_vrml MODULE
v2/vrml2_appearance.cpp
v2/vrml2_material.cpp
v2/vrml2_faceset.cpp
v2/vrml2_lineset.cpp
v2/vrml2_pointset.cpp
v2/vrml2_coords.cpp
v2/vrml2_norms.cpp
v2/vrml2_color.cpp

View File

@ -263,12 +263,6 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
switch( m_current.matbind )
{
case BIND_OVERALL:
// use the first (non-default) appearance definition
sgcolor = m_current.mat->GetAppearance( 0 );
break;
case BIND_PER_FACE:
case BIND_PER_VERTEX:
break;
@ -289,8 +283,8 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
default:
// use the default appearance definition
sgcolor = m_current.mat->GetAppearance( -1 );
// use the first appearance definition
sgcolor = m_current.mat->GetAppearance( 0 );
break;
}
@ -307,13 +301,19 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
continue;
if( coordIndex[idx] >= (int)coordsize )
{
m_current.mat->Reclaim( sgcolor );
return NULL;
}
}
// if the indices are defective just give up
if( i1 < 0 || i2 < 0 || i3 < 0
|| i1 == i2 || i1 == i3 || i2 == i3 )
{
m_current.mat->Reclaim( sgcolor );
return NULL;
}
std::vector< SGPOINT > lCPts; // coordinate points for SG node
std::vector< int > lCIdx; // coordinate index list for SG node (must be triads)
@ -351,10 +351,13 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
// any invalid polygons shall void the entire faceset; this is a requirement
// to ensure correct handling of the normals
if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) )
{
m_current.mat->Reclaim( sgcolor );
return NULL;
}
}
}
}
else
{
// the entity requires a color list
@ -490,7 +493,10 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
}
if( lCIdx.empty() )
{
m_current.mat->Reclaim( sgcolor );
return NULL;
}
// create a vertex list for per-face per-vertex normals
do {

View File

@ -31,6 +31,8 @@
WRL1MATERIAL::WRL1MATERIAL( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary )
{
colors[0] = NULL;
colors[1] = NULL;
m_Type = WRL1_MATERIAL;
return;
}
@ -39,6 +41,8 @@ WRL1MATERIAL::WRL1MATERIAL( NAMEREGISTER* aDictionary ) : WRL1NODE( aDictionary
WRL1MATERIAL::WRL1MATERIAL( NAMEREGISTER* aDictionary, WRL1NODE* aParent ) :
WRL1NODE( aDictionary )
{
colors[0] = NULL;
colors[1] = NULL;
m_Type = WRL1_MATERIAL;
m_Parent = aParent;
@ -478,3 +482,29 @@ void WRL1MATERIAL::checkRange( float& aValue )
return;
}
void WRL1MATERIAL::Reclaim( SGNODE* aColor )
{
if( NULL == aColor )
return;
if( aColor == colors[0] )
{
if( NULL == S3D::GetSGNodeParent( aColor ) )
{
colors[0] = NULL;
S3D::DestroyNode( aColor );
}
return;
}
if( aColor == colors[1] && NULL == S3D::GetSGNodeParent( aColor ) )
{
colors[1] = NULL;
S3D::DestroyNode( aColor );
}
return;
}

View File

@ -77,6 +77,12 @@ public:
* computes an SGCOLOR representing the appearance of a vertex or face
*/
void GetColor( SGCOLOR* aColor, int aIndex );
/**
* Function Reclaim
* will destroy the given color node if it does not have a parent
*/
void Reclaim( SGNODE* aColor );
};
#endif // VRML1_MATERIAL_H

View File

@ -29,6 +29,8 @@
#include "vrml2_appearance.h"
#include "vrml2_material.h"
#include "vrml2_faceset.h"
#include "vrml2_lineset.h"
#include "vrml2_pointset.h"
#include "vrml2_coords.h"
#include "vrml2_norms.h"
#include "vrml2_color.h"
@ -509,6 +511,20 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
break;
case WRL2_INDEXEDLINESET:
if( !readLineSet( proc, aParent, aNode ) )
return false;
break;
case WRL2_POINTSET:
if( !readPointSet( proc, aParent, aNode ) )
return false;
break;
case WRL2_MATERIAL:
if( !readMaterial( proc, aParent, aNode ) )
@ -578,7 +594,6 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
case WRL2_FOG:
case WRL2_FONTSTYLE:
case WRL2_IMAGETEXTURE:
case WRL2_INDEXEDLINESET:
case WRL2_INLINE:
case WRL2_LOD:
case WRL2_MOVIETEXTURE:
@ -588,7 +603,6 @@ bool WRL2BASE::ReadNode( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
case WRL2_PIXELTEXTURE:
case WRL2_PLANESENSOR:
case WRL2_POINTLIGHT:
case WRL2_POINTSET:
case WRL2_POSITIONINTERPOLATOR:
case WRL2_PROXIMITYSENSOR:
case WRL2_SCALARINTERPOLATOR:
@ -741,6 +755,46 @@ bool WRL2BASE::readFaceSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
}
bool WRL2BASE::readLineSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
{
if( NULL != aNode )
*aNode = NULL;
WRL2LINESET* np = new WRL2LINESET( aParent );
if( !np->Read( proc, this ) )
{
delete np;
return false;
}
if( NULL != aNode )
*aNode = (WRL2NODE*) np;
return true;
}
bool WRL2BASE::readPointSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
{
if( NULL != aNode )
*aNode = NULL;
WRL2POINTSET* np = new WRL2POINTSET( aParent );
if( !np->Read( proc, this ) )
{
delete np;
return false;
}
if( NULL != aNode )
*aNode = (WRL2NODE*) np;
return true;
}
bool WRL2BASE::readCoords( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode )
{
if( NULL != aNode )

View File

@ -70,6 +70,8 @@ private:
bool readAppearance( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readMaterial( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readFaceSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readLineSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readPointSet( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readCoords( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readNorms( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );
bool readColor( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode );

View File

@ -221,3 +221,19 @@ void WRL2COLOR::GetColor( int aIndex, float& red, float& green, float& blue )
return;
}
void WRL2COLOR::GetColors( WRLVEC3F*& aColorList, size_t& aListSize)
{
if( colors.empty() )
{
aColorList = NULL;
aListSize = 0;
return;
}
aColorList = &colors[0];
aListSize = colors.size();
return;
}

View File

@ -71,6 +71,12 @@ public:
* retrieves the given color (or default 0.8, 0.8, 0.8 if index is invalid)
*/
void GetColor( int aIndex, float& red, float& green, float& blue );
/**
* Function GetColors
* retrieves the current list of colors
*/
void GetColors( WRLVEC3F*& aColorList, size_t& aListSize);
};
#endif // VRML2_COLOR_H

View File

@ -690,11 +690,11 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
if( colorIndex.empty() )
{
cn->GetColor( 0, tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[0], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( 1, tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[1], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( 2, tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[2], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else
@ -759,21 +759,29 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
++nfaces;
i2 = i3;
i3 = coordIndex[idx++];
if( colorPerVertex && i1 >= 0 && i2 >= 0 && i3 >= 0 )
{
pc1.SetColor( pc2 );
pc2.SetColor( pc3 );
if( colorIndex.empty() || cIndex >= cMaxIdx )
cn->GetColor( cIndex++, tc.x, tc.y, tc.z );
if( colorIndex.empty() )
{
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else
cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
i3 = coordIndex[idx++];
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
{
if( i3 < 0 )
@ -796,21 +804,29 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
i1 = i2;
i2 = i3;
i3 = coordIndex[idx++];
if( colorPerVertex )
{
pc1.SetColor( pc2 );
pc2.SetColor( pc3 );
if( colorIndex.empty() || cIndex >= cMaxIdx )
cn->GetColor( cIndex++, tc.x, tc.y, tc.z );
if( colorIndex.empty() )
{
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc1.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc2.SetColor( tc.x, tc.y, tc.z );
cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
else
cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z );
pc3.SetColor( tc.x, tc.y, tc.z );
}
i3 = coordIndex[idx++];
// any invalid polygons shall void the entire faceset; this is a requirement
// to ensure correct handling of the normals
if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) )

View File

@ -0,0 +1,420 @@
/*
* 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 "vrml2_base.h"
#include "vrml2_lineset.h"
#include "vrml2_coords.h"
#include "vrml2_color.h"
#include "plugins/3dapi/ifsg_all.h"
WRL2LINESET::WRL2LINESET() : WRL2NODE()
{
setDefaults();
m_Type = WRL2_INDEXEDLINESET;
return;
}
WRL2LINESET::WRL2LINESET( WRL2NODE* aParent ) : WRL2NODE()
{
setDefaults();
m_Type = WRL2_INDEXEDLINESET;
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
WRL2LINESET::~WRL2LINESET()
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Destroying IndexedLineSet with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
return;
}
void WRL2LINESET::setDefaults( void )
{
color = NULL;
coord = NULL;
colorPerVertex = true;
}
bool WRL2LINESET::checkNodeType( WRL2NODES aType )
{
// nodes must be one of:
// Color
// Coordinate
switch( aType )
{
case WRL2_COLOR:
case WRL2_COORDINATE:
break;
default:
return false;
break;
}
return true;
}
bool WRL2LINESET::isDangling( void )
{
// this node is dangling unless it has a parent of type WRL2_SHAPE
if( NULL == m_Parent || m_Parent->GetNodeType() != WRL2_SHAPE )
return true;
return false;
}
bool WRL2LINESET::AddRefNode( WRL2NODE* aNode )
{
if( NULL == aNode )
{
#ifdef DEBUG_VRML2
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] NULL passed for aNode\n";
#endif
return false;
}
WRL2NODES type = aNode->GetNodeType();
if( !checkNodeType( type ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; unexpected child node '";
std::cerr << aNode->GetNodeTypeName( type ) << "'\n";
#endif
return false;
}
if( WRL2_COLOR == type )
{
if( NULL != color )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple color nodes\n";
#endif
return false;
}
color = aNode;
return WRL2NODE::AddRefNode( aNode );
}
if( WRL2_COORDINATE == type )
{
if( NULL != coord )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple coordinate nodes\n";
#endif
return false;
}
coord = aNode;
return WRL2NODE::AddRefNode( aNode );
}
return WRL2NODE::AddRefNode( aNode );
}
bool WRL2LINESET::AddChildNode( WRL2NODE* aNode )
{
if( NULL == aNode )
{
#ifdef DEBUG_VRML2
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] NULL passed for aNode\n";
#endif
return false;
}
WRL2NODES type = aNode->GetNodeType();
if( !checkNodeType( type ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; unexpected child node '";
std::cerr << aNode->GetNodeTypeName( type ) << "'\n";
#endif
return false;
}
if( WRL2_COLOR == type )
{
if( NULL != color )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple color nodes\n";
#endif
return false;
}
color = aNode;
return WRL2NODE::AddChildNode( aNode );
}
if( WRL2_COORDINATE == type )
{
if( NULL != coord )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple coordinate nodes\n";
#endif
return false;
}
coord = aNode;
return WRL2NODE::AddChildNode( aNode );
}
return WRL2NODE::AddChildNode( aNode );
}
bool WRL2LINESET::Read( 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;
}
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:
// [node]
// color
// coord
// [bool]
// colorPerVertex
// [ vector<int> ]
// colorIndex
// coordIndex
proc.GetFilePosData( line, column );
if( !glob.compare( "colorPerVertex" ) )
{
if( !proc.ReadSFBool( colorPerVertex ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] invalid colorPerVertex 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( "colorIndex" ) )
{
if( !proc.ReadMFInt( colorIndex ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] invalid colorIndex 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( "coordIndex" ) )
{
if( !proc.ReadMFInt( coordIndex ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] invalid coordIndex 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( "color" ) )
{
if( !aTopNode->ReadNode( proc, this, NULL ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] could not read color node information\n";
#endif
return false;
}
}
else if( !glob.compare( "coord" ) )
{
if( !aTopNode->ReadNode( proc, this, NULL ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] could not read coord node information\n";
#endif
return false;
}
}
else
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad IndexedLineSet at line " << line << ", column ";
std::cerr << column << "\n";
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
#endif
return false;
}
} // while( true ) -- reading contents of IndexedLineSet{}
return true;
}
SGNODE* WRL2LINESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
{
// note: there are no plans to support drawing of lines
return NULL;
}
void WRL2LINESET::unlinkChildNode( const WRL2NODE* aNode )
{
if( NULL == aNode )
return;
if( aNode->GetParent() == this )
{
if( aNode == color )
color = NULL;
else if( aNode == coord )
coord = NULL;
}
WRL2NODE::unlinkChildNode( aNode );
return;
}
void WRL2LINESET::unlinkRefNode( const WRL2NODE* aNode )
{
if( NULL == aNode )
return;
if( aNode->GetParent() != this )
{
if( aNode == color )
color = NULL;
else if( aNode == coord )
coord = NULL;
}
WRL2NODE::unlinkRefNode( aNode );
return;
}
bool WRL2LINESET::HasColors( void )
{
if( NULL == color )
return false;
return ((WRL2COLOR*) color)->HasColors();
}

View File

@ -0,0 +1,89 @@
/*
* 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 vrml2_lineset.h
*/
#ifndef VRML2_LINESET_H
#define VRML2_LINESET_H
#include <vector>
#include "vrml2_node.h"
class WRL2BASE;
class SGNODE;
/**
* Class WRL2LINESET
*/
class WRL2LINESET : public WRL2NODE
{
private:
WRL2NODE* color;
WRL2NODE* coord;
bool colorPerVertex;
std::vector< int > colorIndex;
std::vector< int > coordIndex;
/**
* Function checkNodeType
* returns true if the node type is a valid subnode of LineSet
*/
bool checkNodeType( WRL2NODES aType );
void setDefaults( void );
public:
// functions inherited from WRL2NODE
bool isDangling( void );
// overloads
void unlinkChildNode( const WRL2NODE* aNode );
void unlinkRefNode( const WRL2NODE* aNode );
public:
WRL2LINESET();
WRL2LINESET( WRL2NODE* aParent );
virtual ~WRL2LINESET();
// functions inherited from WRL2NODE
bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
/**
* Function HasColors
* returns true if the face set has a color node
*/
bool HasColors( void );
};
#endif // VRML2_LINESET_H

View File

@ -399,7 +399,7 @@ bool WRL2NODE::AddRefNode( WRL2NODE* aNode )
while( sR != eR )
{
if( *sR == aNode )
return false;
return true;
++sR;
}

View File

@ -0,0 +1,371 @@
/*
* 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 "vrml2_base.h"
#include "vrml2_pointset.h"
#include "vrml2_coords.h"
#include "vrml2_color.h"
#include "plugins/3dapi/ifsg_all.h"
WRL2POINTSET::WRL2POINTSET() : WRL2NODE()
{
setDefaults();
m_Type = WRL2_POINTSET;
return;
}
WRL2POINTSET::WRL2POINTSET( WRL2NODE* aParent ) : WRL2NODE()
{
setDefaults();
m_Type = WRL2_POINTSET;
m_Parent = aParent;
if( NULL != m_Parent )
m_Parent->AddChildNode( this );
return;
}
WRL2POINTSET::~WRL2POINTSET()
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 )
std::cerr << " * [INFO] Destroying PointSet with " << m_Children.size();
std::cerr << " children, " << m_Refs.size() << " references and ";
std::cerr << m_BackPointers.size() << " backpointers\n";
#endif
return;
}
void WRL2POINTSET::setDefaults( void )
{
color = NULL;
coord = NULL;
}
bool WRL2POINTSET::checkNodeType( WRL2NODES aType )
{
// nodes must be one of:
// Color
// Coordinate
switch( aType )
{
case WRL2_COLOR:
case WRL2_COORDINATE:
break;
default:
return false;
break;
}
return true;
}
bool WRL2POINTSET::isDangling( void )
{
// this node is dangling unless it has a parent of type WRL2_SHAPE
if( NULL == m_Parent || m_Parent->GetNodeType() != WRL2_SHAPE )
return true;
return false;
}
bool WRL2POINTSET::AddRefNode( WRL2NODE* aNode )
{
if( NULL == aNode )
{
#ifdef DEBUG_VRML2
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] NULL passed for aNode\n";
#endif
return false;
}
WRL2NODES type = aNode->GetNodeType();
if( !checkNodeType( type ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; unexpected child node '";
std::cerr << aNode->GetNodeTypeName( type ) << "'\n";
#endif
return false;
}
if( WRL2_COLOR == type )
{
if( NULL != color )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple color nodes\n";
#endif
return false;
}
color = aNode;
return WRL2NODE::AddRefNode( aNode );
}
if( WRL2_COORDINATE == type )
{
if( NULL != coord )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple coordinate nodes\n";
#endif
return false;
}
coord = aNode;
return WRL2NODE::AddRefNode( aNode );
}
return WRL2NODE::AddRefNode( aNode );
}
bool WRL2POINTSET::AddChildNode( WRL2NODE* aNode )
{
if( NULL == aNode )
{
#ifdef DEBUG_VRML2
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [BUG] NULL passed for aNode\n";
#endif
return false;
}
WRL2NODES type = aNode->GetNodeType();
if( !checkNodeType( type ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; unexpected child node '";
std::cerr << aNode->GetNodeTypeName( type ) << "'\n";
#endif
return false;
}
if( WRL2_COLOR == type )
{
if( NULL != color )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple color nodes\n";
#endif
return false;
}
color = aNode;
return WRL2NODE::AddChildNode( aNode );
}
if( WRL2_COORDINATE == type )
{
if( NULL != coord )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad file format; multiple coordinate nodes\n";
#endif
return false;
}
coord = aNode;
return WRL2NODE::AddChildNode( aNode );
}
return WRL2NODE::AddChildNode( aNode );
}
bool WRL2POINTSET::Read( 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;
}
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:
// color
// coord
proc.GetFilePosData( line, column );
if( !glob.compare( "color" ) )
{
if( !aTopNode->ReadNode( proc, this, NULL ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] could not read color node information\n";
#endif
return false;
}
}
else if( !glob.compare( "coord" ) )
{
if( !aTopNode->ReadNode( proc, this, NULL ) )
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] could not read coord node information\n";
#endif
return false;
}
}
else
{
#if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 )
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] bad PointSet at line " << line << ", column ";
std::cerr << column << "\n";
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
#endif
return false;
}
} // while( true ) -- reading contents of PointSet{}
return true;
}
SGNODE* WRL2POINTSET::TranslateToSG( SGNODE* aParent, bool calcNormals )
{
// note: there are no plans to support drawing of points
return NULL;
}
void WRL2POINTSET::unlinkChildNode( const WRL2NODE* aNode )
{
if( NULL == aNode )
return;
if( aNode->GetParent() == this )
{
if( aNode == color )
color = NULL;
else if( aNode == coord )
coord = NULL;
}
WRL2NODE::unlinkChildNode( aNode );
return;
}
void WRL2POINTSET::unlinkRefNode( const WRL2NODE* aNode )
{
if( NULL == aNode )
return;
if( aNode->GetParent() != this )
{
if( aNode == color )
color = NULL;
else if( aNode == coord )
coord = NULL;
}
WRL2NODE::unlinkRefNode( aNode );
return;
}
bool WRL2POINTSET::HasColors( void )
{
if( NULL == color )
return false;
return ((WRL2COLOR*) color)->HasColors();
}

View File

@ -0,0 +1,84 @@
/*
* 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 vrml2_pointset.h
*/
#ifndef VRML2_POINTSET_H
#define VRML2_POINTSET_H
#include <vector>
#include "vrml2_node.h"
class WRL2BASE;
class SGNODE;
/**
* Class WRL2POINTSET
*/
class WRL2POINTSET : public WRL2NODE
{
private:
WRL2NODE* color;
WRL2NODE* coord;
/**
* Function checkNodeType
* returns true if the node type is a valid subnode of PointSet
*/
bool checkNodeType( WRL2NODES aType );
void setDefaults( void );
public:
// functions inherited from WRL2NODE
bool isDangling( void );
// overloads
void unlinkChildNode( const WRL2NODE* aNode );
void unlinkRefNode( const WRL2NODE* aNode );
public:
WRL2POINTSET();
WRL2POINTSET( WRL2NODE* aParent );
virtual ~WRL2POINTSET();
// functions inherited from WRL2NODE
bool Read( WRLPROC& proc, WRL2BASE* aTopNode );
bool AddRefNode( WRL2NODE* aNode );
bool AddChildNode( WRL2NODE* aNode );
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
/**
* Function HasColors
* returns true if the face set has a color node
*/
bool HasColors( void );
};
#endif // VRML2_POINTSET_H

View File

@ -319,17 +319,18 @@ bool WRL2SHAPE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
{
// XXX - TO BE IMPLEMENTED:
if( NULL == geometry )
return NULL;
bool vcolors = ((WRL2FACESET*)geometry)->HasColors();
// if there is no appearance, make use of the per vertex colors if available
if( NULL == appearance )
{
if( WRL2_INDEXEDFACESET != geometry->GetNodeType() )
return NULL;
if( !((WRL2FACESET*)geometry)->HasColors() )
if( !vcolors )
return NULL;
}

View File

@ -1435,18 +1435,6 @@ bool WRLPROC::ReadMFColor( std::vector< WRLVEC3F >& aMFColor )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;
@ -1579,18 +1567,6 @@ bool WRLPROC::ReadMFFloat( std::vector< float >& aMFFloat )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;
@ -1723,18 +1699,6 @@ bool WRLPROC::ReadMFInt( std::vector< int >& aMFInt32 )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;
@ -1867,18 +1831,6 @@ bool WRLPROC::ReadMFRotation( std::vector< WRLROTATION >& aMFRotation )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;
@ -2011,18 +1963,6 @@ bool WRLPROC::ReadMFVec2f( std::vector< WRLVEC2F >& aMFVec2f )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;
@ -2155,18 +2095,6 @@ bool WRLPROC::ReadMFVec3f( std::vector< WRLVEC3F >& aMFVec3f )
if( ']' == m_buf[m_linepos] )
break;
if( !lcomma )
{
std::ostringstream ostr;
ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
ostr << " * [INFO] failed on file '" << m_filename << "'\n";
ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
ostr << "line " << m_fileline << ", char " << m_linepos << "\n";
ostr << " * [INFO] comma missing in delimited list";
m_error = ostr.str();
return false;
}
}
++m_linepos;