Rework on 3D viewer (work in progress): Disable or enable layers, grid or 3D footprint shapes should be now faster.
This commit is contained in:
parent
c89d52ee1a
commit
63401f3d95
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -167,13 +167,22 @@ void EDA_3D_FRAME::CreateMenuBar()
|
|||
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_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();
|
||||
|
||||
AddMenuItem( prefsMenu, ID_MENU3D_SHOW_BOARD_BODY,
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -74,7 +74,6 @@ enum DISPLAY3D_FLG {
|
|||
FL_LAST
|
||||
};
|
||||
|
||||
|
||||
class INFO3D_VISU
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue