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 ) : ...@@ -95,7 +95,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) :
m_ZBottom = 0.0; m_ZBottom = 0.0;
m_ZTop = 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: // Clear all gl list identifiers:
for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ ) for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ )
...@@ -591,7 +591,7 @@ void EDA_3D_CANVAS::SetLights() ...@@ -591,7 +591,7 @@ void EDA_3D_CANVAS::SetLights()
light_color[3] = 1.0; light_color[3] = 1.0;
// Light above the xy plane // 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 ); glLightfv( GL_LIGHT0, GL_AMBIENT, light_color );
light_color[0] = light_color[1] = light_color[2] = 1.0; light_color[0] = light_color[1] = light_color[2] = 1.0;
...@@ -605,6 +605,8 @@ void EDA_3D_CANVAS::SetLights() ...@@ -605,6 +605,8 @@ void EDA_3D_CANVAS::SetLights()
light_color[0] = light_color[1] = light_color[2] = 0.2; light_color[0] = light_color[1] = light_color[2] = 0.2;
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, light_color ); 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_LIGHT0 ); // White spot on Z axis ( top )
glEnable( GL_LIGHTING ); glEnable( GL_LIGHTING );
} }
......
...@@ -85,7 +85,7 @@ S3D_MASTER:: ~S3D_MASTER() ...@@ -85,7 +85,7 @@ S3D_MASTER:: ~S3D_MASTER()
{ {
nextmat = m_Materials->Next(); nextmat = m_Materials->Next();
delete m_Materials; delete m_Materials;
m_Materials = 0; m_Materials = NULL;
} }
} }
......
...@@ -446,6 +446,8 @@ void EDA_3D_CANVAS::Redraw() ...@@ -446,6 +446,8 @@ void EDA_3D_CANVAS::Redraw()
glEnable( GL_COLOR_MATERIAL ); glEnable( GL_COLOR_MATERIAL );
SetOpenGlDefaultMaterial(); SetOpenGlDefaultMaterial();
//glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, FALSE );
// Board Body // Board Body
GLint shininess_value = 32; GLint shininess_value = 32;
...@@ -497,6 +499,7 @@ void EDA_3D_CANVAS::Redraw() ...@@ -497,6 +499,7 @@ void EDA_3D_CANVAS::Redraw()
glCallList( m_glLists[GL_ID_AUX_LAYERS] ); glCallList( m_glLists[GL_ID_AUX_LAYERS] );
} }
//glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, TRUE );
// Draw Component Shadow // Draw Component Shadow
...@@ -583,6 +586,7 @@ void EDA_3D_CANVAS::Redraw() ...@@ -583,6 +586,7 @@ void EDA_3D_CANVAS::Redraw()
// non transparent objects // non transparent objects
if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] ) if( isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
{ {
glEnable( GL_COLOR_MATERIAL );
glEnable( GL_BLEND ); glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] ); glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
...@@ -925,6 +929,14 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList, ...@@ -925,6 +929,14 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer ); int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
int zpos = GetPrm3DVisu().GetLayerZcoordBIU( 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 ) if( realistic_mode )
{ {
...@@ -941,17 +953,17 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList, ...@@ -941,17 +953,17 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
// If holes are removed from copper zones, bufferPolys contains all polygons // If holes are removed from copper zones, bufferPolys contains all polygons
// to draw (tracks+zones+texts). // to draw (tracks+zones+texts).
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, 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, // 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: // the zone polygons are stored in bufferZonesPolys and have to be drawn now:
if( bufferZonesPolys.GetCornersCount() ) if( bufferZonesPolys.GetCornersCount() )
{ {
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferZonesPolys, zpos, thickness, Draw3D_SolidHorizontalPolyPolygons( bufferZonesPolys, zpos, thickness,
GetPrm3DVisu().m_BiuTo3Dunits, useTextures ); GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
zNormal );
} }
throughHolesListBuilt = true; throughHolesListBuilt = true;
...@@ -1016,7 +1028,6 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList, ...@@ -1016,7 +1028,6 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
zpos += (copper_thickness + epsilon) / 2.0f; zpos += (copper_thickness + epsilon) / 2.0f;
board_thickness -= copper_thickness + epsilon; board_thickness -= copper_thickness + epsilon;
glNormal3f( 0.0f, 0.0f, Get3DLayer_Z_Orientation( F_Cu ) );
KI_POLYGON_SET currLayerPolyset; KI_POLYGON_SET currLayerPolyset;
KI_POLYGON_SET polysetHoles; KI_POLYGON_SET polysetHoles;
...@@ -1035,7 +1046,8 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList, ...@@ -1035,7 +1046,8 @@ void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
if( bufferPcbOutlines.GetCornersCount() ) if( bufferPcbOutlines.GetCornersCount() )
{ {
Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness / 2.0, Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness / 2.0,
board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures ); board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
1.0f );
} }
glEndList(); glEndList();
...@@ -1256,10 +1268,18 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a ...@@ -1256,10 +1268,18 @@ void EDA_3D_CANVAS::buildTechLayers3DView( REPORTER* aErrorMessages, REPORTER* a
bufferPolys.RemoveAllContours(); bufferPolys.RemoveAllContours();
bufferPolys.ImportFrom( currLayerPolyset ); 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 ); setGLTechLayersColor( layer );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, 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 ...@@ -1361,10 +1381,17 @@ void EDA_3D_CANVAS::buildBoard3DAuxLayers( REPORTER* aErrorMessages, REPORTER* a
bufferPolys.RemoveAllContours(); bufferPolys.RemoveAllContours();
bufferPolys.ImportFrom( currLayerPolyset ); 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 ); setGLTechLayersColor( layer );
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
thickness, GetPrm3DVisu().m_BiuTo3Dunits, false ); thickness, GetPrm3DVisu().m_BiuTo3Dunits, false,
zNormal );
} }
} }
......
...@@ -54,17 +54,6 @@ static void CALLBACK tessEndCB(); ...@@ -54,17 +54,6 @@ static void CALLBACK tessEndCB();
static void CALLBACK tessErrorCB( GLenum errorCode ); static void CALLBACK tessErrorCB( GLenum errorCode );
static void CALLBACK tessCPolyPt2Vertex( const GLvoid* data ); 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 ); void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits );
/* Draw3D_VerticalPolygonalCylinder is a helper function. /* Draw3D_VerticalPolygonalCylinder is a helper function.
...@@ -160,7 +149,8 @@ void SetGLTexture( GLuint text_id, float scale ) ...@@ -160,7 +149,8 @@ void SetGLTexture( GLuint text_id, float scale )
*/ */
void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits, int aZpos, int aThickness, double aBiuTo3DUnits,
bool aUseTextures ) bool aUseTextures,
float aNormal_Z_Orientation )
{ {
// for Tess callback functions: // for Tess callback functions:
s_biuTo3Dunits = aBiuTo3DUnits; s_biuTo3Dunits = aBiuTo3DUnits;
...@@ -173,16 +163,17 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -173,16 +163,17 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )tessErrorCB ); gluTessCallback( tess, GLU_TESS_ERROR, ( void (CALLBACK*) () )tessErrorCB );
gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )tessCPolyPt2Vertex ); gluTessCallback( tess, GLU_TESS_VERTEX, ( void (CALLBACK*) () )tessCPolyPt2Vertex );
GLdouble v_data[3]; GLdouble v_data[3];
double zpos = ( aZpos + (aThickness / 2.0) ) * aBiuTo3DUnits; double zpos = ( aZpos + (aThickness / 2.0) ) * aBiuTo3DUnits;
s_currentZpos = zpos; // for Tess callback functions 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 // 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 // Draw solid areas contained in this list
CPOLYGONS_LIST polylist = aPolysList; // temporary copy for gluTessVertex CPOLYGONS_LIST polylist = aPolysList; // temporary copy for gluTessVertex
...@@ -202,11 +193,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -202,11 +193,6 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
startContour = 0; 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[0] = polylist.GetX( ii ) * aBiuTo3DUnits;
v_data[1] = -polylist.GetY( ii ) * aBiuTo3DUnits; v_data[1] = -polylist.GetY( ii ) * aBiuTo3DUnits;
// gluTessVertex store pointers on data, not data, so do not store // gluTessVertex store pointers on data, not data, so do not store
...@@ -231,9 +217,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -231,9 +217,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
zpos = ( aZpos - (aThickness / 2.0) ) * aBiuTo3DUnits; zpos = ( aZpos - (aThickness / 2.0) ) * aBiuTo3DUnits;
s_currentZpos = zpos; // for Tess callback functions s_currentZpos = zpos; // for Tess callback functions
v_data[2] = zpos; v_data[2] = zpos;
// Set normal toward negative Z axis, for a solid object on bottom side
if( aThickness ) glNormal3f( 0.0, 0.0, -aNormal_Z_Orientation );
SetNormalZneg();
} }
if( startContour == 0 ) if( startContour == 0 )
...@@ -259,12 +244,14 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -259,12 +244,14 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
*/ */
void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList, void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, int aZpos, int aThickness,
double aBiuTo3DUnits, bool aUseTextures ) double aBiuTo3DUnits, bool aUseTextures,
float aNormal_Z_Orientation )
{ {
CPOLYGONS_LIST polygon; CPOLYGONS_LIST polygon;
ConvertPolysListWithHolesToOnePolygon( aPolysList, 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, ...@@ -307,23 +294,21 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
if( aThickness ) if( aThickness )
{ {
// draw top (front) and bottom (back) horizontal sides (rings) // draw top (front) and bottom (back) horizontal sides (rings)
SetNormalZpos();
outer_cornerBuffer.Append( inner_cornerBuffer ); outer_cornerBuffer.Append( inner_cornerBuffer );
CPOLYGONS_LIST polygon; CPOLYGONS_LIST polygon;
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon ); ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
// draw top (front) horizontal ring // 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 ) if( aHeight )
{ {
// draw bottom (back) horizontal ring // 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, ...@@ -372,18 +357,16 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon ); ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
// draw top (front) horizontal side (ring) // 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 ) if( aHeight )
{ {
// draw bottom (back) horizontal side (ring) // 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, ...@@ -401,7 +384,7 @@ void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth ); 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, ...@@ -415,7 +398,7 @@ void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint,
TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle, TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle,
slice, aWidth ); slice, aWidth );
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false ); Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits, false, 1.0f );
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
* @param aThickness = thickness in board internal units * @param aThickness = thickness in board internal units
* @param aBiuTo3DUnits = board internal units to 3D units scaling value * @param aBiuTo3DUnits = board internal units to 3D units scaling value
* @param aUseTextures = true to use textxures for the polygons * @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 polygon area is drawn in a XY plane at Z position = aZpos.
* If aThickness > 0, a solid object is drawn. * If aThickness > 0, a solid object is drawn.
* The top side is located at aZpos + aThickness / 2 * The top side is located at aZpos + aThickness / 2
...@@ -44,7 +45,8 @@ ...@@ -44,7 +45,8 @@
*/ */
void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits, int aZpos, int aThickness, double aBiuTo3DUnits,
bool aUseTextures ); bool aUseTextures,
float aNormal_Z_Orientation );
/** draw the solid polygon found in aPolysList /** draw the solid polygon found in aPolysList
* The first polygonj is the main polygon, others are holes * The first polygonj is the main polygon, others are holes
...@@ -53,6 +55,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -53,6 +55,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
* @param aThickness = thickness in board internal units * @param aThickness = thickness in board internal units
* @param aBiuTo3DUnits = board internal units to 3D units scaling value * @param aBiuTo3DUnits = board internal units to 3D units scaling value
* @param aUseTextures = true to use textxures for the polygons * @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 polygon area is drawn in a XY plane at Z position = aZpos.
* If aThickness > 0, a solid object is drawn. * If aThickness > 0, a solid object is drawn.
* The top side is located at aZpos + aThickness / 2 * The top side is located at aZpos + aThickness / 2
...@@ -60,7 +63,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, ...@@ -60,7 +63,8 @@ void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
*/ */
void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList, void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList,
int aZpos, int aThickness, double aBiuTo3DUnits, 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 /** draw a thick segment using 3D primitives, in a XY plane
* @param aStart = YX position of start point in board units * @param aStart = YX position of start point in board units
......
...@@ -50,6 +50,7 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) : ...@@ -50,6 +50,7 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) :
m_SpecularColor.clear(); m_SpecularColor.clear();
m_Shininess.clear(); m_Shininess.clear();
m_Transparency.clear(); m_Transparency.clear();
m_ColorPerVertex = false;
} }
...@@ -81,17 +82,29 @@ bool S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMate ...@@ -81,17 +82,29 @@ bool S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMate
{ {
transparency_value = m_Transparency[aMaterialIndex]; transparency_value = m_Transparency[aMaterialIndex];
} }
else
{
if( m_Transparency.size() > 0 )
transparency_value = m_Transparency[0];
}
if( m_DiffuseColor.size() > aMaterialIndex ) if( m_DiffuseColor.size() > aMaterialIndex )
{ {
glm::vec3 color = m_DiffuseColor[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 // emissive
......
...@@ -48,6 +48,7 @@ public: ...@@ -48,6 +48,7 @@ public:
std::vector< glm::vec3 > m_SpecularColor; std::vector< glm::vec3 > m_SpecularColor;
std::vector< float > m_Shininess; std::vector< float > m_Shininess;
std::vector< float > m_Transparency; std::vector< float > m_Transparency;
bool m_ColorPerVertex;
public: public:
S3D_MATERIAL( S3D_MASTER* father, const wxString& name ); S3D_MATERIAL( S3D_MASTER* father, const wxString& name );
......
...@@ -116,24 +116,9 @@ void S3D_MESH::calcBBox( ) ...@@ -116,24 +116,9 @@ void S3D_MESH::calcBBox( )
bool firstBBox = true; 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 // Calc boudingbox for all coords
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ ) 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++ ) for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
if( firstBBox ) if( firstBBox )
{ {
...@@ -194,21 +179,56 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects, ...@@ -194,21 +179,56 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
{ {
return; return;
} }
/*
// DEBUG INFO
printf("aIsRenderingJustNonTransparentObjects %d aIsRenderingJustTransparentObjects %d\n", aIsRenderingJustNonTransparentObjects, aIsRenderingJustTransparentObjects);
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 && ( m_MaterialIndex.size() == 0 ) ) if( m_Materials )
{ {
bool isTransparent = m_Materials->SetOpenGLMaterial( 0, useMaterial ); if ( m_Materials->m_ColorPerVertex == false )
{
bool isTransparent = m_Materials->SetOpenGLMaterial( 0, useMaterial );
if( isTransparent && aIsRenderingJustNonTransparentObjects )
return;
if( isTransparent && aIsRenderingJustNonTransparentObjects ) if( !isTransparent && aIsRenderingJustTransparentObjects )
return; return;
if( !isTransparent && aIsRenderingJustTransparentObjects ) // Skip total transparent models
return; if( useMaterial )
if( m_Materials->m_Transparency.size() > 0 )
{
lastTransparency_value = m_Materials->m_Transparency[0];
if( useMaterial ) if( lastTransparency_value >= 1.0f )
if( m_Materials->m_Transparency.size() > 0 ) return;
if( m_Materials->m_Transparency[0] >= 1.0f ) }
return; }
} }
glPushMatrix(); glPushMatrix();
...@@ -228,59 +248,145 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects, ...@@ -228,59 +248,145 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
calcPerPointNormals(); 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++ ) 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 );
bool isTransparent = m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
if( isTransparent && aIsRenderingJustNonTransparentObjects )
continue;
if( !isTransparent && aIsRenderingJustTransparentObjects )
continue;
if( useMaterial ) glm::vec3 point = m_Point[m_CoordIndex[idx][0]];
if( (int)m_Materials->m_Transparency.size() > m_MaterialIndex[idx] ) for( unsigned int ii = 1; ii < m_CoordIndex[idx].size(); ii++ )
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 point += m_Point[m_CoordIndex[idx][ii]];
DBG( m_Materials->SetOpenGLMaterial( 0, useMaterial ) );
} }
point /= m_CoordIndex[idx].size();
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) #if defined(DEBUG)
// Debug Normals if( smoothShapes )
glColor4f( 1.0, 0.0, 1.0, 1.0 ); {
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) // Debug Per Vertex Normals
glColor4f( 0.0, 1.0, 1.0, 0.7 );
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{ {
// Flat if( (m_PerVertexNormalsNormalized.size() > 0) &&
if( m_PerFaceNormalsNormalized.size() > 0 ) g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{ {
S3D_VERTEX normal = m_PerFaceNormalsNormalized[idx];
glNormal3fv( &normal.x );
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) 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]];
glBegin( GL_LINES ); glBegin( GL_LINES );
glVertex3fv( &point.x );
point += normal * 1.00f;
glVertex3fv( &point.x );
glEnd();
}
}
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];
printf("normal(%f, %f, %f), ", normal.x, normal.y, normal.z );
//glNormal3fv( &normal.x );
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]]; glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glBegin( GL_LINES );
glVertex3fv( &point.x ); glVertex3fv( &point.x );
point += normal; point += normal * 1.00f;
glVertex3fv( &point.x ); glVertex3fv( &point.x );
glEnd(); glEnd();
} }
printf("\n");
} }
} }
// Restore material
if( m_Materials )
m_Materials->SetOpenGLMaterial( 0, useMaterial );
}
#endif #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() ) switch( m_CoordIndex[idx].size() )
{ {
case 3: case 3:
...@@ -297,48 +403,159 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects, ...@@ -297,48 +403,159 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
if( smoothShapes ) if( smoothShapes )
{ {
if( (m_PerVertexNormalsNormalized.size() > 0) && if( m_Materials )
g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
{ {
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) // 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 ) )
{ {
glm::vec3 normal = m_PerVertexNormalsNormalized[m_NormalIndex[idx][ii]]; // "If the colorIndex field is not empty, then colours
glNormal3fv( &normal.x ); // are applied to each vertex of the IndexedFaceSet in
/* // exactly the same manner that the coordIndex field is
#if defined(DEBUG) // used to choose coordinates for each vertex from the
// Flag error vertices // Coordinate node. The colorIndex field must contain at
if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0)) // 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 )
{ {
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++ )
{
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 );
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++ )
{
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 );
}
}
}
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 );
}
}
else
{
std::vector< glm::vec3 > normals_list;
normals_list = m_PerFaceVertexNormals[idx];
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 );
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 );
}
} }
#endif
*/
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
} }
} }
else else
{ {
std::vector< glm::vec3 > normals_list; if( (m_PerVertexNormalsNormalized.size() > 0) &&
normals_list = m_PerFaceVertexNormals[idx]; 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 );
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x );
}
}
else
{ {
glm::vec3 normal = normals_list[ii]; std::vector< glm::vec3 > normals_list;
glNormal3fv( &normal.x ); normals_list = m_PerFaceVertexNormals[idx];
/* for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
#if defined(DEBUG)
// Flag error vertices
if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
{ {
glColor4f( 1.0, 0.0, 1.0, 1.0 ); glm::vec3 normal = normals_list[ii];
} glNormal3fv( &normal.x );
#endif
*/
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]]; glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
glVertex3fv( &point.x ); glVertex3fv( &point.x );
}
} }
} }
} }
...@@ -348,29 +565,78 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects, ...@@ -348,29 +565,78 @@ void S3D_MESH::openGL_Render( bool aIsRenderingJustNonTransparentObjects,
if( m_PerFaceNormalsNormalized.size() > 0 ) if( m_PerFaceNormalsNormalized.size() > 0 )
{ {
S3D_VERTEX normal = m_PerFaceNormalsNormalized[idx]; 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) )
{
DBG( printf("%u\n", idx) );
glColor4f( 1.0, 0.0, 1.0, 1.0 );
}
#endif
*/
glNormal3fv( &normal.x ); glNormal3fv( &normal.x );
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) if( m_Materials )
{ {
glm::vec3 point = m_Point[m_CoordIndex[idx][ii]]; // for VRML2:
glVertex3fv( &point.x ); // 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++ )
{
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 );
}
}
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++ )
{
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++ )
{
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 else
{ {
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) 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 ); glVertex3fv( &point.x );
} }
} }
...@@ -474,27 +740,13 @@ void S3D_MESH::calcPointNormalized() ...@@ -474,27 +740,13 @@ void S3D_MESH::calcPointNormalized()
biggerPoint = v; biggerPoint = v;
} }
biggerPoint = 1.0 / biggerPoint;
for( unsigned int i = 0; i < m_Point.size(); i++ ) 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() void S3D_MESH::calcPerFaceNormals()
{ {
//DBG( printf( "calcPerFaceNormals" ) ); //DBG( printf( "calcPerFaceNormals" ) );
...@@ -512,7 +764,8 @@ void S3D_MESH::calcPerFaceNormals() ...@@ -512,7 +764,8 @@ void S3D_MESH::calcPerFaceNormals()
haveAlreadyNormals_from_model_file = true; haveAlreadyNormals_from_model_file = true;
// !TODO: this is a workarround for some VRML2 modules files (ex: from we-online.de website) // !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() ) && if( ( m_PerFaceNormalsNormalized.size() == m_Point.size() ) &&
( m_PerFaceNormalsNormalized.size() != m_CoordIndex.size() ) ) ( m_PerFaceNormalsNormalized.size() != m_CoordIndex.size() ) )
{ {
...@@ -542,11 +795,7 @@ void S3D_MESH::calcPerFaceNormals() ...@@ -542,11 +795,7 @@ void S3D_MESH::calcPerFaceNormals()
for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ ) for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
{ {
glm::vec3 cross_prod; glm::dvec3 cross_prod = glm::dvec3( 0.0, 0.0, 0.0 );
cross_prod.x = 0.0f;
cross_prod.y = 0.0f;
cross_prod.z = 0.0f;
// Newell's Method // Newell's Method
// http://www.opengl.org/wiki/Calculating_a_Surface_Normal // http://www.opengl.org/wiki/Calculating_a_Surface_Normal
...@@ -555,40 +804,41 @@ void S3D_MESH::calcPerFaceNormals() ...@@ -555,40 +804,41 @@ void S3D_MESH::calcPerFaceNormals()
for( unsigned int i = 0; i < m_CoordIndex[idx].size(); i++ ) 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.x += (u.y - v.y) * (u.z + v.z);
cross_prod.y += (u.z - v.z) * (u.x + v.x); cross_prod.y += (u.z - v.z) * (u.x + v.x);
cross_prod.z += (u.x - v.x) * (u.y + v.y); 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 ); 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( haveAlreadyNormals_from_model_file == false )
{ {
if( g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) && if( g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) &&
(m_PerVertexNormalsNormalized.size() > 0) ) (m_PerVertexNormalsNormalized.size() > 0) )
{ {
glm::vec3 normalSum; glm::dvec3 normalSum;
for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ ) 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; normalSum = normalSum / l;
} }
...@@ -596,83 +846,86 @@ void S3D_MESH::calcPerFaceNormals() ...@@ -596,83 +846,86 @@ void S3D_MESH::calcPerFaceNormals()
{ {
if( ( normalSum.x > normalSum.y ) && ( normalSum.x > normalSum.z ) ) if( ( normalSum.x > normalSum.y ) && ( normalSum.x > normalSum.z ) )
{ {
normalSum.x = 0.0f; normalSum.x = 0.0;
normalSum.y = 1.0f; normalSum.y = 1.0;
normalSum.z = 0.0f; normalSum.z = 0.0;
} }
else if( ( normalSum.y > normalSum.x ) && ( normalSum.y > normalSum.z ) ) else if( ( normalSum.y > normalSum.x ) && ( normalSum.y > normalSum.z ) )
{ {
normalSum.x = 0.0f; normalSum.x = 0.0;
normalSum.y = 1.0f; normalSum.y = 1.0;
normalSum.z = 0.0f; normalSum.z = 0.0;
} }
else if( ( normalSum.z > normalSum.x ) && ( normalSum.z > normalSum.y ) ) else if( ( normalSum.z > normalSum.x ) && ( normalSum.z > normalSum.y ) )
{ {
normalSum.x = 0.0f; normalSum.x = 0.0;
normalSum.y = 0.0f; normalSum.y = 0.0;
normalSum.z = 1.0f; normalSum.z = 1.0;
} }
else else
{ {
normalSum.x = 0.0f; normalSum.x = 0.0;
normalSum.y = 0.0f; normalSum.y = 0.0;
normalSum.z = 0.0f; normalSum.z = 0.0;
} }
} }
m_PerFaceNormalsNormalized[idx] = normalSum; m_PerFaceNormalsNormalized[idx] = glm::vec3( normalSum );
} }
else else
{ {
// normalize vertex normal // 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; cross_prod = cross_prod / l;
} }
else else
{ {
/* /*
for( unsigned int i = 0; i < m_CoordIndex[idx].size(); i++ ) 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( "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, idx,
cross_prod.x, cross_prod.y, cross_prod.z, cross_prod.x, cross_prod.y, cross_prod.z,
l, l,
(unsigned int)m_CoordIndex[idx].size()) ); (unsigned int)m_CoordIndex[idx].size()) );
*/ */
if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) ) if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
{ {
cross_prod.x = 0.0f; cross_prod.x = 0.0;
cross_prod.y = 1.0f; cross_prod.y = 1.0;
cross_prod.z = 0.0f; cross_prod.z = 0.0;
} }
else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ) ) else if( ( cross_prod.y > cross_prod.x ) && ( cross_prod.y > cross_prod.z ) )
{ {
cross_prod.x = 0.0f; cross_prod.x = 0.0;
cross_prod.y = 1.0f; cross_prod.y = 1.0;
cross_prod.z = 0.0f; cross_prod.z = 0.0;
} }
else if( ( cross_prod.z > cross_prod.x ) && ( cross_prod.z > cross_prod.y ) ) else if( ( cross_prod.z > cross_prod.x ) && ( cross_prod.z > cross_prod.y ) )
{ {
cross_prod.x = 0.0f; cross_prod.x = 0.0;
cross_prod.y = 0.0f; cross_prod.y = 0.0;
cross_prod.z = 1.0f; cross_prod.z = 1.0;
} }
else else
{ {
cross_prod.x = 0.0f; cross_prod.x = 0.0;
cross_prod.y = 0.0f; cross_prod.y = 0.0;
cross_prod.z = 0.0f; 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: ...@@ -66,7 +66,8 @@ public:
std::vector< S3D_VERTEX > m_PerFaceColor; std::vector< S3D_VERTEX > m_PerFaceColor;
std::vector< S3D_VERTEX > m_PerFaceNormalsNormalized; std::vector< S3D_VERTEX > m_PerFaceNormalsNormalized;
std::vector< S3D_VERTEX > m_PerVertexNormalsNormalized; 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_MESH_PTRS childs;
S3D_VERTEX m_translation; S3D_VERTEX m_translation;
......
...@@ -119,13 +119,6 @@ public: ...@@ -119,13 +119,6 @@ public:
*/ */
static void GetNodeProperties( wxXmlNode* aNode, PROPERTY_MAP& aProps ); 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: private:
wxString m_Filename; wxString m_Filename;
S3D_MESH_PTR m_model; S3D_MESH_PTR m_model;
......
...@@ -422,16 +422,16 @@ int VRML1_MODEL_PARSER::readIndexedFaceSet_materialIndex() ...@@ -422,16 +422,16 @@ int VRML1_MODEL_PARSER::readIndexedFaceSet_materialIndex()
{ {
// DBG( printf( " readIndexedFaceSet_materialIndex\n" ) ); // DBG( printf( " readIndexedFaceSet_materialIndex\n" ) );
m_model->m_MaterialIndex.clear(); m_model->m_MaterialIndexPerFace.clear();
int index; int index;
while( fscanf( m_file, "%d,", &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; return 0;
} }
...@@ -1103,23 +1103,34 @@ int VRML2_MODEL_PARSER::read_appearance() ...@@ -1103,23 +1103,34 @@ int VRML2_MODEL_PARSER::read_appearance()
wxString mat_name; wxString mat_name;
mat_name = FROM_UTF8( text ); mat_name = FROM_UTF8( text );
bool found = false; S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() ) for( material = m_Master->m_Materials; material; material = material->Next() )
{ {
if( material->m_Name == mat_name ) 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 // We dont exit here, since it seems that VRML can have
// multiple material defined, so, it will copy the latest one that was defined. // multiple material defined, so, it will copy the latest one that was defined.
found = true;
} }
} }
debug_exit(); 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; return 0;
}
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance error: material not found" ) ); wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_appearance error: material not found" ) );
return -1; return -1;
...@@ -1228,17 +1239,37 @@ int VRML2_MODEL_PARSER::read_material() ...@@ -1228,17 +1239,37 @@ int VRML2_MODEL_PARSER::read_material()
wxString mat_name; wxString mat_name;
mat_name = FROM_UTF8( text ); mat_name = FROM_UTF8( text );
S3D_MATERIAL* found_material = NULL;
for( material = m_Master->m_Materials; material; material = material->Next() ) for( material = m_Master->m_Materials; material; material = material->Next() )
{ {
if( material->m_Name == mat_name ) if( material->m_Name == mat_name )
{ {
m_model->m_Materials = material; found_material = material;
debug_exit(); // We dont exit here, since it seems that VRML can have
return 0; // 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" ) ); wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_material error: material not found" ) );
return -1;
} }
} }
} }
...@@ -1365,6 +1396,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() ...@@ -1365,6 +1396,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{ {
if( strcmp( text, "TRUE" ) == 0 ) if( strcmp( text, "TRUE" ) == 0 )
{ {
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet m_normalPerVertex TRUE" ) );
m_normalPerVertex = true; m_normalPerVertex = true;
} }
} }
...@@ -1373,12 +1405,15 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet() ...@@ -1373,12 +1405,15 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{ {
GetNextTag( m_file, text, sizeof(text) ); 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; colorPerVertex = true;
m_model->m_Materials->m_ColorPerVertex = true;
} }
else else
{ {
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_IndexedFaceSet colorPerVertex FALSE" ) );
colorPerVertex = false; colorPerVertex = false;
} }
} }
...@@ -1456,37 +1491,51 @@ int VRML2_MODEL_PARSER::read_colorIndex() ...@@ -1456,37 +1491,51 @@ int VRML2_MODEL_PARSER::read_colorIndex()
wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex" ) ); wxLogTrace( traceVrmlV2Parser, m_debugSpacer + wxT( "read_colorIndex" ) );
debug_enter(); debug_enter();
m_model->m_MaterialIndex.clear(); m_model->m_MaterialIndexPerFace.clear();
m_model->m_MaterialIndexPerVertex.clear();
if( colorPerVertex == true ) if( colorPerVertex == true )
{ {
int index; 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 ) if( index == -1 )
{ {
// it only implemented color per face, so it will store as the first in the list m_model->m_MaterialIndexPerVertex.push_back( materialIndexPerVertex );
m_model->m_MaterialIndex.push_back( first_index ); materialIndexPerVertex.clear();
materialIndexPerVertex.reserve( 3 );
} }
else 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 else
{ {
int index; 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 ) ) 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(); debug_exit();
return 0; return 0;
} }
...@@ -1534,21 +1583,21 @@ int VRML2_MODEL_PARSER::read_coordIndex() ...@@ -1534,21 +1583,21 @@ int VRML2_MODEL_PARSER::read_coordIndex()
glm::ivec3 coord; glm::ivec3 coord;
int dummy; // should be -1 int coordIdx; // should be -1
std::vector<int> coord_list; std::vector<int> coord_list;
coord_list.clear(); 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 ); m_model->m_CoordIndex.push_back( coord_list );
coord_list.clear(); coord_list.clear();
} }
else else
{ {
coord_list.push_back( dummy ); coord_list.push_back( coordIdx );
} }
} }
...@@ -1582,6 +1631,7 @@ int VRML2_MODEL_PARSER::read_Color() ...@@ -1582,6 +1631,7 @@ int VRML2_MODEL_PARSER::read_Color()
if( strcmp( text, "color" ) == 0 ) if( strcmp( text, "color" ) == 0 )
{ {
m_model->m_Materials->m_DiffuseColor.clear();
ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor ); ParseVertexList( m_file, m_model->m_Materials->m_DiffuseColor );
} }
} }
......
...@@ -97,41 +97,17 @@ bool X3D_MODEL_PARSER::Load( const wxString& aFilename ) ...@@ -97,41 +97,17 @@ bool X3D_MODEL_PARSER::Load( const wxString& aFilename )
m_model.reset( new S3D_MESH() ); m_model.reset( new S3D_MESH() );
childs.push_back( m_model ); 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, ...@@ -139,7 +115,9 @@ void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent,
const wxString aName, const wxString aName,
std::vector<wxXmlNode*>& aResult ) 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; std::queue<wxXmlNode*> found;
found.push( aParent ); found.push( aParent );
...@@ -153,11 +131,9 @@ void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent, ...@@ -153,11 +131,9 @@ void X3D_MODEL_PARSER::GetChildsByName( wxXmlNode* aParent,
child = child->GetNext() ) child = child->GetNext() )
{ {
if( child->GetName() == aName ) if( child->GetName() == aName )
{
aResult.push_back( child ); aResult.push_back( child );
} else // **NOTE** This function was changed here to get only the first depth of ocorrences
found.push( child );
found.push( child );
} }
found.pop(); found.pop();
...@@ -198,6 +174,9 @@ void X3D_MODEL_PARSER::readTransform( wxXmlNode* aTransformNode ) ...@@ -198,6 +174,9 @@ void X3D_MODEL_PARSER::readTransform( wxXmlNode* aTransformNode )
PROPERTY_MAP properties; PROPERTY_MAP properties;
GetNodeProperties( aTransformNode, properties ); GetNodeProperties( aTransformNode, properties );
GetChildsByName( aTransformNode, wxT( "IndexedFaceSet" ), childnodes ); GetChildsByName( aTransformNode, wxT( "IndexedFaceSet" ), childnodes );
for( NODE_LIST::iterator node = childnodes.begin(); for( NODE_LIST::iterator node = childnodes.begin();
...@@ -430,7 +409,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode, ...@@ -430,7 +409,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode,
double angle = 0.0; double angle = 0.0;
wxStringTokenizer tokens( aTransformProps[ wxT( "rotation" ) ] ); wxStringTokenizer tokens( aTransformProps[ wxT( "rotation" ) ] );
double x, y, z; double x = 0.0, y = 0.0, z = 0.0;
if( !( tokens.GetNextToken().ToDouble( &x ) if( !( tokens.GetNextToken().ToDouble( &x )
&& tokens.GetNextToken().ToDouble( &y ) && tokens.GetNextToken().ToDouble( &y )
...@@ -551,7 +530,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode, ...@@ -551,7 +530,7 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode,
for( unsigned id = 0; id < color_points.size() / 3; id++ ) 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; int color_triplet_indx = id * 3;
glm::vec3 colorface( color_points[ color_triplet_indx + 0 ], glm::vec3 colorface( color_points[ color_triplet_indx + 0 ],
......
...@@ -285,7 +285,6 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet( ...@@ -285,7 +285,6 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
double aCorrectionFactor ) double aCorrectionFactor )
{ {
unsigned cornerscount = GetFilledPolysList().GetCornersCount(); unsigned cornerscount = GetFilledPolysList().GetCornersCount();
CPOLYGONS_LIST polygonslist;
if( cornerscount == 0 ) if( cornerscount == 0 )
return; 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