support for bezier curves
This commit is contained in:
parent
ed50bac88d
commit
cffe0cfcaa
|
@ -10,6 +10,7 @@ set(COMMON_SRCS
|
|||
base_screen.cpp
|
||||
base_struct.cpp
|
||||
basicframe.cpp
|
||||
bezier_curves.cpp
|
||||
block_commande.cpp
|
||||
class_drawpickedstruct.cpp
|
||||
common.cpp
|
||||
|
|
|
@ -9,29 +9,25 @@
|
|||
|
||||
|
||||
#define BUILD_VERSION "(20090621-unstable)"
|
||||
#ifndef KICAD_ABOUT_VERSION
|
||||
#define KICAD_ABOUT_VERSION BUILD_VERSION
|
||||
#endif
|
||||
|
||||
|
||||
wxString g_BuildVersion
|
||||
|
||||
#ifdef HAVE_SVN_VERSION
|
||||
#include "version.h"
|
||||
( wxT( KICAD_SVN_VERSION ) )
|
||||
wxString g_BuildVersion( wxT( KICAD_SVN_VERSION ) );
|
||||
#else
|
||||
( wxT( BUILD_VERSION ) )
|
||||
wxString g_BuildVersion( wxT( BUILD_VERSION ) );
|
||||
#endif
|
||||
;
|
||||
|
||||
wxString g_BuildAboutVersion
|
||||
|
||||
#if defined(HAVE_SVN_VERSION) || defined(HAVE_SVN_REVISION)
|
||||
# include "version.h"
|
||||
( wxT( KICAD_ABOUT_VERSION ) )
|
||||
#else
|
||||
( wxT( BUILD_VERSION ) )
|
||||
#ifndef KICAD_ABOUT_VERSION
|
||||
#define KICAD_ABOUT_VERSION BUILD_VERSION
|
||||
#endif
|
||||
wxString g_BuildAboutVersion( wxT( KICAD_ABOUT_VERSION ) );
|
||||
#else
|
||||
wxString g_BuildAboutVersion( wxT( BUILD_VERSION ) );
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
/**********************************/
|
||||
|
@ -137,6 +133,7 @@ void InitKiCadAbout( wxAboutDialogInfo& info )
|
|||
info.AddDeveloper( SetMsg( wxT( "Jerry Jacobs <jerkejacobs@gmail.com>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "Jonas Diemer <diemer@gmx.de>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "KBool Library <http://boolean.klaasholwerda.nl/bool.html>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "Marco Serantoni <marco.serantoni@gmail.com>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "Rok Markovic <rok@kanardia.eu>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "Tim Hanson <sideskate@gmail.com>" ) ) );
|
||||
info.AddDeveloper( SetMsg( wxT( "Vesa Solonen <vesa.solonen@hut.fi>" ) ) );
|
||||
|
|
|
@ -0,0 +1,398 @@
|
|||
/************************************/
|
||||
/* routines to handle bezier curves */
|
||||
/************************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "bezier_curves.h"
|
||||
|
||||
|
||||
#define add_segment(segment) if(bezier_points[bezier_points.size()-1] != segment) bezier_points.push_back(segment);
|
||||
|
||||
|
||||
// Local variables:
|
||||
static std::vector<wxPoint> bezier_points;
|
||||
|
||||
static int bezier_recursion_limit = 12;
|
||||
static double bezier_approximation_scale = 0.5; // 1
|
||||
|
||||
static double bezier_curve_collinearity_epsilon = 1e-30;
|
||||
static double bezier_curve_angle_tolerance_epsilon = 0.0001;
|
||||
static double bezier_distance_tolerance_square; // derived by approximation_scale
|
||||
static double bezier_angle_tolerance = 0.0;
|
||||
static double bezier_cusp_limit = 0.0;
|
||||
|
||||
// Local functions:
|
||||
static void recursive_bezier( int x1, int y1, int x2, int y2, int x3, int y3, int level );
|
||||
static void recursive_bezier( int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int x3,
|
||||
int y3,
|
||||
int x4,
|
||||
int y4,
|
||||
int level );
|
||||
|
||||
/***********************************************************************************/
|
||||
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly( wxPoint c1, wxPoint c2, wxPoint c3, wxPoint c4 )
|
||||
{
|
||||
return Bezier2Poly( c1.x, c1.y, c2.x, c2.y, c3.x, c3.y, c4.x, c4.y );
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly( wxPoint c1, wxPoint c2, wxPoint c3 )
|
||||
{
|
||||
return Bezier2Poly( c1.x, c1.y, c2.x, c2.y, c3.x, c3.y );
|
||||
}
|
||||
|
||||
|
||||
inline int calc_sq_distance( int x1, int y1, int x2, int y2 )
|
||||
{
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly( int x1, int y1, int x2, int y2, int x3, int y3 )
|
||||
{
|
||||
bezier_points.clear();
|
||||
|
||||
bezier_distance_tolerance_square = 0.5 / bezier_approximation_scale;
|
||||
bezier_distance_tolerance_square *= bezier_distance_tolerance_square;
|
||||
bezier_points.push_back( wxPoint( x1, y1 ) );
|
||||
recursive_bezier( x1, y1, x2, y2, x3, y3, 0 );
|
||||
bezier_points.push_back( wxPoint( x3, y3 ) );
|
||||
|
||||
wxLogDebug( wxT( "Bezier Conversion - End (%d vertex)" ), bezier_points.size() );
|
||||
return bezier_points;
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 )
|
||||
{
|
||||
bezier_points.clear();
|
||||
bezier_distance_tolerance_square = 0.5 / bezier_approximation_scale;
|
||||
bezier_distance_tolerance_square *= bezier_distance_tolerance_square;
|
||||
|
||||
bezier_points.push_back( wxPoint( x1, y1 ) );
|
||||
recursive_bezier( x1, y1, x2, y2, x3, y3, x4, y4, 0 );
|
||||
bezier_points.push_back( wxPoint( x4, y4 ) );
|
||||
wxLogDebug( wxT( "Bezier Conversion - End (%d vertex)" ), bezier_points.size() );
|
||||
return bezier_points;
|
||||
}
|
||||
|
||||
|
||||
void recursive_bezier( int x1, int y1, int x2, int y2, int x3, int y3, int level )
|
||||
{
|
||||
if( abs( level ) > bezier_recursion_limit )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate all the mid-points of the line segments
|
||||
//----------------------
|
||||
int x12 = (x1 + x2) / 2;
|
||||
int y12 = (y1 + y2) / 2;
|
||||
int x23 = (x2 + x3) / 2;
|
||||
int y23 = (y2 + y3) / 2;
|
||||
int x123 = (x12 + x23) / 2;
|
||||
int y123 = (y12 + y23) / 2;
|
||||
|
||||
int dx = x3 - x1;
|
||||
int dy = y3 - y1;
|
||||
double d = fabs( ( (x2 - x3) * dy - (y2 - y3) * dx ) );
|
||||
double da;
|
||||
|
||||
if( d > bezier_curve_collinearity_epsilon )
|
||||
{
|
||||
// Regular case
|
||||
//-----------------
|
||||
if( d * d <= bezier_distance_tolerance_square * (dx * dx + dy * dy) )
|
||||
{
|
||||
// If the curvature doesn't exceed the distance_tolerance value
|
||||
// we tend to finish subdivisions.
|
||||
//----------------------
|
||||
if( bezier_angle_tolerance < bezier_curve_angle_tolerance_epsilon )
|
||||
{
|
||||
add_segment( wxPoint( x123, y123 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle & Cusp Condition
|
||||
//----------------------
|
||||
da = fabs( atan2( y3 - y2, x3 - x2 ) - atan2( y2 - y1, x2 - x1 ) );
|
||||
if( da >=M_PI )
|
||||
da = 2 * M_PI - da;
|
||||
|
||||
if( da < bezier_angle_tolerance )
|
||||
{
|
||||
// Finally we can stop the recursion
|
||||
//----------------------
|
||||
add_segment( wxPoint( x123, y123 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Collinear case
|
||||
//------------------
|
||||
da = dx * dx + dy * dy;
|
||||
if( da == 0 )
|
||||
{
|
||||
d = calc_sq_distance( x1, y1, x2, y2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
d = ( (x2 - x1) * dx + (y2 - y1) * dy ) / da;
|
||||
if( d > 0 && d < 1 )
|
||||
{
|
||||
// Simple collinear case, 1---2---3
|
||||
// We can leave just two endpoints
|
||||
return;
|
||||
}
|
||||
if( d <= 0 )
|
||||
d = calc_sq_distance( x2, y2, x1, y1 );
|
||||
else if( d >= 1 )
|
||||
d = calc_sq_distance( x2, y2, x3, y3 );
|
||||
else
|
||||
d = calc_sq_distance( x2, y2, x1 + d * dx, y1 + d * dy );
|
||||
}
|
||||
if( d < bezier_distance_tolerance_square )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Continue subdivision
|
||||
//----------------------
|
||||
recursive_bezier( x1, y1, x12, y12, x123, y123, level + 1 );
|
||||
recursive_bezier( x123, y123, x23, y23, x3, y3, -(level + 1) );
|
||||
}
|
||||
|
||||
|
||||
void recursive_bezier( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int level )
|
||||
{
|
||||
if( abs( level ) > bezier_recursion_limit )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate all the mid-points of the line segments
|
||||
//----------------------
|
||||
int x12 = (x1 + x2) / 2;
|
||||
int y12 = (y1 + y2) / 2;
|
||||
int x23 = (x2 + x3) / 2;
|
||||
int y23 = (y2 + y3) / 2;
|
||||
int x34 = (x3 + x4) / 2;
|
||||
int y34 = (y3 + y4) / 2;
|
||||
int x123 = (x12 + x23) / 2;
|
||||
int y123 = (y12 + y23) / 2;
|
||||
int x234 = (x23 + x34) / 2;
|
||||
int y234 = (y23 + y34) / 2;
|
||||
int x1234 = (x123 + x234) / 2;
|
||||
int y1234 = (y123 + y234) / 2;
|
||||
|
||||
|
||||
// Try to approximate the full cubic curve by a single straight line
|
||||
//------------------
|
||||
int dx = x4 - x1;
|
||||
int dy = y4 - y1;
|
||||
|
||||
double d2 = fabs( ( (x2 - x4) * dy - (y2 - y4) * dx ) );
|
||||
double d3 = fabs( ( (x3 - x4) * dy - (y3 - y4) * dx ) );
|
||||
double da1, da2, k;
|
||||
|
||||
switch( (int(d2 > bezier_curve_collinearity_epsilon) << 1) +
|
||||
int(d3 > bezier_curve_collinearity_epsilon) )
|
||||
{
|
||||
case 0:
|
||||
|
||||
// All collinear OR p1==p4
|
||||
//----------------------
|
||||
k = dx * dx + dy * dy;
|
||||
if( k == 0 )
|
||||
{
|
||||
d2 = calc_sq_distance( x1, y1, x2, y2 );
|
||||
d3 = calc_sq_distance( x4, y4, x3, y3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 1 / k;
|
||||
da1 = x2 - x1;
|
||||
da2 = y2 - y1;
|
||||
d2 = k * (da1 * dx + da2 * dy);
|
||||
da1 = x3 - x1;
|
||||
da2 = y3 - y1;
|
||||
d3 = k * (da1 * dx + da2 * dy);
|
||||
if( d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1 )
|
||||
{
|
||||
// Simple collinear case, 1---2---3---4
|
||||
// We can leave just two endpoints
|
||||
return;
|
||||
}
|
||||
if( d2 <= 0 )
|
||||
d2 = calc_sq_distance( x2, y2, x1, y1 );
|
||||
else if( d2 >= 1 )
|
||||
d2 = calc_sq_distance( x2, y2, x4, y4 );
|
||||
else
|
||||
d2 = calc_sq_distance( x2, y2, x1 + d2 * dx, y1 + d2 * dy );
|
||||
|
||||
if( d3 <= 0 )
|
||||
d3 = calc_sq_distance( x3, y3, x1, y1 );
|
||||
else if( d3 >= 1 )
|
||||
d3 = calc_sq_distance( x3, y3, x4, y4 );
|
||||
else
|
||||
d3 = calc_sq_distance( x3, y3, x1 + d3 * dx, y1 + d3 * dy );
|
||||
}
|
||||
if( d2 > d3 )
|
||||
{
|
||||
if( d2 < bezier_distance_tolerance_square )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( d3 < bezier_distance_tolerance_square )
|
||||
{
|
||||
add_segment( wxPoint( x3, y3 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
// p1,p2,p4 are collinear, p3 is significant
|
||||
//----------------------
|
||||
if( d3 * d3 <= bezier_distance_tolerance_square * (dx * dx + dy * dy) )
|
||||
{
|
||||
if( bezier_angle_tolerance < bezier_curve_angle_tolerance_epsilon )
|
||||
{
|
||||
add_segment( wxPoint( x23, y23 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle Condition
|
||||
//----------------------
|
||||
da1 = fabs( atan2( y4 - y3, x4 - x3 ) - atan2( y3 - y2, x3 - x2 ) );
|
||||
if( da1 >= M_PI )
|
||||
da1 = 2 * M_PI - da1;
|
||||
|
||||
if( da1 < bezier_angle_tolerance )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
add_segment( wxPoint( x3, y3 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( bezier_cusp_limit != 0.0 )
|
||||
{
|
||||
if( da1 > bezier_cusp_limit )
|
||||
{
|
||||
add_segment( wxPoint( x3, y3 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
// p1,p3,p4 are collinear, p2 is significant
|
||||
//----------------------
|
||||
if( d2 * d2 <= bezier_distance_tolerance_square * (dx * dx + dy * dy) )
|
||||
{
|
||||
if( bezier_angle_tolerance < bezier_curve_angle_tolerance_epsilon )
|
||||
{
|
||||
add_segment( wxPoint( x23, y23 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle Condition
|
||||
//----------------------
|
||||
da1 = fabs( atan2( y3 - y2, x3 - x2 ) - atan2( y2 - y1, x2 - x1 ) );
|
||||
if( da1 >= M_PI )
|
||||
da1 = 2 * M_PI - da1;
|
||||
|
||||
if( da1 < bezier_angle_tolerance )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
add_segment( wxPoint( x3, y3 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( bezier_cusp_limit != 0.0 )
|
||||
{
|
||||
if( da1 > bezier_cusp_limit )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
// Regular case
|
||||
//-----------------
|
||||
if( (d2 + d3) * (d2 + d3) <= bezier_distance_tolerance_square * (dx * dx + dy * dy) )
|
||||
{
|
||||
// If the curvature doesn't exceed the distance_tolerance value
|
||||
// we tend to finish subdivisions.
|
||||
//----------------------
|
||||
if( bezier_angle_tolerance < bezier_curve_angle_tolerance_epsilon )
|
||||
{
|
||||
add_segment( wxPoint( x23, y23 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Angle & Cusp Condition
|
||||
//----------------------
|
||||
k = atan2( y3 - y2, x3 - x2 );
|
||||
da1 = fabs( k - atan2( y2 - y1, x2 - x1 ) );
|
||||
da2 = fabs( atan2( y4 - y3, x4 - x3 ) - k );
|
||||
if( da1 >= M_PI )
|
||||
da1 = 2 * M_PI - da1;
|
||||
if( da2 >= M_PI )
|
||||
da2 = 2 * M_PI - da2;
|
||||
|
||||
if( da1 + da2 < bezier_angle_tolerance )
|
||||
{
|
||||
// Finally we can stop the recursion
|
||||
//----------------------
|
||||
add_segment( wxPoint( x23, y23 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( bezier_cusp_limit != 0.0 )
|
||||
{
|
||||
if( da1 > bezier_cusp_limit )
|
||||
{
|
||||
add_segment( wxPoint( x2, y2 ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if( da2 > bezier_cusp_limit )
|
||||
{
|
||||
add_segment( wxPoint( x3, y3 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue subdivision
|
||||
//----------------------
|
||||
recursive_bezier( x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1 );
|
||||
recursive_bezier( x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1 );
|
||||
}
|
|
@ -289,8 +289,8 @@ void WinEDA_DrawPanel::PostDirtyRect( EDA_Rect aRect )
|
|||
// The pcb units have finer granularity than the pixels, so it can happen
|
||||
// that the rectangle is not large enough for the erase portion.
|
||||
|
||||
aRect.m_Size.x += 2; // += 1 is not enough!
|
||||
aRect.m_Size.y += 2;
|
||||
aRect.m_Size.x += 4; // += 1 is not enough!
|
||||
aRect.m_Size.y += 4;
|
||||
|
||||
// D( printf( "2) PostDirtyRect( x=%d, y=%d, width=%d, height=%d)\n", aRect.m_Pos.x, aRect.m_Pos.y, aRect.m_Size.x, aRect.m_Size.y ); )
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "macros.h"
|
||||
#include "base_struct.h"
|
||||
#include "class_base_screen.h"
|
||||
#include "bezier_curves.h"
|
||||
|
||||
|
||||
#ifndef FILLED
|
||||
#define FILLED 1
|
||||
|
@ -33,7 +35,7 @@
|
|||
|
||||
/* variables generales */
|
||||
|
||||
// pour les tracés en mode XOR = GR_XOR ou GR_NXOR selon couleur de fond
|
||||
// pour les tracÈs en mode XOR = GR_XOR ou GR_NXOR selon couleur de fond
|
||||
int g_XorMode = GR_NXOR;
|
||||
// couleur de fond de la frame de dessin
|
||||
int g_DrawBgColor = WHITE;
|
||||
|
@ -364,7 +366,7 @@ bool GetGRForceBlackPenState( void )
|
|||
void GRSetDrawMode( wxDC* DC, int draw_mode )
|
||||
{
|
||||
if( draw_mode & GR_OR )
|
||||
#if defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS
|
||||
#if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION(2,9,0) )
|
||||
DC->SetLogicalFunction( wxCOPY );
|
||||
#else
|
||||
DC->SetLogicalFunction( wxOR );
|
||||
|
@ -372,7 +374,7 @@ void GRSetDrawMode( wxDC* DC, int draw_mode )
|
|||
else if( draw_mode & GR_XOR )
|
||||
DC->SetLogicalFunction( wxXOR );
|
||||
else if( draw_mode & GR_NXOR )
|
||||
#if defined (__WXMAC__) && wxMAC_USE_CORE_GRAPHICS
|
||||
#if defined (__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION(2,9,0) )
|
||||
DC->SetLogicalFunction( wxXOR );
|
||||
#else
|
||||
DC->SetLogicalFunction( wxEQUIV );
|
||||
|
@ -1497,3 +1499,36 @@ void ClipAndDrawFilledPoly( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPoints[], in
|
|||
aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] );
|
||||
}
|
||||
#endif
|
||||
|
||||
void GRBezier( EDA_Rect* ClipBox,
|
||||
wxDC* DC,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int x3,
|
||||
int y3,
|
||||
int width,
|
||||
int Color )
|
||||
{
|
||||
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3 );
|
||||
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, 0 );
|
||||
}
|
||||
|
||||
|
||||
void GRBezier( EDA_Rect* ClipBox,
|
||||
wxDC* DC,
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int x3,
|
||||
int y3,
|
||||
int x4,
|
||||
int y4,
|
||||
int width,
|
||||
int Color )
|
||||
{
|
||||
std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3, x4, y4 );
|
||||
GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, 0 );
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem,
|
|||
/*******************************************************************************************/
|
||||
{
|
||||
// @todo make this variable length
|
||||
static const wxCheckBox* FieldListCtrl[] = {
|
||||
const wxCheckBox* FieldListCtrl[] = {
|
||||
m_AddField1,
|
||||
m_AddField2,
|
||||
m_AddField3,
|
||||
|
@ -586,7 +586,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef(
|
|||
if( CompactForm )
|
||||
{
|
||||
// @todo make this variable length
|
||||
static const wxCheckBox* FieldListCtrl[FIELD8 - FIELD1 + 1] = {
|
||||
const wxCheckBox* FieldListCtrl[FIELD8 - FIELD1 + 1] = {
|
||||
m_AddField1,
|
||||
m_AddField2,
|
||||
m_AddField3,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "class_drawpanel.h"
|
||||
#include "drawtxt.h"
|
||||
#include "trigo.h"
|
||||
#include "bezier_curves.h"
|
||||
|
||||
#include "program.h"
|
||||
#include "libcmp.h"
|
||||
|
@ -1104,3 +1105,234 @@ void LibDrawPolyline::DisplayInfo( WinEDA_DrawFrame* frame )
|
|||
|
||||
frame->MsgPanel->Affiche_1_Parametre( 40, _( "Bounding box" ), msg, BROWN );
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/** class LibDrawBezier **/
|
||||
/***************************/
|
||||
LibDrawBezier::LibDrawBezier( EDA_LibComponentStruct* aParent ) :
|
||||
LibEDA_BaseStruct( COMPONENT_BEZIER_DRAW_TYPE, aParent )
|
||||
{
|
||||
m_Fill = NO_FILL;
|
||||
m_Width = 0;
|
||||
m_typeName = _( "Bezier" );
|
||||
}
|
||||
|
||||
|
||||
bool LibDrawBezier::Save( FILE* ExportFile ) const
|
||||
{
|
||||
int ccount = GetCornerCount();
|
||||
|
||||
fprintf( ExportFile, "B %d %d %d %d", ccount, m_Unit, m_Convert, m_Width );
|
||||
|
||||
for( unsigned i = 0; i < GetCornerCount(); i++ )
|
||||
{
|
||||
fprintf( ExportFile, " %d %d", m_BezierPoints[i].x, m_BezierPoints[i].y );
|
||||
}
|
||||
|
||||
fprintf( ExportFile, " %c\n", fill_tab[m_Fill] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool LibDrawBezier::Load( char* line, wxString& errorMsg )
|
||||
{
|
||||
char* p;
|
||||
int i, ccount = 0;
|
||||
wxPoint pt;
|
||||
|
||||
i = sscanf( &line[2], "%d %d %d %d", &ccount, &m_Unit, &m_Convert,
|
||||
&m_Width );
|
||||
|
||||
if( i !=4 )
|
||||
{
|
||||
errorMsg.Printf( _( "Bezier only had %d parameters of the required 4" ), i );
|
||||
return false;
|
||||
}
|
||||
if( ccount <= 0 )
|
||||
{
|
||||
errorMsg.Printf( _( "Bezier count parameter %d is invalid" ),
|
||||
ccount );
|
||||
return false;
|
||||
}
|
||||
|
||||
p = strtok( &line[2], " \t\n" );
|
||||
p = strtok( NULL, " \t\n" );
|
||||
p = strtok( NULL, " \t\n" );
|
||||
p = strtok( NULL, " \t\n" );
|
||||
|
||||
for( i = 0; i < ccount; i++ )
|
||||
{
|
||||
wxPoint point;
|
||||
p = strtok( NULL, " \t\n" );
|
||||
if( sscanf( p, "%d", &pt.x ) != 1 )
|
||||
{
|
||||
errorMsg.Printf( _( "Bezier point %d X position not defined" ),
|
||||
i );
|
||||
return false;
|
||||
}
|
||||
p = strtok( NULL, " \t\n" );
|
||||
if( sscanf( p, "%d", &pt.y ) != 1 )
|
||||
{
|
||||
errorMsg.Printf( _( "Bezier point %d Y position not defined" ),
|
||||
i );
|
||||
return false;
|
||||
}
|
||||
m_BezierPoints.push_back( pt );
|
||||
}
|
||||
|
||||
m_Fill = NO_FILL;
|
||||
|
||||
if( ( p = strtok( NULL, " \t\n" ) ) != NULL )
|
||||
{
|
||||
if( p[0] == 'F' )
|
||||
m_Fill = FILLED_SHAPE;
|
||||
if( p[0] == 'f' )
|
||||
m_Fill = FILLED_WITH_BG_BODYCOLOR;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LibDrawBezier* LibDrawBezier::GenCopy()
|
||||
{
|
||||
LibDrawBezier* newitem = new LibDrawBezier(GetParent());
|
||||
|
||||
newitem->m_BezierPoints = m_BezierPoints; // Vector copy
|
||||
newitem->m_Width = m_Width;
|
||||
newitem->m_Unit = m_Unit;
|
||||
newitem->m_Convert = m_Convert;
|
||||
newitem->m_Flags = m_Flags;
|
||||
newitem->m_Fill = m_Fill;
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void LibDrawBezier::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC,
|
||||
const wxPoint& aOffset, int aColor, int aDrawMode,
|
||||
void* aData, const int aTransformMatrix[2][2] )
|
||||
{
|
||||
wxPoint pos1;
|
||||
std::vector<wxPoint> PolyPointsTraslated;
|
||||
|
||||
int color = ReturnLayerColor( LAYER_DEVICE );
|
||||
int linewidth = (m_Width == 0) ? g_DrawDefaultLineThickness : m_Width;
|
||||
|
||||
m_PolyPoints = Bezier2Poly( m_BezierPoints[0] ,
|
||||
m_BezierPoints[1] ,
|
||||
m_BezierPoints[2] ,
|
||||
m_BezierPoints[3]);
|
||||
|
||||
PolyPointsTraslated.clear();
|
||||
for( unsigned int i = 0; i < m_PolyPoints.size() ; i++)
|
||||
PolyPointsTraslated.push_back( TransformCoordinate( aTransformMatrix, m_PolyPoints[i] ) + aOffset);
|
||||
|
||||
if( aColor < 0 ) // Used normal color or selected color
|
||||
{
|
||||
if( m_Selected & IS_SELECTED )
|
||||
color = g_ItemSelectetColor;
|
||||
}
|
||||
else
|
||||
color = aColor;
|
||||
|
||||
FILL_T fill = aData ? NO_FILL : m_Fill;
|
||||
if( aColor >= 0 )
|
||||
fill = NO_FILL;
|
||||
|
||||
if( fill == FILLED_WITH_BG_BODYCOLOR )
|
||||
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
|
||||
&PolyPointsTraslated[0], 1, linewidth, color,
|
||||
ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
|
||||
else if( fill == FILLED_SHAPE )
|
||||
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
|
||||
&PolyPointsTraslated[0], 1, linewidth, color, color );
|
||||
else
|
||||
GRPoly( &aPanel->m_ClipBox, aDC, m_PolyPoints.size(),
|
||||
&PolyPointsTraslated[0], 0, linewidth, color, color );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function HitTest
|
||||
* tests if the given wxPoint is within the bounds of this object.
|
||||
* @param aRefPos A wxPoint to test
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
bool LibDrawBezier::HitTest( const wxPoint& aRefPos )
|
||||
{
|
||||
int mindist = m_Width ? m_Width /2 : g_DrawDefaultLineThickness / 2;
|
||||
// Have a minimal tolerance for hit test
|
||||
if ( mindist < 3 )
|
||||
mindist = 3; // = 3 mils
|
||||
return HitTest( aRefPos, mindist, DefaultTransformMatrix );
|
||||
}
|
||||
|
||||
/** Function HitTest
|
||||
* @return true if the point aPosRef is near a segment
|
||||
* @param aPosRef = a wxPoint to test
|
||||
* @param aThreshold = max distance to a segment
|
||||
* @param aTransMat = the transform matrix
|
||||
*/
|
||||
bool LibDrawBezier::HitTest( wxPoint aPosRef, int aThreshold,
|
||||
const int aTransMat[2][2] )
|
||||
{
|
||||
wxPoint ref, start, end;
|
||||
|
||||
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
|
||||
{
|
||||
start = TransformCoordinate( aTransMat, m_PolyPoints[ii - 1] );
|
||||
end = TransformCoordinate( aTransMat, m_PolyPoints[ii] );
|
||||
if ( TestSegmentHit( aPosRef, start, end, aThreshold ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Function GetBoundingBox
|
||||
* @return the boundary box for this, in library coordinates
|
||||
*/
|
||||
EDA_Rect LibDrawBezier::GetBoundingBox()
|
||||
{
|
||||
EDA_Rect rect;
|
||||
int xmin, xmax, ymin, ymax;
|
||||
if(!GetCornerCount())
|
||||
return rect;
|
||||
xmin = xmax = m_PolyPoints[0].x;
|
||||
ymin = ymax = m_PolyPoints[0].y;
|
||||
|
||||
for( unsigned ii = 1; ii < GetCornerCount(); ii++ )
|
||||
{
|
||||
xmin = MIN( xmin, m_PolyPoints[ii].x );
|
||||
xmax = MAX( xmax, m_PolyPoints[ii].x );
|
||||
ymin = MIN( ymin, m_PolyPoints[ii].y );
|
||||
ymax = MAX( ymax, m_PolyPoints[ii].y );
|
||||
}
|
||||
|
||||
rect.SetOrigin( xmin, ymin * -1 );
|
||||
rect.SetEnd( xmax, ymax * -1 );
|
||||
rect.Inflate( m_Width / 2, m_Width / 2 );
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
void LibDrawBezier::DisplayInfo( WinEDA_DrawFrame* frame )
|
||||
{
|
||||
wxString msg;
|
||||
EDA_Rect bBox = GetBoundingBox();
|
||||
|
||||
LibEDA_BaseStruct::DisplayInfo( frame );
|
||||
|
||||
msg = ReturnStringFromValue( g_UnitMetric, m_Width,
|
||||
EESCHEMA_INTERNAL_UNIT, true );
|
||||
|
||||
frame->MsgPanel->Affiche_1_Parametre( 20, _( "Line width" ), msg, BLUE );
|
||||
|
||||
msg.Printf( wxT( "(%d, %d, %d, %d)" ), bBox.GetOrigin().x,
|
||||
bBox.GetOrigin().y, bBox.GetEnd().x, bBox.GetEnd().y );
|
||||
|
||||
frame->MsgPanel->Affiche_1_Parametre( 40, _( "Bounding box" ), msg, BROWN );
|
||||
}
|
||||
|
|
|
@ -658,4 +658,70 @@ public:
|
|||
virtual void DisplayInfo( WinEDA_DrawFrame* frame );
|
||||
};
|
||||
|
||||
/**********************************************************/
|
||||
/* Graphic Body Item: Bezier Curve (set of lines) */
|
||||
/**********************************************************/
|
||||
class LibDrawBezier : public LibEDA_BaseStruct
|
||||
{
|
||||
public:
|
||||
int m_Width; /* Line width */
|
||||
std::vector<wxPoint> m_BezierPoints; // list of parameter (3|4)
|
||||
std::vector<wxPoint> m_PolyPoints; // list of points (>= 2)
|
||||
|
||||
public:
|
||||
LibDrawBezier(EDA_LibComponentStruct * aParent);
|
||||
~LibDrawBezier() { }
|
||||
|
||||
virtual wxString GetClass() const
|
||||
{
|
||||
return wxT( "LibDrawBezier" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Save
|
||||
* writes the data structures for this object out to a FILE in "*.brd"
|
||||
* format.
|
||||
* @param aFile The FILE to write to.
|
||||
* @return bool - true if success writing else false.
|
||||
*/
|
||||
virtual bool Save( FILE* aFile ) const;
|
||||
virtual bool Load( char* line, wxString& errorMsg );
|
||||
|
||||
LibDrawBezier* GenCopy();
|
||||
void AddPoint( const wxPoint& point );
|
||||
|
||||
/** Function GetCornerCount
|
||||
* @return the number of corners
|
||||
*/
|
||||
unsigned GetCornerCount() const { return m_PolyPoints.size(); }
|
||||
|
||||
/**
|
||||
* Function HitTest
|
||||
* tests if the given wxPoint is within the bounds of this object.
|
||||
* @param aRefPos A wxPoint to test
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
virtual bool HitTest( const wxPoint& aRefPos );
|
||||
|
||||
/** Function HitTest
|
||||
* @return true if the point aPosRef is near a segment
|
||||
* @param aPosRef = a wxPoint to test
|
||||
* @param aThreshold = max distance to a segment
|
||||
* @param aTransMat = the transform matrix
|
||||
*/
|
||||
virtual bool HitTest( wxPoint aPosRef, int aThreshold, const int aTransMat[2][2] );
|
||||
|
||||
/** Function GetBoundingBox
|
||||
* @return the boundary box for this, in library coordinates
|
||||
*/
|
||||
virtual EDA_Rect GetBoundingBox();
|
||||
|
||||
void Draw( WinEDA_DrawPanel * aPanel, wxDC * aDC, const wxPoint &aOffset,
|
||||
int aColor, int aDrawMode, void* aData,
|
||||
const int aTransformMatrix[2][2] );
|
||||
|
||||
virtual void DisplayInfo( WinEDA_DrawFrame* frame );
|
||||
};
|
||||
|
||||
#endif // CLASSES_BODY_ITEMS_H
|
||||
|
|
|
@ -594,6 +594,11 @@ static LibEDA_BaseStruct* ReadDrawEntryItemDescription (EDA_LibComponentStruct*
|
|||
entryLoaded = New->Load( Line, errorMsg );
|
||||
break;
|
||||
|
||||
case 'B': /* Bezier */
|
||||
New = ( LibEDA_BaseStruct* ) new LibDrawBezier(aParent);
|
||||
entryLoaded = New->Load( Line, errorMsg );
|
||||
break;
|
||||
|
||||
default:
|
||||
MsgLine.Printf( wxT( "Undefined DRAW command in line %d\n%s, aborted." ),
|
||||
*LineNum, Line );
|
||||
|
|
|
@ -717,6 +717,13 @@ LibEDA_BaseStruct* LocateDrawItem( SCH_SCREEN* Screen,
|
|||
return DrawItem;
|
||||
break;
|
||||
|
||||
case COMPONENT_BEZIER_DRAW_TYPE:
|
||||
if( (masque & LOCATE_COMPONENT_POLYLINE_DRAW_TYPE) == 0 )
|
||||
break;
|
||||
if( DrawItem->HitTest( aRefPoint ) )
|
||||
return DrawItem;
|
||||
break;
|
||||
|
||||
case COMPONENT_LINE_DRAW_TYPE:
|
||||
if( (masque & LOCATE_COMPONENT_LINE_DRAW_TYPE) == 0 )
|
||||
break;
|
||||
|
|
|
@ -347,6 +347,29 @@ void PlotLibPart( SCH_COMPONENT* DrawLibItem )
|
|||
}
|
||||
break;
|
||||
|
||||
case COMPONENT_BEZIER_DRAW_TYPE:
|
||||
{
|
||||
LibDrawBezier* polyline = (LibDrawBezier*) DEntry;
|
||||
Poly = (int*) MyMalloc( sizeof(int) * 2 * polyline->GetCornerCount() );
|
||||
for( ii = 0; ii < (int) polyline->GetCornerCount(); ii++ )
|
||||
{
|
||||
pos = polyline->m_PolyPoints[ii];
|
||||
pos = TransformCoordinate( TransMat, pos ) + DrawLibItem->m_Pos;
|
||||
Poly[ii * 2] = pos.x;
|
||||
Poly[ii * 2 + 1] = pos.y;
|
||||
}
|
||||
|
||||
if( draw_bgfill && polyline->m_Fill == FILLED_WITH_BG_BODYCOLOR )
|
||||
{
|
||||
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE_BACKGROUND ) );
|
||||
PlotPoly( ii, Poly, true, 0 );
|
||||
}
|
||||
if( (g_PlotFormat == PLOT_FORMAT_POST) && g_PlotPSColorOpt )
|
||||
SetColorMapPS( ReturnLayerColor( LAYER_DEVICE ) );
|
||||
PlotPoly( ii, Poly, polyline->m_Fill == FILLED_SHAPE ? true : false, polyline->m_Width );
|
||||
MyFree( Poly );
|
||||
}
|
||||
|
||||
default:
|
||||
D( printf( "Drawing Type=%d\n", DEntry->Type() ) );
|
||||
}
|
||||
|
|
|
@ -60,6 +60,10 @@ LibEDA_BaseStruct* CopyDrawEntryStruct( wxWindow* frame,
|
|||
NewDrawItem = ( (LibDrawPolyline*) DrawItem )->GenCopy();
|
||||
break;
|
||||
|
||||
case COMPONENT_BEZIER_DRAW_TYPE:
|
||||
NewDrawItem = ( (LibDrawBezier*) DrawItem )->GenCopy();
|
||||
break;
|
||||
|
||||
default:
|
||||
msg.Printf( wxT( "CopyDrawLibEntryStruct: unknown Draw Type %d" ),
|
||||
DrawItem->Type() );
|
||||
|
|
|
@ -77,6 +77,7 @@ enum KICAD_T {
|
|||
COMPONENT_LINE_DRAW_TYPE,
|
||||
COMPONENT_PIN_DRAW_TYPE,
|
||||
COMPONENT_FIELD_DRAW_TYPE,
|
||||
COMPONENT_BEZIER_DRAW_TYPE,
|
||||
|
||||
// End value
|
||||
MAX_STRUCT_TYPE_ID
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef BEZIER_CURVES_H
|
||||
#define BEZIER_CURVES_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly(wxPoint c1, wxPoint c2, wxPoint c3);
|
||||
std::vector<wxPoint> Bezier2Poly(wxPoint c1, wxPoint c2, wxPoint c3,wxPoint c4);
|
||||
|
||||
std::vector<wxPoint> Bezier2Poly(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
std::vector<wxPoint> Bezier2Poly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
|
||||
|
||||
|
||||
#endif // BEZIER_CURVES_H
|
|
@ -19,7 +19,8 @@ enum Track_Shapes {
|
|||
S_SPOT_OVALE, /* Oblong spot (for GERBER)*/
|
||||
S_SPOT_CIRCLE, /* rounded spot (for GERBER)*/
|
||||
S_SPOT_RECT, /* Rectangular spott (for GERBER)*/
|
||||
S_POLYGON /* polygonal shape */
|
||||
S_POLYGON, /* polygonal shape */
|
||||
S_CURVE /* Bezier Curve*/
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#define GR_BASIC
|
||||
|
||||
#include "colors.h"
|
||||
|
||||
|
||||
#include <vector>
|
||||
class EDA_Rect;
|
||||
|
||||
|
||||
|
@ -86,6 +85,8 @@ void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Colo
|
|||
|
||||
void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, wxPoint Points[], bool Fill, int width, int Color, int BgColor);
|
||||
|
||||
void GRBezier(EDA_Rect* ClipBox, wxDC* DC,int x1, int y1, int x2, int y2, int x3, int y3,int width, int Color);
|
||||
void GRBezier(EDA_Rect* ClipBox, wxDC* DC,int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,int width, int Color);
|
||||
|
||||
/**
|
||||
* Function GRClosedPoly
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include <wx/socket.h>
|
||||
#include "wx/log.h"
|
||||
#include "wx/config.h"
|
||||
|
|
|
@ -24,6 +24,7 @@ wxString BOARD_ITEM::ShowShape( Track_Shapes aShape )
|
|||
case S_RECT: return _( "Rect" );
|
||||
case S_ARC: return _( "Arc" );
|
||||
case S_CIRCLE: return _( "Circle" );
|
||||
case S_CURVE: return _( "Bezier Curve" );
|
||||
|
||||
// used in Gerbview:
|
||||
case S_ARC_RECT: return wxT( "arc_rect" );
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "fctsys.h"
|
||||
#include "wxstruct.h"
|
||||
#include "gr_basic.h"
|
||||
#include "bezier_curves.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
#include "kicad_string.h"
|
||||
|
@ -39,6 +40,8 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
|
|||
m_Shape = source->m_Shape;
|
||||
m_Angle = source->m_Angle;
|
||||
m_TimeStamp = source->m_TimeStamp;
|
||||
m_BezierC1 = source->m_BezierC1;
|
||||
m_BezierC2 = source->m_BezierC1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,10 +59,17 @@ bool DRAWSEGMENT::Save( FILE* aFile ) const
|
|||
m_Shape,
|
||||
m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y, m_Width );
|
||||
|
||||
fprintf( aFile, "De %d %d %d %lX %X\n",
|
||||
m_Layer, m_Type, m_Angle,
|
||||
m_TimeStamp, ReturnStatus() );
|
||||
if( m_Type != S_CURVE) {
|
||||
fprintf( aFile, "De %d %d %d %lX %X\n",
|
||||
m_Layer, m_Type, m_Angle,
|
||||
m_TimeStamp, ReturnStatus() );
|
||||
} else {
|
||||
fprintf( aFile, "De %d %d %d %lX %X %d %d %d %d\n",
|
||||
m_Layer, m_Type, m_Angle,
|
||||
m_TimeStamp, ReturnStatus(),
|
||||
m_BezierC1.x,m_BezierC1.y,
|
||||
m_BezierC2.x,m_BezierC2.y);
|
||||
}
|
||||
|
||||
if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 )
|
||||
goto out;
|
||||
|
@ -96,9 +106,44 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( FILE* File, int* LineNum )
|
|||
if( Line[0] == 'D' )
|
||||
{
|
||||
int status;
|
||||
sscanf( Line + 2, " %d %d %d %lX %X",
|
||||
&m_Layer, &m_Type, &m_Angle,
|
||||
&m_TimeStamp, &status );
|
||||
char* token=0;
|
||||
|
||||
token = strtok(Line," ");
|
||||
|
||||
for(int i=0; (token = strtok(NULL," ")) != NULL; i++){
|
||||
switch(i){
|
||||
case 0:
|
||||
sscanf(token,"%d",&m_Layer);
|
||||
break;
|
||||
case 1:
|
||||
sscanf(token,"%d",&m_Type);
|
||||
break;
|
||||
case 2:
|
||||
sscanf(token,"%d",&m_Angle);
|
||||
break;
|
||||
case 3:
|
||||
sscanf(token,"%lX",&m_TimeStamp);
|
||||
break;
|
||||
case 4:
|
||||
sscanf(token,"%X",&status);
|
||||
break;
|
||||
/* Bezier Control Points*/
|
||||
case 5:
|
||||
sscanf(token,"%d",&m_BezierC1.x);
|
||||
break;
|
||||
case 6:
|
||||
sscanf(token,"%d",&m_BezierC1.y);
|
||||
break;
|
||||
case 7:
|
||||
sscanf(token,"%d",&m_BezierC2.x);
|
||||
break;
|
||||
case 8:
|
||||
sscanf(token,"%d",&m_BezierC2.y);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_Layer < FIRST_NO_COPPER_LAYER )
|
||||
m_Layer = FIRST_NO_COPPER_LAYER;
|
||||
|
@ -235,7 +280,30 @@ void DRAWSEGMENT::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
|
|||
rayon, m_Width, color );
|
||||
}
|
||||
break;
|
||||
case S_CURVE:
|
||||
m_BezierPoints = Bezier2Poly(m_Start,m_BezierC1, m_BezierC2, m_End);
|
||||
|
||||
for (unsigned int i=1; i < m_BezierPoints.size(); i++) {
|
||||
if( mode == FILAIRE )
|
||||
GRLine( &panel->m_ClipBox, DC,
|
||||
m_BezierPoints[i].x, m_BezierPoints[i].y,
|
||||
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y, 0, color );
|
||||
else if( mode == SKETCH )
|
||||
{
|
||||
GRCSegm( &panel->m_ClipBox, DC,
|
||||
m_BezierPoints[i].x, m_BezierPoints[i].y,
|
||||
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
|
||||
m_Width, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFillCSegm( &panel->m_ClipBox, DC,
|
||||
m_BezierPoints[i].x, m_BezierPoints[i].y,
|
||||
m_BezierPoints[i-1].x, m_BezierPoints[i-1].y,
|
||||
m_Width, color );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( mode == FILAIRE )
|
||||
GRLine( &panel->m_ClipBox, DC, ux0, uy0, dx, dy, 0, color );
|
||||
|
@ -274,19 +342,24 @@ void DRAWSEGMENT::DisplayInfo( WinEDA_DrawFrame* frame )
|
|||
|
||||
wxString shape = _( "Shape" );
|
||||
|
||||
if( m_Shape == S_CIRCLE )
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Circle" ), RED );
|
||||
switch( m_Shape ) {
|
||||
case S_CIRCLE:
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Circle" ), RED );
|
||||
break;
|
||||
|
||||
else if( m_Shape == S_ARC )
|
||||
{
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Arc" ), RED );
|
||||
case S_ARC:
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Arc" ), RED );
|
||||
|
||||
msg.Printf( wxT( "%d.%d" ), m_Angle/10, m_Angle % 10 );
|
||||
Affiche_1_Parametre( frame, 18, _("Angle"), msg, RED );
|
||||
msg.Printf( wxT( "%d.%d" ), m_Angle/10, m_Angle % 10 );
|
||||
Affiche_1_Parametre( frame, 18, _("Angle"), msg, RED );
|
||||
break;
|
||||
case S_CURVE:
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Curve" ), RED );
|
||||
break;
|
||||
|
||||
default:
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Segment" ), RED );
|
||||
}
|
||||
else
|
||||
Affiche_1_Parametre( frame, 10, shape, _( "Segment" ), RED );
|
||||
|
||||
wxString start;
|
||||
start << GetStart();
|
||||
|
||||
|
@ -322,37 +395,46 @@ bool DRAWSEGMENT::HitTest( const wxPoint& ref_pos )
|
|||
int spot_cX = ref_pos.x - ux0;
|
||||
int spot_cY = ref_pos.y - uy0;
|
||||
|
||||
if( m_Shape==S_CIRCLE || m_Shape==S_ARC )
|
||||
{
|
||||
int rayon, dist, stAngle, endAngle, mouseAngle;
|
||||
switch(m_Shape){
|
||||
case S_CIRCLE:
|
||||
case S_ARC:
|
||||
|
||||
rayon = (int) hypot( (double) (dx), (double) (dy) );
|
||||
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
|
||||
int rayon, dist, stAngle, endAngle, mouseAngle;
|
||||
|
||||
if( abs( rayon - dist ) <= ( m_Width / 2 ) )
|
||||
{
|
||||
if( m_Shape == S_CIRCLE )
|
||||
return true;
|
||||
rayon = (int) hypot( (double) (dx), (double) (dy) );
|
||||
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
|
||||
|
||||
/* pour un arc, controle complementaire */
|
||||
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
|
||||
stAngle = (int) ArcTangente( dy, dx );
|
||||
endAngle = stAngle + m_Angle;
|
||||
|
||||
if( endAngle > 3600 )
|
||||
if( abs( rayon - dist ) <= ( m_Width / 2 ) )
|
||||
{
|
||||
stAngle -= 3600;
|
||||
endAngle -= 3600;
|
||||
}
|
||||
if( m_Shape == S_CIRCLE )
|
||||
return true;
|
||||
|
||||
if( mouseAngle >= stAngle && mouseAngle <= endAngle )
|
||||
/* pour un arc, controle complementaire */
|
||||
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
|
||||
stAngle = (int) ArcTangente( dy, dx );
|
||||
endAngle = stAngle + m_Angle;
|
||||
|
||||
if( endAngle > 3600 )
|
||||
{
|
||||
stAngle -= 3600;
|
||||
endAngle -= 3600;
|
||||
}
|
||||
|
||||
if( mouseAngle >= stAngle && mouseAngle <= endAngle )
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
for( unsigned int i= 1; i < m_BezierPoints.size(); i++)
|
||||
{
|
||||
if( TestSegmentHit( ref_pos,m_BezierPoints[i-1],m_BezierPoints[i-1], m_Width / 2 ) )
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@ public:
|
|||
int m_Shape; // Shape: line, Circle, Arc
|
||||
int m_Type; // Used in complex associations ( Dimensions.. )
|
||||
int m_Angle; // Used only for Arcs: Arc angle in 1/10 deg
|
||||
wxPoint m_BezierC1; // Bezier Control Point 1
|
||||
wxPoint m_BezierC2; // Bezier Control Point 1
|
||||
|
||||
std::vector<wxPoint> m_BezierPoints;
|
||||
public:
|
||||
DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT );
|
||||
~DRAWSEGMENT();
|
||||
|
|
|
@ -46,8 +46,8 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
|
|||
if( frame->m_DisplayPadFill == FILLED )
|
||||
fillpad = 1;
|
||||
|
||||
#ifdef PCBNEW
|
||||
if( m_Flags & IS_MOVED )
|
||||
#if defined(PCBNEW) || defined(__WXMAC__)
|
||||
if( m_Flags & IS_MOVED || !DisplayOpt.DisplayPadFill )
|
||||
fillpad = 0;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -348,6 +348,8 @@ void WinEDA_PcbFrame::Install_Edit_Cotation( COTATION* Cotation,
|
|||
|
||||
WinEDA_CotationPropertiesFrame* frame = new WinEDA_CotationPropertiesFrame( this,
|
||||
Cotation, DC, pos );
|
||||
|
||||
Ajuste_Details_Cotation( Cotation );
|
||||
frame->ShowModal();
|
||||
frame->Destroy();
|
||||
}
|
||||
|
|
|
@ -787,8 +787,11 @@ void DrawModuleOutlines( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module )
|
|||
if( g_Show_Pads_Module_in_Move )
|
||||
{
|
||||
pad_fill_tmp = DisplayOpt.DisplayPadFill;
|
||||
#ifndef __WXMAC__
|
||||
DisplayOpt.DisplayPadFill = true; /* Trace en SKETCH en deplacement */
|
||||
|
||||
#else
|
||||
DisplayOpt.DisplayPadFill = false;
|
||||
#endif
|
||||
pt_pad = module->m_Pads;
|
||||
for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
|
||||
{
|
||||
|
|
|
@ -753,32 +753,69 @@ void PlotDrawSegment( DRAWSEGMENT* pt_segm, int Format, int masque_layer )
|
|||
{
|
||||
case PLOT_FORMAT_GERBER:
|
||||
SelectD_CODE_For_LineDraw( thickness );
|
||||
if( pt_segm->m_Shape == S_CIRCLE )
|
||||
PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius );
|
||||
else if( pt_segm->m_Shape == S_ARC )
|
||||
PlotArc( PLOT_FORMAT_GERBER, start,
|
||||
|
||||
switch(pt_segm->m_Shape)
|
||||
{
|
||||
case S_CIRCLE:
|
||||
PlotCircle( PLOT_FORMAT_GERBER, thickness, start, radius );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
PlotArc( PLOT_FORMAT_GERBER, start,
|
||||
StAngle, EndAngle, radius, thickness );
|
||||
else
|
||||
PlotGERBERLine( start, end, thickness );
|
||||
break;
|
||||
break;
|
||||
case S_CURVE:
|
||||
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
|
||||
PlotGERBERLine( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PlotGERBERLine( start, end, thickness );
|
||||
}
|
||||
break;
|
||||
|
||||
case PLOT_FORMAT_HPGL:
|
||||
if( pt_segm->m_Shape == S_CIRCLE )
|
||||
PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
|
||||
else if( pt_segm->m_Shape == S_ARC )
|
||||
PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
|
||||
else
|
||||
Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
|
||||
break;
|
||||
|
||||
switch(pt_segm->m_Shape)
|
||||
{
|
||||
case S_CIRCLE:
|
||||
PlotCircle( PLOT_FORMAT_HPGL, thickness, start, radius );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
PlotArc( PLOT_FORMAT_HPGL, start, StAngle, EndAngle, radius, thickness );
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
|
||||
Plot_Filled_Segment_HPGL( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness,(GRFillMode) g_Plot_Mode);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Plot_Filled_Segment_HPGL( start, end, thickness, (GRFillMode) g_Plot_Mode );
|
||||
}
|
||||
break;
|
||||
case PLOT_FORMAT_POST:
|
||||
if( pt_segm->m_Shape == S_CIRCLE )
|
||||
PlotCircle( PLOT_FORMAT_POST, thickness, start, radius );
|
||||
else if( pt_segm->m_Shape == S_ARC )
|
||||
PlotArc( PLOT_FORMAT_POST, start,
|
||||
switch(pt_segm->m_Shape)
|
||||
{
|
||||
case S_CIRCLE:
|
||||
PlotCircle( PLOT_FORMAT_POST, thickness, start, radius );
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
PlotArc( PLOT_FORMAT_POST, start,
|
||||
StAngle, EndAngle, radius, thickness );
|
||||
else
|
||||
PlotFilledSegmentPS( start, end, thickness );
|
||||
break;
|
||||
|
||||
case S_CURVE:
|
||||
for (unsigned int i=1; i < pt_segm->m_BezierPoints.size(); i++) {
|
||||
PlotFilledSegmentPS( pt_segm->m_BezierPoints[i-1], pt_segm->m_BezierPoints[i], thickness);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
PlotFilledSegmentPS( start, end, thickness );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@
|
|||
#include "fctsys.h"
|
||||
|
||||
#include "PolyLine.h"
|
||||
#include "gr_basic.h"
|
||||
#include "bezier_curves.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#define pi 3.14159265359
|
||||
#define pi M_PI
|
||||
|
||||
CPolyLine::CPolyLine()
|
||||
{
|
||||
|
@ -1571,3 +1573,21 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
|
|||
|
||||
Close( STRAIGHT );
|
||||
}
|
||||
|
||||
// Bezier Support
|
||||
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
std::vector<wxPoint> bezier_points;
|
||||
|
||||
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3);
|
||||
for( unsigned int i = 0; i < bezier_points.size() ; i++)
|
||||
AppendCorner( bezier_points[i].x, bezier_points[i].y);
|
||||
}
|
||||
|
||||
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4){
|
||||
std::vector<wxPoint> bezier_points;
|
||||
|
||||
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
for( unsigned int i = 0; i < bezier_points.size() ; i++)
|
||||
AppendCorner( bezier_points[i].x, bezier_points[i].y);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,6 +243,11 @@ public:
|
|||
private:
|
||||
Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data
|
||||
bool bDrawn;
|
||||
|
||||
// Bezier Support
|
||||
public:
|
||||
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3);
|
||||
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
|
||||
};
|
||||
|
||||
#endif // #ifndef POLYLINE_H
|
||||
|
|
Loading…
Reference in New Issue