From 63401f3d953e675fa9cd0f2e935ee353a10de364 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 8 Mar 2014 20:04:23 +0100 Subject: [PATCH] Rework on 3D viewer (work in progress): Disable or enable layers, grid or 3D footprint shapes should be now faster. --- 3d-viewer/3d_canvas.cpp | 27 +- 3d-viewer/3d_canvas.h | 64 +++- 3d-viewer/3d_draw.cpp | 349 ++++++++++++++++++---- 3d-viewer/3d_frame.cpp | 58 ++-- 3d-viewer/3d_toolbar.cpp | 21 +- 3d-viewer/3d_viewer.h | 6 +- 3d-viewer/info3d_visu.h | 1 - include/layers_id_colors_and_visibility.h | 31 +- pcbnew/dialogs/dialog_layers_setup.cpp | 10 +- pcbnew/dialogs/dialog_plot.cpp | 2 +- 10 files changed, 456 insertions(+), 113 deletions(-) diff --git a/3d-viewer/3d_canvas.cpp b/3d-viewer/3d_canvas.cpp index 1764d6faa0..db1ace2851 100644 --- a/3d-viewer/3d_canvas.cpp +++ b/3d-viewer/3d_canvas.cpp @@ -78,7 +78,11 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( EDA_3D_FRAME* parent, int* attribList ) : wxFULL_REPAINT_ON_RESIZE ) { m_init = false; - m_gllist = 0; + + // Clear all gl list identifiers: + for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ ) + m_glLists[ii] = 0; + // Explicitly create a new rendering context instance for this canvas. m_glRC = new wxGLContext( this ); @@ -94,12 +98,25 @@ EDA_3D_CANVAS::~EDA_3D_CANVAS() } -void EDA_3D_CANVAS::ClearLists() +void EDA_3D_CANVAS::ClearLists( GLuint aGlList ) { - if( m_gllist > 0 ) - glDeleteLists( m_gllist, 1 ); + if( aGlList ) + { + if( m_glLists[aGlList] > 0 ) + glDeleteLists( m_glLists[aGlList], 1 ); - m_gllist = 0; + m_glLists[aGlList] = 0; + + return; + } + + for( int ii = GL_ID_BEGIN; ii < GL_ID_END; ii++ ) + { + if( m_glLists[ii] > 0 ) + glDeleteLists( m_glLists[ii], 1 ); + + m_glLists[ii] = 0; + } } diff --git a/3d-viewer/3d_canvas.h b/3d-viewer/3d_canvas.h index cb931c991f..fa84fec602 100644 --- a/3d-viewer/3d_canvas.h +++ b/3d-viewer/3d_canvas.h @@ -50,14 +50,29 @@ class S3D_VERTEX; class SEGVIA; class D_PAD; +// We are using GL lists to store layers and other items +// to draw or not +// GL_LIST_ID are the GL lists indexes in m_glLists +enum GL_LIST_ID +{ + GL_ID_BEGIN = 0, + GL_ID_AXIS = GL_ID_BEGIN, // list id for 3D axis + GL_ID_GRID, // list id for 3D grid + GL_ID_BOARD, // List id for copper layers + GL_ID_TECH_LAYERS, // List id for non copper layers (masks...) + GL_ID_AUX_LAYERS, // List id for user layers (draw, eco, comment) + GL_ID_3DSHAPES_SOLID, // List id for 3D shapes, non transparent entities + GL_ID_3DSHAPES_TRANSP, // List id for 3D shapes, transparent entities + GL_ID_END +}; class EDA_3D_CANVAS : public wxGLCanvas { private: bool m_init; - GLuint m_gllist; + GLuint m_glLists[GL_ID_END]; // GL lists wxGLContext* m_glRC; - wxRealPoint m_draw3dOffset; // offset to draw the 3 mesh. + wxRealPoint m_draw3dOffset; // offset to draw the 3D mesh. double m_ZBottom; // position of the back layer double m_ZTop; // position of the front layer @@ -67,7 +82,15 @@ public: EDA_3D_FRAME* Parent() { return (EDA_3D_FRAME*)GetParent(); } - void ClearLists(); + BOARD* GetBoard() { return Parent()->GetBoard(); } + + /** + * Function ClearLists + * Clear the display list. + * @param aGlList = the list to clear. + * if 0 (default) all lists are cleared + */ + void ClearLists( GLuint aGlList = 0 ); // Event functions: void OnPaint( wxPaintEvent& event ); @@ -92,7 +115,7 @@ public: * Prepares the parameters of the OpenGL draw list * creates the OpenGL draw list items (board, grid ... */ - GLuint CreateDrawGL_List(); + void CreateDrawGL_List(); void InitGL(); void SetLights(); void SetOffset(double aPosX, double aPosY) @@ -104,11 +127,40 @@ public: /** * Function BuildBoard3DView * Called by CreateDrawGL_List() - * Fills the OpenGL draw list with board items draw list. + * Populates the OpenGL GL_ID_BOARD draw list with board items only on copper layers. + * 3D footprint shapes, tech layers and aux layers are not on this list */ void BuildBoard3DView(); - void DrawGrid( double aGriSizeMM ); + /** + * Function BuildTechLayers3DView + * Called by CreateDrawGL_List() + * Populates the OpenGL GL_ID_BOARD draw list with items on tech layers + */ + void BuildTechLayers3DView(); + + /** + * Function BuildFootprintShape3DList + * Called by CreateDrawGL_List() + * Fills the OpenGL GL_ID_3DSHAPES_SOLID and GL_ID_3DSHAPES_TRANSP + * draw lists with 3D footprint shapes + * @param aOpaqueList is the gl list for non transparent items + * @param aTransparentList is the gl list for non transparent items, + * which need to be drawn after all other items + */ + void BuildFootprintShape3DList( GLuint aOpaqueList, + GLuint aTransparentList); + /** + * Function BuildBoard3DAuxLayers + * Called by CreateDrawGL_List() + * Fills the OpenGL GL_ID_AUX_LAYERS draw list + * with items on aux layers only + */ + void BuildBoard3DAuxLayers(); + + void Draw3DGrid( double aGriSizeMM ); + void Draw3DAxis(); + void Draw3DViaHole( SEGVIA * aVia ); void Draw3DPadHole( D_PAD * aPad ); diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 909d15a4aa..991916294b 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -133,11 +133,45 @@ void EDA_3D_CANVAS::Redraw() glRotatef( g_Parm_3D_Visu.m_Rot[1], 0.0, 1.0, 0.0 ); glRotatef( g_Parm_3D_Visu.m_Rot[2], 0.0, 0.0, 1.0 ); - if( m_gllist ) - glCallList( m_gllist ); - else + if( ! m_glLists[GL_ID_BOARD] || ! m_glLists[GL_ID_TECH_LAYERS] ) CreateDrawGL_List(); + if( g_Parm_3D_Visu.GetFlag( FL_AXIS ) && m_glLists[GL_ID_AXIS] ) + glCallList( m_glLists[GL_ID_AXIS] ); + + // move the board in order to draw it with its center at 0,0 3D coordinates + glTranslatef( -g_Parm_3D_Visu.m_BoardPos.x * g_Parm_3D_Visu.m_BiuTo3Dunits, + -g_Parm_3D_Visu.m_BoardPos.y * g_Parm_3D_Visu.m_BiuTo3Dunits, + 0.0F ); + + + glCallList( m_glLists[GL_ID_BOARD] ); + glCallList( m_glLists[GL_ID_TECH_LAYERS] ); + + if( g_Parm_3D_Visu.GetFlag( FL_COMMENTS ) || g_Parm_3D_Visu.GetFlag( FL_COMMENTS ) ) + { + if( ! m_glLists[GL_ID_AUX_LAYERS] ) + CreateDrawGL_List(); + + glCallList( m_glLists[GL_ID_AUX_LAYERS] ); + } + + if( g_Parm_3D_Visu.GetFlag( FL_GRID ) && m_glLists[GL_ID_GRID] ) + glCallList( m_glLists[GL_ID_GRID] ); + + if( g_Parm_3D_Visu.GetFlag( FL_MODULE ) ) + { + if( ! m_glLists[GL_ID_3DSHAPES_SOLID] ) + CreateDrawGL_List(); + + glCallList( m_glLists[GL_ID_3DSHAPES_SOLID] ); + + // This list must be drawn last, because it contains the + // transparent gl objects, which should be drawn after all + // non tyransparent objects + glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP] ); + } + SwapBuffers(); } @@ -198,8 +232,7 @@ static inline void SetGLTechLayersColor( LAYER_NUM aLayer ) void EDA_3D_CANVAS::BuildBoard3DView() { - PCB_BASE_FRAME* pcbframe = Parent()->Parent(); - BOARD* pcb = pcbframe->GetBoard(); + BOARD* pcb = GetBoard(); bool realistic_mode = g_Parm_3D_Visu.IsRealisticMode(); // Number of segments to draw a circle using segments @@ -456,14 +489,74 @@ void EDA_3D_CANVAS::BuildBoard3DView() Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness/2, board_thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } +} + + +void EDA_3D_CANVAS::BuildTechLayers3DView() +{ + BOARD* pcb = GetBoard(); + + // Number of segments to draw a circle using segments + const int segcountforcircle = 16; + double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2) ); + const int segcountLowQuality = 12; // segments to draw a circle with low quality + // to reduce time calculations + // for holes and items which do not need + // a fine representation + + CPOLYGONS_LIST bufferPolys; + bufferPolys.reserve( 200000 ); // Reserve for large board (tracks mainly) + + CPOLYGONS_LIST allLayerHoles; // Contains through holes, calculated only once + allLayerHoles.reserve( 20000 ); + + CPOLYGONS_LIST bufferPcbOutlines; // stores the board main outlines + // Build a polygon from edge cut items + wxString msg; + if( ! pcb->GetBoardPolygonOutlines( bufferPcbOutlines, + allLayerHoles, &msg ) ) + { + msg << wxT("\n\n") << + _("Unable to calculate the board outlines.\n" + "Therefore use the board boundary box."); + 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() ) + { + // Add via hole + if( track->Type() == PCB_VIA_T ) + { + int shape = track->GetShape(); + int holediameter = track->GetDrillValue(); + int hole_outer_radius = (holediameter + thickness) / 2; + + if( shape == VIA_THROUGH ) + TransformCircleToPolygon( allLayerHoles, + track->GetStart(), hole_outer_radius, + segcountLowQuality ); + } + } + + + // draw graphic items, on technical layers - // draw graphic items, not on copper layers KI_POLYGON_SET brdpolysetHoles; allLayerHoles.ExportTo( brdpolysetHoles ); for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER; layer <= LAST_NON_COPPER_LAYER; layer++ ) { + // Skip user layers, which are not drawn here + if( IsUserLayer( layer) ) + continue; + if( !Is3DLayerEnabled( layer ) ) continue; @@ -481,9 +574,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() { case PCB_LINE_T: ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( - bufferPolys, 0, - segcountforcircle, - correctionFactor ); + bufferPolys, 0, segcountforcircle, correctionFactor ); break; case PCB_TEXT_T: @@ -556,10 +647,8 @@ void EDA_3D_CANVAS::BuildBoard3DView() currLayerPolyset += polyset; } - SetGLTechLayersColor( layer ); int thickness = g_Parm_3D_Visu.GetLayerObjectThicknessBIU( layer ); int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); - glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); if( layer == EDGE_N ) { @@ -582,38 +671,210 @@ void EDA_3D_CANVAS::BuildBoard3DView() bufferPolys.RemoveAllContours(); bufferPolys.ImportFrom( currLayerPolyset ); + + SetGLTechLayersColor( layer ); + glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } +} - // draw modules 3D shapes - if( g_Parm_3D_Visu.GetFlag( FL_MODULE ) ) +/** + * Function BuildBoard3DAuxLayers + * Called by CreateDrawGL_List() + * Fills the OpenGL GL_ID_BOARD draw list with items + * on aux layers only + */ +void EDA_3D_CANVAS::BuildBoard3DAuxLayers() +{ + const int segcountforcircle = 16; + double correctionFactor = 1.0 / cos( M_PI / (segcountforcircle * 2) ); + BOARD* pcb = GetBoard(); + CPOLYGONS_LIST bufferPolys; + bufferPolys.reserve( 5000 ); // Reserve for items not on board + + for( LAYER_NUM layer = FIRST_USER_LAYER; layer <= LAST_USER_LAYER; + layer++ ) { - for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) - module->ReadAndInsert3DComponentShape( this ); + if( !Is3DLayerEnabled( layer ) ) + continue; + + bufferPolys.RemoveAllContours(); + + for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() ) + { + if( !item->IsOnLayer( layer ) ) + continue; + + switch( item->Type() ) + { + case PCB_LINE_T: + ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( + bufferPolys, 0, segcountforcircle, correctionFactor ); + break; + + case PCB_TEXT_T: + ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( + bufferPolys, 0, segcountforcircle, correctionFactor ); + break; + + default: + break; + } + } + + for( MODULE* module = pcb->m_Modules; module != NULL; module = module->Next() ) + { + module->TransformPadsShapesWithClearanceToPolygon( layer, + bufferPolys, + 0, + segcountforcircle, + correctionFactor ); + + module->TransformGraphicShapesWithClearanceToPolygonSet( layer, + bufferPolys, + 0, + segcountforcircle, + correctionFactor ); + } + + // bufferPolys contains polygons to merge. Many overlaps . + // Calculate merged polygons and remove pads and vias holes + if( bufferPolys.GetCornersCount() == 0 ) + continue; + KI_POLYGON_SET currLayerPolyset; + KI_POLYGON_SET polyset; + bufferPolys.ExportTo( polyset ); + currLayerPolyset += polyset; + + int thickness = g_Parm_3D_Visu.GetLayerObjectThicknessBIU( layer ); + int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); + // for Draw3D_SolidHorizontalPolyPolygons, + // zpos it the middle between bottom and top sides. + // However for top layers, zpos should be the bottom layer pos, + // and for bottom layers, zpos should be the top layer pos. + if( Get3DLayer_Z_Orientation( layer ) > 0 ) + zpos += thickness/2; + else + zpos -= thickness/2 ; + + bufferPolys.RemoveAllContours(); + bufferPolys.ImportFrom( currLayerPolyset ); + + SetGLTechLayersColor( layer ); + glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); + Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, + thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } } - -GLuint EDA_3D_CANVAS::CreateDrawGL_List() +void EDA_3D_CANVAS::CreateDrawGL_List() { - PCB_BASE_FRAME* pcbframe = Parent()->Parent(); - BOARD* pcb = pcbframe->GetBoard(); + BOARD* pcb = GetBoard(); wxBusyCursor dummy; - m_gllist = glGenLists( 1 ); - // Build 3D board parameters: g_Parm_3D_Visu.InitSettings( pcb ); - glNewList( m_gllist, GL_COMPILE_AND_EXECUTE ); - glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); - // draw axis - if( g_Parm_3D_Visu.GetFlag( FL_AXIS ) ) + // Create axis gl list (if it is not shown, the list will be not called + Draw3DAxis(); + + // Create grid gl list + if( ! m_glLists[GL_ID_GRID] ) { + m_glLists[GL_ID_GRID] = glGenLists( 1 ); + glNewList( m_glLists[GL_ID_GRID], GL_COMPILE ); + + Draw3DGrid( g_Parm_3D_Visu.m_3D_Grid ); + glEndList(); + } + + // Create Board full gl lists: + +// For testing purpose only, display calculation time to generate 3D data +// #define PRINT_CALCULATION_TIME + +#ifdef PRINT_CALCULATION_TIME + unsigned strtime = GetRunningMicroSecs(); +#endif + + if( ! m_glLists[GL_ID_BOARD] ) + { + m_glLists[GL_ID_BOARD] = glGenLists( 1 ); + glNewList( m_glLists[GL_ID_BOARD], GL_COMPILE ); + BuildBoard3DView(); + glEndList(); + } + + if( ! m_glLists[GL_ID_TECH_LAYERS] ) + { + m_glLists[GL_ID_TECH_LAYERS] = glGenLists( 1 ); + glNewList( m_glLists[GL_ID_TECH_LAYERS], GL_COMPILE ); + BuildTechLayers3DView(); + glEndList(); + } + + if( ! m_glLists[GL_ID_AUX_LAYERS] ) + { + m_glLists[GL_ID_AUX_LAYERS] = glGenLists( 1 ); + glNewList( m_glLists[GL_ID_AUX_LAYERS], GL_COMPILE ); + BuildBoard3DAuxLayers(); + glEndList(); + } + + + // draw modules 3D shapes + if( ! m_glLists[GL_ID_3DSHAPES_SOLID] && g_Parm_3D_Visu.GetFlag( FL_MODULE ) ) + { + m_glLists[GL_ID_3DSHAPES_SOLID] = glGenLists( 1 ); + + // GL_ID_3DSHAPES_TRANSP is an auxiliary list for 3D shapes; + // Ensure it is cleared before rebuilding it + if( m_glLists[GL_ID_3DSHAPES_TRANSP] ) + glDeleteLists( m_glLists[GL_ID_3DSHAPES_TRANSP], 1 ); + + m_glLists[GL_ID_3DSHAPES_TRANSP] = glGenLists( 1 ); + BuildFootprintShape3DList( m_glLists[GL_ID_3DSHAPES_SOLID], + m_glLists[GL_ID_3DSHAPES_TRANSP] ); + } + + // Test for errors + CheckGLError(); + +#ifdef PRINT_CALCULATION_TIME + unsigned endtime = GetRunningMicroSecs(); + wxString msg; + msg.Printf( "Built data %.1f ms", (double) (endtime - strtime) / 1000 ); + Parent()->SetStatusText( msg, 0 ); +#endif +} + +void EDA_3D_CANVAS::BuildFootprintShape3DList( GLuint aOpaqueList, + GLuint aTransparentList) +{ + // aOpaqueList 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 + + BOARD* pcb = GetBoard(); + glNewList( m_glLists[GL_ID_3DSHAPES_SOLID], GL_COMPILE ); + + for( MODULE* module = pcb->m_Modules; module; module = module->Next() ) + module->ReadAndInsert3DComponentShape( this ); + + glEndList(); +} + +void EDA_3D_CANVAS::Draw3DAxis() +{ + if( ! m_glLists[GL_ID_AXIS] ) + { + m_glLists[GL_ID_AXIS] = glGenLists( 1 ); + glNewList( m_glLists[GL_ID_AXIS], GL_COMPILE ); + glEnable( GL_COLOR_MATERIAL ); SetGLColor( WHITE ); glBegin( GL_LINES ); @@ -626,46 +887,14 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() glVertex3f( 0.0f, 0.0f, 0.0f ); glVertex3f( 0.0f, 0.0f, 0.3f ); // Z axis glEnd(); + + glEndList(); } - - // move the board in order to draw it with its center at 0,0 3D coordinates - glTranslatef( -g_Parm_3D_Visu.m_BoardPos.x * g_Parm_3D_Visu.m_BiuTo3Dunits, - -g_Parm_3D_Visu.m_BoardPos.y * g_Parm_3D_Visu.m_BiuTo3Dunits, - 0.0F ); - - // Draw Board: -// For testing purpose only, display calculation time to generate 3D data -// #define PRINT_CALCULATION_TIME - -#ifdef PRINT_CALCULATION_TIME - unsigned strtime = GetRunningMicroSecs(); -#endif - - BuildBoard3DView(); - - // Draw grid - if( g_Parm_3D_Visu.GetFlag( FL_GRID ) ) - DrawGrid( g_Parm_3D_Visu.m_3D_Grid ); - - glEndList(); - - // Test for errors - CheckGLError(); - -#ifdef PRINT_CALCULATION_TIME - unsigned endtime = GetRunningMicroSecs(); - wxString msg; - msg.Printf( "Built data %.1f ms", (double) (endtime - strtime) / 1000 ); - Parent()->SetStatusText( msg, 0 ); -#endif - - return m_gllist; } - // draw a 3D grid: an horizontal grid (XY plane and Z = 0, // and a vertical grid (XZ plane and Y = 0) -void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) +void EDA_3D_CANVAS::Draw3DGrid( double aGriSizeMM ) { double zpos = 0.0; EDA_COLOR_T gridcolor = DARKGRAY; // Color of grid lines diff --git a/3d-viewer/3d_frame.cpp b/3d-viewer/3d_frame.cpp index 1b0561bb16..1afa6cb64e 100644 --- a/3d-viewer/3d_frame.cpp +++ b/3d-viewer/3d_frame.cpp @@ -45,6 +45,8 @@ static const wxString keyBgColor_Green( wxT( "BgColor_Green" ) ); static const wxString keyBgColor_Blue( wxT( "BgColor_Blue" ) ); static const wxString keyShowRealisticMode( wxT( "ShowRealisticMode" ) ); static const wxString keyShowAxis( wxT( "ShowAxis" ) ); +static const wxString keyShowGrid( wxT( "ShowGrid3D" ) ); +static const wxString keyShowGridSize( wxT( "Grid3DSize" ) ); static const wxString keyShowZones( wxT( "ShowZones" ) ); static const wxString keyShowFootprints( wxT( "ShowFootprints" ) ); static const wxString keyShowCopperThickness( wxT( "ShowCopperThickness" ) ); @@ -148,9 +150,9 @@ void EDA_3D_FRAME::GetSettings() { EDA_BASE_FRAME::LoadSettings(); - config->Read( keyBgColor_Red, &g_Parm_3D_Visu.m_BgColor.m_Red, 0.0 ); - config->Read( keyBgColor_Green, &g_Parm_3D_Visu.m_BgColor.m_Green, 0.0 ); - config->Read( keyBgColor_Blue, &g_Parm_3D_Visu.m_BgColor.m_Blue, 0.0 ); + config->Read( keyBgColor_Red, &prms.m_BgColor.m_Red, 0.0 ); + config->Read( keyBgColor_Green, &prms.m_BgColor.m_Green, 0.0 ); + config->Read( keyBgColor_Blue, &prms.m_BgColor.m_Blue, 0.0 ); bool tmp; config->Read( keyShowRealisticMode, &tmp, false ); @@ -159,6 +161,12 @@ void EDA_3D_FRAME::GetSettings() config->Read( keyShowAxis, &tmp, true ); prms.SetFlag( FL_AXIS, tmp ); + config->Read( keyShowGrid, &tmp, true ); + prms.SetFlag( FL_GRID, tmp ); + + config->Read( keyShowGridSize, &prms.m_3D_Grid, 10.0 ); + prms.SetFlag( FL_MODULE, tmp ); + config->Read( keyShowFootprints, &tmp, true ); prms.SetFlag( FL_MODULE, tmp ); @@ -201,12 +209,14 @@ void EDA_3D_FRAME::SaveSettings() EDA_BASE_FRAME::SaveSettings(); - config->Write( keyBgColor_Red, g_Parm_3D_Visu.m_BgColor.m_Red ); - config->Write( keyBgColor_Green, g_Parm_3D_Visu.m_BgColor.m_Green ); - config->Write( keyBgColor_Blue, g_Parm_3D_Visu.m_BgColor.m_Blue ); class INFO3D_VISU& prms = g_Parm_3D_Visu; + config->Write( keyBgColor_Red, prms.m_BgColor.m_Red ); + config->Write( keyBgColor_Green, prms.m_BgColor.m_Green ); + config->Write( keyBgColor_Blue, prms.m_BgColor.m_Blue ); config->Write( keyShowRealisticMode, prms.GetFlag( FL_USE_REALISTIC_MODE ) ); config->Write( keyShowAxis, prms.GetFlag( FL_AXIS ) ); + config->Write( keyShowGrid, prms.GetFlag( FL_GRID ) ); + config->Write( keyShowGridSize, prms.m_3D_Grid ); config->Write( keyShowFootprints, prms.GetFlag( FL_MODULE ) ); config->Write( keyShowCopperThickness, prms.GetFlag( FL_USE_COPPER_THICKNESS ) ); config->Write( keyShowZones, prms.GetFlag( FL_ZONE ) ); @@ -364,52 +374,52 @@ void EDA_3D_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_MENU3D_AXIS_ONOFF: g_Parm_3D_Visu.SetFlag( FL_AXIS, isChecked ); - NewDisplay(); + m_canvas->Refresh(); return; case ID_MENU3D_MODULE_ONOFF: g_Parm_3D_Visu.SetFlag( FL_MODULE, isChecked ); - NewDisplay(); + m_canvas->Refresh(); return; case ID_MENU3D_USE_COPPER_THICKNESS: g_Parm_3D_Visu.SetFlag( FL_USE_COPPER_THICKNESS, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_BOARD); return; case ID_MENU3D_ZONE_ONOFF: g_Parm_3D_Visu.SetFlag( FL_ZONE, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_BOARD); return; case ID_MENU3D_ADHESIVE_ONOFF: g_Parm_3D_Visu.SetFlag( FL_ADHESIVE, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_TECH_LAYERS); return; case ID_MENU3D_SILKSCREEN_ONOFF: g_Parm_3D_Visu.SetFlag( FL_SILKSCREEN, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_TECH_LAYERS); return; case ID_MENU3D_SOLDER_MASK_ONOFF: g_Parm_3D_Visu.SetFlag( FL_SOLDERMASK, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_TECH_LAYERS); return; case ID_MENU3D_SOLDER_PASTE_ONOFF: g_Parm_3D_Visu.SetFlag( FL_SOLDERPASTE, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_TECH_LAYERS); return; case ID_MENU3D_COMMENTS_ONOFF: g_Parm_3D_Visu.SetFlag( FL_COMMENTS, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_AUX_LAYERS); return; case ID_MENU3D_ECO_ONOFF: g_Parm_3D_Visu.SetFlag( FL_ECO, isChecked ); - NewDisplay(); + NewDisplay(GL_ID_AUX_LAYERS); return; default: @@ -434,7 +444,6 @@ void EDA_3D_FRAME::On3DGridSelection( wxCommandEvent& event ) GetMenuBar()->Check( ii, false ); } - switch( id ) { case ID_MENU3D_GRID_NOGRID: @@ -466,18 +475,17 @@ void EDA_3D_FRAME::On3DGridSelection( wxCommandEvent& event ) return; } - NewDisplay(); + NewDisplay( GL_ID_GRID ); } -void EDA_3D_FRAME::NewDisplay() +void EDA_3D_FRAME::NewDisplay( GLuint aGlList ) { m_reloadRequest = false; - m_canvas->ClearLists(); + m_canvas->ClearLists( aGlList ); m_canvas->CreateDrawGL_List(); -// m_canvas->InitGL(); m_canvas->Refresh( true ); m_canvas->DisplayStatus(); } @@ -507,6 +515,9 @@ void EDA_3D_FRAME::Set3DBgColor() newcolor = wxGetColourFromUser( this, oldcolor ); + if( ! newcolor.IsOk() ) // Happens on cancel dialog + return; + if( newcolor != oldcolor ) { g_Parm_3D_Visu.m_BgColor.m_Red = (double) newcolor.Red() / 255.0; @@ -515,3 +526,8 @@ void EDA_3D_FRAME::Set3DBgColor() NewDisplay(); } } + +BOARD* EDA_3D_FRAME::GetBoard() +{ + return Parent()->GetBoard(); +} diff --git a/3d-viewer/3d_toolbar.cpp b/3d-viewer/3d_toolbar.cpp index ed0e3eefbe..a1c7d2c90a 100644 --- a/3d-viewer/3d_toolbar.cpp +++ b/3d-viewer/3d_toolbar.cpp @@ -166,13 +166,22 @@ void EDA_3D_FRAME::CreateMenuBar() wxMenu * gridlistMenu = new wxMenu; AddMenuItem( prefsMenu, gridlistMenu, ID_MENU3D_GRID, _( "3D Grid" ), KiBitmap( grid_xpm ) ); - gridlistMenu->Append( ID_MENU3D_GRID_NOGRID, _( "No 3D Grid" ), wxEmptyString, true ); - gridlistMenu->Check( ID_MENU3D_GRID_NOGRID, true ); + gridlistMenu->Append( ID_MENU3D_GRID_NOGRID, _( "No 3D Grid" ), wxEmptyString, true ); + gridlistMenu->Append( ID_MENU3D_GRID_10_MM, _( "3D Grid 10 mm" ), wxEmptyString, true ); + gridlistMenu->Append( ID_MENU3D_GRID_5_MM, _( "3D Grid 5 mm" ), wxEmptyString, true ); + gridlistMenu->Append( ID_MENU3D_GRID_2P5_MM, _( "3D Grid 2.5 mm" ), wxEmptyString, true ); + gridlistMenu->Append( ID_MENU3D_GRID_1_MM, _( "3D Grid 1 mm" ), wxEmptyString, true ); - gridlistMenu->Append( ID_MENU3D_GRID_10_MM, _( "3D Grid 10 mm" ), wxEmptyString, true ); - gridlistMenu->Append( ID_MENU3D_GRID_5_MM, _( "3D Grid 5 mm" ), wxEmptyString, true ); - gridlistMenu->Append( ID_MENU3D_GRID_2P5_MM, _( "3D Grid 2.5 mm" ), wxEmptyString, true ); - gridlistMenu->Append( ID_MENU3D_GRID_1_MM, _( "3D Grid 1 mm" ), wxEmptyString, true ); + // If the grid is on, check the corresponding menuitem showing the grid size + if( g_Parm_3D_Visu.GetFlag( FL_GRID ) ) + { + gridlistMenu->Check( ID_MENU3D_GRID_10_MM, g_Parm_3D_Visu.m_3D_Grid == 10.0 ); + gridlistMenu->Check( ID_MENU3D_GRID_5_MM, g_Parm_3D_Visu.m_3D_Grid == 5.0 ); + gridlistMenu->Check( ID_MENU3D_GRID_2P5_MM, g_Parm_3D_Visu.m_3D_Grid == 2.5 ); + gridlistMenu->Check( ID_MENU3D_GRID_1_MM, g_Parm_3D_Visu.m_3D_Grid == 1.0 ); + } + else + gridlistMenu->Check( ID_MENU3D_GRID_NOGRID, true ); prefsMenu->AppendSeparator(); diff --git a/3d-viewer/3d_viewer.h b/3d-viewer/3d_viewer.h index dc94f933ef..a1645c1e81 100644 --- a/3d-viewer/3d_viewer.h +++ b/3d-viewer/3d_viewer.h @@ -78,6 +78,8 @@ public: PCB_BASE_FRAME* Parent() { return (PCB_BASE_FRAME*)GetParent(); } + BOARD* GetBoard(); + /** * Function ReloadRequest * must be called when reloading data from Pcbnew is needed @@ -93,8 +95,10 @@ public: * Function NewDisplay * Rebuild the display list. * must be called when 3D opengl data is modified + * @param aGlList = the list to rebuild. + * if 0 (default) all lists are rebuilt */ - void NewDisplay(); + void NewDisplay( GLuint aGlList = 0 ); void SetDefaultFileName(const wxString &aFn) { m_defaultFileName = aFn; } const wxString &GetDefaultFileName() const { return m_defaultFileName; } diff --git a/3d-viewer/info3d_visu.h b/3d-viewer/info3d_visu.h index 00acbbd226..7c7fe02918 100644 --- a/3d-viewer/info3d_visu.h +++ b/3d-viewer/info3d_visu.h @@ -74,7 +74,6 @@ enum DISPLAY3D_FLG { FL_LAST }; - class INFO3D_VISU { public: diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index 5df67215be..2137c5a1f0 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -63,6 +63,8 @@ typedef int LAYER_NUM; #define NB_COPPER_LAYERS (LAST_COPPER_LAYER - FIRST_COPPER_LAYER + 1) #define FIRST_NON_COPPER_LAYER 16 +#define FIRST_TECHNICAL_LAYER 16 +#define FIRST_USER_LAYER 24 #define ADHESIVE_N_BACK 16 #define ADHESIVE_N_FRONT 17 #define SOLDERPASTE_N_BACK 18 @@ -77,6 +79,8 @@ typedef int LAYER_NUM; #define ECO2_N 27 #define EDGE_N 28 #define LAST_NON_COPPER_LAYER 28 +#define LAST_TECHNICAL_LAYER 23 +#define LAST_USER_LAYER 27 #define NB_PCB_LAYERS (LAST_NON_COPPER_LAYER + 1) #define UNUSED_LAYER_29 29 #define UNUSED_LAYER_30 30 @@ -128,13 +132,16 @@ typedef unsigned LAYER_MSK; #define ALL_CU_LAYERS 0x0000FFFF #define INTERNAL_CU_LAYERS 0x00007FFE #define EXTERNAL_CU_LAYERS 0x00008001 -#define FRONT_AUX_LAYERS (SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT \ +#define FRONT_TECH_LAYERS (SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT \ | ADHESIVE_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT) -#define BACK_AUX_LAYERS (SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK \ +#define BACK_TECH_LAYERS (SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK \ | ADHESIVE_LAYER_BACK | SOLDERPASTE_LAYER_BACK) -#define ALL_AUX_LAYERS (FRONT_AUX_LAYERS | BACK_AUX_LAYERS) -#define BACK_LAYERS (LAYER_BACK | BACK_AUX_LAYERS) -#define FRONT_LAYERS (LAYER_FRONT | FRONT_AUX_LAYERS) +#define ALL_TECH_LAYERS (FRONT_TECH_LAYERS | BACK_TECH_LAYERS) +#define BACK_LAYERS (LAYER_BACK | BACK_TECH_LAYERS) +#define FRONT_LAYERS (LAYER_FRONT | FRONT_TECH_LAYERS) + +#define ALL_USER_LAYERS (DRAW_LAYER | COMMENT_LAYER |\ + ECO1_LAYER | ECO2_LAYER ) #define NO_LAYERS 0x00000000 @@ -329,8 +336,18 @@ inline bool IsCopperLayer( LAYER_NUM aLayer ) */ inline bool IsNonCopperLayer( LAYER_NUM aLayer ) { - return aLayer >= FIRST_NON_COPPER_LAYER - && aLayer <= LAST_NON_COPPER_LAYER; + return aLayer >= FIRST_NON_COPPER_LAYER && aLayer <= LAST_NON_COPPER_LAYER; +} + +/** + * Function IsUserLayer + * tests whether a layer is a non copper and a non tech layer + * @param aLayer = Layer to test + * @return true if aLayer is a user layer + */ +inline bool IsUserLayer( LAYER_NUM aLayer ) +{ + return aLayer >= FIRST_USER_LAYER && aLayer <= LAST_USER_LAYER; } /* IMPORTANT: If a layer is not a front layer not necessarily is true diff --git a/pcbnew/dialogs/dialog_layers_setup.cpp b/pcbnew/dialogs/dialog_layers_setup.cpp index fc26fe399e..82b76e6c63 100644 --- a/pcbnew/dialogs/dialog_layers_setup.cpp +++ b/pcbnew/dialogs/dialog_layers_setup.cpp @@ -176,19 +176,19 @@ static const LAYER_MSK presets[] = NO_LAYERS, // shift the array index up by one, matches with "Custom". // "Two layers, parts on Front only" - EDGE_LAYER | LAYER_FRONT | LAYER_BACK | FRONT_AUX_LAYERS, + EDGE_LAYER | LAYER_FRONT | LAYER_BACK | FRONT_TECH_LAYERS, // "Two layers, parts on Back only", - EDGE_LAYER | LAYER_FRONT | LAYER_BACK | BACK_AUX_LAYERS, + EDGE_LAYER | LAYER_FRONT | LAYER_BACK | BACK_TECH_LAYERS, // "Two layers, parts on Front and Back", - EDGE_LAYER | LAYER_FRONT | LAYER_BACK | ALL_AUX_LAYERS, + EDGE_LAYER | LAYER_FRONT | LAYER_BACK | ALL_TECH_LAYERS, // "Four layers, parts on Front only" - EDGE_LAYER | LAYER_FRONT | LAYER_BACK | LAYER_2 | LAYER_3 | FRONT_AUX_LAYERS, + EDGE_LAYER | LAYER_FRONT | LAYER_BACK | LAYER_2 | LAYER_3 | FRONT_TECH_LAYERS, // "Four layers, parts on Front and Back" - EDGE_LAYER | LAYER_FRONT | LAYER_BACK | LAYER_2 | LAYER_3 | ALL_AUX_LAYERS, + EDGE_LAYER | LAYER_FRONT | LAYER_BACK | LAYER_2 | LAYER_3 | ALL_TECH_LAYERS, // "All layers on", ALL_LAYERS, diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index bc13af8558..4da92e068d 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -246,7 +246,7 @@ void DIALOG_PLOT::OnPopUpLayers( wxCommandEvent& event ) for( i = 0; i < m_layerList.size(); i++ ) { LAYER_MSK layermask = GetLayerMask( m_layerList[ i ] ); - if( layermask & ( ALL_CU_LAYERS | ALL_AUX_LAYERS ) ) + if( layermask & ( ALL_CU_LAYERS | ALL_TECH_LAYERS ) ) m_layerCheckListBox->Check( i, true ); else m_layerCheckListBox->Check( i, false );