From 4fd3dbb5a5ca160198b9eab12450bca8c33e7c39 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 9 Mar 2014 19:43:53 +0100 Subject: [PATCH] Finishing work on a better 3D viewer. this also fix bugs like Bug #1129630 . --- 3d-viewer/3d_aux.cpp | 49 ++------------------------ 3d-viewer/3d_canvas.h | 1 - 3d-viewer/3d_class.cpp | 22 +++++++++++- 3d-viewer/3d_draw.cpp | 50 +++++++++++++++++++-------- 3d-viewer/3d_draw_basic_functions.cpp | 4 +-- 3d-viewer/3d_struct.h | 43 ++++++++++++++++++++++- 3d-viewer/modelparsers.h | 2 +- 3d-viewer/vrmlmodelparser.cpp | 8 +++-- 3d-viewer/x3dmodelparser.cpp | 7 ++-- pcbnew/class_module.h | 8 ++++- 10 files changed, 122 insertions(+), 72 deletions(-) diff --git a/3d-viewer/3d_aux.cpp b/3d-viewer/3d_aux.cpp index 0878053869..a8ccab2b8d 100644 --- a/3d-viewer/3d_aux.cpp +++ b/3d-viewer/3d_aux.cpp @@ -45,16 +45,11 @@ #include #include -// Exported function: -void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ); - -void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices ) +void S3D_MASTER::ObjectCoordsTo3DUnits( std::vector< S3D_VERTEX >& aVertices ) { - unsigned ii; - /* adjust object scale, rotation and offset position */ - for( ii = 0; ii < aVertices.size(); ii++ ) + for( unsigned ii = 0; ii < aVertices.size(); ii++ ) { aVertices[ii].x *= m_MatScale.x; aVertices[ii].y *= m_MatScale.y; @@ -79,7 +74,7 @@ void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices ) } -void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ) +void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ) { unsigned ii; GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, r; @@ -138,44 +133,6 @@ void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits glEnd(); } - -GLuint EDA_3D_CANVAS::DisplayCubeforTest() -{ - GLuint gllist = glGenLists( 1 ); - - glNewList( gllist, GL_COMPILE_AND_EXECUTE ); - /* draw six faces of a cube */ - glBegin( GL_QUADS ); - glNormal3f( 0.0F, 0.0F, 1.0F ); - glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( -0.5F, 0.5F, 0.5F ); - glVertex3f( -0.5F, -0.5F, 0.5F ); glVertex3f( 0.5F, -0.5F, 0.5F ); - - glNormal3f( 0.0F, 0.0F, -1.0F ); - glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( -0.5F, 0.5F, -0.5F ); - glVertex3f( 0.5F, 0.5F, -0.5F ); glVertex3f( 0.5F, -0.5F, -0.5F ); - - glNormal3f( 0.0F, 1.0F, 0.0F ); - glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( 0.5F, 0.5F, -0.5F ); - glVertex3f( -0.5F, 0.5F, -0.5F ); glVertex3f( -0.5F, 0.5F, 0.5F ); - - glNormal3f( 0.0F, -1.0F, 0.0F ); - glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( 0.5F, -0.5F, -0.5F ); - glVertex3f( 0.5F, -0.5F, 0.5F ); glVertex3f( -0.5F, -0.5F, 0.5F ); - - glNormal3f( 1.0F, 0.0F, 0.0F ); - glVertex3f( 0.5F, 0.5F, 0.5F ); glVertex3f( 0.5F, -0.5F, 0.5F ); - glVertex3f( 0.5F, -0.5F, -0.5F ); glVertex3f( 0.5F, 0.5F, -0.5F ); - - glNormal3f( -1.0F, 0.0F, 0.0F ); - glVertex3f( -0.5F, -0.5F, -0.5F ); glVertex3f( -0.5F, -0.5F, 0.5F ); - glVertex3f( -0.5F, 0.5F, 0.5F ); glVertex3f( -0.5F, 0.5F, -0.5F ); - glEnd(); - - glEndList(); - - return gllist; -} - VERTEX_VALUE_CTRL::VERTEX_VALUE_CTRL( wxWindow* aParent, wxBoxSizer* aBoxSizer ) { wxString text; diff --git a/3d-viewer/3d_canvas.h b/3d-viewer/3d_canvas.h index fa84fec602..43a1f7ed85 100644 --- a/3d-viewer/3d_canvas.h +++ b/3d-viewer/3d_canvas.h @@ -104,7 +104,6 @@ public: void OnEnterWindow( wxMouseEvent& event ); // Display functions - GLuint DisplayCubeforTest(); // Just a test function void SetView3D( int keycode ); void DisplayStatus(); void Redraw(); diff --git a/3d-viewer/3d_class.cpp b/3d-viewer/3d_class.cpp index 79ea755b2f..b364d23e5b 100644 --- a/3d-viewer/3d_class.cpp +++ b/3d-viewer/3d_class.cpp @@ -41,9 +41,14 @@ S3D_MATERIAL::S3D_MATERIAL( S3D_MASTER* father, const wxString& name ) : m_Name = name; } - void S3D_MATERIAL::SetMaterial() { + S3D_MASTER * s3dParent = (S3D_MASTER *) GetParent(); + s3dParent->SetLastTransparency( m_Transparency ); + + if( ! s3dParent->IsOpenGlAllowed() ) + return; + glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); glColor4f( m_DiffuseColor.x * m_AmbientIntensity, m_DiffuseColor.y * m_AmbientIntensity, @@ -56,6 +61,20 @@ void S3D_MATERIAL::SetMaterial() #endif } +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 ) { @@ -79,6 +98,7 @@ S3D_MASTER::S3D_MASTER( EDA_ITEM* aParent ) : EDA_ITEM( aParent, NOT_USED ) { m_MatScale.x = m_MatScale.y = m_MatScale.z = 1.0; + m_lastTransparency = 0.0; m_3D_Drawings = NULL; m_Materials = NULL; m_ShapeType = FILE3D_NONE; diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 991916294b..dffd7e17cc 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -356,7 +356,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() } } - // draw graphic items + // draw graphic items on copper layers (texts) for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() ) { if( !item->IsOnLayer( layer ) ) @@ -364,11 +364,9 @@ void EDA_3D_CANVAS::BuildBoard3DView() switch( item->Type() ) { - case PCB_LINE_T: + case PCB_LINE_T: // should not exist on copper layers ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( - bufferPolys, 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); break; case PCB_TEXT_T: @@ -505,8 +503,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() // a fine representation CPOLYGONS_LIST bufferPolys; - bufferPolys.reserve( 200000 ); // Reserve for large board (tracks mainly) - + bufferPolys.reserve( 100000 ); // Reserve for large board CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once allLayerHoles.reserve( 20000 ); @@ -522,11 +519,6 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() wxMessageBox( msg ); } - CPOLYGONS_LIST bufferZonesPolys; - bufferZonesPolys.reserve( 500000 ); // Reserve for large board ( copper zones mainly ) - - CPOLYGONS_LIST currLayerHoles; // Contains holes for the current layer - int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) { @@ -544,6 +536,16 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() } } + // draw pads holes + for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) + { + // Add pad hole, if any + D_PAD* pad = module->Pads(); + + for( ; pad != NULL; pad = pad->Next() ) + pad->BuildPadDrillShapePolygon( allLayerHoles, 0, + segcountLowQuality ); + } // draw graphic items, on technical layers @@ -852,6 +854,7 @@ void EDA_3D_CANVAS::CreateDrawGL_List() #endif } + void EDA_3D_CANVAS::BuildFootprintShape3DList( GLuint aOpaqueList, GLuint aTransparentList) { @@ -860,10 +863,21 @@ void EDA_3D_CANVAS::BuildFootprintShape3DList( GLuint aOpaqueList, // which need to be drawn after all other items BOARD* pcb = GetBoard(); - glNewList( m_glLists[GL_ID_3DSHAPES_SOLID], GL_COMPILE ); + glNewList( aOpaqueList, GL_COMPILE ); + bool loadTransparentObjects = false; for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) - module->ReadAndInsert3DComponentShape( this ); + module->ReadAndInsert3DComponentShape( this, !loadTransparentObjects, + loadTransparentObjects ); + + glEndList(); + + glNewList( aTransparentList, GL_COMPILE ); + loadTransparentObjects = true; + + for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) + module->ReadAndInsert3DComponentShape( this, !loadTransparentObjects, + loadTransparentObjects ); glEndList(); } @@ -1055,8 +1069,11 @@ void EDA_3D_CANVAS::Draw3DViaHole( SEGVIA* aVia ) } -void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas ) +void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas, + bool aAllowNonTransparentObjects, + bool aAllowTransparentObjects ) { + // Read from disk and draws the footprint 3D shapes if exists S3D_MASTER* shape3D = m_3D_Drawings; double zpos = g_Parm_3D_Visu.GetModulesZcoord3DIU( IsFlipped() ); @@ -1078,6 +1095,9 @@ void MODULE::ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas ) for( ; shape3D != NULL; shape3D = shape3D->Next() ) { + shape3D->SetLoadNonTransparentObjects( aAllowNonTransparentObjects ); + shape3D->SetLoadTransparentObjects( aAllowTransparentObjects ); + if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) ) shape3D->ReadData(); } diff --git a/3d-viewer/3d_draw_basic_functions.cpp b/3d-viewer/3d_draw_basic_functions.cpp index ef49a3e4bb..81654c4af7 100644 --- a/3d-viewer/3d_draw_basic_functions.cpp +++ b/3d-viewer/3d_draw_basic_functions.cpp @@ -35,7 +35,7 @@ #include <3d_draw_basic_functions.h> // Imported function: -extern void Set_Object_Data( std::vector& aVertices, double aBiuTo3DUnits ); +extern void TransfertToGLlist( std::vector& aVertices, double aBiuTo3DUnits ); extern void CheckGLError(); // Number of segments to approximate a circle by segments @@ -116,7 +116,7 @@ static void Draw3D_VerticalPolygonalCylinder( const CPOLYGONS_LIST& aPolysList, coords[3].y = coords[2].y; // only z change // Creates the GL_QUAD - Set_Object_Data( coords, aBiuTo3DUnits ); + TransfertToGLlist( coords, aBiuTo3DUnits ); } } diff --git a/3d-viewer/3d_struct.h b/3d-viewer/3d_struct.h index 56a083f8c9..2a82effd93 100644 --- a/3d-viewer/3d_struct.h +++ b/3d-viewer/3d_struct.h @@ -109,6 +109,10 @@ public: private: wxString m_Shape3DName; /* 3D shape name in 3D library */ FILE3D_TYPE m_ShapeType; + double m_lastTransparency; // last transparency value from + // last material in use + bool m_loadTransparentObjects; + bool m_loadNonTransparentObjects; public: S3D_MASTER( EDA_ITEM* aParent ); @@ -117,11 +121,41 @@ public: S3D_MASTER* Next() const { return (S3D_MASTER*) Pnext; } S3D_MASTER* Back() const { return (S3D_MASTER*) Pback; } + // Accessors + void SetLastTransparency( double aValue ) { m_lastTransparency = aValue; } + + void SetLoadTransparentObjects( bool aLoad ) + { m_loadTransparentObjects = aLoad; } + + void SetLoadNonTransparentObjects( bool aLoad ) + { m_loadNonTransparentObjects = aLoad; } + void Insert( S3D_MATERIAL* aMaterial ); + /** + * Function IsOpenGlAllowed + * @return true if opengl current list accepts a gl data + * used to filter transparent objects, which are drawn after + * non transparent objects + */ + bool IsOpenGlAllowed(); + void Copy( S3D_MASTER* pattern ); + + /** + * Function ReadData + * Select the parser to read the 3D data file (vrml, x3d ...) + * and build the description objects list + */ int ReadData(); - void Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices ); + + /** + * Function ObjectCoordsTo3DUnits + * @param aVertices = a list of 3D coordinates in shape units + * to convert to 3D canvas units, according to the + * footprint 3Dshape rotation, offset and scale parameters + */ + void ObjectCoordsTo3DUnits( std::vector< S3D_VERTEX >& aVertices ); #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override @@ -147,6 +181,13 @@ public: */ const wxString GetShape3DFullFilename(); + /** + * Function SetShape3DName + * @param aShapeName = file name of the data file relative to the 3D shape + * + * Set the filename of the 3D shape, and depending on the file extention + * (vrl, x3d, idf ) the type of file. + */ void SetShape3DName( const wxString& aShapeName ); }; diff --git a/3d-viewer/modelparsers.h b/3d-viewer/modelparsers.h index 147a0fda16..d1c5f23461 100644 --- a/3d-viewer/modelparsers.h +++ b/3d-viewer/modelparsers.h @@ -37,7 +37,7 @@ class S3D_MASTER; class S3D_VERTEX; -extern void Set_Object_Data( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ); +extern void TransfertToGLlist( std::vector< S3D_VERTEX >& aVertices, double aBiuTo3DUnits ); class S3D_MODEL_PARSER; class X3D_MODEL_PARSER; diff --git a/3d-viewer/vrmlmodelparser.cpp b/3d-viewer/vrmlmodelparser.cpp index fa6367793b..8891a424aa 100644 --- a/3d-viewer/vrmlmodelparser.cpp +++ b/3d-viewer/vrmlmodelparser.cpp @@ -519,8 +519,12 @@ int VRML_MODEL_PARSER::readGeometry( FILE* file, int* LineNum ) vertices.push_back( vertex ); } - GetMaster()->Set_Object_Coords( vertices ); - Set_Object_Data( vertices, vrmlunits_to_3Dunits ); + if( GetMaster()->IsOpenGlAllowed() ) + { + GetMaster()->ObjectCoordsTo3DUnits( vertices ); + TransfertToGLlist( vertices, vrmlunits_to_3Dunits ); + } + vertices.clear(); coordIndex.clear(); } diff --git a/3d-viewer/x3dmodelparser.cpp b/3d-viewer/x3dmodelparser.cpp index 012d3df959..e4f7d283b2 100644 --- a/3d-viewer/x3dmodelparser.cpp +++ b/3d-viewer/x3dmodelparser.cpp @@ -479,8 +479,11 @@ void X3D_MODEL_PARSER::readIndexedFaceSet( wxXmlNode* aFaceNode, vertices.push_back( triplets.at( *id ) ); } - GetMaster()->Set_Object_Coords( vertices ); - Set_Object_Data( vertices, vrmlunits_to_3Dunits ); + if( GetMaster()->IsOpenGlAllowed() ) + { + GetMaster()->ObjectCoordsTo3DUnits( vertices ); + TransfertToGLlist( vertices, vrmlunits_to_3Dunits ); + } vertices.clear(); coordIndex.clear(); diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 184e9e7288..34a8c11788 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -250,8 +250,14 @@ public: * function ReadandInsert3DComponentShape * read the 3D component shape(s) of the footprint (physical shape) * and insert mesh in gl list + * @param glcanvas = the openGL canvas + * @param aAllowNonTransparentObjects = true to load non transparent objects + * @param aAllowTransparentObjects = true to load non transparent objects + * in openGL, transparent objects should be drawn *after* non transparent objects */ - void ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas ); + void ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas, + bool aAllowNonTransparentObjects, + bool aAllowTransparentObjects ); /** * function TransformPadsShapesWithClearanceToPolygon