From 76e44c2f4b632b50c5d673585cb848cf44eb655e Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 21 Sep 2020 16:57:25 -0700 Subject: [PATCH] pcbnew: Really deal with missing segments this time The OpenGL missing segments (when small) are due to rounding in larger coordinates. The GAL shader uses floats to represent int32 values for position and distance. Thus, at larger coordinates, the smaller integer values cannot be represented accurately. This tests for the rounding error and, if it exists, draws a plain circle instead Fixes https://gitlab.com/kicad/code/kicad/issues/5751 --- common/gal/opengl/opengl_gal.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index e4455d7619..36604ec127 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -654,9 +654,15 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP VECTOR2D startEndVector = aEndPoint - aStartPoint; double lineLength = startEndVector.EuclideanNorm(); - // segments having a length <= 1 are just a circle. - // Moreover trying to draw them as a segment does not work fine. - if( lineLength <= 1 ) + float startx = aStartPoint.x; + float starty = aStartPoint.y; + float endx = aStartPoint.x + lineLength; + float endy = aStartPoint.y + lineLength; + + // Be careful about floating point rounding. As we draw segments in larger and larger coordinates, + // the shader (which uses floats) will lose precision and stop drawing small segments. + // In this case, we need to draw a circle for the minimal segment + if( startx == endx || starty == endy ) { DrawCircle( aStartPoint, aWidth/2 ); return;