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_SilkScreenColorBot = SFVEC4F( 0.9, 0.9, 0.9, 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;
}
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
* @return the map containers of holes from this board
@ -536,6 +546,16 @@ class BOARD_ADAPTER
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
{
return m_layers_inner_holes_poly;
@ -571,7 +591,9 @@ class BOARD_ADAPTER
CGENERICCONTAINER2D *aDstContainer,
PCB_LAYER_ID aLayerId,
int aInflateValue,
bool aSkipNPTHPadsWihNoCopper );
bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads );
void AddGraphicsShapesWithClearanceToContainer( const MODULE *aModule,
CGENERICCONTAINER2D *aDstContainer,
@ -685,6 +707,9 @@ private:
/// It contains polygon contours for each layer
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)
MAP_POLY m_layers_outer_holes_poly;
@ -712,6 +737,9 @@ private:
/// It contains the 2d elements of each layer
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
MAP_CONTAINER_2D m_layers_holes2D;

View File

@ -459,7 +459,9 @@ void BOARD_ADAPTER::AddPadsShapesWithClearanceToContainer( const MODULE* aModule
CGENERICCONTAINER2D *aDstContainer,
PCB_LAYER_ID aLayerId,
int aInflateValue,
bool aSkipNPTHPadsWihNoCopper )
bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads )
{
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 );
switch( aLayerId )

View File

@ -63,6 +63,9 @@ void BOARD_ADAPTER::destroyLayers()
m_layers_poly.clear();
}
delete m_F_Cu_PlatedPads_poly;
delete m_B_Cu_PlatedPads_poly;
if( !m_layers_inner_holes_poly.empty() )
{
for( auto& poly : m_layers_inner_holes_poly )
@ -87,6 +90,9 @@ void BOARD_ADAPTER::destroyLayers()
m_layers_container2D.clear();
}
delete m_platedpads_container2D_F_Cu;
delete m_platedpads_container2D_B_Cu;
if( !m_layers_holes2D.empty() )
{
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 )
aStatusReporter->Report( _( "Create tracks and vias" ) );
@ -512,7 +524,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
layerContainer,
curr_layer_id,
0,
true );
true,
true,
false );
// Micro-wave modules may have items on copper layers
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)
if( GetFlag( FL_RENDER_OPENGL_COPPER_THICKNESS )
&& ( 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
// has same shape as its hole
module->TransformPadsShapesWithClearanceToPolygon( curr_layer_id, *layerPoly,
0, ARC_HIGH_DEF, true );
0, ARC_HIGH_DEF, true,
true, false );
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
for( PCB_LAYER_ID curr_layer_id : layer_id )
{
@ -735,6 +787,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
while( threadsFinished < parallelThreadCount )
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
@ -884,6 +942,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
else
{
AddPadsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0,
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 )
{
m_reloadRequested = false;
@ -516,6 +594,8 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
if( aStatusReporter )
aStatusReporter->Report( _( "Load OpenGL: layers" ) );
const MAP_POLY &map_poly = m_boardAdapter.GetPolyMap();
for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
ii != m_boardAdapter.GetMapLayers().end();
++ii )
@ -526,82 +606,26 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin
continue;
const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second);
const LIST_OBJECT2D &listObject2d = container2d->GetList();
if( listObject2d.size() == 0 )
continue;
// Load the vertical (Z axis) component of shapes
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() )
{
const SHAPE_POLY_SET *polyList = map_poly.at( layer_id );
if( polyList->OutlineCount() > 0 )
layerTriangles->AddToMiddleContourns( *polyList, layer_z_bot, layer_z_top,
m_boardAdapter.BiuTo3Dunits(), false );
aPolyList = map_poly.at( layer_id );
}
// Create display list
// /////////////////////////////////////////////////////////////////////
m_ogl_disp_lists_layers[layer_id] = new CLAYERS_OGL_DISP_LISTS( *layerTriangles,
m_ogl_circle_texture,
layer_z_bot,
layer_z_top );
}// for each layer on map
CLAYERS_OGL_DISP_LISTS* oglList = generateLayerListFromContainer( container2d, aPolyList, layer_id );
if( oglList != nullptr )
m_ogl_disp_lists_layers[layer_id] = oglList;
}// for each layer on
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
// /////////////////////////////////////////////////////////////////////////

View File

@ -60,6 +60,9 @@ C3D_RENDER_OGL_LEGACY::C3D_RENDER_OGL_LEGACY( BOARD_ADAPTER& aAdapter, CCAMERA&
m_triangles.clear();
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 = 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
// Plated copper
// Copper material mixed with the copper color
m_materials.m_Copper.m_Ambient = SFVEC3F( m_boardAdapter.m_CopperColor.r * 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 );
// 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
m_materials.m_Paste.m_Ambient = SFVEC3F( m_boardAdapter.m_SolderPasteColor.r,
m_boardAdapter.m_SolderPasteColor.g,
@ -496,6 +507,22 @@ void init_lights(void)
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 )
{
@ -703,13 +730,28 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
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) )
{
setCopperMaterial();
if( skipRenderHoles )
{
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
{
@ -732,6 +774,26 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
m_ogl_disp_list_through_holes_outer,
viasHolesLayer,
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
@ -740,11 +802,33 @@ bool C3D_RENDER_OGL_LEGACY::Redraw(
m_ogl_disp_list_through_holes_outer,
NULL,
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
{
set_layer_material( layer_id );
CLAYERS_OGL_DISP_LISTS* dispListThoughHolesOuter =
( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS )
&& ( ( 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();
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();
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();
for( MAP_TRIANGLES::const_iterator ii = m_triangles.begin();
for( LIST_TRIANGLES::const_iterator ii = m_triangles.begin();
ii != m_triangles.end();
++ii )
{
CLAYER_TRIANGLES *pointer = static_cast<CLAYER_TRIANGLES*>(ii->second);
delete pointer;
delete *ii;
}
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, CLAYER_TRIANGLES * > MAP_TRIANGLES;
typedef std::list<CLAYER_TRIANGLES * > LIST_TRIANGLES;
typedef std::map< wxString, C_OGL_3DMODEL * > MAP_3DMODEL;
#define SIZE_OF_CIRCLE_TEXTURE 1024
@ -77,6 +77,8 @@ private:
void ogl_free_all_display_lists();
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_inner;
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_outer_contourn_and_caps;
MAP_TRIANGLES m_triangles;
LIST_TRIANGLES m_triangles; // store pointers so can be deleted latter
GLuint m_ogl_circle_texture;
@ -113,6 +115,10 @@ private:
float aZbot,
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,
const SFVEC2F &v0,
const SFVEC2F &v1,
@ -197,6 +203,10 @@ private:
// Materials
void setupMaterials();
void setCopperMaterial();
void setPlatedCopperAndDepthOffset( PCB_LAYER_ID aLayer_id );
void unsetDepthOffset();
struct
{
SMATERIAL m_Paste;
@ -204,6 +214,7 @@ private:
SMATERIAL m_SilkSTop;
SMATERIAL m_SolderMask;
SMATERIAL m_EpoxyBoard;
SMATERIAL m_NonPlatedCopper; // raw copper
SMATERIAL m_Copper;
SMATERIAL m_Plastic;
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,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue, int aMaxError,
bool aSkipNPTHPadsWihNoCopper ) const
bool aSkipNPTHPadsWihNoCopper,
bool aSkipPlatedPads,
bool aSkipNonPlatedPads ) const
{
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 );
switch( aLayer )

View File

@ -369,10 +369,14 @@ public:
* 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
* 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,
bool aSkipNPTHPadsWihNoCopper = false ) const;
bool aSkipNPTHPadsWihNoCopper = false,
bool aSkipPlatedPads = false,
bool aSkipNonPlatedPads = false ) const;
/**
* function TransformGraphicShapesWithClearanceToPolygonSet