3D-Viewer, raytracing: implement bevel edges on item layers

This commit is contained in:
Mario Luzeiro 2022-05-15 09:38:46 +01:00 committed by Seth Hillbrand
parent 2aa56e2c86
commit ef4f0b49fc
4 changed files with 93 additions and 7 deletions

View File

@ -1,7 +1,7 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -37,6 +37,7 @@
#include <pgm_base.h> #include <pgm_base.h>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
#include <wx/log.h> #include <wx/log.h>
#include <advanced_config.h>
#define DEFAULT_BOARD_THICKNESS Millimeter2iu( 1.6 ) #define DEFAULT_BOARD_THICKNESS Millimeter2iu( 1.6 )
@ -62,6 +63,9 @@ KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSolderPaste;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSurfaceFinish; KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultSurfaceFinish;
KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultBoardBody; KIGFX::COLOR4D BOARD_ADAPTER::g_DefaultBoardBody;
// To be used in Raytracing render to create bevels on layer items
float g_BevelThickness3DU = 0.0f;
static bool g_ColorsLoaded = false; static bool g_ColorsLoaded = false;
/** /**
@ -349,6 +353,8 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits; m_nonCopperLayerThickness3DU = DEFAULT_TECH_LAYER_THICKNESS * m_biuTo3Dunits;
m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits; m_solderPasteLayerThickness3DU = SOLDERPASTE_LAYER_THICKNESS * m_biuTo3Dunits;
g_BevelThickness3DU = Millimeter2iu( ADVANCED_CFG::GetCfg().m_3DRT_BevelHeight_um / 1000.0 ) * m_biuTo3Dunits;
if( m_board ) if( m_board )
{ {
const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();

View File

@ -1,8 +1,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -25,6 +25,10 @@
#include "layer_item_3d.h" #include "layer_item_3d.h"
#include "3d_fastmath.h" #include "3d_fastmath.h"
#include <wx/debug.h> #include <wx/debug.h>
#include <advanced_config.h>
extern float g_BevelThickness3DU;
LAYER_ITEM::LAYER_ITEM( const OBJECT_2D* aObject2D, float aZMin, float aZMax ) : LAYER_ITEM::LAYER_ITEM( const OBJECT_2D* aObject2D, float aZMin, float aZMax ) :
@ -223,17 +227,52 @@ bool LAYER_ITEM::Intersect( const RAY& aRay, HITINFO& aHitInfo ) const
{ {
aHitInfo.m_tHit = t; aHitInfo.m_tHit = t;
aHitInfo.m_HitPoint = hitPoint; aHitInfo.m_HitPoint = hitPoint;
aHitInfo.pHitObject = this;
const float zNormalDir = hit_top?1.0f:hit_bot?-1.0f:0.0f;
if( ( outNormal.x == 0.0f ) && ( outNormal.y == 0.0f ) ) if( ( outNormal.x == 0.0f ) && ( outNormal.y == 0.0f ) )
{ {
aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, 1.0f ); aHitInfo.m_HitNormal = SFVEC3F( 0.0f, 0.0f, zNormalDir );
} }
else else
{ {
aHitInfo.m_HitNormal = SFVEC3F( outNormal.x, outNormal.y, 0.0f ); // Calculate smooth bevel normal
} float zBend = 0.0f;
aHitInfo.pHitObject = this; if( hit_top || hit_bot )
{
float zDistanceToTopOrBot;
// Calculate the distance from hitpoint z to the Max/Min z of the layer
if( hit_top )
{
zDistanceToTopOrBot = ( m_bbox.Max().z - hitPoint.z );
}
else
{
zDistanceToTopOrBot = ( hitPoint.z - m_bbox.Min().z );
}
// For items that are > than g_BevelThickness3DU
// (eg on board vias / plated holeS) use a factor based on m_bbox.GetExtent().z
const float bevelThickness = glm::max( g_BevelThickness3DU,
m_bbox.GetExtent().z *
(float)ADVANCED_CFG::GetCfg().m_3DRT_BevelExtentFactor );
if( ( zDistanceToTopOrBot > 0.0f ) && ( zDistanceToTopOrBot < bevelThickness ) )
{
// Invert and Normalize the distance 0..1
zBend = ( bevelThickness - zDistanceToTopOrBot ) / bevelThickness;
}
}
const SFVEC3F normalLateral = SFVEC3F( outNormal.x, outNormal.y, 0.0f );
const SFVEC3F normalTopBot = SFVEC3F( 0.0f, 0.0f, zNormalDir );
// Interpolate between the regular lateral normal and the top/bot normal
aHitInfo.m_HitNormal = glm::mix( normalLateral, normalTopBot, zBend );
}
m_material->Generate( aHitInfo.m_HitNormal, aRay, aHitInfo ); m_material->Generate( aHitInfo.m_HitNormal, aRay, aHitInfo );

View File

@ -192,9 +192,22 @@ static const wxChar AllowManualCanvasScale[] = wxT( "AllowManualCanvasScale" );
static const wxChar UpdateUIEventInterval[] = wxT( "UpdateUIEventInterval" ); static const wxChar UpdateUIEventInterval[] = wxT( "UpdateUIEventInterval" );
static const wxChar AllowTeardrops[] = wxT( "AllowTeardrops" ); static const wxChar AllowTeardrops[] = wxT( "AllowTeardrops" );
static const wxChar V3DRT_BevelHeight_um[] = wxT( "V3DRT_BevelHeight_um" );
static const wxChar V3DRT_BevelExtentFactor[] = wxT( "V3DRT_BevelExtentFactor" );
} // namespace KEYS } // namespace KEYS
/**
* List of known groups for advanced configuration options.
*
*/
namespace AC_GROUPS
{
static const wxChar V3D_RayTracing[] = wxT( "G_3DV_RayTracing" );
}
/* /*
* Get a simple string for common parameters. * Get a simple string for common parameters.
* *
@ -308,6 +321,9 @@ ADVANCED_CFG::ADVANCED_CFG()
m_AllowTeardrops = false; m_AllowTeardrops = false;
m_ShowRepairSchematic = false; m_ShowRepairSchematic = false;
m_3DRT_BevelHeight_um = 30;
m_3DRT_BevelExtentFactor = 1.0 / 16.0;
loadFromConfigFile(); loadFromConfigFile();
} }
@ -440,6 +456,18 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::AllowTeardrops, configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::AllowTeardrops,
&m_AllowTeardrops, m_AllowTeardrops ) ); &m_AllowTeardrops, m_AllowTeardrops ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::V3DRT_BevelHeight_um,
&m_3DRT_BevelHeight_um, m_3DRT_BevelHeight_um,
0, std::numeric_limits<int>::max(),
AC_GROUPS::V3D_RayTracing ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::V3DRT_BevelExtentFactor,
&m_3DRT_BevelExtentFactor, m_3DRT_BevelExtentFactor,
0.0, 100.0,
AC_GROUPS::V3D_RayTracing ) );
// Special case for trace mask setting...we just grab them and set them immediately // Special case for trace mask setting...we just grab them and set them immediately
// Because we even use wxLogTrace inside of advanced config // Because we even use wxLogTrace inside of advanced config
wxString traceMasks = ""; wxString traceMasks = "";

View File

@ -225,6 +225,19 @@ public:
*/ */
bool m_AllowTeardrops; bool m_AllowTeardrops;
/**
* 3D-Viewer, Raytracing
* Bevel height of layer items. Controls the start of curvature normal on the edge.
* Value is in micrometre. Good values should be arround or less than the copper thickness.
*/
int m_3DRT_BevelHeight_um;
/**
* 3D-Viewer, Raytracing
* Factor applied to Extent.z of the item layer, used on calculation of the bevel's height.
*/
double m_3DRT_BevelExtentFactor;
private: private:
ADVANCED_CFG(); ADVANCED_CFG();