3d-viewer and polygon functions: remove duplicate code about conversion from basic shapes to polygons.
This commit is contained in:
parent
2dbb428b23
commit
b19cc14ef2
|
@ -30,7 +30,6 @@
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
#include <pcbstruct.h>
|
#include <pcbstruct.h>
|
||||||
#include <drawtxt.h>
|
#include <drawtxt.h>
|
||||||
//include <confirm.h>
|
|
||||||
#include <layers_id_colors_and_visibility.h>
|
#include <layers_id_colors_and_visibility.h>
|
||||||
|
|
||||||
#include <class_board.h>
|
#include <class_board.h>
|
||||||
|
@ -40,9 +39,8 @@
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
#include <class_drawsegment.h>
|
#include <class_drawsegment.h>
|
||||||
#include <class_pcb_text.h>
|
#include <class_pcb_text.h>
|
||||||
#include <class_board_design_settings.h>
|
|
||||||
//#include <class_marker_pcb.h>
|
|
||||||
#include <colors_selection.h>
|
#include <colors_selection.h>
|
||||||
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
#include <3d_viewer.h>
|
#include <3d_viewer.h>
|
||||||
#include <info3d_visu.h>
|
#include <info3d_visu.h>
|
||||||
|
@ -51,15 +49,21 @@
|
||||||
// angle increment to draw a circle, approximated by segments
|
// angle increment to draw a circle, approximated by segments
|
||||||
#define ANGLE_INC(x) (3600/(x))
|
#define ANGLE_INC(x) (3600/(x))
|
||||||
|
|
||||||
|
// Thickness of copper
|
||||||
|
// TODO: use the actual copper thickness to draw copper items with thickness
|
||||||
|
#define COPPER_THICKNESS (int)(0.035 * IU_PER_MM)
|
||||||
|
|
||||||
extern void CheckGLError();
|
extern void CheckGLError();
|
||||||
|
|
||||||
/* draw a segment using 3D primitives, in a XY plane
|
/* draw a thick segment using 3D primitives, in a XY plane
|
||||||
* aStartPos = 3D position of the starting point (3D units)
|
* wxPoint aStart, wxPoint aEnd = YX position of ends in board units
|
||||||
* aEndx, aEndy = 3D position of the ending point (3D units)
|
* aWidth = width of segment in board units
|
||||||
* aWidth = width of the segment (3D units)
|
* aThickness = thickness of segment in board units
|
||||||
|
* aZpos = z position of segment in board units
|
||||||
*/
|
*/
|
||||||
static void Draw3D_FilledSegment( const S3D_VERTEX& aStartPos,
|
static void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
|
||||||
double aEndx, double aEndy, double aWidth );
|
int aWidth, int aThickness, int aZpos,
|
||||||
|
double aBiuTo3DUnits );
|
||||||
|
|
||||||
static void Draw3D_SegmentWithHole( double startx, double starty,
|
static void Draw3D_SegmentWithHole( double startx, double starty,
|
||||||
double endx, double endy,
|
double endx, double endy,
|
||||||
|
@ -116,12 +120,12 @@ static void Draw3D_ZaxisCylinder( const S3D_VERTEX& aPos, double aRadius, dou
|
||||||
|
|
||||||
/* draw an oblong cylinder (oblong hole) using 3D primitives.
|
/* draw an oblong cylinder (oblong hole) using 3D primitives.
|
||||||
* the cylinder axis are parallel to the Z axis
|
* the cylinder axis are parallel to the Z axis
|
||||||
* aCenterPos = 3D position of the first axis cylinder
|
* aStartPos = 3D position of the first axis cylinder
|
||||||
* aEndx, aEndy = 3D position of the second axis cylinder
|
* aEndx, aEndy = 3D position of the second axis cylinder
|
||||||
* aRadius = radius of the cylinder (3D units)
|
* aRadius = radius of the cylinder (3D units)
|
||||||
* aHeight = height of the cylinder (3D units)
|
* aHeight = height of the cylinder (3D units)
|
||||||
*/
|
*/
|
||||||
static void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aCenterPos,
|
static void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aStartPos,
|
||||||
double aEndx, double aEndy,
|
double aEndx, double aEndy,
|
||||||
double aRadius, double aHeight );
|
double aRadius, double aHeight );
|
||||||
|
|
||||||
|
@ -410,8 +414,7 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone )
|
||||||
if( layer == LAST_COPPER_LAYER )
|
if( layer == LAST_COPPER_LAYER )
|
||||||
layer = g_Parm_3D_Visu.m_CopperLayersCount - 1;
|
layer = g_Parm_3D_Visu.m_CopperLayersCount - 1;
|
||||||
|
|
||||||
double zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
|
int zpos = KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] / g_Parm_3D_Visu.m_BoardScale );
|
||||||
double width = aZone->m_ZoneMinThickness * g_Parm_3D_Visu.m_BoardScale;
|
|
||||||
|
|
||||||
SetGLColor( color );
|
SetGLColor( color );
|
||||||
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
||||||
|
@ -428,14 +431,10 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone )
|
||||||
{
|
{
|
||||||
// segments are used to fill areas
|
// segments are used to fill areas
|
||||||
for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ )
|
for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ )
|
||||||
{
|
Draw3D_SolidSegment( aZone->m_FillSegmList[iseg].m_Start,
|
||||||
double ox = aZone->m_FillSegmList[iseg].m_Start.x * g_Parm_3D_Visu.m_BoardScale;
|
aZone->m_FillSegmList[iseg].m_End,
|
||||||
double oy = aZone->m_FillSegmList[iseg].m_Start.y * g_Parm_3D_Visu.m_BoardScale;
|
aZone->m_ZoneMinThickness, COPPER_THICKNESS, zpos,
|
||||||
double fx = aZone->m_FillSegmList[iseg].m_End.x * g_Parm_3D_Visu.m_BoardScale;
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
double fy = aZone->m_FillSegmList[iseg].m_End.y * g_Parm_3D_Visu.m_BoardScale;
|
|
||||||
S3D_VERTEX pos( ox, -oy, zpos );
|
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, width );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw copper area outlines
|
// Draw copper area outlines
|
||||||
|
@ -458,12 +457,11 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone )
|
||||||
if( begincorner->m_utility == 0 )
|
if( begincorner->m_utility == 0 )
|
||||||
{
|
{
|
||||||
// Draw only basic outlines, not extra segments
|
// Draw only basic outlines, not extra segments
|
||||||
double ox = begincorner->x * g_Parm_3D_Visu.m_BoardScale;
|
wxPoint start( begincorner->x, begincorner->y );
|
||||||
double oy = begincorner->y * g_Parm_3D_Visu.m_BoardScale;
|
wxPoint end( endcorner->x, endcorner->y );
|
||||||
double fx = endcorner->x * g_Parm_3D_Visu.m_BoardScale;
|
Draw3D_SolidSegment( start, end,
|
||||||
double fy = endcorner->y * g_Parm_3D_Visu.m_BoardScale;
|
aZone->m_ZoneMinThickness, COPPER_THICKNESS, zpos,
|
||||||
S3D_VERTEX pos( ox, -oy, zpos );
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, width );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (endcorner->end_contour) || (ic == imax) )
|
if( (endcorner->end_contour) || (ic == imax) )
|
||||||
|
@ -472,12 +470,11 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone )
|
||||||
if( endcorner->m_utility == 0 )
|
if( endcorner->m_utility == 0 )
|
||||||
{
|
{
|
||||||
// Draw only basic outlines, not extra segments
|
// Draw only basic outlines, not extra segments
|
||||||
double ox = endcorner->x * g_Parm_3D_Visu.m_BoardScale;
|
wxPoint start( endcorner->x, endcorner->y );
|
||||||
double oy = endcorner->y * g_Parm_3D_Visu.m_BoardScale;
|
wxPoint end( firstcorner->x, firstcorner->y );
|
||||||
double fx = firstcorner->x * g_Parm_3D_Visu.m_BoardScale;
|
Draw3D_SolidSegment( start, end,
|
||||||
double fy = firstcorner->y * g_Parm_3D_Visu.m_BoardScale;
|
aZone->m_ZoneMinThickness, COPPER_THICKNESS, zpos,
|
||||||
S3D_VERTEX pos( ox, -oy, zpos );
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, width );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ic++;
|
ic++;
|
||||||
|
@ -632,19 +629,14 @@ void EDA_3D_CANVAS::Draw3D_Track( TRACK* aTrack )
|
||||||
if( layer == LAST_COPPER_LAYER )
|
if( layer == LAST_COPPER_LAYER )
|
||||||
layer = g_Parm_3D_Visu.m_CopperLayersCount - 1;
|
layer = g_Parm_3D_Visu.m_CopperLayersCount - 1;
|
||||||
|
|
||||||
double zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
|
int zpos = KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] / g_Parm_3D_Visu.m_BoardScale );
|
||||||
|
|
||||||
SetGLColor( color );
|
SetGLColor( color );
|
||||||
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
||||||
|
|
||||||
double w = aTrack->m_Width * g_Parm_3D_Visu.m_BoardScale;
|
Draw3D_SolidSegment( aTrack->m_Start, aTrack->m_End,
|
||||||
double ox = aTrack->m_Start.x * g_Parm_3D_Visu.m_BoardScale;
|
aTrack->m_Width, COPPER_THICKNESS, zpos,
|
||||||
double oy = aTrack->m_Start.y * g_Parm_3D_Visu.m_BoardScale;
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
double fx = aTrack->m_End.x * g_Parm_3D_Visu.m_BoardScale;
|
|
||||||
double fy = aTrack->m_End.y * g_Parm_3D_Visu.m_BoardScale;
|
|
||||||
|
|
||||||
S3D_VERTEX pos( ox, -oy, zpos );
|
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, w );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -801,10 +793,11 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(),
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
segment->GetWidth(), COPPER_THICKNESS,
|
||||||
Draw3D_FilledSegment( pos, xf, -yf, w );
|
KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] /
|
||||||
}
|
g_Parm_3D_Visu.m_BoardScale ),
|
||||||
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,10 +826,11 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(),
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
segment->GetWidth(), COPPER_THICKNESS,
|
||||||
Draw3D_FilledSegment( pos , xf, -yf, w );
|
KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] /
|
||||||
}
|
g_Parm_3D_Visu.m_BoardScale ),
|
||||||
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -847,18 +841,14 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
|
||||||
// These variables are used in Draw3dTextSegm.
|
// These variables are used in Draw3dTextSegm.
|
||||||
// But Draw3dTextSegm is a call back function, so we cannot send them as arguments,
|
// But Draw3dTextSegm is a call back function, so we cannot send them as arguments,
|
||||||
// so they are static.
|
// so they are static.
|
||||||
static double s_Text3DWidth, s_Text3DZPos;
|
int s_Text3DWidth, s_Text3DZPos;
|
||||||
|
|
||||||
// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
|
// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
|
||||||
static void Draw3dTextSegm( int x0, int y0, int xf, int yf )
|
static void Draw3dTextSegm( int x0, int y0, int xf, int yf )
|
||||||
{
|
{
|
||||||
double startx = x0 * g_Parm_3D_Visu.m_BoardScale;
|
Draw3D_SolidSegment( wxPoint( x0, y0), wxPoint( xf, yf ),
|
||||||
double starty = y0 * g_Parm_3D_Visu.m_BoardScale;
|
s_Text3DWidth, COPPER_THICKNESS, s_Text3DZPos,
|
||||||
double endx = xf * g_Parm_3D_Visu.m_BoardScale;
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
double endy = yf * g_Parm_3D_Visu.m_BoardScale;
|
|
||||||
|
|
||||||
S3D_VERTEX pos( startx, -starty, s_Text3DZPos );
|
|
||||||
Draw3D_FilledSegment( pos, endx, -endy, s_Text3DWidth );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -868,8 +858,8 @@ void EDA_3D_CANVAS::Draw3D_DrawText( TEXTE_PCB* text )
|
||||||
int color = g_ColorsSettings.GetLayerColor( layer );
|
int color = g_ColorsSettings.GetLayerColor( layer );
|
||||||
|
|
||||||
SetGLColor( color );
|
SetGLColor( color );
|
||||||
s_Text3DZPos = g_Parm_3D_Visu.m_LayerZcoord[layer];
|
s_Text3DZPos = KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] / g_Parm_3D_Visu.m_BoardScale );
|
||||||
s_Text3DWidth = text->GetThickness() * g_Parm_3D_Visu.m_BoardScale;
|
s_Text3DWidth = text->GetThickness();
|
||||||
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
||||||
wxSize size = text->m_Size;
|
wxSize size = text->m_Size;
|
||||||
|
|
||||||
|
@ -993,7 +983,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
{
|
{
|
||||||
wxString s;
|
wxString s;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
double x, y, fx, fy, w, zpos;
|
double x, y, fx, fy, w;
|
||||||
|
|
||||||
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( m_Layer ) == false )
|
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( m_Layer ) == false )
|
||||||
return;
|
return;
|
||||||
|
@ -1016,27 +1006,26 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
for( int layer = 0; layer < g_Parm_3D_Visu.m_CopperLayersCount; layer++ )
|
for( int layer = 0; layer < g_Parm_3D_Visu.m_CopperLayersCount; layer++ )
|
||||||
{
|
{
|
||||||
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
glNormal3f( 0.0, 0.0, (layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
||||||
zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
|
int izpos = KiROUND( g_Parm_3D_Visu.m_LayerZcoord[layer] / g_Parm_3D_Visu.m_BoardScale );
|
||||||
|
|
||||||
switch( m_Shape )
|
switch( m_Shape )
|
||||||
{
|
{
|
||||||
case S_SEGMENT:
|
case S_SEGMENT:
|
||||||
{
|
Draw3D_SolidSegment( m_Start, m_End, m_Width,
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
COPPER_THICKNESS, izpos,
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, w );
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CIRCLE:
|
case S_CIRCLE:
|
||||||
{
|
{
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
S3D_VERTEX pos( x, -y, g_Parm_3D_Visu.m_LayerZcoord[layer] );
|
||||||
Draw3D_ThickCircle( pos, hypot( x - fx, y - fy ), w);
|
Draw3D_ThickCircle( pos, hypot( x - fx, y - fy ), w);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ARC:
|
case S_ARC:
|
||||||
{
|
{
|
||||||
S3D_VERTEX pos( fx, -fy, zpos );
|
S3D_VERTEX pos( fx, -fy, g_Parm_3D_Visu.m_LayerZcoord[layer] );
|
||||||
Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w );
|
Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1059,7 +1048,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
pt += module->m_Pos;
|
pt += module->m_Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
glcanvas->Draw3D_Polygon( points, zpos );
|
glcanvas->Draw3D_Polygon( points, g_Parm_3D_Visu.m_LayerZcoord[layer] );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1073,27 +1062,26 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glNormal3f( 0.0, 0.0, (m_Layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
glNormal3f( 0.0, 0.0, (m_Layer == LAYER_N_BACK) ? -1.0 : 1.0 );
|
||||||
zpos = g_Parm_3D_Visu.m_LayerZcoord[m_Layer];
|
int izpos = KiROUND( g_Parm_3D_Visu.m_LayerZcoord[m_Layer] / g_Parm_3D_Visu.m_BoardScale );
|
||||||
|
|
||||||
switch( m_Shape )
|
switch( m_Shape )
|
||||||
{
|
{
|
||||||
case S_SEGMENT:
|
case S_SEGMENT:
|
||||||
{
|
Draw3D_SolidSegment( m_Start, m_End, m_Width,
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
COPPER_THICKNESS, izpos,
|
||||||
Draw3D_FilledSegment( pos, fx, -fy, w );
|
g_Parm_3D_Visu.m_BoardScale );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CIRCLE:
|
case S_CIRCLE:
|
||||||
{
|
{
|
||||||
S3D_VERTEX pos( x, -y, zpos );
|
S3D_VERTEX pos( x, -y, g_Parm_3D_Visu.m_LayerZcoord[m_Layer] );
|
||||||
Draw3D_ThickCircle( pos, hypot( x - fx, y - fy ), w );
|
Draw3D_ThickCircle( pos, hypot( x - fx, y - fy ), w );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ARC:
|
case S_ARC:
|
||||||
{
|
{
|
||||||
S3D_VERTEX pos( fx, -fy, zpos );
|
S3D_VERTEX pos( fx, -fy, g_Parm_3D_Visu.m_LayerZcoord[m_Layer] );
|
||||||
Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w );
|
Draw3D_ArcSegment( pos, x, -y, (double) m_Angle, w );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1116,7 +1104,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||||
pt += module->m_Pos;
|
pt += module->m_Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
glcanvas->Draw3D_Polygon( points, zpos );
|
glcanvas->Draw3D_Polygon( points, g_Parm_3D_Visu.m_LayerZcoord[m_Layer] );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1460,56 +1448,72 @@ static void Draw3D_ZaxisCylinder( const S3D_VERTEX& aPos, double aRadius, double
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Draw a polygon similar to a segment has rounded tips
|
/* draw a thick segment using 3D primitives, in a XY plane
|
||||||
static void Draw3D_FilledSegment( const S3D_VERTEX& aStartPos,
|
* wxPoint aStart, wxPoint aEnd = YX position of end in board units
|
||||||
double aEndx, double aEndy, double aWidth )
|
* aWidth = width of segment in board units
|
||||||
|
* aThickness = thickness of segment in board units
|
||||||
|
* aZpos = z position of segment in board units
|
||||||
|
*/
|
||||||
|
void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
|
||||||
|
int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
double dx, dy, x, y, firstx = 0, firsty = 0;
|
std::vector <CPolyPt> cornerBuffer;
|
||||||
int ii, angle;
|
|
||||||
|
|
||||||
// Calculate the coordinates of the segment assumed horizontal.
|
|
||||||
// Then turn the strips of the desired angle.
|
|
||||||
dx = aEndx - aStartPos.x;
|
|
||||||
dy = aEndy - aStartPos.y;
|
|
||||||
angle = (int) ( ( atan2( dy, dx ) * 1800 / M_PI ) + 0.5 );
|
|
||||||
|
|
||||||
RotatePoint( &dx, &dy, angle );
|
|
||||||
aWidth /= 2;
|
|
||||||
|
|
||||||
glBegin( GL_POLYGON );
|
|
||||||
|
|
||||||
// Trace the flare to right (1st half polygon at the end of the segment)
|
|
||||||
const int slice = 16;
|
const int slice = 16;
|
||||||
for( ii = 0; ii <= slice/2; ii++ )
|
TransformRoundedEndsSegmentToPolygon(cornerBuffer, aStart, aEnd, slice, aWidth );
|
||||||
{
|
|
||||||
x = 0.0;
|
|
||||||
y = -aWidth;
|
|
||||||
RotatePoint( &x, &y, -ii * ANGLE_INC(slice) );
|
|
||||||
x += dx;
|
|
||||||
RotatePoint( &x, &y, -angle );
|
|
||||||
glVertex3f( aStartPos.x + x, aStartPos.y + y, aStartPos.z );
|
|
||||||
|
|
||||||
if( ii == 0 )
|
//Build the 3D data : upper side then lower side
|
||||||
{
|
double zupperpos = ( aZpos + (aThickness/2) ) * aBiuTo3DUnits;
|
||||||
firstx = aStartPos.x + x;
|
double zlowerpos = ( aZpos - (aThickness/2) ) * aBiuTo3DUnits;
|
||||||
firsty = aStartPos.y + y;
|
if( aThickness )
|
||||||
}
|
glNormal3f( 0.0, 0.0, 1.0 ); // Normale is Z axis
|
||||||
}
|
|
||||||
|
|
||||||
// Rounding the left (2nd half polygon is the origin of the segment)
|
double zpos = zupperpos; // start with upper side
|
||||||
for( ii = 0; ii <= slice/2; ii++ )
|
for( int face = 0; face < 2; face ++ )
|
||||||
{
|
{
|
||||||
int jj = ii * ANGLE_INC(slice);
|
glBegin( GL_POLYGON );
|
||||||
x = 0.0;
|
for( unsigned ii = 0; ii < cornerBuffer.size(); ii++ )
|
||||||
y = aWidth;
|
glVertex3f( cornerBuffer[ii].x * aBiuTo3DUnits,
|
||||||
RotatePoint( &x, &y, -angle - jj );
|
- cornerBuffer[ii].y * aBiuTo3DUnits, zpos );
|
||||||
glVertex3f( aStartPos.x + x, aStartPos.y + y, aStartPos.z );
|
|
||||||
}
|
|
||||||
|
|
||||||
glVertex3f( firstx, firsty, aStartPos.z );
|
// Close the polygon shape
|
||||||
|
glVertex3f( cornerBuffer[0].x * aBiuTo3DUnits,
|
||||||
|
- cornerBuffer[0].y * aBiuTo3DUnits, zpos );
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
|
||||||
|
|
||||||
|
if( aThickness == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Prepare the creation of lower side
|
||||||
|
glNormal3f( 0.0, 0.0, -1.0 ); // Normale now is -Z axis
|
||||||
|
zpos = zlowerpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Build the 3D data : vertical sides
|
||||||
|
std::vector< S3D_VERTEX > vertices;
|
||||||
|
vertices.resize(4);
|
||||||
|
for( int ii = 0; ii < slice; ii++ )
|
||||||
|
{
|
||||||
|
int jj = ii+1;
|
||||||
|
if( jj >=slice )
|
||||||
|
jj = 0;
|
||||||
|
vertices[0].x = cornerBuffer[ii].x;
|
||||||
|
vertices[0].y = -cornerBuffer[ii].y;
|
||||||
|
vertices[0].z = aZpos + (aThickness/2);
|
||||||
|
vertices[1].x = cornerBuffer[ii].x;
|
||||||
|
vertices[1].y = -cornerBuffer[ii].y;
|
||||||
|
vertices[1].z = aZpos - (aThickness/2);
|
||||||
|
vertices[2].x = cornerBuffer[jj].x;
|
||||||
|
vertices[2].y = -cornerBuffer[jj].y;
|
||||||
|
vertices[2].z = aZpos - (aThickness/2);
|
||||||
|
vertices[3].x = cornerBuffer[jj].x;
|
||||||
|
vertices[3].y = -cornerBuffer[jj].y;
|
||||||
|
vertices[3].z = aZpos + (aThickness/2);
|
||||||
|
|
||||||
|
Set_Object_Data( vertices );
|
||||||
|
}
|
||||||
|
|
||||||
|
glNormal3f( 0.0, 0.0, 1.0 ); // Normal is Z axis
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw a polygon similar to a segment ends with round hole
|
/* Draw a polygon similar to a segment ends with round hole
|
||||||
*/
|
*/
|
||||||
|
@ -1646,7 +1650,7 @@ static void Draw3D_ThickCircle( const S3D_VERTEX& aCenterPos, double aRadius, do
|
||||||
* draw a segment with an oblong hole.
|
* draw a segment with an oblong hole.
|
||||||
* Used to draw oblong holes
|
* Used to draw oblong holes
|
||||||
*/
|
*/
|
||||||
void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aCenterPos,
|
void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aStartPos,
|
||||||
double aEndx, double aEndy,
|
double aEndx, double aEndy,
|
||||||
double aRadius, double aHeight )
|
double aRadius, double aHeight )
|
||||||
{
|
{
|
||||||
|
@ -1659,20 +1663,20 @@ void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aCenterPos,
|
||||||
|
|
||||||
DataScale3D = 1.0; // Coordinate is already in range for Set_Object_Data();
|
DataScale3D = 1.0; // Coordinate is already in range for Set_Object_Data();
|
||||||
|
|
||||||
double dx = aEndx - aCenterPos.x;
|
double dx = aEndx - aStartPos.x;
|
||||||
double dy = aEndy - aCenterPos.y;
|
double dy = aEndy - aStartPos.y;
|
||||||
double angle = atan2( dy, dx ) * 1800 / M_PI;
|
double angle = atan2( dy, dx ) * 1800 / M_PI;
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy = aRadius;
|
dy = aRadius;
|
||||||
|
|
||||||
// draws the first rectangle between half cylinders
|
// draws the first rectangle between half cylinders
|
||||||
RotatePoint( &dx, &dy, angle );
|
RotatePoint( &dx, &dy, angle );
|
||||||
coords[0].x = coords[1].x = aCenterPos.x + dx;
|
coords[0].x = coords[1].x = aStartPos.x + dx;
|
||||||
coords[0].y = coords[1].y = aCenterPos.y - dy;
|
coords[0].y = coords[1].y = aStartPos.y - dy;
|
||||||
coords[2].x = coords[3].x = aEndx + dx;
|
coords[2].x = coords[3].x = aEndx + dx;
|
||||||
coords[2].y = coords[3].y = aEndy - dy;
|
coords[2].y = coords[3].y = aEndy - dy;
|
||||||
coords[0].z = coords[3].z = aCenterPos.z;
|
coords[0].z = coords[3].z = aStartPos.z;
|
||||||
coords[1].z = coords[2].z = aCenterPos.z + aHeight;
|
coords[1].z = coords[2].z = aStartPos.z + aHeight;
|
||||||
Set_Object_Data( coords );
|
Set_Object_Data( coords );
|
||||||
|
|
||||||
// Draw the first half cylinder
|
// Draw the first half cylinder
|
||||||
|
@ -1693,10 +1697,10 @@ void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aCenterPos,
|
||||||
// draws the second rectangle between half cylinders
|
// draws the second rectangle between half cylinders
|
||||||
coords[0].x = coords[1].x = aEndx - dx;
|
coords[0].x = coords[1].x = aEndx - dx;
|
||||||
coords[0].y = coords[1].y = aEndy + dy;
|
coords[0].y = coords[1].y = aEndy + dy;
|
||||||
coords[2].x = coords[3].x = aCenterPos.x - dx;
|
coords[2].x = coords[3].x = aStartPos.x - dx;
|
||||||
coords[2].y = coords[3].y = aCenterPos.y + dy;
|
coords[2].y = coords[3].y = aStartPos.y + dy;
|
||||||
coords[0].z = coords[3].z = aCenterPos.z;
|
coords[0].z = coords[3].z = aStartPos.z;
|
||||||
coords[1].z = coords[2].z = aCenterPos.z + aHeight;
|
coords[1].z = coords[2].z = aStartPos.z + aHeight;
|
||||||
Set_Object_Data( coords );
|
Set_Object_Data( coords );
|
||||||
|
|
||||||
// Draw the second half cylinder
|
// Draw the second half cylinder
|
||||||
|
@ -1709,8 +1713,8 @@ void Draw3D_ZaxisOblongCylinder( const S3D_VERTEX& aCenterPos,
|
||||||
coords[0].y = coords[2].y;
|
coords[0].y = coords[2].y;
|
||||||
coords[1].x = coords[3].x;
|
coords[1].x = coords[3].x;
|
||||||
coords[1].y = coords[3].y;
|
coords[1].y = coords[3].y;
|
||||||
coords[2].x = coords[3].x = aCenterPos.x + ddx;
|
coords[2].x = coords[3].x = aStartPos.x + ddx;
|
||||||
coords[2].y = coords[3].y = aCenterPos.y + ddy;
|
coords[2].y = coords[3].y = aStartPos.y + ddy;
|
||||||
Set_Object_Data( coords );
|
Set_Object_Data( coords );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ set(PCB_COMMON_SRCS
|
||||||
base_screen.cpp
|
base_screen.cpp
|
||||||
eda_text.cpp
|
eda_text.cpp
|
||||||
class_page_info.cpp
|
class_page_info.cpp
|
||||||
|
convert_basic_shapes_to_polygon.cpp
|
||||||
pcbcommon.cpp
|
pcbcommon.cpp
|
||||||
footprint_info.cpp
|
footprint_info.cpp
|
||||||
../pcbnew/basepcbframe.cpp
|
../pcbnew/basepcbframe.cpp
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/**
|
||||||
|
* @file convert_basic_shapes_to_polygon.cpp
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
|
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fctsys.h>
|
||||||
|
#include <trigo.h>
|
||||||
|
#include <macros.h>
|
||||||
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformCircleToPolygon
|
||||||
|
* convert a circle to a polygon, using multiple straight lines
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCenter = the center of the circle
|
||||||
|
* @param aRadius = the radius of the circle
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* Note: the polygon is inside the circle, so if you want to have the polygon
|
||||||
|
* outside the circle, you should give aRadius calculated with a corrrection factor
|
||||||
|
*/
|
||||||
|
void TransformCircleToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCenter, int aRadius,
|
||||||
|
int aCircleToSegmentsCount )
|
||||||
|
{
|
||||||
|
wxPoint corner_position;
|
||||||
|
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
||||||
|
int halfstep = 1800 / aCircleToSegmentsCount; // the starting value for rot angles
|
||||||
|
|
||||||
|
for( int ii = 0; ii < aCircleToSegmentsCount; ii++ )
|
||||||
|
{
|
||||||
|
corner_position.x = aRadius;
|
||||||
|
corner_position.y = 0;
|
||||||
|
int angle = (ii * delta) + halfstep;
|
||||||
|
RotatePoint( &corner_position.x, &corner_position.y, angle );
|
||||||
|
corner_position += aCenter;
|
||||||
|
CPolyPt polypoint( corner_position.x, corner_position.y );
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
aCornerBuffer.back().end_contour = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformRoundedEndsSegmentToPolygon
|
||||||
|
* convert a segment with rounded ends to a polygon
|
||||||
|
* Convert arcs to multiple straight lines
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aStart = the segment start point coordinate
|
||||||
|
* @param aEnd = the segment end point coordinate
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = the segment width
|
||||||
|
* Note: the polygon is inside the arc ends, so if you want to have the polygon
|
||||||
|
* outside the circle, you should give aStart and aEnd calculated with a correction factor
|
||||||
|
*/
|
||||||
|
void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aStart, wxPoint aEnd,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
int aWidth )
|
||||||
|
{
|
||||||
|
int radius = aWidth / 2;
|
||||||
|
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
|
||||||
|
wxPoint startp = aStart;
|
||||||
|
wxPoint corner;
|
||||||
|
int seg_len;
|
||||||
|
CPolyPt polypoint;
|
||||||
|
|
||||||
|
// normalize the position in order to have endp.x >= 0;
|
||||||
|
if( endp.x < 0 )
|
||||||
|
{
|
||||||
|
endp = aStart - aEnd;
|
||||||
|
startp = aEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
|
||||||
|
seg_len = (int) sqrt( ( (double) endp.y * endp.y ) + ( (double) endp.x * endp.x ) );
|
||||||
|
|
||||||
|
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
||||||
|
|
||||||
|
// Compute the outlines of the segment, and creates a polygon
|
||||||
|
// add right rounded end:
|
||||||
|
for( int ii = 0; ii < 1800; ii += delta )
|
||||||
|
{
|
||||||
|
corner = wxPoint( 0, radius );
|
||||||
|
RotatePoint( &corner, ii );
|
||||||
|
corner.x += seg_len;
|
||||||
|
RotatePoint( &corner, -delta_angle );
|
||||||
|
corner += startp;
|
||||||
|
polypoint.x = corner.x;
|
||||||
|
polypoint.y = corner.y;
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish arc:
|
||||||
|
corner = wxPoint( seg_len, -radius );
|
||||||
|
RotatePoint( &corner, -delta_angle );
|
||||||
|
corner += startp;
|
||||||
|
polypoint.x = corner.x;
|
||||||
|
polypoint.y = corner.y;
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
|
||||||
|
// add left rounded end:
|
||||||
|
for( int ii = 0; ii < 1800; ii += delta )
|
||||||
|
{
|
||||||
|
corner = wxPoint( 0, -radius );
|
||||||
|
RotatePoint( &corner, ii );
|
||||||
|
RotatePoint( &corner, -delta_angle );
|
||||||
|
corner += startp;
|
||||||
|
polypoint.x = corner.x;
|
||||||
|
polypoint.y = corner.y;
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish arc:
|
||||||
|
corner = wxPoint( 0, radius );
|
||||||
|
RotatePoint( &corner, -delta_angle );
|
||||||
|
corner += startp;
|
||||||
|
polypoint.x = corner.x;
|
||||||
|
polypoint.y = corner.y;
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
|
||||||
|
aCornerBuffer.back().end_contour = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformArcToPolygon
|
||||||
|
* Creates a polygon from an Arc
|
||||||
|
* Convert arcs to multiple straight segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCentre = centre of the arc or circle
|
||||||
|
* @param aStart = start point of the arc, or a point on the circle
|
||||||
|
* @param aArcAngle = arc angle in 0.1 degrees. For a circle, aArcAngle = 3600
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = width (thickness) of the line
|
||||||
|
*/
|
||||||
|
void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCentre, wxPoint aStart, int aArcAngle,
|
||||||
|
int aCircleToSegmentsCount, int aWidth )
|
||||||
|
{
|
||||||
|
wxPoint arc_start, arc_end;
|
||||||
|
int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
|
||||||
|
|
||||||
|
arc_end = arc_start = aStart;
|
||||||
|
|
||||||
|
if( aArcAngle != 3600 )
|
||||||
|
{
|
||||||
|
RotatePoint( &arc_end, aCentre, -aArcAngle );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aArcAngle < 0 )
|
||||||
|
{
|
||||||
|
EXCHG( arc_start, arc_end );
|
||||||
|
NEGATE( aArcAngle );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the ends of segments and creates poly
|
||||||
|
wxPoint curr_end = arc_start;
|
||||||
|
wxPoint curr_start = arc_start;
|
||||||
|
|
||||||
|
for( int ii = delta; ii < aArcAngle; ii += delta )
|
||||||
|
{
|
||||||
|
curr_end = arc_start;
|
||||||
|
RotatePoint( &curr_end, aCentre, -ii );
|
||||||
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
|
||||||
|
aCircleToSegmentsCount, aWidth );
|
||||||
|
curr_start = curr_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( curr_end != arc_end )
|
||||||
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||||
|
curr_end, arc_end, aCircleToSegmentsCount, aWidth );
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* @file convert_basic_shapes_to_polygon.h
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
|
* Copyright (C) 1992-2012 KiCad Developers, see change_log.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
||||||
|
#define CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fctsys.h>
|
||||||
|
#include <trigo.h>
|
||||||
|
#include <macros.h>
|
||||||
|
#include <PolyLine.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformCircleToPolygon
|
||||||
|
* convert a circle to a polygon, using multiple straight lines
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCenter = the center of the circle
|
||||||
|
* @param aRadius = the radius of the circle
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* Note: the polygon is inside the circle, so if you want to have the polygon
|
||||||
|
* outside the circle, you should give aRadius calculated with a correction factor
|
||||||
|
*/
|
||||||
|
void TransformCircleToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCenter, int aRadius,
|
||||||
|
int aCircleToSegmentsCount );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformRoundedEndsSegmentToPolygon
|
||||||
|
* convert a segment with rounded ends to a polygon
|
||||||
|
* Convert arcs to multiple straight lines
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aStart = the segment start point coordinate
|
||||||
|
* @param aEnd = the segment end point coordinate
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = the segment width
|
||||||
|
* Note: the polygon is inside the arc ends, so if you want to have the polygon
|
||||||
|
* outside the circle, you should give aStart and aEnd calculated with a correction factor
|
||||||
|
*/
|
||||||
|
void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aStart, wxPoint aEnd,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
int aWidth );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformArcToPolygon
|
||||||
|
* Creates a polygon from an Arc
|
||||||
|
* Convert arcs to multiple straight segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCentre = centre of the arc or circle
|
||||||
|
* @param aStart = start point of the arc, or a point on the circle
|
||||||
|
* @param aArcAngle = arc angle in 0.1 degrees. For a circle, aArcAngle = 3600
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = width (thickness) of the line
|
||||||
|
*/
|
||||||
|
void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCentre, wxPoint aStart, int aArcAngle,
|
||||||
|
int aCircleToSegmentsCount, int aWidth );
|
||||||
|
|
||||||
|
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
|
@ -19,75 +19,7 @@
|
||||||
#include <class_drawsegment.h>
|
#include <class_drawsegment.h>
|
||||||
#include <class_pcb_text.h>
|
#include <class_pcb_text.h>
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
// Exported functions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function TransformRoundedEndsSegmentToPolygon
|
|
||||||
* convert a segment with rounded ends to a polygon
|
|
||||||
* Convert arcs to multiple straight lines
|
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
|
||||||
* @param aStart = the segment start point coordinate
|
|
||||||
* @param aEnd = the segment end point coordinate
|
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
|
||||||
* @param aWidth = the segment width
|
|
||||||
*/
|
|
||||||
void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
|
||||||
wxPoint aStart, wxPoint aEnd,
|
|
||||||
int aCircleToSegmentsCount,
|
|
||||||
int aWidth );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function TransformArcToPolygon
|
|
||||||
* Creates a polygon from an Arc
|
|
||||||
* Convert arcs to multiple straight segments
|
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
|
||||||
* @param aCentre = centre of the arc or circle
|
|
||||||
* @param aStart = start point of the arc, or a point on the circle
|
|
||||||
* @param aArcAngle = arc angle in 0.1 degrees. For a circle, aArcAngle = 3600
|
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
|
||||||
* @param aWidth = width (thickness) of the line
|
|
||||||
*/
|
|
||||||
void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
|
||||||
wxPoint aCentre, wxPoint aStart, int aArcAngle,
|
|
||||||
int aCircleToSegmentsCount, int aWidth )
|
|
||||||
{
|
|
||||||
wxPoint arc_start, arc_end;
|
|
||||||
int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
|
|
||||||
|
|
||||||
arc_end = arc_start = aStart;
|
|
||||||
|
|
||||||
if( aArcAngle != 3600 )
|
|
||||||
{
|
|
||||||
RotatePoint( &arc_end, aCentre, -aArcAngle );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aArcAngle < 0 )
|
|
||||||
{
|
|
||||||
EXCHG( arc_start, arc_end );
|
|
||||||
NEGATE( aArcAngle );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the ends of segments and creates poly
|
|
||||||
wxPoint curr_end = arc_start;
|
|
||||||
wxPoint curr_start = arc_start;
|
|
||||||
|
|
||||||
for( int ii = delta; ii < aArcAngle; ii += delta )
|
|
||||||
{
|
|
||||||
curr_end = arc_start;
|
|
||||||
RotatePoint( &curr_end, aCentre, -ii );
|
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
|
|
||||||
aCircleToSegmentsCount, aWidth );
|
|
||||||
curr_start = curr_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( curr_end != arc_end )
|
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
|
||||||
curr_end, arc_end, aCircleToSegmentsCount, aWidth );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
* Function TransformShapeWithClearanceToPolygon
|
||||||
|
@ -276,29 +208,14 @@ void TRACK:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor )
|
double aCorrectionFactor )
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
|
||||||
int ii, angle;
|
|
||||||
int dx = (m_Width / 2) + aClearanceValue;
|
|
||||||
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
|
||||||
|
|
||||||
switch( Type() )
|
switch( Type() )
|
||||||
{
|
{
|
||||||
case PCB_VIA_T:
|
case PCB_VIA_T:
|
||||||
dx = (int) ( dx * aCorrectionFactor );
|
|
||||||
|
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount; ii++ )
|
|
||||||
{
|
{
|
||||||
corner_position = wxPoint( dx, 0 );
|
int radius = (m_Width / 2) + aClearanceValue;
|
||||||
RotatePoint( &corner_position.x, &corner_position.y, (1800 / aCircleToSegmentsCount) );
|
radius = KiROUND( radius * aCorrectionFactor );
|
||||||
angle = ii * delta;
|
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aCircleToSegmentsCount );
|
||||||
RotatePoint( &corner_position.x, &corner_position.y, angle );
|
|
||||||
corner_position.x += m_Start.x;
|
|
||||||
corner_position.y += m_Start.y;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aCornerBuffer.back().end_contour = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -311,78 +228,6 @@ void TRACK:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function TransformRoundedEndsSegmentToPolygon
|
|
||||||
*/
|
|
||||||
void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
|
||||||
wxPoint aStart, wxPoint aEnd,
|
|
||||||
int aCircleToSegmentsCount,
|
|
||||||
int aWidth )
|
|
||||||
{
|
|
||||||
int radius = aWidth / 2;
|
|
||||||
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
|
|
||||||
wxPoint startp = aStart;
|
|
||||||
wxPoint corner;
|
|
||||||
int seg_len;
|
|
||||||
CPolyPt polypoint;
|
|
||||||
|
|
||||||
// normalize the position in order to have endp.x >= 0;
|
|
||||||
if( endp.x < 0 )
|
|
||||||
{
|
|
||||||
endp = aStart - aEnd;
|
|
||||||
startp = aEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
|
|
||||||
seg_len = (int) sqrt( ( (double) endp.y * endp.y ) + ( (double) endp.x * endp.x ) );
|
|
||||||
|
|
||||||
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
|
||||||
|
|
||||||
// Compute the outlines of the segment, and creates a polygon
|
|
||||||
// add right rounded end:
|
|
||||||
for( int ii = 0; ii < 1800; ii += delta )
|
|
||||||
{
|
|
||||||
corner = wxPoint( 0, radius );
|
|
||||||
RotatePoint( &corner, ii );
|
|
||||||
corner.x += seg_len;
|
|
||||||
RotatePoint( &corner, -delta_angle );
|
|
||||||
corner += startp;
|
|
||||||
polypoint.x = corner.x;
|
|
||||||
polypoint.y = corner.y;
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish arc:
|
|
||||||
corner = wxPoint( seg_len, -radius );
|
|
||||||
RotatePoint( &corner, -delta_angle );
|
|
||||||
corner += startp;
|
|
||||||
polypoint.x = corner.x;
|
|
||||||
polypoint.y = corner.y;
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
|
|
||||||
// add left rounded end:
|
|
||||||
for( int ii = 0; ii < 1800; ii += delta )
|
|
||||||
{
|
|
||||||
corner = wxPoint( 0, -radius );
|
|
||||||
RotatePoint( &corner, ii );
|
|
||||||
RotatePoint( &corner, -delta_angle );
|
|
||||||
corner += startp;
|
|
||||||
polypoint.x = corner.x;
|
|
||||||
polypoint.y = corner.y;
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish arc:
|
|
||||||
corner = wxPoint( 0, radius );
|
|
||||||
RotatePoint( &corner, -delta_angle );
|
|
||||||
corner += startp;
|
|
||||||
polypoint.x = corner.x;
|
|
||||||
polypoint.y = corner.y;
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
|
|
||||||
aCornerBuffer.back().end_contour = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
* Function TransformShapeWithClearanceToPolygon
|
||||||
* Convert the pad shape to a closed polygon
|
* Convert the pad shape to a closed polygon
|
||||||
|
@ -401,7 +246,7 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
double aCorrectionFactor )
|
double aCorrectionFactor )
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
int ii, angle;
|
int angle;
|
||||||
int dx = (m_Size.x / 2) + aClearanceValue;
|
int dx = (m_Size.x / 2) + aClearanceValue;
|
||||||
int dy = (m_Size.y / 2) + aClearanceValue;
|
int dy = (m_Size.y / 2) + aClearanceValue;
|
||||||
|
|
||||||
|
@ -416,98 +261,36 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
{
|
{
|
||||||
case PAD_CIRCLE:
|
case PAD_CIRCLE:
|
||||||
dx = (int) ( dx * aCorrectionFactor );
|
dx = (int) ( dx * aCorrectionFactor );
|
||||||
|
TransformCircleToPolygon( aCornerBuffer, PadShapePos, dx,
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount; ii++ )
|
aCircleToSegmentsCount );
|
||||||
{
|
|
||||||
corner_position = wxPoint( dx, 0 );
|
|
||||||
RotatePoint( &corner_position, (1800 / aCircleToSegmentsCount) );
|
|
||||||
|
|
||||||
// Half increment offset to get more space between
|
|
||||||
angle = ii * delta;
|
|
||||||
RotatePoint( &corner_position, angle );
|
|
||||||
corner_position += PadShapePos;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
aCornerBuffer.back().end_contour = true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAD_OVAL:
|
case PAD_OVAL:
|
||||||
|
// An oval pad has the same shape as a segment with rounded ends
|
||||||
angle = m_Orient;
|
angle = m_Orient;
|
||||||
if( dy > dx ) // Oval pad X/Y ratio for choosing translation axles
|
{
|
||||||
|
int width;
|
||||||
|
wxPoint shape_offset;
|
||||||
|
if( dy > dx ) // Oval pad X/Y ratio for choosing translation axis
|
||||||
{
|
{
|
||||||
dy = (int) ( dy * aCorrectionFactor );
|
dy = (int) ( dy * aCorrectionFactor );
|
||||||
int angle_pg; // Polygon angle
|
shape_offset.y = dy - dx;
|
||||||
wxPoint shape_offset = wxPoint( 0, dy - dx );
|
width = dx * 2;
|
||||||
|
|
||||||
RotatePoint( &shape_offset, angle ); // Rotating shape offset vector with component
|
|
||||||
|
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount / 2 + 1; ii++ ) // Half circle end cap...
|
|
||||||
{
|
|
||||||
corner_position = wxPoint( dx, 0 );
|
|
||||||
|
|
||||||
// Coordinate translation +dx
|
|
||||||
RotatePoint( &corner_position, (1800 / aCircleToSegmentsCount) );
|
|
||||||
RotatePoint( &corner_position, angle );
|
|
||||||
angle_pg = ii * delta;
|
|
||||||
RotatePoint( &corner_position, angle_pg );
|
|
||||||
corner_position += PadShapePos - shape_offset;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount / 2 + 1; ii++ ) // Second half circle end cap...
|
|
||||||
{
|
|
||||||
corner_position = wxPoint( -dx, 0 );
|
|
||||||
|
|
||||||
// Coordinate translation -dx
|
|
||||||
RotatePoint( &corner_position, (1800 / aCircleToSegmentsCount) );
|
|
||||||
RotatePoint( &corner_position, angle );
|
|
||||||
angle_pg = ii * delta;
|
|
||||||
RotatePoint( &corner_position, angle_pg );
|
|
||||||
corner_position += PadShapePos + shape_offset;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
aCornerBuffer.back().end_contour = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else //if( dy <= dx )
|
else //if( dy <= dx )
|
||||||
{
|
{
|
||||||
dx = (int) ( dx * aCorrectionFactor );
|
dx = (int) ( dx * aCorrectionFactor );
|
||||||
int angle_pg; // Polygon angle
|
shape_offset.x = dy - dx;
|
||||||
wxPoint shape_offset = wxPoint( (dy - dx), 0 );
|
width = dy * 2;
|
||||||
|
}
|
||||||
|
|
||||||
RotatePoint( &shape_offset, angle );
|
RotatePoint( &shape_offset, angle );
|
||||||
|
wxPoint start = PadShapePos - shape_offset;
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount / 2 + 1; ii++ )
|
wxPoint end = PadShapePos + shape_offset;
|
||||||
{
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, start, end,
|
||||||
corner_position = wxPoint( 0, dy );
|
aCircleToSegmentsCount, width );
|
||||||
RotatePoint( &corner_position, (1800 / aCircleToSegmentsCount) );
|
|
||||||
RotatePoint( &corner_position, angle );
|
|
||||||
angle_pg = ii * delta;
|
|
||||||
RotatePoint( &corner_position, angle_pg );
|
|
||||||
corner_position += PadShapePos - shape_offset;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( ii = 0; ii < aCircleToSegmentsCount / 2 + 1; ii++ )
|
|
||||||
{
|
|
||||||
corner_position = wxPoint( 0, -dy );
|
|
||||||
RotatePoint( &corner_position, (1800 / aCircleToSegmentsCount) );
|
|
||||||
RotatePoint( &corner_position, angle );
|
|
||||||
angle_pg = ii * delta;
|
|
||||||
RotatePoint( &corner_position, angle_pg );
|
|
||||||
corner_position += PadShapePos + shape_offset;
|
|
||||||
CPolyPt polypoint( corner_position.x, corner_position.y );
|
|
||||||
aCornerBuffer.push_back( polypoint );
|
|
||||||
}
|
|
||||||
|
|
||||||
aCornerBuffer.back().end_contour = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case PAD_TRAPEZOID:
|
case PAD_TRAPEZOID:
|
||||||
|
|
Loading…
Reference in New Issue