3D-Viewer: add antiboard as a single object

improves ray transversal,
fixes previous csg operation issues.

Fixes https://gitlab.com/kicad/code/kicad/issues/6097
This commit is contained in:
Mario Luzeiro 2020-10-31 23:31:55 +00:00 committed by Wayne Stambaugh
parent b06db80151
commit 386a0bbe4a
4 changed files with 32 additions and 45 deletions

View File

@ -523,7 +523,7 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
antiboardPoly,
*m_antioutlineBoard2dObjects,
m_boardAdapter.BiuTo3Dunits(),
divFactor,
-1.0f,
*dynamic_cast<const BOARD_ITEM*>( m_boardAdapter.GetBoard() ),
iOutlinePolyIdx );
}
@ -1167,10 +1167,10 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
CONST_LIST_OBJECT2D antiOutlineIntersectionList;
const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
m_boardAdapter.GetCopperThickness3DU();
m_boardAdapter.GetCopperThickness3DU() * 0.99f;
const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) -
m_boardAdapter.GetCopperThickness3DU();
m_boardAdapter.GetCopperThickness3DU() * 0.99f;
if( drillsize.x == drillsize.y ) // usual round hole
{

View File

@ -87,39 +87,31 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
if( m_objectA->GetObjectType() == OBJECT2D_TYPE::DUMMYBLOCK )
return false;
float currentRayDist;
SFVEC2F currentRayPos;
SFVEC2F currentRayPos = aSegRay.m_Start;
SFVEC2F currentNormal;
RAYSEG2D currentRay = aSegRay;
if( m_objectA->IsPointInside( aSegRay.m_Start ) )
{
// start ray point off where it is now (at the origin)
currentRayDist = 0.0f;
currentRayPos = aSegRay.m_Start;
}
else
if( !m_objectA->IsPointInside( aSegRay.m_Start ) )
{
//move ray point to start of main object
if( !m_objectA->Intersect( aSegRay, &currentRayDist, &currentNormal ) )
float tmpRayDist;
if( !m_objectA->Intersect( aSegRay, &tmpRayDist, &currentNormal ) )
return false;
currentRayPos = aSegRay.atNormalized( currentRayDist + 0.01f );
currentRayPos = aSegRay.atNormalized( tmpRayDist + 0.003f );
currentRay = RAYSEG2D( currentRayPos, aSegRay.m_End );
}
currentRayDist = 0.0f;
//wxASSERT( (currentRayDist >= 0.0f) && (currentRayDist <= 1.0f) );
// move through the union of subtracted regions
if( m_objectB )
{
for( unsigned int l = 0; l < 4; ++l )
for( unsigned int l = 0; l < ( m_objectB->size() * 2 ); ++l )
{
bool wasInsideSubVol = false;
bool wasCrossedSubVol = false;
//check against all subbed objects
for( unsigned int i = 0; i < m_objectB->size(); ++i )
@ -137,14 +129,12 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
wxASSERT( hitDist <= 1.0f );
if( hitDist > currentRayDist )
if( hitDist > FLT_EPSILON )
{
wasInsideSubVol = true;
wasCrossedSubVol = true;
currentRayPos = currentRay.atNormalized( glm::min( hitDist + 0.0001f, 1.0f ) );
currentRayDist = 0.0001f;
currentRay = RAYSEG2D( currentRayPos, aSegRay.m_End );
currentNormal = tmpNormal * -1.0f;
@ -152,15 +142,13 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
}
}
if( !wasInsideSubVol )
{
if( !wasCrossedSubVol )
break;
}
}
}
*aNormalOut = currentNormal;
*aOutT = glm::min( glm::max( 1.0f - glm::length( currentRayPos - aSegRay.m_End ) / aSegRay.m_Length, 0.0f ), 1.0f );
*aOutT = glm::min( glm::max( glm::length( currentRayPos - aSegRay.m_Start ) / aSegRay.m_Length, 0.0f ), 1.0f );
return true;
}

View File

@ -539,16 +539,25 @@ void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
glm::normalize( (normalAfterSeg * dotAfter ) + normalSeg );
}
if( aDivFactor == 0.0f )
aDivFactor = medOfTheSquaresSegmentLength;
SFVEC2UI grid_divisions;
grid_divisions.x = (unsigned int)( (bbox.GetExtent().x / aDivFactor) );
grid_divisions.y = (unsigned int)( (bbox.GetExtent().y / aDivFactor) );
grid_divisions = glm::clamp( grid_divisions ,
SFVEC2UI( 1, 1 ),
SFVEC2UI( MAX_NR_DIVISIONS, MAX_NR_DIVISIONS ) );
if( aDivFactor < 0.0f)
{
grid_divisions = SFVEC2UI( 1 );
}
else
{
if( aDivFactor <= FLT_EPSILON )
aDivFactor = medOfTheSquaresSegmentLength;
grid_divisions.x = (unsigned int)( (bbox.GetExtent().x / aDivFactor) );
grid_divisions.y = (unsigned int)( (bbox.GetExtent().y / aDivFactor) );
grid_divisions = glm::clamp( grid_divisions ,
SFVEC2UI( 1, 1 ),
SFVEC2UI( MAX_NR_DIVISIONS, MAX_NR_DIVISIONS ) );
}
// Calculate the steps advance of the grid
SFVEC2F blockAdvance;

View File

@ -64,7 +64,7 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
if( tBBoxStart >= aHitInfo.m_tHit )
return false;
if( fabs(tBBoxStart - tBBoxEnd) < FLT_EPSILON )
if( fabs(tBBoxStart - tBBoxEnd) <= FLT_EPSILON )
return false;
const bool startedInside = m_bbox.Inside( aRay.m_Origin );
@ -96,9 +96,6 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
}
}
tBBoxStart = NextFloatDown( tBBoxStart );
tBBoxEnd = NextFloatUp( tBBoxEnd );
SFVEC2F topHitPoint2d;
SFVEC2F botHitPoint2d;
@ -213,8 +210,6 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
SFVEC3F boxHitPointEnd = aRay.at( tBBoxEnd );
SFVEC2F boxHitPointStart2D( boxHitPointStart.x, boxHitPointStart.y );
//SFVEC2F boxHitPointStart2D( m_bbox.GetCenter().x, m_bbox.GetCenter().y );
SFVEC2F boxHitPointEnd2D( boxHitPointEnd.x, boxHitPointEnd.y );
float tOut;
@ -223,11 +218,6 @@ bool CLAYERITEM::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
if( m_object2d->Intersect( raySeg, &tOut, &outNormal ) )
{
if( tOut > 0.99f ) // Workarround for refraction artifacts on board sides
{
return false;
}
// The hitT is a hit value for the segment length 'start' - 'end',
// so it ranges from 0.0 - 1.0. We now convert it to a 3D hit position
// and calculate the real hitT of the ray.