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

Rework on 3D viewer. Fix some issues, some optimizations and better rendering.

parent 9004ed88
Loading
Loading
Loading
Loading
+28 −1
Original line number Original line Diff line number Diff line
@@ -43,6 +43,7 @@
#endif
#endif


#include <3d_struct.h>
#include <3d_struct.h>
#include <class_module.h>
 
 
class BOARD_DESIGN_SETTINGS;
class BOARD_DESIGN_SETTINGS;
class EDA_3D_FRAME;
class EDA_3D_FRAME;
@@ -274,6 +275,32 @@ private:
     */
     */
    void   Draw3DPadHole( const D_PAD * aPad );
    void   Draw3DPadHole( const D_PAD * aPad );


    /**
     * function Render3DComponentShape
     * insert mesh in gl list
     * @param module
     * @param  aIsRenderingJustNonTransparentObjects = true to load non transparent objects
     * @param  aIsRenderingJustTransparentObjects = true to load non transparent objects
     * @param  aSideToLoad = false will load not fliped, true will load fliped objects
     * in openGL, transparent objects should be drawn *after* non transparent objects
     */
    void Render3DComponentShape( MODULE* module,
                                 bool aIsRenderingJustNonTransparentObjects,
                                 bool aIsRenderingJustTransparentObjects,
                                 bool aSideToLoad );

    /**
     * function Read3DComponentShape
     * read the 3D component shape(s) of the footprint (physical shape).
     * @param module
     * @param model_parsers_list = list of each new model loaded
     * @param model_filename_list = list of each new filename model loaded
     * @return true if load was succeeded, false otherwise
     */
    bool Read3DComponentShape( MODULE* module,
                               std::vector<S3D_MODEL_PARSER *>& model_parsers_list,
                               std::vector<wxString>& model_filename_list );

    void   GenerateFakeShadowsTextures();
    void   GenerateFakeShadowsTextures();


    DECLARE_EVENT_TABLE()
    DECLARE_EVENT_TABLE()
+5 −23
Original line number Original line Diff line number Diff line
@@ -28,26 +28,9 @@


#include <fctsys.h>
#include <fctsys.h>


#include <3d_viewer.h>
#include "3d_viewer.h"
#include <3d_struct.h>
#include "3d_struct.h"

#include "modelparsers.h"

bool S3D_MASTER::IsOpenGlAllowed()
{
    if( m_loadNonTransparentObjects )    // return true for non transparent objects only
    {
        if( m_lastTransparency == 0.0 )
            return true;
    }

    if( m_loadTransparentObjects )      // return true for transparent objects only
    {
        if( m_lastTransparency != 0.0 )
            return true;
    }

    return false;
}




void S3D_MASTER::Insert( S3D_MATERIAL* aMaterial )
void S3D_MASTER::Insert( S3D_MATERIAL* aMaterial )
@@ -72,9 +55,10 @@ S3D_MASTER::S3D_MASTER( EDA_ITEM* aParent ) :
    EDA_ITEM( aParent, NOT_USED )
    EDA_ITEM( aParent, NOT_USED )
{
{
    m_MatScale.x  = m_MatScale.y = m_MatScale.z = 1.0;
    m_MatScale.x  = m_MatScale.y = m_MatScale.z = 1.0;
    m_lastTransparency = 0.0;
    
    m_3D_Drawings = NULL;
    m_3D_Drawings = NULL;
    m_Materials   = NULL;
    m_Materials   = NULL;
    m_parser      = NULL;
    m_ShapeType   = FILE3D_NONE;
    m_ShapeType   = FILE3D_NONE;


    m_use_modelfile_diffuseColor = true;
    m_use_modelfile_diffuseColor = true;
@@ -83,8 +67,6 @@ S3D_MASTER::S3D_MASTER( EDA_ITEM* aParent ) :
    m_use_modelfile_ambientIntensity = true;
    m_use_modelfile_ambientIntensity = true;
    m_use_modelfile_transparency = true;
    m_use_modelfile_transparency = true;
    m_use_modelfile_shininess = true;
    m_use_modelfile_shininess = true;
    m_loadTransparentObjects = true;
    m_loadNonTransparentObjects = true;
}
}




+130 −31
Original line number Original line Diff line number Diff line
@@ -547,11 +547,7 @@ void EDA_3D_CANVAS::Redraw()
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_COLOR_MATERIAL);
    SetOpenGlDefaultMaterial();
    SetOpenGlDefaultMaterial();



    glDisable( GL_BLEND );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    glColor4f( 1.0, 1.0, 1.0, 1.0 );


    // Draw Solid Shapes
    // Draw Solid Shapes
    if( isEnabled( FL_MODULE ) )
    if( isEnabled( FL_MODULE ) )
@@ -562,6 +558,9 @@ void EDA_3D_CANVAS::Redraw()
        glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] );
        glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] );
    }
    }


    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    // Grid uses transparency: draw it after all objects
    // Grid uses transparency: draw it after all objects
    if( isEnabled( FL_GRID ) && m_glLists[GL_ID_GRID] )
    if( isEnabled( FL_GRID ) && m_glLists[GL_ID_GRID] )
        glCallList( m_glLists[GL_ID_GRID] );
        glCallList( m_glLists[GL_ID_GRID] );
@@ -572,6 +571,8 @@ void EDA_3D_CANVAS::Redraw()
    if(  isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
    if(  isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
        glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
        glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );


    glDisable( GL_BLEND );

    // Draw Board Shadow
    // Draw Board Shadow
    if( isEnabled( FL_MODULE ) && isRealisticMode() &&
    if( isEnabled( FL_MODULE ) && isRealisticMode() &&
        isEnabled( FL_RENDER_SHADOWS ) )
        isEnabled( FL_RENDER_SHADOWS ) )
@@ -1315,6 +1316,7 @@ void EDA_3D_CANVAS::CreateDrawGL_List()
// For testing purpose only, display calculation time to generate 3D data
// For testing purpose only, display calculation time to generate 3D data
// #define PRINT_CALCULATION_TIME
// #define PRINT_CALCULATION_TIME



#ifdef PRINT_CALCULATION_TIME
#ifdef PRINT_CALCULATION_TIME
    unsigned strtime = GetRunningMicroSecs();
    unsigned strtime = GetRunningMicroSecs();
#endif
#endif
@@ -1355,7 +1357,13 @@ void EDA_3D_CANVAS::CreateDrawGL_List()
        if( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
        if( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
            glDeleteLists( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], 1 );
            glDeleteLists( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], 1 );


        bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL );

        if( useMaterial )
            m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] = glGenLists( 1 );
            m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] = glGenLists( 1 );
        else
            m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] = 0;

        BuildFootprintShape3DList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT],
        BuildFootprintShape3DList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT],
                                   m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], false );
                                   m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT], false );


@@ -1364,6 +1372,7 @@ void EDA_3D_CANVAS::CreateDrawGL_List()
        m_glLists[GL_ID_SHADOW_FRONT] = glGenLists( 1 );
        m_glLists[GL_ID_SHADOW_FRONT] = glGenLists( 1 );
        m_glLists[GL_ID_SHADOW_BACK]  = glGenLists( 1 );
        m_glLists[GL_ID_SHADOW_BACK]  = glGenLists( 1 );
        m_glLists[GL_ID_SHADOW_BOARD] = glGenLists( 1 );
        m_glLists[GL_ID_SHADOW_BOARD] = glGenLists( 1 );

        BuildShadowList(m_glLists[GL_ID_SHADOW_FRONT], m_glLists[GL_ID_SHADOW_BACK], m_glLists[GL_ID_SHADOW_BOARD]);
        BuildShadowList(m_glLists[GL_ID_SHADOW_FRONT], m_glLists[GL_ID_SHADOW_BACK], m_glLists[GL_ID_SHADOW_BOARD]);


        CheckGLError( __FILE__, __LINE__ );
        CheckGLError( __FILE__, __LINE__ );
@@ -1381,66 +1390,156 @@ void EDA_3D_CANVAS::CreateDrawGL_List()


void EDA_3D_CANVAS::BuildFootprintShape3DList( GLuint aOpaqueList,
void EDA_3D_CANVAS::BuildFootprintShape3DList( GLuint aOpaqueList,
                                               GLuint aTransparentList, bool aSideToLoad)
                                               GLuint aTransparentList, bool aSideToLoad)
{
#ifdef PRINT_CALCULATION_TIME
    unsigned strtime = GetRunningMicroSecs();
#endif
    // This lists are used to just load once of each filename model
    std::vector<S3D_MODEL_PARSER *> model_parsers_list;
    std::vector<wxString> model_filename_list;

    BOARD* pcb = GetBoard();

    for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
        Read3DComponentShape( module, model_parsers_list, model_filename_list );

#ifdef PRINT_CALCULATION_TIME
    {
    unsigned    endtime = GetRunningMicroSecs();
    wxString    msg;
    msg.Printf( "  Read3DComponentShape total time %.1f ms", (double) (endtime - strtime) / 1000 );
    DBG( printf( "%s\n", (const char*)msg.c_str() ) );
    }
#endif

#ifdef PRINT_CALCULATION_TIME
    strtime = GetRunningMicroSecs();
#endif

    bool useMaterial = g_Parm_3D_Visu.GetFlag( FL_RENDER_MATERIAL );

    if( useMaterial )
    {
    {
        // aOpaqueList is the gl list for non transparent items
        // aOpaqueList is the gl list for non transparent items
        // aTransparentList is the gl list for non transparent items,
        // aTransparentList is the gl list for non transparent items,
        // which need to be drawn after all other items
        // which need to be drawn after all other items


        BOARD* pcb = GetBoard();
        glNewList( aOpaqueList, GL_COMPILE );
        glNewList( aOpaqueList, GL_COMPILE );
        bool loadTransparentObjects = false;
        bool loadOpaqueObjects = true;


        for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
        for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
            module->ReadAndInsert3DComponentShape( this, !loadTransparentObjects,
            Render3DComponentShape( module,  loadOpaqueObjects,
                                                   loadTransparentObjects, aSideToLoad );
                                             !loadOpaqueObjects, aSideToLoad );

        glEndList();
        glEndList();



        glNewList( aTransparentList, GL_COMPILE );
        glNewList( aTransparentList, GL_COMPILE );
        loadTransparentObjects = true;
        bool loadTransparentObjects = true;


        for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
        for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
            module->ReadAndInsert3DComponentShape( this, !loadTransparentObjects,
            Render3DComponentShape( module, !loadTransparentObjects,
                                            loadTransparentObjects, aSideToLoad );
                                            loadTransparentObjects, aSideToLoad );


        glEndList();
        glEndList();
    }
    }
    else
    {
        // Just create one list
        glNewList( aOpaqueList, GL_COMPILE );

        for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
            Render3DComponentShape( module, false, false, aSideToLoad );
        glEndList();
    }

#ifdef PRINT_CALCULATION_TIME
    {
    unsigned    endtime = GetRunningMicroSecs();
    wxString    msg;
    msg.Printf( "  Render3DComponentShape total time %.1f ms", (double) (endtime - strtime) / 1000 );
    DBG( printf( "%s\n", (const char*)msg.c_str() ) );
    }
#endif
}




void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas,
bool EDA_3D_CANVAS::Read3DComponentShape( MODULE* module,
                                    bool aAllowNonTransparentObjects,
                                          std::vector<S3D_MODEL_PARSER *>& model_parsers_list,
                                    bool aAllowTransparentObjects,
                                          std::vector<wxString>& model_filename_list )
                                    bool aSideToLoad )
{
{
    S3D_MASTER* shape3D = module->Models();


    for( ; shape3D; shape3D = shape3D->Next() )
    {
        if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) )
        {
            bool found = false;

            unsigned int i;
            wxString shape_filename = shape3D->GetShape3DFullFilename();

            // Search for already loaded files
            for( i = 0; i < model_filename_list.size(); i++ )
            {
                if( shape_filename.Cmp(model_filename_list[i]) == 0 )
                {
                    found = true;
                    break;
                }
            }

            if( found == false )
            {
                shape3D->ReadData();
                model_filename_list.push_back( shape_filename );
                model_parsers_list.push_back( shape3D->m_parser );
            }
            else
            {
                DBG( printf( "  Read3DComponentShape reusing %s\n", (const char*)shape_filename.c_str() ) );
                shape3D->m_parser = model_parsers_list[i];
            }
        }
    }

    return true;
}


void EDA_3D_CANVAS::Render3DComponentShape( MODULE* module,
                                            bool aIsRenderingJustNonTransparentObjects,
                                            bool aIsRenderingJustTransparentObjects,
                                            bool aSideToLoad )
{
    // Read from disk and draws the footprint 3D shapes if exists
    // Read from disk and draws the footprint 3D shapes if exists
    double zpos = glcanvas->GetPrm3DVisu().GetModulesZcoord3DIU( IsFlipped() );
    double zpos = GetPrm3DVisu().GetModulesZcoord3DIU( module->IsFlipped() );


    glPushMatrix();
    glPushMatrix();


    glTranslatef( m_Pos.x * glcanvas->GetPrm3DVisu().m_BiuTo3Dunits,
    wxPoint pos = module->GetPosition();
                  -m_Pos.y * glcanvas->GetPrm3DVisu().m_BiuTo3Dunits,

    glTranslatef(  pos.x * GetPrm3DVisu().m_BiuTo3Dunits,
                  -pos.y * GetPrm3DVisu().m_BiuTo3Dunits,
                   zpos );
                   zpos );


    if( m_Orient )
    if( module->GetOrientation() )
        glRotatef( (double) m_Orient / 10, 0.0, 0.0, 1.0 );
        glRotatef( (double) module->GetOrientation() / 10.0, 0.0, 0.0, 1.0 );


    if( IsFlipped() )
    if( module->IsFlipped() )
    {
    {
        glRotatef( 180.0, 0.0, 1.0, 0.0 );
        glRotatef( 180.0, 0.0, 1.0, 0.0 );
        glRotatef( 180.0, 0.0, 0.0, 1.0 );
        glRotatef( 180.0, 0.0, 0.0, 1.0 );
    }
    }


    S3D_MASTER* shape3D = Models();
    S3D_MASTER* shape3D = module->Models();

    for( ; shape3D; shape3D = shape3D->Next() )
    for( ; shape3D; shape3D = shape3D->Next() )
    {
    {
        shape3D->SetLoadNonTransparentObjects( aAllowNonTransparentObjects );
        shape3D->SetLoadTransparentObjects( aAllowTransparentObjects );

        if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) )
        if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) )
        {
        {
            glPushMatrix();
            glPushMatrix();
            shape3D->ReadData();
            shape3D->Render( aIsRenderingJustNonTransparentObjects,
                             aIsRenderingJustTransparentObjects );
            glPopMatrix();
            glPopMatrix();
        }
        }
    }
    }
+7 −12
Original line number Original line Diff line number Diff line
@@ -71,31 +71,23 @@ void SetOpenGlDefaultMaterial()
}
}




void S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMaterial )
bool S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMaterial )
{
{
    S3D_MASTER * s3dParent = (S3D_MASTER *) GetParent();
    S3D_MASTER * s3dParent = (S3D_MASTER *) GetParent();


    if( ! s3dParent->IsOpenGlAllowed() )
        return;

    if( aUseMaterial )
    if( aUseMaterial )
    {
    {
        float transparency_value = 0.0f;
        float transparency_value = 0.0f;

        if( m_Transparency.size() > aMaterialIndex )
        if( m_Transparency.size() > aMaterialIndex )
        {
        {
            transparency_value = m_Transparency[aMaterialIndex];
            transparency_value = m_Transparency[aMaterialIndex];
            s3dParent->SetLastTransparency( transparency_value );
        }
        }
        
        
        if( m_DiffuseColor.size() > aMaterialIndex )
        if( m_DiffuseColor.size() > aMaterialIndex )
        {
        {
            glm::vec3 color = m_DiffuseColor[aMaterialIndex];
            glm::vec3 color = m_DiffuseColor[aMaterialIndex];


            if( m_AmbientColor.size() == 0 )
            {
                glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
            }

            glColor4f( color.x, color.y, color.z, 1.0 - transparency_value );
            glColor4f( color.x, color.y, color.z, 1.0 - transparency_value );
        }
        }


@@ -136,15 +128,18 @@ void S3D_MATERIAL::SetOpenGLMaterial( unsigned int aMaterialIndex, bool aUseMate
            ambient[3] = 1.0f;
            ambient[3] = 1.0f;
            glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,  &ambient.x );
            glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT,  &ambient.x );
        }
        }

        return (transparency_value != 0.0f);
    }
    }
    else
    else
    {
    {
        if( m_DiffuseColor.size() > aMaterialIndex )
        if( m_DiffuseColor.size() > aMaterialIndex )
        {
        {
            glm::vec3 color = m_DiffuseColor[aMaterialIndex];
            glm::vec3 color = m_DiffuseColor[aMaterialIndex];
            glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
            glColor4f( color.x, color.y, color.z, 1.0 );
            glColor4f( color.x, color.y, color.z, 1.0 );
        }
        }
    }
    }

    return false;
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -59,8 +59,9 @@ public:
     * @param aMaterialIndex = the index in list of available materials
     * @param aMaterialIndex = the index in list of available materials
     * @param aUseMaterial = true to use the values found in the available material
     * @param aUseMaterial = true to use the values found in the available material
     *                     = false to use only the color, and other prms are fixed
     *                     = false to use only the color, and other prms are fixed
     * @return true if the material is transparency
     */
     */
    void SetOpenGLMaterial(unsigned int aMaterialIndex, bool aUseMaterial);
    bool SetOpenGLMaterial(unsigned int aMaterialIndex, bool aUseMaterial);


#if defined(DEBUG)
#if defined(DEBUG)
    void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
    void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
Loading