Commit 8e7bc566 authored by unknown's avatar unknown Committed by jean-pierre charras
Browse files

3d viewer: fix current shading issues with some models.

parent f87577ca
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -563,7 +563,7 @@ void EDA_3D_CANVAS::InitGL()
void EDA_3D_CANVAS::SetLights()
{
    // activate light. the source is above the xy plane, at source_pos
    GLfloat source_pos[4]    = { 0.0, 0.0, 30.0, 0.0 };
    GLfloat source_pos[4]    = { 0.0, 0.0, 1000.0, 0.0 };
    GLfloat light_color[4];     // color of lights (RGBA values)
    light_color[3] = 1.0;

+3 −10
Original line number Diff line number Diff line
@@ -343,14 +343,7 @@ void EDA_3D_CANVAS::Redraw()
    glClearDepth( 1.0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
   
	if( isEnabled( FL_RENDER_SMOOTH ) )
	{
    glShadeModel( GL_SMOOTH );
	}
	else
	{
		glShadeModel( GL_FLAT );
	}
	
    // Draw background
    glMatrixMode( GL_PROJECTION );
+16 −6
Original line number Diff line number Diff line
@@ -54,7 +54,8 @@ static const wxChar keyShowRealisticMode[] = wxT( "ShowRealisticMode" );
static const wxChar keyRenderShadows[] =        wxT( "Render_Shadows" );
static const wxChar keyRenderRemoveHoles[] =    wxT( "Render_RemoveHoles" );
static const wxChar keyRenderTextures[] =       wxT( "Render_Textures" );
static const wxChar keyRenderSmooth[] =         wxT( "Render_Smooth" );
static const wxChar keyRenderSmoothNormals[] =  wxT( "Render_Smooth_Normals" );
static const wxChar keyRenderUseModelNormals[] =wxT( "Render_Use_Model_Normals" );
static const wxChar keyRenderMaterial[] =       wxT( "Render_Material" );

static const wxChar keyShowAxis[] =             wxT( "ShowAxis" );
@@ -247,8 +248,11 @@ void EDA_3D_FRAME::LoadSettings( wxConfigBase* aCfg )
    aCfg->Read( keyRenderTextures, &tmp, false );
    prms.SetFlag( FL_RENDER_TEXTURES, tmp );

    aCfg->Read( keyRenderSmooth, &tmp, false );
    prms.SetFlag( FL_RENDER_SMOOTH, tmp );
    aCfg->Read( keyRenderSmoothNormals, &tmp, false );
    prms.SetFlag( FL_RENDER_SMOOTH_NORMALS, tmp );

    aCfg->Read( keyRenderUseModelNormals, &tmp, false );
    prms.SetFlag( FL_RENDER_USE_MODEL_NORMALS, tmp );

    aCfg->Read( keyRenderMaterial, &tmp, false );
    prms.SetFlag( FL_RENDER_MATERIAL, tmp );
@@ -312,7 +316,8 @@ void EDA_3D_FRAME::SaveSettings( wxConfigBase* aCfg )
    aCfg->Write( keyRenderShadows, prms.GetFlag( FL_RENDER_SHADOWS ) );
    aCfg->Write( keyRenderRemoveHoles, prms.GetFlag( FL_RENDER_SHOW_HOLES_IN_ZONES ) );
    aCfg->Write( keyRenderTextures, prms.GetFlag( FL_RENDER_TEXTURES ) );
    aCfg->Write( keyRenderSmooth, prms.GetFlag( FL_RENDER_SMOOTH ) );
    aCfg->Write( keyRenderSmoothNormals, prms.GetFlag( FL_RENDER_SMOOTH_NORMALS ) );
    aCfg->Write( keyRenderUseModelNormals, prms.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) );
    aCfg->Write( keyRenderMaterial, prms.GetFlag( FL_RENDER_MATERIAL ) );

    aCfg->Write( keyShowAxis, prms.GetFlag( FL_AXIS ) );
@@ -488,8 +493,13 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event )
        NewDisplay(GL_ID_TECH_LAYERS);
        return;

    case ID_MENU3D_FL_RENDER_SMOOTH:
        GetPrm3DVisu().SetFlag( FL_RENDER_SMOOTH, isChecked );
    case ID_MENU3D_FL_RENDER_SMOOTH_NORMALS:
        GetPrm3DVisu().SetFlag( FL_RENDER_SMOOTH_NORMALS, isChecked );
        NewDisplay();
        return;

    case ID_MENU3D_FL_RENDER_USE_MODEL_NORMALS:
        GetPrm3DVisu().SetFlag( FL_RENDER_USE_MODEL_NORMALS, isChecked );
        NewDisplay();
        return;

+143 −59
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ S3D_MESH::S3D_MESH()
    isPerFaceNormalsComputed = false;
    isPointNormalizedComputed = false;
    isPerPointNormalsComputed = false;
    isPerVertexNormalsVerified = false;
    m_Materials = NULL;
    childs.clear();

@@ -91,10 +92,7 @@ void S3D_MESH::openGL_Render()
    //DBG( printf( "openGL_Render" ) );
    bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL );
    bool smoothShapes = g_Parm_3D_Visu.IsRealisticMode()
                        && g_Parm_3D_Visu.GetFlag( FL_RENDER_SMOOTH );

    if( m_Materials )
        m_Materials->SetOpenGLMaterial( 0, useMaterial );
                        && g_Parm_3D_Visu.GetFlag( FL_RENDER_SMOOTH_NORMALS );

    if( m_CoordIndex.size() == 0 )
        return;
@@ -109,19 +107,23 @@ void S3D_MESH::openGL_Render()
    calcPointNormalized();
    calcPerFaceNormals();

    if( m_PerVertexNormalsNormalized.size() == 0 )
    {
    if( smoothShapes )
    {
        if( (m_PerVertexNormalsNormalized.size() > 0) &&
            g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
            perVertexNormalsVerify_and_Repair();
        else
            calcPerPointNormals();
            
    }

    for( unsigned int idx = 0; idx < m_CoordIndex.size(); idx++ )
    {
        if( m_MaterialIndex.size() > 1 )
        {
        if( m_MaterialIndex.size() == 0 )
            m_Materials->SetOpenGLMaterial( 0, useMaterial );
        else
            if( m_Materials )
                m_Materials->SetOpenGLMaterial( m_MaterialIndex[idx], useMaterial );
        }


        switch( m_CoordIndex[idx].size() )
@@ -138,18 +140,25 @@ void S3D_MESH::openGL_Render()
        }


        if( m_PerVertexNormalsNormalized.size() > 0 )
        if( smoothShapes )
        {
            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 );

                    // Flag error vertices
                    if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
                        glColor3f( 1.0, 0.0, 0.0 );

                    glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
                    glVertex3fv( &point.x );
                }
            }
        else if( smoothShapes )
            else
            {
                std::vector< glm::vec3 > normals_list;
                normals_list = m_PerFaceVertexNormals[idx];
@@ -159,23 +168,43 @@ void S3D_MESH::openGL_Render()
                    glm::vec3 normal = normals_list[ii];
                    glNormal3fv( &normal.x );

                    // Flag error vertices
                    if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
                        glColor3f( 1.0, 0.0, 0.0 );

                    glm::vec3 point = m_Point[m_CoordIndex[idx][ii]];
                    glVertex3fv( &point.x );
                }
            }
        }
        else
        {
            // Flat
            if( m_PerFaceNormalsNormalized.size() > 0 )
            {
                glm::vec3 normal = m_PerFaceNormalsNormalized[idx];

                for( unsigned int ii = 0; ii < m_CoordIndex[idx].size(); ii++ )
                {
                    glNormal3fv( &normal.x );

                    // Flag error vertices
                    if ((normal.x == 0.0) && (normal.y == 0.0) && (normal.z == 0.0))
                        glColor3f( 1.0, 0.0, 0.0 );

                    glm::vec3 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]];
                    glVertex3fv( &point.x );
                }
            }
        }

        glEnd();
    }
@@ -184,6 +213,68 @@ void S3D_MESH::openGL_Render()
}


void S3D_MESH::perVertexNormalsVerify_and_Repair()
{
    if( isPerVertexNormalsVerified == true )
        return;

    isPerVertexNormalsVerified = true;

    //DBG( printf( "perVertexNormalsVerify_and_Repair\n" ) );

    for( unsigned int idx = 0; idx < m_PerVertexNormalsNormalized.size(); idx++ )
    {
        glm::vec3 normal = m_PerVertexNormalsNormalized[idx];

        if( (normal.x == 1.0) && ((normal.y != 0.0) || (normal.z != 0.0)) )
        {
            normal.y = 0.0;
            normal.z = 0.0;
        }
        else
        if( (normal.y == 1.0) && ((normal.x != 0.0) || (normal.z != 0.0)) )
        {
            normal.x = 0.0;
            normal.z = 0.0;
        }
        else
        if( (normal.z == 1.0) && ((normal.x != 0.0) || (normal.y != 0.0)) )
        {
            normal.x = 0.0;
            normal.y = 0.0;
        }
        else
        if( (normal.x < FLT_EPSILON) && (normal.x > -FLT_EPSILON) )
        {
            normal.x = 0.0;
        }
        else
        if( (normal.y < FLT_EPSILON) && (normal.y > -FLT_EPSILON) )
        {
            normal.y = 0.0;
        }
        else
        if( (normal.z < FLT_EPSILON) && (normal.z > -FLT_EPSILON) )
        {
            normal.z = 0.0;
        }

        float l = glm::length( normal );

        if( l > FLT_EPSILON ) // avoid division by zero
        {
            normal = normal / l;
        }
        else
        {
            //DBG( printf( "idx:%u\n", idx ) );
        }

        m_PerVertexNormalsNormalized[idx] = normal;
    }
}


void S3D_MESH::calcPointNormalized()
{
    //DBG( printf( "calcPointNormalized\n" ) );
@@ -193,9 +284,6 @@ void S3D_MESH::calcPointNormalized()

    isPointNormalizedComputed = true;

    if( m_PerVertexNormalsNormalized.size() > 0 )
        return;

    m_PointNormalized.clear();

    float biggerPoint = 0.0f;
@@ -245,20 +333,17 @@ void S3D_MESH::calcPerFaceNormals()

    isPerFaceNormalsComputed = true;

    if( m_PerVertexNormalsNormalized.size() > 0 )
        return;

    bool haveAlreadyNormals_from_model_file = false;

    if( m_PerFaceNormalsNormalized.size() > 0 )
    if( ( m_PerFaceNormalsNormalized.size() > 0 ) &&
        g_Parm_3D_Visu.GetFlag( FL_RENDER_USE_MODEL_NORMALS ) )
        haveAlreadyNormals_from_model_file = true;
    else
        m_PerFaceNormalsNormalized.clear();

    m_PerFaceNormalsRaw.clear();
    m_PerFaceSquaredArea.clear();

    //DBG( printf("m_CoordIndex.size %u\n", m_CoordIndex.size()) );
    //DBG( printf("m_PointNormalized.size %u\n", m_PointNormalized.size()) );

    // There are no points defined for the coordIndex
    if( m_PointNormalized.size() == 0 )
    {
@@ -273,13 +358,6 @@ void S3D_MESH::calcPerFaceNormals()
        glm::vec3 v1 = m_PointNormalized[m_CoordIndex[idx][1]];
        glm::vec3 v2 = m_PointNormalized[m_CoordIndex[idx][m_CoordIndex[idx].size() - 1]];

        /*
        // !TODO: improove and check what is best to calc the normal (check what have more resolution)
        glm::vec3 v0 = m_Point[m_CoordIndex[idx][0]];
        glm::vec3 v1 = m_Point[m_CoordIndex[idx][1]];
        glm::vec3 v2 = m_Point[m_CoordIndex[idx][m_CoordIndex[idx].size() - 1]];
        */

        glm::vec3 cross_prod;

        /*
@@ -317,11 +395,11 @@ void S3D_MESH::calcPerFaceNormals()
            }
            else
            {
                // Cannot calc normal
                //DBG( printf( "Cannot calc normal idx: %u", idx ) );
                if( ( cross_prod.x > cross_prod.y ) && ( cross_prod.x > cross_prod.z ) )
                {
                    cross_prod.x = 1.0;
                    cross_prod.y = 0.0;
                    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 ) )
@@ -355,9 +433,6 @@ void S3D_MESH::calcPerPointNormals()

    isPerPointNormalsComputed = true;

    if( m_PerVertexNormalsNormalized.size() > 0 )
        return;

    m_PerFaceVertexNormals.clear();

    // Pre-allocate space for the entire vector of vertex normals so we can do parallel writes
@@ -389,9 +464,18 @@ void S3D_MESH::calcPerPointNormals()
                //if A != B { // ignore self
                if( each_face_A_idx != each_face_B_idx )
                {
                    if( (m_CoordIndex[each_face_B_idx][0] == vertexIndex)
                      || (m_CoordIndex[each_face_B_idx][1] == vertexIndex)
                      || (m_CoordIndex[each_face_B_idx][2] == vertexIndex) )
                    bool addThisVertex = false;
                    
                    for( unsigned int ii = 0; ii < m_CoordIndex[each_face_B_idx].size(); ii++ )
                    {
                        if( m_CoordIndex[each_face_B_idx][ii] == vertexIndex )
                        {
                            addThisVertex = true;
                            break;
                        }
                    }
                    
                    if( addThisVertex )
                    {
                        glm::vec3 vector_face_B = m_PerFaceNormalsNormalized[each_face_B_idx];

+3 −0
Original line number Diff line number Diff line
@@ -95,6 +95,9 @@ private:

    bool isPerPointNormalsComputed;
    void calcPerPointNormals();

    bool isPerVertexNormalsVerified;
    void perVertexNormalsVerify_and_Repair();
};


Loading