Added GAL::DrawPolygon(SHAPE_POLY_SET) & GAL::DrawPolyLine(SHAPE_LINE_CHAIN)
This commit is contained in:
parent
1eb7e7161e
commit
80956ef1e6
|
@ -3,6 +3,8 @@
|
|||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2017 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* CAIRO_GAL - Graphics Abstraction Layer for Cairo
|
||||
*
|
||||
|
@ -30,6 +32,7 @@
|
|||
#include <gal/cairo/cairo_gal.h>
|
||||
#include <gal/cairo/cairo_compositor.h>
|
||||
#include <gal/definitions.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
|
@ -253,6 +256,13 @@ void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawPolygon( const SHAPE_POLY_SET& aPolySet )
|
||||
{
|
||||
for( int i = 0; i < aPolySet.OutlineCount(); ++i )
|
||||
drawPoly( aPolySet.COutline( i ) );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA,
|
||||
const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
|
@ -1050,6 +1060,25 @@ void CAIRO_GAL::drawPoly( const VECTOR2D aPointList[], int aListSize )
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::drawPoly( const SHAPE_LINE_CHAIN& aLineChain )
|
||||
{
|
||||
if( aLineChain.PointCount() < 2 )
|
||||
return;
|
||||
|
||||
const VECTOR2I start = aLineChain.CPoint( 0 );
|
||||
cairo_move_to( currentContext, start.x, start.y );
|
||||
|
||||
for( int i = 1; i < aLineChain.PointCount(); ++i )
|
||||
{
|
||||
const VECTOR2I& p = aLineChain.CPoint( i );
|
||||
cairo_line_to( currentContext, p.x, p.y );
|
||||
}
|
||||
|
||||
flushPath();
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
||||
unsigned int CAIRO_GAL::getNewGroupNumber()
|
||||
{
|
||||
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <gal/opengl/utils.h>
|
||||
#include <gal/definitions.h>
|
||||
#include <gl_context_mgr.h>
|
||||
#include <geometry/shape_poly_set.h>
|
||||
|
||||
#include <macros.h>
|
||||
|
||||
|
@ -619,123 +620,75 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
|
|||
|
||||
void OPENGL_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
if( aPointList.size() < 2 )
|
||||
return;
|
||||
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||
|
||||
// Start from the second point
|
||||
for( ++it; it != aPointList.end(); ++it )
|
||||
{
|
||||
const VECTOR2D startEndVector = ( *it - *( it - 1 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( *( it - 1 ), *it );
|
||||
|
||||
// There is no need to draw line caps on both ends of polyline's segments
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
}
|
||||
|
||||
// ..and now - draw the ending cap
|
||||
const VECTOR2D startEndVector = ( *( it - 1 ) - *( it - 2 ) );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
drawFilledSemiCircle( *( it - 1 ), lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
drawPolyline( [&](int idx) { return aPointList[idx]; }, aPointList.size() );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolyline( const VECTOR2D aPointList[], int aListSize )
|
||||
{
|
||||
if( aListSize < 2 )
|
||||
return;
|
||||
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
|
||||
// Start from the second point
|
||||
for( int i = 1; i < aListSize; ++i )
|
||||
{
|
||||
const VECTOR2D startEndVector = ( aPointList[i] - aPointList[i - 1] );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( aPointList[i - 1], aPointList[i] );
|
||||
|
||||
// There is no need to draw line caps on both ends of polyline's segments
|
||||
drawFilledSemiCircle( aPointList[i - 1], lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
drawPolyline( [&](int idx) { return aPointList[idx]; }, aListSize );
|
||||
}
|
||||
|
||||
// ..and now - draw the ending cap
|
||||
const VECTOR2D startEndVector = ( aPointList[aListSize - 1] - aPointList[aListSize - 2] );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
drawFilledSemiCircle( aPointList[aListSize - 1], lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
|
||||
void OPENGL_GAL::DrawPolyline( const SHAPE_LINE_CHAIN& aLineChain )
|
||||
{
|
||||
drawPolyline( [&](int idx) { return aLineChain.CPoint(idx); }, aLineChain.PointCount() + 1 );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
|
||||
{
|
||||
currentManager->Shader( SHADER_NONE );
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
auto points = std::unique_ptr<GLdouble[]>( new GLdouble[3 * aPointList.size()] );
|
||||
GLdouble* ptr = points.get();
|
||||
|
||||
// Any non convex polygon needs to be tesselated
|
||||
// for this purpose the GLU standard functions are used
|
||||
TessParams params = { currentManager, tessIntersects };
|
||||
gluTessBeginPolygon( tesselator, ¶ms );
|
||||
gluTessBeginContour( tesselator );
|
||||
|
||||
std::unique_ptr<GLdouble[]> points( new GLdouble[ 3 * aPointList.size() ] );
|
||||
int v = 0;
|
||||
|
||||
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it )
|
||||
for( const VECTOR2D& p : aPointList )
|
||||
{
|
||||
points[v] = it->x;
|
||||
points[v + 1] = it->y;
|
||||
points[v + 2] = layerDepth;
|
||||
gluTessVertex( tesselator, &points[v], &points[v] );
|
||||
v += 3;
|
||||
*ptr++ = p.x;
|
||||
*ptr++ = p.y;
|
||||
*ptr++ = layerDepth;
|
||||
}
|
||||
|
||||
gluTessEndContour( tesselator );
|
||||
gluTessEndPolygon( tesselator );
|
||||
|
||||
// Free allocated intersecting points
|
||||
tessIntersects.clear();
|
||||
|
||||
// vertexList destroyed here
|
||||
drawPolygon( points.get(), aPointList.size() );
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawPolygon( const VECTOR2D aPointList[], int aListSize )
|
||||
{
|
||||
currentManager->Shader( SHADER_NONE );
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
// Any non convex polygon needs to be tesselated
|
||||
// for this purpose the GLU standard functions are used
|
||||
TessParams params = { currentManager, tessIntersects };
|
||||
gluTessBeginPolygon( tesselator, ¶ms );
|
||||
gluTessBeginContour( tesselator );
|
||||
|
||||
std::unique_ptr<GLdouble[]> points( new GLdouble[3 * aListSize] );
|
||||
int v = 0;
|
||||
const VECTOR2D* ptr = aPointList;
|
||||
auto points = std::unique_ptr<GLdouble[]>( new GLdouble[3 * aListSize] );
|
||||
GLdouble* target = points.get();
|
||||
const VECTOR2D* src = aPointList;
|
||||
|
||||
for( int i = 0; i < aListSize; ++i )
|
||||
{
|
||||
points[v] = ptr->x;
|
||||
points[v + 1] = ptr->y;
|
||||
points[v + 2] = layerDepth;
|
||||
gluTessVertex( tesselator, &points[v], &points[v] );
|
||||
++ptr;
|
||||
v += 3;
|
||||
*target++ = src->x;
|
||||
*target++ = src->y;
|
||||
*target++ = layerDepth;
|
||||
++src;
|
||||
}
|
||||
|
||||
gluTessEndContour( tesselator );
|
||||
gluTessEndPolygon( tesselator );
|
||||
drawPolygon( points.get(), aListSize );
|
||||
}
|
||||
|
||||
// Free allocated intersecting points
|
||||
tessIntersects.clear();
|
||||
|
||||
// vertexList destroyed here
|
||||
void OPENGL_GAL::DrawPolygon( const SHAPE_POLY_SET& aPolySet )
|
||||
{
|
||||
for( int j = 0; j < aPolySet.OutlineCount(); ++j )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& outline = aPolySet.COutline( j );
|
||||
const int pointCount = outline.PointCount();
|
||||
std::unique_ptr<GLdouble[]> points( new GLdouble[3 * pointCount] );
|
||||
GLdouble* ptr = points.get();
|
||||
|
||||
for( int i = 0; i < outline.PointCount(); ++i )
|
||||
{
|
||||
const VECTOR2I& p = outline.CPoint( i );
|
||||
*ptr++ = p.x;
|
||||
*ptr++ = p.y;
|
||||
*ptr++ = layerDepth;
|
||||
}
|
||||
|
||||
drawPolygon( points.get(), pointCount );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1341,6 +1294,63 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa
|
|||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawPolygon( GLdouble* aPoints, int aPointCount )
|
||||
{
|
||||
currentManager->Shader( SHADER_NONE );
|
||||
currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||
|
||||
// Any non convex polygon needs to be tesselated
|
||||
// for this purpose the GLU standard functions are used
|
||||
TessParams params = { currentManager, tessIntersects };
|
||||
gluTessBeginPolygon( tesselator, ¶ms );
|
||||
gluTessBeginContour( tesselator );
|
||||
|
||||
GLdouble* point = aPoints;
|
||||
|
||||
for( int i = 0; i < aPointCount; ++i )
|
||||
{
|
||||
gluTessVertex( tesselator, point, point );
|
||||
point += 3; // 3 coordinates
|
||||
}
|
||||
|
||||
gluTessEndContour( tesselator );
|
||||
gluTessEndPolygon( tesselator );
|
||||
|
||||
// Free allocated intersecting points
|
||||
tessIntersects.clear();
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawPolyline( std::function<VECTOR2D (int)> aPointGetter, int aPointCount )
|
||||
{
|
||||
if( aPointCount < 2 )
|
||||
return;
|
||||
|
||||
currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||
int i;
|
||||
|
||||
for( i = 1; i < aPointCount; ++i )
|
||||
{
|
||||
auto start = aPointGetter( i - 1 );
|
||||
auto end = aPointGetter( i );
|
||||
const VECTOR2D startEndVector = ( end - start );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
|
||||
drawLineQuad( start, end );
|
||||
|
||||
// There is no need to draw line caps on both ends of polyline's segments
|
||||
drawFilledSemiCircle( start, lineWidth / 2, lineAngle + M_PI / 2 );
|
||||
}
|
||||
|
||||
// ..and now - draw the ending cap
|
||||
auto start = aPointGetter( i - 2 );
|
||||
auto end = aPointGetter( i - 1 );
|
||||
const VECTOR2D startEndVector = ( end - start );
|
||||
double lineAngle = startEndVector.Angle();
|
||||
drawFilledSemiCircle( end, lineWidth / 2, lineAngle - M_PI / 2 );
|
||||
}
|
||||
|
||||
|
||||
int OPENGL_GAL::drawBitmapChar( unsigned long aChar )
|
||||
{
|
||||
const float TEX_X = font_image.width;
|
||||
|
|
|
@ -120,10 +120,12 @@ public:
|
|||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) override { drawPoly( aPointList ); }
|
||||
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) override { drawPoly( aPointList, aListSize ); }
|
||||
virtual void DrawPolyline( const SHAPE_LINE_CHAIN& aLineChain ) override { drawPoly( aLineChain ); }
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) override { drawPoly( aPointList ); }
|
||||
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) override { drawPoly( aPointList, aListSize ); }
|
||||
virtual void DrawPolygon( const SHAPE_POLY_SET& aPolySet ) override;
|
||||
|
||||
/// @copydoc GAL::DrawCurve()
|
||||
virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
|
||||
|
@ -397,6 +399,7 @@ private:
|
|||
/// Drawing polygons & polylines is the same in cairo, so here is the common code
|
||||
void drawPoly( const std::deque<VECTOR2D>& aPointList );
|
||||
void drawPoly( const VECTOR2D aPointList[], int aListSize );
|
||||
void drawPoly( const SHAPE_LINE_CHAIN& aLineChain );
|
||||
|
||||
/**
|
||||
* @brief Returns a valid key that can be used as a new group number.
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
#include <gal/stroke_font.h>
|
||||
#include <newstroke_font.h>
|
||||
|
||||
class SHAPE_LINE_CHAIN;
|
||||
class SHAPE_POLY_SET;
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
/**
|
||||
|
@ -117,6 +120,7 @@ public:
|
|||
*/
|
||||
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) {};
|
||||
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) {};
|
||||
virtual void DrawPolyline( const SHAPE_LINE_CHAIN& aLineChain ) {};
|
||||
|
||||
/**
|
||||
* @brief Draw a circle using world coordinates.
|
||||
|
@ -152,6 +156,7 @@ public:
|
|||
*/
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) {};
|
||||
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) {};
|
||||
virtual void DrawPolygon( const SHAPE_POLY_SET& aPolySet ) {};
|
||||
|
||||
/**
|
||||
* @brief Draw a cubic bezier spline.
|
||||
|
|
|
@ -137,10 +137,12 @@ public:
|
|||
/// @copydoc GAL::DrawPolyline()
|
||||
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) override;
|
||||
virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) override;
|
||||
virtual void DrawPolyline( const SHAPE_LINE_CHAIN& aLineChain ) override;
|
||||
|
||||
/// @copydoc GAL::DrawPolygon()
|
||||
virtual void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) override;
|
||||
virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) override;
|
||||
virtual void DrawPolygon( const SHAPE_POLY_SET& aPolySet ) override;
|
||||
|
||||
/// @copydoc GAL::DrawCurve()
|
||||
virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
|
||||
|
@ -365,6 +367,21 @@ private:
|
|||
*/
|
||||
void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
|
||||
|
||||
/**
|
||||
* @param Generic way of drawing a polyline stored in different containers.
|
||||
* @param aPointGetter is a function to obtain coordinates of n-th vertex.
|
||||
* @param aPointCount is the number of points to be drawn.
|
||||
*/
|
||||
void drawPolyline( std::function<VECTOR2D (int)> aPointGetter, int aPointCount );
|
||||
|
||||
/**
|
||||
* @brief Draws a filled polygon. It does not need the last point to have the same coordinates
|
||||
* as the first one.
|
||||
* @param aPoints is the vertices data (3 coordinates: x, y, z).
|
||||
* @param aPointCount is the number of points.
|
||||
*/
|
||||
void drawPolygon( GLdouble* aPoints, int aPointCount );
|
||||
|
||||
/**
|
||||
* @brief Draws a single character using bitmap font.
|
||||
* Its main purpose is to be used in BitmapText() function.
|
||||
|
|
Loading…
Reference in New Issue