Commit d40ea8ad authored by unknown's avatar unknown Committed by jean-pierre charras

3D viewer: fix issues with transparencies in some models (material issues in VRML2 parser)

Fix some issues in filling zones normals.
Fix an issue with some models that have materials but didn't defined the diffuse color.
Workaround for Bug #1443431.
Implement some missing "code logic" for pervertexperface normals.
Remove some not used functions.
Calculate normals using double type.
parent b85ed89e
......@@ -95,7 +95,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) :
m_ZBottom = 0.0;
m_ZTop = 0.0;
m_lightPos = S3D_VERTEX(0.0f, 0.0f, 50.0f);
m_lightPos = S3D_VERTEX(0.0f, 0.0f, 30.0f);
// Clear all gl list identifiers:
for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ )
......@@ -591,7 +591,7 @@ void EDA_3D_CANVAS::SetLights()
light_color[3] = 1.0;
// Light above the xy plane
light_color[0] = light_color[1] = light_color[2] = 0.2;
light_color[0] = light_color[1] = light_color[2] = 0.0;
glLightfv( GL_LIGHT0, GL_AMBIENT, light_color );
light_color[0] = light_color[1] = light_color[2] = 1.0;
......@@ -605,6 +605,8 @@ void EDA_3D_CANVAS::SetLights()
light_color[0] = light_color[1] = light_color[2] = 0.2;
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, light_color );
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
glEnable( GL_LIGHT0 ); // White spot on Z axis ( top )
glEnable( GL_LIGHTING );
}
......
......@@ -85,7 +85,7 @@ S3D_MASTER:: ~S3D_MASTER()
{
nextmat = m_Materials->Next();
delete m_Materials;
m_Materials = 0;
m_Materials = NULL;
}
}
......
......@@ -446,6 +446,8 @@ void EDA_3D_CANVAS::Redraw()
glEnable( GL_COLOR_MATERIAL );
SetOpenGlDefaultMaterial();
//glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, FALSE );
// Board Body
GLint shininess_value = 32;
......@@ -497,6 +499,7 @@ void EDA_3D_CANVAS::Redraw()
glCallList( m_glLists[GL_ID_AUX_LAYERS] );
}
//glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, TRUE );
// Draw Component Shadow
......@@ -583,6 +586,7 @@ void EDA_3D_CANVAS::Redraw()
// non transparent objects
if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
{
glEnable( GL_COLOR_MATERIAL );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
......@@ -926,6 +930,14 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );
float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted)
// If we are not using thickness, then the znormal must face the layer direction
// because it will draw just one plane
if( !thickness )
zNormal = Get3DLayer_Z_Orientation( layer );
if( realistic_mode )
{
setGLCopperColor();
......@@ -941,17 +953,17 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
// If holes are removed from copper zones, bufferPolys contains all polygons
// to draw (tracks+zones+texts).
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness,
GetPrm3DVisu().m_BiuTo3Dunits, useTextures );
GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
zNormal );
// If holes are not removed from copper zones (for calculation time reasons,
// the zone polygons are stored in bufferZonesPolys and have to be drawn now:
if( bufferZonesPolys.GetCornersCount() )
{
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferZonesPolys, zpos, thickness,
GetPrm3DVisu().m_BiuTo3Dunits, useTextures );
GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
zNormal );
}
throughHolesListBuilt = true;
......@@ -1016,7 +1028,6 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
zpos += (copper_thickness + epsilon) / 2.0f;
board_thickness -= copper_thickness + epsilon;
glNormal3f( 0.0f, 0.0f, Get3DLayer_Z_Orientation( F_Cu ) );
KI_POLYGON_SET currLayerPolyset;
KI_POLYGON_SET polysetHoles;
......@@ -1035,7 +1046,8 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
if( bufferPcbOutlines.GetCornersCount() )
{
Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness / 2.0,
board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures );
board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
1.0f );
}
glEndList();
......@@ -1256,10 +1268,18 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
bufferPolys.RemoveAllContours();
bufferPolys.ImportFrom( currLayerPolyset );
float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted)
// If we are not using thickness, then the znormal must face the layer direction
// because it will draw just one plane
if( !thickness )
zNormal = Get3DLayer_Z_Orientation( layer );
setGLTechLayersColor( layer );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures );
thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
zNormal );
}
}
......@@ -1361,10 +1381,17 @@ void EDA_3D_CANVAS::buildBoard3DAuxLayers( REPORTER* aErrorMessages, REPORTER* a
bufferPolys.RemoveAllContours();
bufferPolys.ImportFrom( currLayerPolyset );
float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted)
// If we are not using thickness, then the znormal must face the layer direction
// because it will draw just one plane
if( !thickness )
zNormal = Get3DLayer_Z_Orientation( layer );
setGLTechLayersColor( layer );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
thickness, GetPrm3DVisu().m_BiuTo3Dunits, false );
thickness, GetPrm3DVisu().m_BiuTo3Dunits, false,
zNormal );
}
}
......
......@@ -54,17 +54,6 @@ static void CALLBACK tessEndCB();
static void CALLBACK tessErrorCB( GLenum errorCode );
static void CALLBACK tessCPolyPt2Vertex( const GLvoid* data );
// 2 helper functions to set the current normal vector for gle items
static inline void SetNormalZpos()
{
glNormal3f( 0.0, 0.0, 1.0 );
}
static inline void SetNormalZneg()
{
glNormal3f( 0.0, 0.0, -1.0 );
}
void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
/* Draw3D_VerticalPolygonalCylinder is a helper function.
......@@ -160,7 +149,8 @@ void SetGLTexture( GLuint text_id, float scale )
*/
void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits,
bool aUseTextures )
bool aUseTextures,
float aNormal_Z_Orientation )
{
// for Tess callback functions:
s_biuTo3Dunits = aBiuTo3DUnits;
......@@ -176,13 +166,14 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
GLdouble v_data[3];
double zpos = ( aZpos + (aThickness / 2.0) ) * aBiuTo3DUnits;
s_currentZpos = zpos; // for Tess callback functions
v_data[2] = aZpos + (aThickness / 2.0);
v_data[2] = zpos;
// Set normal toward positive Z axis, for a solid object on the top side
if( aThickness )
SetNormalZpos();
// gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
//gluTessProperty( tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE );
//gluTessProperty( tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD );
glNormal3f( 0.0, 0.0, aNormal_Z_Orientation );
// Draw solid areas contained in this list
CPOLYGONS_LIST polylist = aPolysList; // temporary copy for gluTessVertex
......@@ -202,11 +193,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
startContour = 0;
}
// https://www.opengl.org/sdk/docs/man2/xhtml/gluTessNormal.xml
if( !aThickness )
gluTessNormal( tess, 0.0, 0.0, 0.0 );
v_data[0] = polylist.GetX( ii ) * aBiuTo3DUnits;
v_data[1] = -polylist.GetY( ii ) * aBiuTo3DUnits;
// gluTessVertex store pointers on data, not data, so do not store
......@@ -231,9 +217,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
zpos = ( aZpos - (aThickness / 2.0) ) * aBiuTo3DUnits;
s_currentZpos = zpos; // for Tess callback functions
v_data[2] = zpos;
// Set normal toward negative Z axis, for a solid object on bottom side
if( aThickness )
SetNormalZneg();
glNormal3f( 0.0, 0.0, -aNormal_Z_Orientation );
}
if( startContour == 0 )
......@@ -259,12 +244,14 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
*/
void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness,
double aBiuTo3DUnits, bool aUseTextures )
double aBiuTo3DUnits, bool aUseTextures,
float aNormal_Z_Orientation )
{
CPOLYGONS_LIST polygon;
ConvertPolysListWithHolesToOnePolygon( aPolysList, polygon );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits, aUseTextures );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits, aUseTextures,
aNormal_Z_Orientation );
}
......@@ -307,23 +294,21 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
if( aThickness )
{
// draw top (front) and bottom (back) horizontal sides (rings)
SetNormalZpos();
outer_cornerBuffer.Append( inner_cornerBuffer );
CPOLYGONS_LIST polygon;
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
// draw top (front) horizontal ring
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false,
1.0f );
if( aHeight )
{
// draw bottom (back) horizontal ring
SetNormalZneg();
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false,
-1.0f );
}
}
SetNormalZpos();
}
......@@ -372,18 +357,16 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
// draw top (front) horizontal side (ring)
SetNormalZpos();
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos + aHeight, 0, aBiuTo3DUnits, false,
1.0f );
if( aHeight )
{
// draw bottom (back) horizontal side (ring)
SetNormalZneg();
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, 0, aBiuTo3DUnits, false,
-1.0f );
}
}
SetNormalZpos();
}
......@@ -401,7 +384,7 @@ void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth );
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false, 1.0f );
}
......@@ -415,7 +398,7 @@ void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint,
TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle,
slice, aWidth );
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false );
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false, 1.0f );
}
......
......@@ -37,6 +37,7 @@
* @param aThickness = thickness in board internal units
* @param aBiuTo3DUnits = board internal units to 3D units scaling value
* @param aUseTextures = true to use textxures for the polygons
* @param aNormal_Z_Orientation = the normal Z orientation to apply
* If aThickness = 0, a polygon area is drawn in a XY plane at Z position = aZpos.
* If aThickness > 0, a solid object is drawn.
* The top side is located at aZpos + aThickness / 2
......@@ -44,7 +45,8 @@
*/
void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits,
bool aUseTextures );
bool aUseTextures,
float aNormal_Z_Orientation );
/** draw the solid polygon found in aPolysList
* The first polygonj is the main polygon, others are holes
......@@ -53,6 +55,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
* @param aThickness = thickness in board internal units
* @param aBiuTo3DUnits = board internal units to 3D units scaling value
* @param aUseTextures = true to use textxures for the polygons
* @param aNormal_Z_Orientation = the normal Z orientation to apply
* If aThickness = 0, a polygon area is drawn in a XY plane at Z position = aZpos.
* If aThickness > 0, a solid object is drawn.
* The top side is located at aZpos + aThickness / 2
......@@ -60,7 +63,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
*/
void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits,
bool aUseTextures );
bool aUseTextures,
float aNormal_Z_Orientation );
/** draw a thick segment using 3D primitives, in a XY plane
* @param aStart = YX position of start point in board units
......
......@@ -50,6 +50,7 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) :
m_SpecularColor.clear();
m_Shininess.clear();
m_Transparency.clear();
m_ColorPerVertex = false;
}
......@@ -81,17 +82,29 @@ bool S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMate
{
transparency_value = m_Transparency[aMaterialIndex];
}
else
{
if( m_Transparency.size() > 0 )
transparency_value = m_Transparency[0];
}
if( m_DiffuseColor.size() > aMaterialIndex )
{
glm::vec3 color = m_DiffuseColor[aMaterialIndex];
glColor4f( color.x, color.y, color.z, 1.0 - transparency_value );
glColor4f( color.x, color.y, color.z, 1.0f - transparency_value );
}
else
{
if( m_DiffuseColor.size() == 0 )
{
glColor4f( 0.8f, 0.8f, 0.8f, 1.0f );
}
}
if( m_Shininess.size() > aMaterialIndex )
if( m_Shininess.size() > 0 )
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_Shininess[aMaterialIndex] );
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m_Shininess[0] );
}
// emissive
......
......@@ -48,6 +48,7 @@ public:
std::vector< glm::vec3 > m_SpecularColor;
std::vector< float > m_Shininess;
std::vector< float > m_Transparency;
bool m_ColorPerVertex;
public:
S3D_MATERIAL( S3D_MASTER* father, const wxString& name );
......
......@@ -116,24 +116,9 @@ void S3D_MESH::calcBBox( )
bool firstBBox = true;
bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL );
// Do not add complete transparent materials
if( useMaterial && (m_Materials != 0) && ( m_MaterialIndex.size() == 0 ) )
if( m_Materials->m_Transparency.size() > 0 )
if( m_Materials->m_Transparency[0] >= 1.0f )
return;
// Calc boudingbox for all coords
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
// Do not add complete transparent materials
if( useMaterial && (m_Materials != 0) && ( m_MaterialIndex.size() > idx ) )
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndex[idx] )
if( m_Materials->m_Transparency[m_MaterialIndex[idx]] >= 1.0f )
continue;
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
if( firstBBox )
{
......@@ -194,8 +179,37 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
{
return;
}
/*
// DEBUG INFO
printf("aIsRenderingJustNonTransparentObjects %d aIsRenderingJustTransparentObjects %d\n", aIsRenderingJustNonTransparentObjects, aIsRenderingJustTransparentObjects);
if( m_Materials && ( m_MaterialIndex.size() == 0 ) )
printf("m_CoordIndex.size() %lu\n", m_CoordIndex.size() );
printf("m_MaterialIndexPerFace.size() %lu\n", m_MaterialIndexPerFace.size() );
printf("m_MaterialIndexPerVertex.size() %lu\n", m_MaterialIndexPerVertex.size() );
printf("m_PerVertexNormalsNormalized.size() %lu\n", m_PerVertexNormalsNormalized.size() );
printf("m_PerFaceVertexNormals.size() %lu\n", m_PerFaceVertexNormals.size() );
printf("smoothShapes %d\n", smoothShapes );
if( m_Materials )
{
printf(" m_Name %s\n", static_cast<const char*>(m_Materials->m_Name.c_str()) );
printf(" m_ColorPerVertex %d\n", m_Materials->m_ColorPerVertex );
printf(" m_Transparency.size() %lu\n", m_Materials->m_Transparency.size() );
printf(" m_DiffuseColor.size() %lu\n", m_Materials->m_DiffuseColor.size() );
printf(" m_Shininess.size() %lu\n", m_Materials->m_Shininess.size() );
printf(" m_EmissiveColor.size() %lu\n", m_Materials->m_EmissiveColor.size() );
printf(" m_SpecularColor.size() %lu\n", m_Materials->m_SpecularColor.size() );
printf(" m_AmbientColor.size() %lu\n", m_Materials->m_AmbientColor.size() );
}
printf("m_Materials %p\n", ( void * )m_Materials );
*/
float lastTransparency_value = 0.0f;
if( m_Materials )
{
if ( m_Materials->m_ColorPerVertex == false )
{
bool isTransparent = m_Materials->SetOpenGLMaterial( 0, useMaterial );
......@@ -205,11 +219,17 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
if( !isTransparent && aIsRenderingJustTransparentObjects )
return;
// Skip total transparent models
if( useMaterial )
if( m_Materials->m_Transparency.size() > 0 )
if( m_Materials->m_Transparency[0] >= 1.0f )
{
lastTransparency_value = m_Materials->m_Transparency[0];
if( lastTransparency_value >= 1.0f )
return;
}
}
}
glPushMatrix();
glTranslatef( m_translation.x, m_translation.y, m_translation.z );
......@@ -228,59 +248,145 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
calcPerPointNormals();
}
/*
#if defined(DEBUG)
// Debug Normals
glColor4f( 1.0, 0.0, 1.0, 0.7 );
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
if( m_Materials && ( m_MaterialIndex.size() != 0 ) )
if( m_PerFaceNormalsNormalized.size() > 0 )
{
if ( m_MaterialIndex.size() > idx )
S3D_VERTEX normal = m_PerFaceNormalsNormalized[idx];
//glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][0]];
for( unsigned int ii = 1; ii < m_CoordIndex[idx].size(); ii++ )
{
bool isTransparent = m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
point += m_Point[m_CoordIndex[idx][ii]];
}
if( isTransparent && aIsRenderingJustNonTransparentObjects )
continue;
point /= m_CoordIndex[idx].size();
if( !isTransparent && aIsRenderingJustTransparentObjects )
continue;
if( useMaterial )
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndex[idx] )
if( m_Materials->m_Transparency[m_MaterialIndex[idx]] >= 1.0f )
continue;
}
else
{
// This is only need on debug, because above we are marking the bad elements
DBG( m_Materials->SetOpenGLMaterial( 0, useMaterial ) );
glBegin( GL_LINES );
glVertex3fv( &point.x );
point += normal * 0.01f;
glVertex3fv( &point.x );
glEnd();
}
}
// Restore material
if( m_Materials )
m_Materials->SetOpenGLMaterial( 0, useMaterial );
#endif
*/
/*
#if defined(DEBUG)
// Debug Normals
glColor4f( 1.0, 0.0, 1.0, 1.0 );
if( smoothShapes )
{
// Debug Per Vertex Normals
glColor4f( 0.0, 1.0, 1.0, 0.7 );
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
if( (m_PerVertexNormalsNormalized.size() > 0) &&
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
// Flat
if( m_PerFaceNormalsNormalized.size() > 0 )
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
//glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glBegin( GL_LINES );
glVertex3fv( &point.x );
point += normal * 1.00f;
glVertex3fv( &point.x );
glEnd();
}
}
else
{
S3D_VERTEX normal = m_PerFaceNormalsNormalized[idx];
glNormal3fv( &normal.x );
std::vector< glm::vec3 > normals_list;
normals_list = m_PerFaceVertexNormals[idx];
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glBegin( GL_LINES );
glm::vec3 normal = normals_list[ii];
printf("normal(%f, %f, %f), ", normal.x, normal.y, normal.z );
//glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glBegin( GL_LINES );
glVertex3fv( &point.x );
point += normal;
point += normal * 1.00f;
glVertex3fv( &point.x );
glEnd();
}
printf("\n");
}
}
// Restore material
if( m_Materials )
m_Materials->SetOpenGLMaterial( 0, useMaterial );
}
#endif
*/
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
if( m_Materials )
{
// http://accad.osu.edu/~pgerstma/class/vnv/resources/info/AnnotatedVrmlRef/ch3-323.htm
// "If colorPerVertex is FALSE, colours are applied to each face, as follows:"
if( ( m_Materials->m_ColorPerVertex == false ) &&
( m_Materials->m_DiffuseColor.size() > 1 ) )
{
bool isTransparent;
// "If the colorIndex field is not empty, then one colour is
// used for each face of the IndexedFaceSet. There must be
// at least as many indices in the colorIndex field as
// there are faces in the IndexedFaceSet."
if ( m_MaterialIndexPerFace.size() == m_CoordIndex.size() )
{
isTransparent = m_Materials->SetOpenGLMaterial( m_MaterialIndexPerFace[idx], useMaterial );
// Skip total transparent faces
if( useMaterial )
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndexPerFace[idx] )
{
if( m_Materials->m_Transparency[m_MaterialIndexPerFace[idx]] >= 1.0f )
continue;
}
}
else
{
// "If the colorIndex field is empty, then the colours in the
// Color node are applied to each face of the IndexedFaceSet
// in order. There must be at least as many colours in the
// Color node as there are faces."
isTransparent = m_Materials->SetOpenGLMaterial( idx, useMaterial );
// Skip total transparent faces
if( useMaterial )
if( m_Materials->m_Transparency.size() > idx )
{
if( m_Materials->m_Transparency[idx] >= 1.0f )
continue;
}
}
if( isTransparent && aIsRenderingJustNonTransparentObjects )
continue;
if( !isTransparent && aIsRenderingJustTransparentObjects )
continue;
}
}
switch( m_CoordIndex[idx].size() )
{
case 3:
......@@ -296,23 +402,80 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
if( smoothShapes )
{
if( m_Materials )
{
// for VRML2:
// http://accad.osu.edu/~pgerstma/class/vnv/resources/info/AnnotatedVrmlRef/ch3-323.htm
// "If colorPerVertex is TRUE, colours are applied to each vertex, as follows:
if( ( m_Materials->m_ColorPerVertex == true ) &&
( m_Materials->m_DiffuseColor.size() > 1 ) )
{
// "If the colorIndex field is not empty, then colours
// are applied to each vertex of the IndexedFaceSet in
// exactly the same manner that the coordIndex field is
// used to choose coordinates for each vertex from the
// Coordinate node. The colorIndex field must contain at
// least as many indices as the coordIndex field, and
// must contain end-of-face markers (-1) in exactly the
// same places as the coordIndex field. If the greatest
// index in the colorIndex field is N, then there must
// be N+1 colours in the Color node."
if ( m_MaterialIndexPerVertex.size() != 0 )
{
if( (m_PerVertexNormalsNormalized.size() > 0) &&
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_MaterialIndexPerVertex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
glNormal3fv( &normal.x );
/*
#if defined(DEBUG)
// Flag error vertices
if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
else
{
std::vector< glm::vec3 > normals_list;
normals_list = m_PerFaceVertexNormals[idx];
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glColor4f( 1.0, 0.0, 1.0, 1.0 );
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_MaterialIndexPerVertex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
glm::vec3 normal = normals_list[ii];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
#endif
*/
}
}
else
{
// "If the colorIndex field is empty, then the
// coordIndex field is used to choose colours from
// the Color node. If the greatest index in the
// coordIndex field is N, then there must be N+1
// colours in the Color node."
if( (m_PerVertexNormalsNormalized.size() > 0) &&
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_CoordIndex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
......@@ -324,53 +487,156 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_CoordIndex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
glm::vec3 normal = normals_list[ii];
glNormal3fv( &normal.x );
/*
#if defined(DEBUG)
// Flag error vertices
if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
}
else
{
glColor4f( 1.0, 0.0, 1.0, 1.0 );
if( (m_PerVertexNormalsNormalized.size() > 0) &&
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
#endif
*/
}
else
{
std::vector< glm::vec3 > normals_list;
normals_list = m_PerFaceVertexNormals[idx];
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 normal = normals_list[ii];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
}
else
{
if( (m_PerVertexNormalsNormalized.size() > 0) &&
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
else
{
std::vector< glm::vec3 > normals_list;
normals_list = m_PerFaceVertexNormals[idx];
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 normal = normals_list[ii];
glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
}
else
{
// Flat
if( m_PerFaceNormalsNormalized.size() > 0 )
{
S3D_VERTEX normal = m_PerFaceNormalsNormalized[idx];
/*
#if defined(DEBUG)
// Flag error vertices
if( (normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0) )
glNormal3fv( &normal.x );
if( m_Materials )
{
// for VRML2:
// http://accad.osu.edu/~pgerstma/class/vnv/resources/info/AnnotatedVrmlRef/ch3-323.htm
// "If colorPerVertex is TRUE, colours are applied to each vertex, as follows:
if( ( m_Materials->m_ColorPerVertex == true ) &&
( m_Materials->m_DiffuseColor.size() > 1 ) )
{
// "If the colorIndex field is not empty, then colours
// are applied to each vertex of the IndexedFaceSet in
// exactly the same manner that the coordIndex field is
// used to choose coordinates for each vertex from the
// Coordinate node. The colorIndex field must contain at
// least as many indices as the coordIndex field, and
// must contain end-of-face markers (-1) in exactly the
// same places as the coordIndex field. If the greatest
// index in the colorIndex field is N, then there must
// be N+1 colours in the Color node."
if ( m_MaterialIndexPerVertex.size() != 0 )
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
DBG( printf("%u\n", idx) );
glColor4f( 1.0, 0.0, 1.0, 1.0 );
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_MaterialIndexPerVertex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
S3D_VERTEX point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
#endif
*/
glNormal3fv( &normal.x );
}
else
{
// "If the colorIndex field is empty, then the
// coordIndex field is used to choose colours from
// the Color node. If the greatest index in the
// coordIndex field is N, then there must be N+1
// colours in the Color node."
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
S3D_VERTEX color = m_Materials->m_DiffuseColor[m_CoordIndex[idx][ii]];
glColor4f( color.x, color.y, color.z, 1.0f - lastTransparency_value );
S3D_VERTEX point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
else
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
S3D_VERTEX point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
else
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
S3D_VERTEX point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
}
else
{
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
S3D_VERTEX point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
......@@ -474,27 +740,13 @@ void S3D_MESH::calcPointNormalized()
biggerPoint = v;
}
biggerPoint = 1.0 / biggerPoint;
for( unsigned int i = 0; i < m_Point.size(); i++ )
{
m_PointNormalized[i] = m_Point[i] * biggerPoint;
m_PointNormalized[i] = m_Point[i] / biggerPoint;
}
}
bool IsClockwise( glm::vec3 v0, glm::vec3 v1, glm::vec3 v2 )
{
double sum = 0.0;
sum += (v1.x - v0.x) * (v1.y + v0.y);
sum += (v2.x - v1.x) * (v2.y + v1.y);
sum += (v0.x - v2.x) * (v0.y + v2.y);
return sum > FLT_EPSILON;
}
void S3D_MESH::calcPerFaceNormals()
{
//DBG( printf( "calcPerFaceNormals" ) );
......@@ -512,7 +764,8 @@ void S3D_MESH::calcPerFaceNormals()
haveAlreadyNormals_from_model_file = true;
// !TODO: this is a workarround for some VRML2 modules files (ex: from we-online.de website)
// are using (incorrectly) the normals with m_CoordIndex as per face normal. This maybe be addressed by the parser in the future.
// are using (incorrectly) the normals with m_CoordIndex as per face normal.
// This maybe be addressed by the parser in the future.
if( ( m_PerFaceNormalsNormalized.size() == m_Point.size() ) &&
( m_PerFaceNormalsNormalized.size() != m_CoordIndex.size() ) )
{
......@@ -542,11 +795,7 @@ void S3D_MESH::calcPerFaceNormals()
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{
glm::vec3 cross_prod;
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 0.0f;
glm::dvec3 cross_prod = glm::dvec3( 0.0, 0.0, 0.0 );
// Newell's Method
// http://www.opengl.org/wiki/Calculating_a_Surface_Normal
......@@ -555,40 +804,41 @@ void S3D_MESH::calcPerFaceNormals()
for( unsigned int i = 0; i < m_CoordIndex[idx].size(); i++ )
{
glm::vec3 u = m_PointNormalized[m_CoordIndex[idx][i]];
glm::vec3 v = m_PointNormalized[m_CoordIndex[idx][(i + 1) % m_CoordIndex[idx].size()]];
glm::dvec3 u = glm::dvec3( m_PointNormalized[m_CoordIndex[idx][i]] );
glm::dvec3 v = glm::dvec3( m_PointNormalized[m_CoordIndex[idx][(i + 1) % m_CoordIndex[idx].size()]] );
cross_prod.x += (u.y - v.y) * (u.z + v.z);
cross_prod.y += (u.z - v.z) * (u.x + v.x);
cross_prod.z += (u.x - v.x) * (u.y + v.y);
// This method works same way
/*
cross_prod.x += (u.y * v.z) - (u.z * v.y);
cross_prod.y += (u.z * v.x) - (u.x * v.z);
cross_prod.z += (u.x * v.y) - (u.y * v.x);*/
}
float area = glm::dot( cross_prod, cross_prod );
double area = glm::dot( cross_prod, cross_prod );
area = fabs( area );
m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx] = cross_prod * area;
m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx] = glm::vec3( cross_prod * area );
//printf("cross_prod(%g, %g, %g), area:%g m_PerFaceNormalsRaw_X_PerFaceSquaredArea(%f, %f, %f)\n", cross_prod.x, cross_prod.y, cross_prod.z, area,
//m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx].x,
//m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx].y,
//m_PerFaceNormalsRaw_X_PerFaceSquaredArea[idx].z);
if( haveAlreadyNormals_from_model_file == false )
{
if( g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) &&
(m_PerVertexNormalsNormalized.size() > 0) )
{
glm::vec3 normalSum;
glm::dvec3 normalSum;
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
{
normalSum += m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]];
normalSum += glm::dvec3( m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]] );
}
float l = glm::length( normalSum );
double l = glm::length( normalSum );
if( l > FLT_EPSILON ) // avoid division by zero
if( l > DBL_EPSILON ) // avoid division by zero
{
normalSum = normalSum / l;
}
......@@ -596,83 +846,86 @@ void S3D_MESH::calcPerFaceNormals()
{
if( ( normalSum.x > normalSum.y ) && ( normalSum.x > normalSum.z ) )
{
normalSum.x = 0.0f;
normalSum.y = 1.0f;
normalSum.z = 0.0f;
normalSum.x = 0.0;
normalSum.y = 1.0;
normalSum.z = 0.0;
}
else if( ( normalSum.y > normalSum.x ) && ( normalSum.y > normalSum.z ) )
{
normalSum.x = 0.0f;
normalSum.y = 1.0f;
normalSum.z = 0.0f;
normalSum.x = 0.0;
normalSum.y = 1.0;
normalSum.z = 0.0;
}
else if( ( normalSum.z > normalSum.x ) && ( normalSum.z > normalSum.y ) )
{
normalSum.x = 0.0f;
normalSum.y = 0.0f;
normalSum.z = 1.0f;
normalSum.x = 0.0;
normalSum.y = 0.0;
normalSum.z = 1.0;
}
else
{
normalSum.x = 0.0f;
normalSum.y = 0.0f;
normalSum.z = 0.0f;
normalSum.x = 0.0;
normalSum.y = 0.0;
normalSum.z = 0.0;
}
}
m_PerFaceNormalsNormalized[idx] = normalSum;
m_PerFaceNormalsNormalized[idx] = glm::vec3( normalSum );
}
else
{
// normalize vertex normal
float l = glm::length( cross_prod );
double l = glm::length( cross_prod );
if( l > FLT_EPSILON ) // avoid division by zero
if( l > DBL_EPSILON ) // avoid division by zero
{
cross_prod = cross_prod / l;
}
else
{
/*
for( unsigned int i = 0; i < m_CoordIndex[idx].size(); i++ )
{
glm::vec3 v = m_PointNormalized[m_CoordIndex[idx][i]];
glm::vec3 v = m_Point[m_CoordIndex[idx][i]];
DBG( printf( "v[%u](%f, %f, %f)", i, v.x, v.y, v.z ) );
}
DBG( printf( "Cannot calc normal idx: %u cross(%f, %f, %f) l:%f m_CoordIndex[idx].size: %u\n",
DBG( printf( "Cannot calc normal idx: %u cross(%g, %g, %g) l:%g m_CoordIndex[idx].size: %u\n",
idx,
cross_prod.x, cross_prod.y, cross_prod.z,
l,
(unsigned int)m_CoordIndex[idx].size()) );
*/
if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
{
cross_prod.x = 0.0f;
cross_prod.y = 1.0f;
cross_prod.z = 0.0f;
cross_prod.x = 0.0;
cross_prod.y = 1.0;
cross_prod.z = 0.0;
}
else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ) )
{
cross_prod.x = 0.0f;
cross_prod.y = 1.0f;
cross_prod.z = 0.0f;
cross_prod.x = 0.0;
cross_prod.y = 1.0;
cross_prod.z = 0.0;
}
else if( ( cross_prod.z > cross_prod.x ) && ( cross_prod.z > cross_prod.y ) )
{
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 1.0f;
cross_prod.x = 0.0;
cross_prod.y = 0.0;
cross_prod.z = 1.0;
}
else
{
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 0.0f;
cross_prod.x = 0.0;
cross_prod.y = 0.0;
cross_prod.z = 0.0;
}
}
m_PerFaceNormalsNormalized[idx] = cross_prod;
m_PerFaceNormalsNormalized[idx] = glm::vec3( cross_prod );
//printf("normal(%g, %g, %g)\n", m_PerFaceNormalsNormalized[idx].x, m_PerFaceNormalsNormalized[idx].y, m_PerFaceNormalsNormalized[idx].z );
}
}
}
......
......@@ -66,7 +66,8 @@ public:
std::vector< S3D_VERTEX > m_PerFaceColor;
std::vector< S3D_VERTEX > m_PerFaceNormalsNormalized;
std::vector< S3D_VERTEX > m_PerVertexNormalsNormalized;
std::vector< int > m_MaterialIndex;
std::vector< int > m_MaterialIndexPerFace;
std::vector< std::vector<int> > m_MaterialIndexPerVertex;
S3D_MESH_PTRS childs;
S3D_VERTEX m_translation;
......
......@@ -119,13 +119,6 @@ public:
*/
static void GetNodeProperties( wxXmlNode* aNode, PROPERTY_MAP& aProps );
/**
* Return string representing x3d file in vrml2 format
* Function Load must be called before this function, otherwise empty
* data set is returned.
*/
wxString VRML2_representation();
private:
wxString m_Filename;
S3D_MESH_PTR m_model;
......
......@@ -422,16 +422,16 @@ int VRML1_MODEL_PARSER::readIndexedFaceSet_materialIndex()
{
// DBG( printf( " readIndexedFaceSet_materialIndex\n" ) );
m_model->m_MaterialIndex.clear();
m_model->m_MaterialIndexPerFace.clear();
int index;
while( fscanf( m_file, "%d,", &index ) )
{
m_model->m_MaterialIndex.push_back( index );
m_model->m_MaterialIndexPerFace.push_back( index );
}
// DBG( printf( " m_MaterialIndex.size: %ld\n", m_model->m_MaterialIndex.size() ) );
// DBG( printf( " m_MaterialIndexPerFace.size: %ld\n", m_model->m_MaterialIndexPerFace.size() ) );
return 0;
}
......@@ -1103,23 +1103,34 @@ int VRML2_MODEL_PARSER::read_appearance()
wxString mat_name;
mat_name = FROM_UTF8( text );
bool found = false;
S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() )
{
if( material->m_Name == mat_name )
{
m_model->m_Materials = material;
found_material = material;
// We dont exit here, since it seems that VRML can have
// multiple material defined, so, it will copy the latest one that was defined.
found = true;
}
}
debug_exit();
if( found )
if( found_material )
{
// Create a new material instead of assign a pointer because
// the indexfaceset can set color pervertex and that will be stored in the material.
m_model->m_Materials = new S3D_MATERIAL( m_Master, found_material->m_Name );
m_model->m_Materials->m_AmbientColor = found_material->m_AmbientColor;
m_model->m_Materials->m_DiffuseColor = found_material->m_DiffuseColor;
m_model->m_Materials->m_EmissiveColor = found_material->m_EmissiveColor;
m_model->m_Materials->m_SpecularColor = found_material->m_SpecularColor;
m_model->m_Materials->m_Shininess = found_material->m_Shininess;
m_model->m_Materials->m_Transparency = found_material->m_Transparency;
m_model->m_Materials->m_ColorPerVertex = false;
return 0;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance error: material not found" ) );
return -1;
......@@ -1228,17 +1239,37 @@ int VRML2_MODEL_PARSER::read_material()
wxString mat_name;
mat_name = FROM_UTF8( text );
S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() )
{
if( material->m_Name == mat_name )
{
m_model->m_Materials = material;
found_material = material;
// We dont exit here, since it seems that VRML can have
// multiple material defined, so, it will copy the latest one that was defined.
}
}
debug_exit();
if( found_material )
{
// Create a new material instead of assign a pointer because
// the indexfaceset can set color pervertex and that will be stored in the material.
m_model->m_Materials = new S3D_MATERIAL( m_Master, found_material->m_Name );
m_model->m_Materials->m_AmbientColor = found_material->m_AmbientColor;
m_model->m_Materials->m_DiffuseColor = found_material->m_DiffuseColor;
m_model->m_Materials->m_EmissiveColor = found_material->m_EmissiveColor;
m_model->m_Materials->m_SpecularColor = found_material->m_SpecularColor;
m_model->m_Materials->m_Shininess = found_material->m_Shininess;
m_model->m_Materials->m_Transparency = found_material->m_Transparency;
m_model->m_Materials->m_ColorPerVertex = false;
return 0;
}
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_material error: material not found" ) );
return -1;
}
}
}
......@@ -1365,6 +1396,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{
if( strcmp( text, "TRUE" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet m_normalPerVertex TRUE" ) );
m_normalPerVertex = true;
}
}
......@@ -1373,12 +1405,15 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{
GetNextTag( m_file, text, sizeof(text) );
if( strcmp( text, "TRUE" ) )
if( strcmp( text, "TRUE" ) == 0 )
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet colorPerVertex TRUE" ) );
colorPerVertex = true;
m_model->m_Materials->m_ColorPerVertex = true;
}
else
{
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet colorPerVertex FALSE" ) );
colorPerVertex = false;
}
}
......@@ -1456,37 +1491,51 @@ int VRML2_MODEL_PARSER::read_colorIndex()
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex" ) );
debug_enter();
m_model->m_MaterialIndex.clear();
m_model->m_MaterialIndexPerFace.clear();
m_model->m_MaterialIndexPerVertex.clear();
if( colorPerVertex == true )
{
int index;
int first_index;
while( fscanf( m_file, "%d, ", &index ) )
if( m_model->m_CoordIndex.size() > 0 )
m_model->m_MaterialIndexPerVertex.reserve( m_model->m_CoordIndex.size() );
std::vector<int> materialIndexPerVertex;
materialIndexPerVertex.reserve( 3 ); // Start at least with 3
while( fscanf( m_file, "%d, ", &index ) == 1 )
{
if( index == -1 )
{
// it only implemented color per face, so it will store as the first in the list
m_model->m_MaterialIndex.push_back( first_index );
m_model->m_MaterialIndexPerVertex.push_back( materialIndexPerVertex );
materialIndexPerVertex.clear();
materialIndexPerVertex.reserve( 3 );
}
else
{
first_index = index;
materialIndexPerVertex.push_back( index );
}
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex m_MaterialIndexPerVertex.size: %lu" ), m_model->m_MaterialIndexPerVertex.size() );
}
else
{
int index;
if( m_model->m_CoordIndex.size() > 0 )
m_model->m_MaterialIndexPerFace.reserve( m_model->m_CoordIndex.size() );
while( fscanf( m_file, "%d,", &index ) )
{
m_model->m_MaterialIndex.push_back( index );
m_model->m_MaterialIndexPerFace.push_back( index );
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex m_MaterialIndexPerFace.size: %lu" ), m_model->m_MaterialIndexPerFace.size() );
}
//wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex m_MaterialIndex.size: %u" ), (unsigned int)m_model->m_MaterialIndex.size() );
debug_exit();
return 0;
}
......@@ -1534,21 +1583,21 @@ int VRML2_MODEL_PARSER::read_coordIndex()
glm::ivec3 coord;
int dummy; // should be -1
int coordIdx; // should be -1
std::vector<int> coord_list;
coord_list.clear();
while( fscanf( m_file, "%d, ", &dummy ) == 1 )
while( fscanf( m_file, "%d, ", &coordIdx ) == 1 )
{
if( dummy == -1 )
if( coordIdx == -1 )
{
m_model->m_CoordIndex.push_back( coord_list );
coord_list.clear();
}
else
{
coord_list.push_back( dummy );
coord_list.push_back( coordIdx );
}
}
......@@ -1582,6 +1631,7 @@ int VRML2_MODEL_PARSER::read_Color()
if( strcmp( text, "color" ) == 0 )
{
m_model->m_Materials->m_DiffuseColor.clear();
ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
}
}
......
......@@ -97,41 +97,17 @@ bool X3D_MODEL_PARSER::Load( const wxString& aFilename )
m_model.reset( new S3D_MESH() );
childs.push_back( m_model );
readTransform( *node_it );
}
wxXmlNode* node = *node_it;
wxXmlAttribute* prop = node->GetAttributes();
return true;
}
wxLogTrace( traceX3DParser, wxT( "Transform: %s %s" ), prop->GetName(), prop->GetValue() );
readTransform( node );
wxString X3D_MODEL_PARSER::VRML2_representation()
{
wxString output;
for( unsigned i = 0; i < vrml_points.size(); i++ )
{
output +=
wxT( "Shape {\n"
" appearance Appearance {\n"
" material Material {\n" ) +
vrml_materials[i] +
wxT( " }\n"
" }\n"
" geometry IndexedFaceSet {\n"
" solid TRUE\n"
" coord Coordinate {\n"
" point [\n" ) +
vrml_points[i] +
wxT( " ]\n"
" }\n"
" coordIndex [\n" ) +
vrml_coord_indexes[i] +
wxT( " ]\n"
" }\n"
"},\n" );
}
return output;
}
return true;
}
......@@ -139,7 +115,9 @@ void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent,
const wxString aName,
std::vector<wxXmlNode*>& aResult )
{
// Breadth-first search (BFS)
// (-Breadth-first search (BFS)-)
// **NOTE** This function was changed to get only the first depth of ocorrences
// so it will be an workarround for the Bug #1443431
std::queue<wxXmlNode*> found;
found.push( aParent );
......@@ -153,10 +131,8 @@ void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent,
child = child->GetNext() )
{
if( child->GetName() == aName )
{
aResult.push_back( child );
}
else // **NOTE** This function was changed here to get only the first depth of ocorrences
found.push( child );
}
......@@ -198,6 +174,9 @@ void X3D_MODEL_PARSER::readTransform( wxXmlNode* aTransformNode )
PROPERTY_MAP properties;
GetNodeProperties( aTransformNode, properties );
GetChildsByName( aTransformNode, wxT( "IndexedFaceSet" ), childnodes );
for( NODE_LIST::iterator node = childnodes.begin();
......@@ -430,7 +409,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode,
double angle = 0.0;
wxStringTokenizer tokens( aTransformProps[ wxT( "rotation" ) ] );
double x, y, z;
double x = 0.0, y = 0.0, z = 0.0;
if( !( tokens.GetNextToken().ToDouble( &x )
&& tokens.GetNextToken().ToDouble( &y )
......@@ -551,7 +530,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode,
for( unsigned id = 0; id < color_points.size() / 3; id++ )
{
m_model->m_MaterialIndex.push_back( id );
m_model->m_MaterialIndexPerFace.push_back( id );
int color_triplet_indx = id * 3;
glm::vec3 colorface( color_points[ color_triplet_indx + 0 ],
......
......@@ -285,7 +285,6 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
double aCorrectionFactor )
{
unsigned cornerscount = GetFilledPolysList().GetCornersCount();
CPOLYGONS_LIST polygonslist;
if( cornerscount == 0 )
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment