3D-Viewer: render different materials plated and non plated copper

implement on OpenGL
This commit is contained in:
Mario Luzeiro 2020-09-06 20:09:43 +01:00 committed by Jon Evans
parent 3544bc09fd
commit 1ab968e72f
9 changed files with 323 additions and 83 deletions

View File

@ -119,6 +119,12 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_SilkScreenColorTop = SFVEC4F( 0.9, 0.9, 0.9, 1.0 ); m_SilkScreenColorTop = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
m_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 1.0 ); m_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 1.0 );
m_CopperColor = SFVEC4F( 0.75, 0.61, 0.23, 1.0 ); m_CopperColor = SFVEC4F( 0.75, 0.61, 0.23, 1.0 );
m_platedpads_container2D_F_Cu = nullptr;
m_platedpads_container2D_B_Cu = nullptr;
m_F_Cu_PlatedPads_poly = nullptr;
m_B_Cu_PlatedPads_poly = nullptr;
} }

View File

@ -362,6 +362,16 @@ class BOARD_ADAPTER
return m_layers_container2D; return m_layers_container2D;
} }
const CBVHCONTAINER2D* GetPlatedPads_Front() const noexcept
{
return m_platedpads_container2D_F_Cu;
}
const CBVHCONTAINER2D* GetPlatedPads_Back() const noexcept
{
return m_platedpads_container2D_B_Cu;
}
/** /**
* @brief GetMapLayersHoles -Get the map of container that have the holes per layer * @brief GetMapLayersHoles -Get the map of container that have the holes per layer
* @return the map containers of holes from this board * @return the map containers of holes from this board
@ -536,6 +546,16 @@ class BOARD_ADAPTER
return m_layers_poly; return m_layers_poly;
} }
const SHAPE_POLY_SET *GetPolyPlatedPads_Front()
{
return m_F_Cu_PlatedPads_poly;
}
const SHAPE_POLY_SET *GetPolyPlatedPads_Back()
{
return m_B_Cu_PlatedPads_poly;
}
const MAP_POLY &GetPolyMapHoles_Inner() const noexcept const MAP_POLY &GetPolyMapHoles_Inner() const noexcept
{ {
return m_layers_inner_holes_poly; return m_layers_inner_holes_poly;
@ -571,7 +591,9 @@ class BOARD_ADAPTER
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
PCB_LAYER_ID aLayerId, PCB_LAYER_ID aLayerId,
int aInflateValue, int aInflateValue,
bool aSkipNPTHPadsWihNoCopper ); bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads );
void AddGraphicsShapesWithClearanceToContainer( const MODULE *aModule, void AddGraphicsShapesWithClearanceToContainer( const MODULE *aModule,
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
@ -685,6 +707,9 @@ private:
/// It contains polygon contours for each layer /// It contains polygon contours for each layer
MAP_POLY m_layers_poly; MAP_POLY m_layers_poly;
SHAPE_POLY_SET* m_F_Cu_PlatedPads_poly;
SHAPE_POLY_SET* m_B_Cu_PlatedPads_poly;
/// It contains polygon contours for holes of each layer (outer holes) /// It contains polygon contours for holes of each layer (outer holes)
MAP_POLY m_layers_outer_holes_poly; MAP_POLY m_layers_outer_holes_poly;
@ -712,6 +737,9 @@ private:
/// It contains the 2d elements of each layer /// It contains the 2d elements of each layer
MAP_CONTAINER_2D m_layers_container2D; MAP_CONTAINER_2D m_layers_container2D;
CBVHCONTAINER2D* m_platedpads_container2D_F_Cu;
CBVHCONTAINER2D* m_platedpads_container2D_B_Cu;
/// It contains the holes per each layer /// It contains the holes per each layer
MAP_CONTAINER_2D m_layers_holes2D; MAP_CONTAINER_2D m_layers_holes2D;

View File

@ -459,7 +459,9 @@ void BOARD_ADAPTER::AddPadsShapesWithClearanceToContainer( const MODULE* aModule
CGENERICCONTAINER2D *aDstContainer, CGENERICCONTAINER2D *aDstContainer,
PCB_LAYER_ID aLayerId, PCB_LAYER_ID aLayerId,
int aInflateValue, int aInflateValue,
bool aSkipNPTHPadsWihNoCopper ) bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads )
{ {
for( D_PAD* pad : aModule->Pads() ) for( D_PAD* pad : aModule->Pads() )
{ {
@ -495,6 +497,15 @@ void BOARD_ADAPTER::AddPadsShapesWithClearanceToContainer( const MODULE* aModule
} }
} }
const bool isPlated = ( ( aLayerId == F_Cu ) && pad->IsPadOnLayer( F_Mask ) ) ||
( ( aLayerId == B_Cu ) && pad->IsPadOnLayer( B_Mask ) );
if( aSkipPlatedPads && isPlated )
continue;
if( aSkipNonPlatedPads && !isPlated )
continue;
wxSize margin( aInflateValue, aInflateValue ); wxSize margin( aInflateValue, aInflateValue );
switch( aLayerId ) switch( aLayerId )

View File

@ -63,6 +63,9 @@ void BOARD_ADAPTER::destroyLayers()
m_layers_poly.clear(); m_layers_poly.clear();
} }
delete m_F_Cu_PlatedPads_poly;
delete m_B_Cu_PlatedPads_poly;
if( !m_layers_inner_holes_poly.empty() ) if( !m_layers_inner_holes_poly.empty() )
{ {
for( auto& poly : m_layers_inner_holes_poly ) for( auto& poly : m_layers_inner_holes_poly )
@ -87,6 +90,9 @@ void BOARD_ADAPTER::destroyLayers()
m_layers_container2D.clear(); m_layers_container2D.clear();
} }
delete m_platedpads_container2D_F_Cu;
delete m_platedpads_container2D_B_Cu;
if( !m_layers_holes2D.empty() ) if( !m_layers_holes2D.empty() )
{ {
for( auto& poly : m_layers_holes2D ) for( auto& poly : m_layers_holes2D )
@ -197,6 +203,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
} }
} }
m_F_Cu_PlatedPads_poly = new SHAPE_POLY_SET;
m_B_Cu_PlatedPads_poly = new SHAPE_POLY_SET;
m_platedpads_container2D_F_Cu = new CBVHCONTAINER2D;
m_platedpads_container2D_B_Cu = new CBVHCONTAINER2D;
if( aStatusReporter ) if( aStatusReporter )
aStatusReporter->Report( _( "Create tracks and vias" ) ); aStatusReporter->Report( _( "Create tracks and vias" ) );
@ -512,7 +524,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
layerContainer, layerContainer,
curr_layer_id, curr_layer_id,
0, 0,
true ); true,
true,
false );
// Micro-wave modules may have items on copper layers // Micro-wave modules may have items on copper layers
AddGraphicsShapesWithClearanceToContainer( module, AddGraphicsShapesWithClearanceToContainer( module,
@ -522,6 +536,26 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
} }
} }
// ADD PLATED PADS
for( MODULE* module : m_board->Modules() )
{
AddPadsShapesWithClearanceToContainer( module,
m_platedpads_container2D_F_Cu,
F_Cu,
0,
true,
false,
true );
AddPadsShapesWithClearanceToContainer( module,
m_platedpads_container2D_B_Cu,
B_Cu,
0,
true,
false,
true );
}
// Add modules PADs poly contourns (vertical outlines) // Add modules PADs poly contourns (vertical outlines)
if( GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS ) if( GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS )
&& ( m_render_engine == RENDER_ENGINE::OPENGL_LEGACY ) ) && ( m_render_engine == RENDER_ENGINE::OPENGL_LEGACY ) )
@ -538,13 +572,31 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// Note: NPTH pads are not drawn on copper layers when the pad // Note: NPTH pads are not drawn on copper layers when the pad
// has same shape as its hole // has same shape as its hole
module->TransformPadsShapesWithClearanceToPolygon( curr_layer_id, *layerPoly, module->TransformPadsShapesWithClearanceToPolygon( curr_layer_id, *layerPoly,
0, ARC_HIGH_DEF, true ); 0, ARC_HIGH_DEF, true,
true, false );
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly ); transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
} }
} }
// ADD PLATED PADS contourns
for( auto module : m_board->Modules() )
{
module->TransformPadsShapesWithClearanceToPolygon( F_Cu, *m_F_Cu_PlatedPads_poly,
0, ARC_HIGH_DEF, true,
false, true );
//transformGraphicModuleEdgeToPolygonSet( module, F_Cu, *m_F_Cu_PlatedPads_poly );
module->TransformPadsShapesWithClearanceToPolygon( B_Cu, *m_B_Cu_PlatedPads_poly,
0, ARC_HIGH_DEF, true,
false, true );
//transformGraphicModuleEdgeToPolygonSet( module, B_Cu, *m_B_Cu_PlatedPads_poly );
}
} }
// Add graphic item on copper layers to object containers // Add graphic item on copper layers to object containers
for( PCB_LAYER_ID curr_layer_id : layer_id ) for( PCB_LAYER_ID curr_layer_id : layer_id )
{ {
@ -735,6 +787,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
while( threadsFinished < parallelThreadCount ) while( threadsFinished < parallelThreadCount )
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
if( m_F_Cu_PlatedPads_poly )
m_F_Cu_PlatedPads_poly->Simplify( SHAPE_POLY_SET::PM_FAST );
if( m_B_Cu_PlatedPads_poly )
m_B_Cu_PlatedPads_poly->Simplify( SHAPE_POLY_SET::PM_FAST );
} }
// Simplify holes polygon contours // Simplify holes polygon contours
@ -884,6 +942,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
else else
{ {
AddPadsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0, AddPadsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0,
false,
false,
false ); false );
} }

View File

@ -334,6 +334,84 @@ CLAYERS_OGL_DISP_LISTS *C3D_RENDER_OGL_LEGACY::generate_holes_display_list(
} }
CLAYERS_OGL_DISP_LISTS* C3D_RENDER_OGL_LEGACY::generateLayerListFromContainer( const CBVHCONTAINER2D *aContainer,
const SHAPE_POLY_SET *aPolyList,
PCB_LAYER_ID aLayerId )
{
if( aContainer == nullptr )
return nullptr;
const LIST_OBJECT2D &listObject2d = aContainer->GetList();
if( listObject2d.size() == 0 )
return nullptr;
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
get_layer_z_pos( aLayerId, layer_z_top, layer_z_bot );
// Calculate an estimation for the nr of triangles based on the nr of objects
unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
CLAYER_TRIANGLES *layerTriangles = new CLAYER_TRIANGLES( nrTrianglesEstimation );
// store in a list so it will be latter deleted
m_triangles.push_back( layerTriangles );
// Load the 2D (X,Y axis) component of shapes
for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin();
itemOnLayer != listObject2d.end();
++itemOnLayer )
{
const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
switch( object2d_A->GetObjectType() )
{
case OBJECT2D_TYPE::FILLED_CIRCLE:
add_object_to_triangle_layer( (const CFILLEDCIRCLE2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::POLYGON4PT:
add_object_to_triangle_layer( (const CPOLYGON4PTS2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::RING:
add_object_to_triangle_layer( (const CRING2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::TRIANGLE:
add_object_to_triangle_layer( (const CTRIANGLE2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::ROUNDSEG:
add_object_to_triangle_layer( (const CROUNDSEGMENT2D *) object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
default:
wxFAIL_MSG("C3D_RENDER_OGL_LEGACY: Object type is not implemented");
break;
}
}
if( aPolyList )
if( aPolyList->OutlineCount() > 0 )
layerTriangles->AddToMiddleContourns( *aPolyList, layer_z_bot, layer_z_top,
m_boardAdapter.BiuTo3Dunits(), false );
// Create display list
// /////////////////////////////////////////////////////////////////////
return new CLAYERS_OGL_DISP_LISTS( *layerTriangles,
m_ogl_circle_texture,
layer_z_bot,
layer_z_top );
}
void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ) void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter )
{ {
m_reloadRequested = false; m_reloadRequested = false;
@ -516,6 +594,8 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
if( aStatusReporter ) if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: layers" ) ); aStatusReporter->Report( _( "Load OpenGL: layers" ) );
const MAP_POLY &map_poly = m_boardAdapter.GetPolyMap();
for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin(); for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
ii != m_boardAdapter.GetMapLayers().end(); ii != m_boardAdapter.GetMapLayers().end();
++ii ) ++ii )
@ -526,82 +606,26 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
continue; continue;
const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second); const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second);
const LIST_OBJECT2D &listObject2d = container2d->GetList();
if( listObject2d.size() == 0 ) // Load the vertical (Z axis) component of shapes
continue; const SHAPE_POLY_SET *aPolyList = nullptr;
float layer_z_bot = 0.0f;
float layer_z_top = 0.0f;
get_layer_z_pos( layer_id, layer_z_top, layer_z_bot );
// Calculate an estimation for the nr of triangles based on the nr of objects
unsigned int nrTrianglesEstimation = listObject2d.size() * 8;
CLAYER_TRIANGLES *layerTriangles = new CLAYER_TRIANGLES( nrTrianglesEstimation );
m_triangles[layer_id] = layerTriangles;
// Load the 2D (X,Y axis) component of shapes
for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin();
itemOnLayer != listObject2d.end();
++itemOnLayer )
{
const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
switch( object2d_A->GetObjectType() )
{
case OBJECT2D_TYPE::FILLED_CIRCLE:
add_object_to_triangle_layer( (const CFILLEDCIRCLE2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::POLYGON4PT:
add_object_to_triangle_layer( (const CPOLYGON4PTS2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::RING:
add_object_to_triangle_layer( (const CRING2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::TRIANGLE:
add_object_to_triangle_layer( (const CTRIANGLE2D *)object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
case OBJECT2D_TYPE::ROUNDSEG:
add_object_to_triangle_layer( (const CROUNDSEGMENT2D *) object2d_A,
layerTriangles, layer_z_top, layer_z_bot );
break;
default:
wxFAIL_MSG("C3D_RENDER_OGL_LEGACY: Object type is not implemented");
break;
}
}
const MAP_POLY &map_poly = m_boardAdapter.GetPolyMap();
// Load the vertical (Z axis) component of shapes
if( map_poly.find( layer_id ) != map_poly.end() ) if( map_poly.find( layer_id ) != map_poly.end() )
{ {
const SHAPE_POLY_SET *polyList = map_poly.at( layer_id ); aPolyList = map_poly.at( layer_id );
if( polyList->OutlineCount() > 0 )
layerTriangles->AddToMiddleContourns( *polyList, layer_z_bot, layer_z_top,
m_boardAdapter.BiuTo3Dunits(), false );
} }
// Create display list CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer( container2d, aPolyList, layer_id );
// /////////////////////////////////////////////////////////////////////
m_ogl_disp_lists_layers[layer_id] = new CLAYERS_OGL_DISP_LISTS( *layerTriangles, if( oglList != nullptr )
m_ogl_circle_texture, m_ogl_disp_lists_layers[layer_id] = oglList;
layer_z_bot,
layer_z_top ); }// for each layer on
}// for each layer on map
m_ogl_disp_lists_platedPads_F_Cu = generateLayerListFromContainer( m_boardAdapter.GetPlatedPads_Front(),
m_boardAdapter.GetPolyPlatedPads_Front(), F_Cu );
m_ogl_disp_lists_platedPads_B_Cu = generateLayerListFromContainer( m_boardAdapter.GetPlatedPads_Back(),
m_boardAdapter.GetPolyPlatedPads_Back(), B_Cu );
// Load 3D models // Load 3D models
// ///////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////

View File

@ -60,6 +60,9 @@ C3D_RENDER_OGL_LEGACY::C3D_RENDER_OGL_LEGACY( BOARD_ADAPTER& aAdapter, CCAMERA&
m_triangles.clear(); m_triangles.clear();
m_ogl_disp_list_board = NULL; m_ogl_disp_list_board = NULL;
m_ogl_disp_lists_platedPads_F_Cu = nullptr;
m_ogl_disp_lists_platedPads_B_Cu = nullptr;
m_ogl_disp_list_through_holes_outer_with_npth = NULL; m_ogl_disp_list_through_holes_outer_with_npth = NULL;
m_ogl_disp_list_through_holes_outer = NULL; m_ogl_disp_list_through_holes_outer = NULL;
m_ogl_disp_list_through_holes_vias_outer = NULL; m_ogl_disp_list_through_holes_vias_outer = NULL;
@ -186,6 +189,7 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
{ {
// http://devernay.free.fr/cours/opengl/materials.html // http://devernay.free.fr/cours/opengl/materials.html
// Plated copper
// Copper material mixed with the copper color // Copper material mixed with the copper color
m_materials.m_Copper.m_Ambient = SFVEC3F( m_boardAdapter.m_CopperColor.r * 0.1f, m_materials.m_Copper.m_Ambient = SFVEC3F( m_boardAdapter.m_CopperColor.r * 0.1f,
m_boardAdapter.m_CopperColor.g * 0.1f, m_boardAdapter.m_CopperColor.g * 0.1f,
@ -206,6 +210,13 @@ void C3D_RENDER_OGL_LEGACY::setupMaterials()
m_materials.m_Copper.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f ); m_materials.m_Copper.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
// Non plated copper (raw copper)
m_materials.m_NonPlatedCopper.m_Ambient = SFVEC3F( 0.191f, 0.073f, 0.022f );
m_materials.m_NonPlatedCopper.m_Diffuse = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
m_materials.m_NonPlatedCopper.m_Specular = SFVEC3F( 0.256f, 0.137f, 0.086f );
m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f;
m_materials.m_NonPlatedCopper.m_Emissive = SFVEC3F( 0.0f, 0.0f, 0.0f );
// Paste material mixed with paste color // Paste material mixed with paste color
m_materials.m_Paste.m_Ambient = SFVEC3F( m_boardAdapter.m_SolderPasteColor.r, m_materials.m_Paste.m_Ambient = SFVEC3F( m_boardAdapter.m_SolderPasteColor.r,
m_boardAdapter.m_SolderPasteColor.g, m_boardAdapter.m_SolderPasteColor.g,
@ -496,6 +507,22 @@ void init_lights(void)
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE ); glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
} }
void C3D_RENDER_OGL_LEGACY::setCopperMaterial()
{
OGL_SetMaterial( m_materials.m_NonPlatedCopper, 1.0f );
}
void C3D_RENDER_OGL_LEGACY::setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id )
{
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( -1.0f, -1.0f );
set_layer_material( aLayer_id );
}
void C3D_RENDER_OGL_LEGACY::unsetDepthOffset()
{
glDisable( GL_POLYGON_OFFSET_FILL );
}
void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles ) void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles )
{ {
@ -703,13 +730,28 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second); CLAYERS_OGL_DISP_LISTS *pLayerDispList = static_cast<CLAYERS_OGL_DISP_LISTS*>(ii->second);
set_layer_material( layer_id );
if( (layer_id >= F_Cu) && (layer_id <= B_Cu) ) if( (layer_id >= F_Cu) && (layer_id <= B_Cu) )
{ {
setCopperMaterial();
if( skipRenderHoles ) if( skipRenderHoles )
{ {
pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments ); pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_ogl_disp_lists_platedPads_F_Cu || m_ogl_disp_lists_platedPads_B_Cu ) )
setPlatedCopperAndDepthOffset( layer_id );
if( ( layer_id == F_Cu ) && m_ogl_disp_lists_platedPads_F_Cu )
m_ogl_disp_lists_platedPads_F_Cu->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
else
if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu )
m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments );
unsetDepthOffset();
} }
else else
{ {
@ -732,6 +774,26 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
m_ogl_disp_list_through_holes_outer, m_ogl_disp_list_through_holes_outer,
viasHolesLayer, viasHolesLayer,
drawMiddleSegments ); drawMiddleSegments );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_ogl_disp_lists_platedPads_F_Cu || m_ogl_disp_lists_platedPads_B_Cu ) )
setPlatedCopperAndDepthOffset( layer_id );
if( ( layer_id == F_Cu ) && m_ogl_disp_lists_platedPads_F_Cu )
m_ogl_disp_lists_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer,
viasHolesLayer,
drawMiddleSegments );
else
if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu )
m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer,
viasHolesLayer,
drawMiddleSegments );
unsetDepthOffset();
} }
} }
else else
@ -740,11 +802,33 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
m_ogl_disp_list_through_holes_outer, m_ogl_disp_list_through_holes_outer,
NULL, NULL,
drawMiddleSegments ); drawMiddleSegments );
// Draw copper plated pads
if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) &&
( m_ogl_disp_lists_platedPads_F_Cu || m_ogl_disp_lists_platedPads_B_Cu ) )
setPlatedCopperAndDepthOffset( layer_id );
if( ( layer_id == F_Cu ) && m_ogl_disp_lists_platedPads_F_Cu )
m_ogl_disp_lists_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer,
NULL,
drawMiddleSegments );
else
if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu )
m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer(
m_ogl_disp_list_through_holes_outer,
NULL,
drawMiddleSegments );
unsetDepthOffset();
} }
} }
} }
else else
{ {
set_layer_material( layer_id );
CLAYERS_OGL_DISP_LISTS* dispListThoughHolesOuter = CLAYERS_OGL_DISP_LISTS* dispListThoughHolesOuter =
( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) ( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS )
&& ( ( layer_id == B_SilkS ) || ( layer_id == F_SilkS ) ) ) ? && ( ( layer_id == B_SilkS ) || ( layer_id == F_SilkS ) ) ) ?
@ -997,6 +1081,8 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
m_ogl_disp_lists_layers.clear(); m_ogl_disp_lists_layers.clear();
delete m_ogl_disp_lists_platedPads_F_Cu;
delete m_ogl_disp_lists_platedPads_B_Cu;
for( MAP_OGL_DISP_LISTS::const_iterator ii = m_ogl_disp_lists_layers_holes_outer.begin(); for( MAP_OGL_DISP_LISTS::const_iterator ii = m_ogl_disp_lists_layers_holes_outer.begin();
ii != m_ogl_disp_lists_layers_holes_outer.end(); ii != m_ogl_disp_lists_layers_holes_outer.end();
@ -1019,12 +1105,11 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists()
m_ogl_disp_lists_layers_holes_inner.clear(); m_ogl_disp_lists_layers_holes_inner.clear();
for( MAP_TRIANGLES::const_iterator ii = m_triangles.begin(); for( LIST_TRIANGLES::const_iterator ii = m_triangles.begin();
ii != m_triangles.end(); ii != m_triangles.end();
++ii ) ++ii )
{ {
CLAYER_TRIANGLES *pointer = static_cast<CLAYER_TRIANGLES*>(ii->second); delete *ii;
delete pointer;
} }
m_triangles.clear(); m_triangles.clear();

View File

@ -48,7 +48,7 @@
typedef std::map< PCB_LAYER_ID, CLAYERS_OGL_DISP_LISTS* > MAP_OGL_DISP_LISTS; typedef std::map< PCB_LAYER_ID, CLAYERS_OGL_DISP_LISTS* > MAP_OGL_DISP_LISTS;
typedef std::map< PCB_LAYER_ID, CLAYER_TRIANGLES * > MAP_TRIANGLES; typedef std::list<CLAYER_TRIANGLES * > LIST_TRIANGLES;
typedef std::map< wxString, C_OGL_3DMODEL * > MAP_3DMODEL; typedef std::map< wxString, C_OGL_3DMODEL * > MAP_3DMODEL;
#define SIZE_OF_CIRCLE_TEXTURE 1024 #define SIZE_OF_CIRCLE_TEXTURE 1024
@ -77,6 +77,8 @@ private:
void ogl_free_all_display_lists(); void ogl_free_all_display_lists();
MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers; MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers;
CLAYERS_OGL_DISP_LISTS* m_ogl_disp_lists_platedPads_F_Cu;
CLAYERS_OGL_DISP_LISTS* m_ogl_disp_lists_platedPads_B_Cu;
MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_outer; MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_outer;
MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_inner; MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_inner;
CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_board; CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_board;
@ -93,7 +95,7 @@ private:
//CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_vias_and_pad_holes_inner_contourn_and_caps; //CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_vias_and_pad_holes_inner_contourn_and_caps;
CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_vias_and_pad_holes_outer_contourn_and_caps; CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_vias_and_pad_holes_outer_contourn_and_caps;
MAP_TRIANGLES m_triangles; LIST_TRIANGLES m_triangles; // store pointers so can be deleted latter
GLuint m_ogl_circle_texture; GLuint m_ogl_circle_texture;
@ -113,6 +115,10 @@ private:
float aZbot, float aZbot,
bool aInvertFaces ); bool aInvertFaces );
CLAYERS_OGL_DISP_LISTS* generateLayerListFromContainer( const CBVHCONTAINER2D *aContainer,
const SHAPE_POLY_SET *aPolyList,
PCB_LAYER_ID aLayerId );
void add_triangle_top_bot( CLAYER_TRIANGLES *aDst, void add_triangle_top_bot( CLAYER_TRIANGLES *aDst,
const SFVEC2F &v0, const SFVEC2F &v0,
const SFVEC2F &v1, const SFVEC2F &v1,
@ -197,6 +203,10 @@ private:
// Materials // Materials
void setupMaterials(); void setupMaterials();
void setCopperMaterial();
void setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id );
void unsetDepthOffset();
struct struct
{ {
SMATERIAL m_Paste; SMATERIAL m_Paste;
@ -204,6 +214,7 @@ private:
SMATERIAL m_SilkSTop; SMATERIAL m_SilkSTop;
SMATERIAL m_SolderMask; SMATERIAL m_SolderMask;
SMATERIAL m_EpoxyBoard; SMATERIAL m_EpoxyBoard;
SMATERIAL m_NonPlatedCopper; // raw copper
SMATERIAL m_Copper; SMATERIAL m_Copper;
SMATERIAL m_Plastic; SMATERIAL m_Plastic;
SMATERIAL m_GrayMaterial; SMATERIAL m_GrayMaterial;

View File

@ -118,7 +118,9 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer, void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue, int aMaxError, int aInflateValue, int aMaxError,
bool aSkipNPTHPadsWihNoCopper ) const bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads ) const
{ {
for( D_PAD* pad : m_pads ) for( D_PAD* pad : m_pads )
{ {
@ -152,6 +154,15 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
} }
} }
const bool isPlated = ( ( aLayer == F_Cu ) && pad->IsPadOnLayer( F_Mask ) ) ||
( ( aLayer == B_Cu ) && pad->IsPadOnLayer( B_Mask ) );
if( aSkipPlatedPads && isPlated )
continue;
if( aSkipNonPlatedPads && !isPlated )
continue;
wxSize clearance( aInflateValue, aInflateValue ); wxSize clearance( aInflateValue, aInflateValue );
switch( aLayer ) switch( aLayer )

View File

@ -369,10 +369,14 @@ public:
* Due to diff between layers and holes, these pads must be skipped to be sure * Due to diff between layers and holes, these pads must be skipped to be sure
* there is no copper left on the board (for instance when creating Gerber Files or * there is no copper left on the board (for instance when creating Gerber Files or
* 3D shapes). Defaults to false. * 3D shapes). Defaults to false.
* @param aSkipPlatedPads = used on 3D-Viewer to extract plated and nontplated pads.
* @param aSkipNonPlatedPads = used on 3D-Viewer to extract plated and plated pads.
*/ */
void TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer, void TransformPadsShapesWithClearanceToPolygon(PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aMaxError = ARC_HIGH_DEF, SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aMaxError = ARC_HIGH_DEF,
bool aSkipNPTHPadsWihNoCopper = false ) const; bool aSkipNPTHPadsWihNoCopper = false,
bool aSkipPlatedPads = false,
bool aSkipNonPlatedPads = false ) const;
/** /**
* function TransformGraphicShapesWithClearanceToPolygonSet * function TransformGraphicShapesWithClearanceToPolygonSet