From 386a0bbe4a57bbde292bc8d5404a8a9bad681469 Mon Sep 17 00:00:00 2001 From: Mario Luzeiro Date: Sat, 31 Oct 2020 23:31:55 +0000 Subject: [PATCH] 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 --- .../c3d_render_createscene.cpp | 6 ++-- .../shapes2D/citemlayercsg2d.cpp | 34 ++++++------------- .../shapes2D/cpolygon2d.cpp | 25 +++++++++----- .../shapes3D/clayeritem.cpp | 12 +------ 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp index 2215383cc9..acbd804aba 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp @@ -523,7 +523,7 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, antiboardPoly, *m_antioutlineBoard2dObjects, m_boardAdapter.BiuTo3Dunits(), - divFactor, + -1.0f, *dynamic_cast( 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 { diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/citemlayercsg2d.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/citemlayercsg2d.cpp index 3bbead7b99..cd25870779 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/citemlayercsg2d.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/citemlayercsg2d.cpp @@ -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, ¤tRayDist, ¤tNormal ) ) + float tmpRayDist; + if( !m_objectA->Intersect( aSegRay, &tmpRayDist, ¤tNormal ) ) 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; } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cpolygon2d.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cpolygon2d.cpp index fcae0106c0..693ebd7d86 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cpolygon2d.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cpolygon2d.cpp @@ -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; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp index f26b94799f..ce5033897a 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/clayeritem.cpp @@ -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.