3D viewer: Modify yhe way board items shapes are built:
* All items shapes are converted to polygons. * Polygons are merged layer by layer (for calculation time reasons,zones are not merged) * for copper layers, vias and pads holes are substracted from polygons (but, for calculation time reasons, not inside zones areas). * the look is better, mainly when displaying the copper thickness * solder and paste layers are now shown in 3D viewer. * the code was seriously cleaned (but still needs to be enhanced). * Note this is a work in progress which needs refinements.
This commit is contained in:
parent
0e903dba5b
commit
4ac7dd5845
|
@ -100,7 +100,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CreateDrawGL_List
|
* Function CreateDrawGL_List
|
||||||
* creates the OpenGL draw list items.
|
* Prepares the parameters of the OpenGL draw list
|
||||||
|
* creates the OpenGL draw list items (board, grid ...
|
||||||
*/
|
*/
|
||||||
GLuint CreateDrawGL_List();
|
GLuint CreateDrawGL_List();
|
||||||
void InitGL();
|
void InitGL();
|
||||||
|
@ -111,47 +112,16 @@ public:
|
||||||
m_draw3dOffset.y = aPosY;
|
m_draw3dOffset.y = aPosY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BuildBoard3DView
|
||||||
|
* Called by CreateDrawGL_List()
|
||||||
|
* Fills the OpenGL draw list with board items draw list.
|
||||||
|
*/
|
||||||
|
void BuildBoard3DView();
|
||||||
|
|
||||||
void DrawGrid( double aGriSizeMM );
|
void DrawGrid( double aGriSizeMM );
|
||||||
|
void Draw3DViaHole( SEGVIA * aVia );
|
||||||
/**
|
void Draw3DPadHole( D_PAD * aPad );
|
||||||
* Function Draw3D_Track
|
|
||||||
* @param aTrack = the aTrack to draw
|
|
||||||
*/
|
|
||||||
void Draw3D_Track( TRACK* aTrack );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Draw3D_Via
|
|
||||||
* draws 3D via as a cylinder and filled circles.
|
|
||||||
*/
|
|
||||||
void Draw3D_Via( SEGVIA* via );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Draw3D_DrawSegment
|
|
||||||
* draws a 3D segment (line, arc or circle).
|
|
||||||
*/
|
|
||||||
void Draw3D_DrawSegment( DRAWSEGMENT* segment );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Draw3D_Zone
|
|
||||||
* draw all solid areas in aZone
|
|
||||||
* @param aZone = the zone to draw
|
|
||||||
*/
|
|
||||||
void Draw3D_Zone( ZONE_CONTAINER* aZone );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function Draw3D_DrawText
|
|
||||||
* draws 3D segments to create text objects.
|
|
||||||
* When DrawGraphicText is called to draw a text to an OpenGL DC
|
|
||||||
* it calls Draw3dTextSegm to each segment to draw.
|
|
||||||
* 2 parameters used by Draw3D_FilledSegment are not handled by DrawGraphicText
|
|
||||||
* but are used in Draw3D_FilledSegment().
|
|
||||||
* they are 2 local variables. This is an ugly, but trivial code.
|
|
||||||
* Using DrawGraphicText to draw all texts ensure texts have the same shape
|
|
||||||
* in all contexts
|
|
||||||
*/
|
|
||||||
void Draw3D_DrawText( TEXTE_PCB* text );
|
|
||||||
|
|
||||||
//int Get3DLayerEnable(int act_layer);
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,6 +32,82 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
|
/* Helper functions:
|
||||||
|
* We are using a lots polygons in calculations.
|
||||||
|
* and we are using 2 descriptions,
|
||||||
|
* one easy to use with boost::polygon (KI_POLYGON_SET)
|
||||||
|
* one easy to use in zones and in draw functions (std::vector<CPolyPt>)
|
||||||
|
* Copy polygons from a KI_POLYGON_SET set of polygons to
|
||||||
|
* a std::vector<CPolyPt> polygon list
|
||||||
|
* Therefore we need conversion functions between these 2 descriptions
|
||||||
|
*/
|
||||||
|
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
|
||||||
|
std::vector<CPolyPt>& aPolysList )
|
||||||
|
{
|
||||||
|
for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ )
|
||||||
|
{
|
||||||
|
KI_POLYGON& poly = aKiPolyList[ii];
|
||||||
|
CPolyPt corner( 0, 0, false );
|
||||||
|
|
||||||
|
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
||||||
|
{
|
||||||
|
KI_POLY_POINT point = *(poly.begin() + jj);
|
||||||
|
corner.x = point.x();
|
||||||
|
corner.y = point.y();
|
||||||
|
corner.end_contour = false;
|
||||||
|
aPolysList.push_back( corner );
|
||||||
|
}
|
||||||
|
|
||||||
|
corner.end_contour = true;
|
||||||
|
aPolysList.pop_back();
|
||||||
|
aPolysList.push_back( corner );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function AddPolygonCornersToKiPolygonList
|
||||||
|
* This function adds a KI_POLYGON_SET description to a
|
||||||
|
* std::vector<CPolyPt> description
|
||||||
|
* @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
|
||||||
|
* @param aPolysList = destination (set of polygons)
|
||||||
|
*/
|
||||||
|
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
|
||||||
|
KI_POLYGON_SET& aKiPolyList )
|
||||||
|
{
|
||||||
|
std::vector<KI_POLY_POINT> cornerslist;
|
||||||
|
unsigned corners_count = aCornersBuffer.size();
|
||||||
|
|
||||||
|
// Count the number of polygons in aCornersBuffer
|
||||||
|
int polycount = 0;
|
||||||
|
for( unsigned ii = 0; ii < corners_count; ii++ )
|
||||||
|
{
|
||||||
|
if( aCornersBuffer[ii].end_contour )
|
||||||
|
polycount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
aKiPolyList.reserve( polycount );
|
||||||
|
|
||||||
|
for( unsigned icnt = 0; icnt < corners_count; )
|
||||||
|
{
|
||||||
|
KI_POLYGON poly;
|
||||||
|
cornerslist.clear();
|
||||||
|
|
||||||
|
unsigned ii;
|
||||||
|
for( ii = icnt; ii < aCornersBuffer.size(); ii++ )
|
||||||
|
{
|
||||||
|
cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) );
|
||||||
|
|
||||||
|
if( aCornersBuffer[ii].end_contour )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
||||||
|
aKiPolyList.push_back( poly );
|
||||||
|
icnt = ii + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformCircleToPolygon
|
* Function TransformCircleToPolygon
|
||||||
* convert a circle to a polygon, using multiple straight lines
|
* convert a circle to a polygon, using multiple straight lines
|
||||||
|
@ -192,5 +268,68 @@ void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
|
||||||
if( curr_end != arc_end )
|
if( curr_end != arc_end )
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||||
curr_end, arc_end, aCircleToSegmentsCount, aWidth );
|
curr_end, arc_end,
|
||||||
|
aCircleToSegmentsCount, aWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformRingToPolygon
|
||||||
|
* Creates a polygon from a ring
|
||||||
|
* Convert arcs to multiple straight segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCentre = centre of the arc or circle
|
||||||
|
* @param aRadius = radius of the circle
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = width (thickness) of the ring
|
||||||
|
*/
|
||||||
|
void TransformRingToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCentre, int aRadius,
|
||||||
|
int aCircleToSegmentsCount, int aWidth )
|
||||||
|
{
|
||||||
|
int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
|
||||||
|
|
||||||
|
// Compute the corners posituions and creates poly
|
||||||
|
wxPoint curr_point;
|
||||||
|
int inner_radius = aRadius - ( aWidth / 2 );
|
||||||
|
int outer_radius = inner_radius + aWidth;
|
||||||
|
CPolyPt polycorner;
|
||||||
|
|
||||||
|
// Draw the inner circle of the ring
|
||||||
|
for( int ii = 0; ii < 3600; ii += delta )
|
||||||
|
{
|
||||||
|
curr_point.x = inner_radius;
|
||||||
|
curr_point.y = 0;
|
||||||
|
RotatePoint( &curr_point, ii );
|
||||||
|
curr_point += aCentre;
|
||||||
|
polycorner.x = curr_point.x;
|
||||||
|
polycorner.y = curr_point.y;
|
||||||
|
aCornerBuffer.push_back( polycorner );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the last point of inner circle
|
||||||
|
polycorner.x = aCentre.x + inner_radius;
|
||||||
|
polycorner.y = aCentre.y;
|
||||||
|
aCornerBuffer.push_back( polycorner );
|
||||||
|
|
||||||
|
// Draw the outer circle of the ring
|
||||||
|
for( int ii = 0; ii < 3600; ii += delta )
|
||||||
|
{
|
||||||
|
curr_point.x = outer_radius;
|
||||||
|
curr_point.y = 0;
|
||||||
|
RotatePoint( &curr_point, -ii );
|
||||||
|
curr_point += aCentre;
|
||||||
|
polycorner.x = curr_point.x;
|
||||||
|
polycorner.y = curr_point.y;
|
||||||
|
aCornerBuffer.push_back( polycorner );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the last point of outer circle
|
||||||
|
polycorner.x = aCentre.x + outer_radius;
|
||||||
|
polycorner.y = aCentre.y;
|
||||||
|
aCornerBuffer.push_back( polycorner );
|
||||||
|
|
||||||
|
// Close the polygon
|
||||||
|
polycorner.x = aCentre.x + inner_radius;
|
||||||
|
polycorner.end_contour = true;
|
||||||
|
aCornerBuffer.push_back( polycorner );
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ set(CVPCB_DIALOGS
|
||||||
|
|
||||||
set(CVPCB_SRCS
|
set(CVPCB_SRCS
|
||||||
../common/base_units.cpp
|
../common/base_units.cpp
|
||||||
|
../pcbnew/board_items_to_polygon_shape_transform.cpp
|
||||||
../pcbnew/class_drc_item.cpp
|
../pcbnew/class_drc_item.cpp
|
||||||
autosel.cpp
|
autosel.cpp
|
||||||
cfg.cpp
|
cfg.cpp
|
||||||
|
|
|
@ -35,6 +35,33 @@
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <PolyLine.h>
|
#include <PolyLine.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function CopyPolygonsFromKiPolygonListToPolysList
|
||||||
|
* We are using a lots polygons in calculations.
|
||||||
|
* and we are using 2 descriptions,
|
||||||
|
* one easy to use with boost::polygon (KI_POLYGON_SET)
|
||||||
|
* one easy to use in zones and in draw functions (std::vector<CPolyPt>)
|
||||||
|
* Copy polygons from a KI_POLYGON_SET set of polygons to
|
||||||
|
* a std::vector<CPolyPt> polygon list
|
||||||
|
* Therefore we need conversion functions between these 2 descriptions
|
||||||
|
* This function converts a KI_POLYGON_SET description to a
|
||||||
|
* std::vector<CPolyPt> description
|
||||||
|
* @param aKiPolyList = source (set of polygons)
|
||||||
|
* @param aPolysList = destination (set of polygons using CPolyPt corners descr)
|
||||||
|
*/
|
||||||
|
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
|
||||||
|
std::vector<CPolyPt>& aPolysList );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function AddPolygonCornersToKiPolygonList
|
||||||
|
* This function adds a KI_POLYGON_SET description to a
|
||||||
|
* std::vector<CPolyPt> description
|
||||||
|
* @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
|
||||||
|
* @param aPolysList = destination (set of polygons)
|
||||||
|
*/
|
||||||
|
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
|
||||||
|
KI_POLYGON_SET& aKiPolyList );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformCircleToPolygon
|
* Function TransformCircleToPolygon
|
||||||
* convert a circle to a polygon, using multiple straight lines
|
* convert a circle to a polygon, using multiple straight lines
|
||||||
|
@ -82,4 +109,18 @@ void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
wxPoint aCentre, wxPoint aStart, int aArcAngle,
|
wxPoint aCentre, wxPoint aStart, int aArcAngle,
|
||||||
int aCircleToSegmentsCount, int aWidth );
|
int aCircleToSegmentsCount, int aWidth );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformRingToPolygon
|
||||||
|
* Creates a polygon from a ring
|
||||||
|
* Convert arcs to multiple straight segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aCentre = centre of the arc or circle
|
||||||
|
* @param aRadius = radius of the circle
|
||||||
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* @param aWidth = width (thickness) of the ring
|
||||||
|
*/
|
||||||
|
void TransformRingToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxPoint aCentre, int aRadius,
|
||||||
|
int aCircleToSegmentsCount, int aWidth );
|
||||||
|
|
||||||
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
#endif // CONVERT_BASIC_SHAPES_TO_POLYGON_H
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <polygons_defs.h>
|
#include <polygons_defs.h>
|
||||||
|
#include <drawtxt.h>
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <wxPcbStruct.h>
|
#include <wxPcbStruct.h>
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
|
@ -18,24 +19,206 @@
|
||||||
#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 <class_module.h>
|
||||||
|
#include <class_edge_mod.h>
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
|
/* generate pads shapes on layer aLayer as polygons,
|
||||||
|
* and adds these polygons to aCornerBuffer
|
||||||
|
* aCornerBuffer = the buffer to store polygons
|
||||||
|
* aInflateValue = an additionnal size to add to pad shapes
|
||||||
|
* aCircleToSegmentsCount = number of segments to approximate a circle
|
||||||
|
* aCorrectionFactor = the correction to apply to a circle radius
|
||||||
|
* to generate the polygon.
|
||||||
|
* if aCorrectionFactor = 1.0, the polygon is inside the circle
|
||||||
|
* the radius of circle approximated by segments is
|
||||||
|
* initial radius * aCorrectionFactor
|
||||||
|
*/
|
||||||
|
void MODULE::TransformPadsShapesWithClearanceToPolygon( LAYER_NUM aLayer,
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor )
|
||||||
|
{
|
||||||
|
D_PAD* pad = Pads();
|
||||||
|
|
||||||
|
wxSize margin;
|
||||||
|
for( ; pad != NULL; pad = pad->Next() )
|
||||||
|
{
|
||||||
|
if( !pad->IsOnLayer(aLayer) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
switch( aLayer )
|
||||||
|
{
|
||||||
|
case SOLDERMASK_N_FRONT:
|
||||||
|
case SOLDERMASK_N_BACK:
|
||||||
|
margin.x = margin.y = pad->GetSolderMaskMargin() + aInflateValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOLDERPASTE_N_FRONT:
|
||||||
|
case SOLDERPASTE_N_BACK:
|
||||||
|
margin = pad->GetSolderPasteMargin();
|
||||||
|
margin.x += aInflateValue;
|
||||||
|
margin.y += aInflateValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
margin.x = margin.y = aInflateValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pad->BuildPadShapePolygon( aCornerBuffer, margin,
|
||||||
|
aCircleToSegmentsCount, aCorrectionFactor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate shapes of graphic items (outlines) on layer aLayer as polygons,
|
||||||
|
* and adds these polygons to aCornerBuffer
|
||||||
|
* aCornerBuffer = the buffer to store polygons
|
||||||
|
* aInflateValue = a value to inflate shapes
|
||||||
|
* aCircleToSegmentsCount = number of segments to approximate a circle
|
||||||
|
* aCorrectionFactor = the correction to apply to the circle radius
|
||||||
|
* to generate the polygon.
|
||||||
|
* if aCorrectionFactor = 1.0, the polygon is inside the circle
|
||||||
|
* the radius of circle approximated by segments is
|
||||||
|
* initial radius * aCorrectionFactor
|
||||||
|
*/
|
||||||
|
void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
|
||||||
|
LAYER_NUM aLayer,
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor )
|
||||||
|
{
|
||||||
|
EDGE_MODULE* outline;
|
||||||
|
for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() )
|
||||||
|
{
|
||||||
|
switch( item->Type() )
|
||||||
|
{
|
||||||
|
case PCB_MODULE_TEXT_T:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PCB_MODULE_EDGE_T:
|
||||||
|
outline = (EDGE_MODULE*) item;
|
||||||
|
if( outline->GetLayer() != aLayer )
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch( outline->GetShape() )
|
||||||
|
{
|
||||||
|
case S_SEGMENT:
|
||||||
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||||
|
outline->GetStart(),
|
||||||
|
outline->GetEnd(),
|
||||||
|
aCircleToSegmentsCount,
|
||||||
|
outline->GetWidth() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_CIRCLE:
|
||||||
|
TransformRingToPolygon( aCornerBuffer, outline->GetCenter(),
|
||||||
|
outline->GetRadius(), aCircleToSegmentsCount,
|
||||||
|
outline->GetWidth() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_ARC:
|
||||||
|
TransformArcToPolygon( aCornerBuffer,
|
||||||
|
outline->GetCenter(), outline->GetArcStart(),
|
||||||
|
outline->GetAngle(),
|
||||||
|
aCircleToSegmentsCount, outline->GetWidth() );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case S_POLYGON:
|
||||||
|
// for outline shape = S_POLYGON:
|
||||||
|
// We must compute true coordinates from m_PolyPoints
|
||||||
|
// which are relative to module position and module orientation = 0
|
||||||
|
for( unsigned ii = 0; ii < outline->GetPolyPoints().size(); ii++ )
|
||||||
|
{
|
||||||
|
CPolyPt corner( outline->GetPolyPoints()[ii] );
|
||||||
|
RotatePoint( &corner.x, &corner.y, GetOrientation() );
|
||||||
|
corner.x += GetPosition().x;
|
||||||
|
corner.y += GetPosition().y;
|
||||||
|
aCornerBuffer.push_back( corner );
|
||||||
|
}
|
||||||
|
aCornerBuffer.back().end_contour = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
D( printf( "Error: Shape %d not implemented!\n",
|
||||||
|
((EDGE_MODULE*) item)->m_Shape ); )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function TransformSolidAreasShapesToPolygonSet
|
||||||
|
* Convert solid areas full shapes to polygon set
|
||||||
|
* (the full shape is the polygon area with a thick outline)
|
||||||
|
* Used in 3D view
|
||||||
|
* Arcs (ends of segments) are approximated by segments
|
||||||
|
* aCornerBuffer = a buffer to store the polygons
|
||||||
|
* aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
|
* aCorrectionFactor = the correction to apply to arcs radius to roughly
|
||||||
|
* keep arc radius when approximated by segments
|
||||||
|
*/
|
||||||
|
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor )
|
||||||
|
{
|
||||||
|
unsigned cornerscount = GetFilledPolysList().size();
|
||||||
|
std::vector <CPolyPt> polygonslist;
|
||||||
|
|
||||||
|
if( cornerscount == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add filled areas polygons
|
||||||
|
aCornerBuffer.insert( aCornerBuffer.end(), m_FilledPolysList.begin(),
|
||||||
|
m_FilledPolysList.end() );
|
||||||
|
|
||||||
|
// add filled areas outlines, which are drawn with thich lines
|
||||||
|
wxPoint seg_start, seg_end;
|
||||||
|
int i_start_contour = 0;
|
||||||
|
for( unsigned ic = 0; ic < cornerscount; ic++ )
|
||||||
|
{
|
||||||
|
seg_start.x = m_FilledPolysList[ ic ].x;
|
||||||
|
seg_start.y = m_FilledPolysList[ ic ].y;
|
||||||
|
unsigned ic_next = ic+1;
|
||||||
|
|
||||||
|
if( !m_FilledPolysList[ic].end_contour &&
|
||||||
|
ic_next < cornerscount )
|
||||||
|
{
|
||||||
|
seg_end.x = m_FilledPolysList[ ic_next ].x;
|
||||||
|
seg_end.y = m_FilledPolysList[ ic_next ].y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
seg_end.x = m_FilledPolysList[ i_start_contour ].x;
|
||||||
|
seg_end.y = m_FilledPolysList[ i_start_contour ].y;
|
||||||
|
i_start_contour = ic_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, seg_start, seg_end,
|
||||||
|
aCircleToSegmentsCount,
|
||||||
|
GetMinThickness() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
* Function TransformBoundingBoxWithClearanceToPolygon
|
||||||
* Convert the track shape to a closed polygon
|
* Convert the text bonding box to a rectangular polygon
|
||||||
* Used in filling zones calculations
|
* Used in filling zones calculations
|
||||||
* Circles and arcs are approximated by segments
|
* Circles and arcs are approximated by segments
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
* @param aClearanceValue = the clearance around the pad
|
* @param aClearanceValue = the clearance around the pad
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
|
||||||
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
|
||||||
* clearance when the circle is approximated by segment bigger or equal
|
|
||||||
* to the real clearance value (usually near from 1.0)
|
|
||||||
*/
|
*/
|
||||||
void TEXTE_PCB::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void TEXTE_PCB::TransformBoundingBoxWithClearanceToPolygon(
|
||||||
int aClearanceValue,
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aCircleToSegmentsCount,
|
int aClearanceValue ) const
|
||||||
double aCorrectionFactor )
|
|
||||||
{
|
{
|
||||||
if( GetText().Length() == 0 )
|
if( GetText().Length() == 0 )
|
||||||
return;
|
return;
|
||||||
|
@ -63,89 +246,80 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCo
|
||||||
aCornerBuffer.back().end_contour = true;
|
aCornerBuffer.back().end_contour = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function TransformShapeWithClearanceToPolygon
|
|
||||||
* Convert the track shape to a closed polygon
|
/* Function TransformShapeWithClearanceToPolygonSet
|
||||||
* Used in filling zones calculations
|
* Convert the text shape to a set of polygons (one by segment)
|
||||||
* Circles (vias) and arcs (ends of tracks) are approximated by segments
|
* Used in filling zones calculations and 3D view
|
||||||
* param aCornerBuffer = a buffer to store the polygon
|
* Circles and arcs are approximated by segments
|
||||||
* param aClearanceValue = the clearance around the pad
|
* aCornerBuffer = vector <CPolyPt> to store the polygon corners
|
||||||
* param aCircleToSegmentsCount = the number of segments to approximate a circle
|
* aClearanceValue = the clearance around the text
|
||||||
* param aCorrectionFactor = the correction to apply to circles radius to keep
|
* aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
* param aAddClearance = true to add a clearance area to the polygon
|
* aCorrectionFactor = the correction to apply to circles radius to keep
|
||||||
* false to create the outline polygon.
|
* clearance when the circle is approximated by segment bigger or equal
|
||||||
* clearance when the circle is approximated by segment bigger or equal
|
* to the real clearance value (usually near from 1.0)
|
||||||
* to the real clearance value (usually near from 1.0)
|
*/
|
||||||
*/
|
// These variables are parameters used in addTextSegmToPoly.
|
||||||
void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
// But addTextSegmToPoly is a call-back function,
|
||||||
int aClearanceValue,
|
// so we cannot send them as arguments.
|
||||||
int aCircleToSegmentsCount,
|
int s_textWidth;
|
||||||
double aCorrectionFactor,
|
int s_textCircle2SegmentCount;
|
||||||
bool aAddClearance )
|
std::vector <CPolyPt>* s_cornerBuffer;
|
||||||
|
|
||||||
|
// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
|
||||||
|
static void addTextSegmToPoly( int x0, int y0, int xf, int yf )
|
||||||
{
|
{
|
||||||
|
TransformRoundedEndsSegmentToPolygon( *s_cornerBuffer,
|
||||||
/* Creates the main polygon (i.e. the filled area using only one outline)
|
wxPoint( x0, y0), wxPoint( xf, yf ),
|
||||||
* and reserve a clearance margin around the outlines and holes
|
s_textCircle2SegmentCount, s_textWidth );
|
||||||
*/
|
|
||||||
std::vector <CPolyPt> zoneOutines;
|
|
||||||
BuildFilledPolysListData( NULL, &zoneOutines );
|
|
||||||
int clearance = 0;
|
|
||||||
if( aAddClearance )
|
|
||||||
{
|
|
||||||
GetClearance();
|
|
||||||
if( aClearanceValue > clearance )
|
|
||||||
clearance = aClearanceValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the polygon with clearance and holes
|
|
||||||
// holes are linked to the main outline, so only one polygon should be created.
|
|
||||||
KI_POLYGON_SET polyset_zone_solid_areas;
|
|
||||||
std::vector<KI_POLY_POINT> cornerslist;
|
|
||||||
unsigned ic = 0;
|
|
||||||
unsigned corners_count = zoneOutines.size();
|
|
||||||
while( ic < corners_count )
|
|
||||||
{
|
|
||||||
cornerslist.clear();
|
|
||||||
KI_POLYGON poly;
|
|
||||||
{
|
|
||||||
for( ; ic < corners_count; ic++ )
|
|
||||||
{
|
|
||||||
CPolyPt* corner = &zoneOutines[ic];
|
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner->x, corner->y ) );
|
|
||||||
if( corner->end_contour )
|
|
||||||
{
|
|
||||||
ic++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
|
||||||
polyset_zone_solid_areas.push_back( poly );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
polyset_zone_solid_areas += clearance;
|
|
||||||
|
|
||||||
// Put the resultng polygon in buffer
|
|
||||||
for( unsigned ii = 0; ii < polyset_zone_solid_areas.size(); ii++ )
|
|
||||||
{
|
|
||||||
KI_POLYGON& poly = polyset_zone_solid_areas[ii];
|
|
||||||
CPolyPt corner( 0, 0, false );
|
|
||||||
|
|
||||||
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
|
||||||
{
|
|
||||||
KI_POLY_POINT point = *(poly.begin() + jj);
|
|
||||||
corner.x = point.x();
|
|
||||||
corner.y = point.y();
|
|
||||||
corner.end_contour = false;
|
|
||||||
aCornerBuffer.push_back( corner );
|
|
||||||
}
|
|
||||||
|
|
||||||
corner.end_contour = true;
|
|
||||||
aCornerBuffer.pop_back();
|
|
||||||
aCornerBuffer.push_back( corner );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aClearanceValue,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor ) const
|
||||||
|
{
|
||||||
|
wxSize size = GetSize();
|
||||||
|
|
||||||
|
if( IsMirrored() )
|
||||||
|
NEGATE( size.x );
|
||||||
|
|
||||||
|
s_cornerBuffer = &aCornerBuffer;
|
||||||
|
s_textWidth = GetThickness() + ( 2 * aClearanceValue );
|
||||||
|
s_textCircle2SegmentCount = aCircleToSegmentsCount;
|
||||||
|
EDA_COLOR_T color = BLACK; // not actually used, but needed by DrawGraphicText
|
||||||
|
|
||||||
|
if( IsMultilineAllowed() )
|
||||||
|
{
|
||||||
|
wxPoint pos = GetTextPosition();
|
||||||
|
wxArrayString* list = wxStringSplit( GetText(), '\n' );
|
||||||
|
wxPoint offset;
|
||||||
|
|
||||||
|
offset.y = GetInterline();
|
||||||
|
RotatePoint( &offset, GetOrientation() );
|
||||||
|
|
||||||
|
for( unsigned i = 0; i<list->Count(); i++ )
|
||||||
|
{
|
||||||
|
wxString txt = list->Item( i );
|
||||||
|
DrawGraphicText( NULL, NULL, pos, color,
|
||||||
|
txt, GetOrientation(), size,
|
||||||
|
GetHorizJustify(), GetVertJustify(),
|
||||||
|
GetThickness(), IsItalic(),
|
||||||
|
true, addTextSegmToPoly );
|
||||||
|
pos += offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawGraphicText( NULL, NULL, GetTextPosition(), (EDA_COLOR_T) color,
|
||||||
|
GetText(), GetOrientation(), size,
|
||||||
|
GetHorizJustify(), GetVertJustify(),
|
||||||
|
GetThickness(), IsItalic(),
|
||||||
|
true, addTextSegmToPoly );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,20 +337,19 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>
|
||||||
void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor )
|
double aCorrectionFactor ) const
|
||||||
{
|
{
|
||||||
switch( m_Shape )
|
switch( m_Shape )
|
||||||
{
|
{
|
||||||
case S_CIRCLE:
|
case S_CIRCLE:
|
||||||
TransformArcToPolygon( aCornerBuffer, m_Start, // Circle centre
|
TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius(),
|
||||||
m_End, 3600,
|
aCircleToSegmentsCount,
|
||||||
aCircleToSegmentsCount,
|
m_Width + (2 * aClearanceValue) ) ;
|
||||||
m_Width + (2 * aClearanceValue) );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ARC:
|
case S_ARC:
|
||||||
TransformArcToPolygon( aCornerBuffer, m_Start,
|
TransformArcToPolygon( aCornerBuffer, GetCenter(),
|
||||||
m_End, m_Angle,
|
GetArcStart(), m_Angle,
|
||||||
aCircleToSegmentsCount,
|
aCircleToSegmentsCount,
|
||||||
m_Width + (2 * aClearanceValue) );
|
m_Width + (2 * aClearanceValue) );
|
||||||
break;
|
break;
|
||||||
|
@ -199,13 +372,13 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& a
|
||||||
* @param aClearanceValue = the clearance around the pad
|
* @param aClearanceValue = the clearance around the pad
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
||||||
* clearance when the circle is approxiamted by segment bigger or equal
|
* clearance when the circle is approximated by segment bigger or equal
|
||||||
* to the real clearance value (usually near from 1.0)
|
* to the real clearance value (usually near from 1.0)
|
||||||
*/
|
*/
|
||||||
void TRACK:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCornerBuffer,
|
void TRACK:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor )
|
double aCorrectionFactor ) const
|
||||||
{
|
{
|
||||||
switch( Type() )
|
switch( Type() )
|
||||||
{
|
{
|
||||||
|
@ -227,22 +400,21 @@ void TRACK:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Function TransformShapeWithClearanceToPolygon
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
|
||||||
* Convert the pad shape to a closed polygon
|
* Convert the pad shape to a closed polygon
|
||||||
* Used in filling zones calculations
|
* Used in filling zones calculations and 3D view generation
|
||||||
* Circles and arcs are approximated by segments
|
* Circles and arcs are approximated by segments
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
* aCornerBuffer = a vector < CPolyPt> to store the polygon corners
|
||||||
* @param aClearanceValue = the clearance around the pad
|
* aClearanceValue = the clearance around the pad
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
* aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
* aCorrectionFactor = the correction to apply to circles radius to keep
|
||||||
* clearance when the circle is approxiamted by segment bigger or equal
|
* clearance when the circle is approximated by segment bigger or equal
|
||||||
* to the real clearance value (usually near from 1.0)
|
* to the real clearance value (usually near from 1.0)
|
||||||
*/
|
*/
|
||||||
void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCornerBuffer,
|
void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor )
|
double aCorrectionFactor ) const
|
||||||
{
|
{
|
||||||
wxPoint corner_position;
|
wxPoint corner_position;
|
||||||
int angle;
|
int angle;
|
||||||
|
@ -368,6 +540,95 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( std:: vector < CPolyPt>& aCor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function BuildPadShapePolygon
|
||||||
|
* Build the Corner list of the polygonal shape,
|
||||||
|
* depending on shape, extra size (clearance ...) pad and orientation
|
||||||
|
* Note: for Round and oval pads this function is equivalent to
|
||||||
|
* TransformShapeWithClearanceToPolygon, but not for other shapes
|
||||||
|
*/
|
||||||
|
void D_PAD::BuildPadShapePolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxSize aInflateValue, int aSegmentsPerCircle,
|
||||||
|
double aCorrectionFactor ) const
|
||||||
|
{
|
||||||
|
wxPoint corners[4];
|
||||||
|
wxPoint PadShapePos = ReturnShapePos(); /* Note: for pad having a shape offset,
|
||||||
|
* the pad position is NOT the shape position */
|
||||||
|
switch( m_PadShape )
|
||||||
|
{
|
||||||
|
case PAD_CIRCLE:
|
||||||
|
case PAD_OVAL:
|
||||||
|
TransformShapeWithClearanceToPolygon( aCornerBuffer, aInflateValue.x,
|
||||||
|
aSegmentsPerCircle, aCorrectionFactor );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case PAD_TRAPEZOID:
|
||||||
|
case PAD_RECT:
|
||||||
|
BuildPadPolygon( corners, aInflateValue, m_Orient );
|
||||||
|
for( int ii = 0; ii < 4; ii++ )
|
||||||
|
{
|
||||||
|
corners[ii] += PadShapePos; // Shift origin to position
|
||||||
|
CPolyPt polypoint( corners[ii].x, corners[ii].y );
|
||||||
|
aCornerBuffer.push_back( polypoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
aCornerBuffer.back().end_contour = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function BuildPadDrillShapePolygon
|
||||||
|
* Build the Corner list of the polygonal drill shape,
|
||||||
|
* depending on shape pad hole and orientation
|
||||||
|
* return false if the pad has no hole, true otherwise
|
||||||
|
*/
|
||||||
|
bool D_PAD::BuildPadDrillShapePolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue, int aSegmentsPerCircle ) const
|
||||||
|
{
|
||||||
|
wxSize drillsize = GetDrillSize();
|
||||||
|
bool hasHole = drillsize.x && drillsize.y;
|
||||||
|
|
||||||
|
if( ! hasHole )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
drillsize.x += aInflateValue;
|
||||||
|
drillsize.y += aInflateValue;
|
||||||
|
|
||||||
|
if( drillsize.x == drillsize.y ) // usual round hole
|
||||||
|
{
|
||||||
|
TransformCircleToPolygon( aCornerBuffer, GetPosition(),
|
||||||
|
drillsize.x /2, aSegmentsPerCircle );
|
||||||
|
}
|
||||||
|
else // Oblong hole
|
||||||
|
{
|
||||||
|
wxPoint ends_offset;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
if( drillsize.x > drillsize.y ) // Horizontal oval
|
||||||
|
{
|
||||||
|
ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
|
||||||
|
width = drillsize.y;
|
||||||
|
}
|
||||||
|
else // Vertical oval
|
||||||
|
{
|
||||||
|
ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
|
||||||
|
width = drillsize.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
RotatePoint( &ends_offset, GetOrientation() );
|
||||||
|
|
||||||
|
wxPoint start = GetPosition() + ends_offset;
|
||||||
|
wxPoint end = GetPosition() - ends_offset;
|
||||||
|
|
||||||
|
// Prepare the shape creation
|
||||||
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, start, end,
|
||||||
|
aSegmentsPerCircle, width );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CreateThermalReliefPadPolygon
|
* Function CreateThermalReliefPadPolygon
|
||||||
|
|
|
@ -214,7 +214,7 @@ public:
|
||||||
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor );
|
double aCorrectionFactor ) const;
|
||||||
|
|
||||||
virtual wxString GetSelectMenuText() const;
|
virtual wxString GetSelectMenuText() const;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
|
|
||||||
class LINE_READER;
|
class LINE_READER;
|
||||||
class EDA_3D_CANVAS;
|
|
||||||
class MSG_PANEL_ITEM;
|
class MSG_PANEL_ITEM;
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,15 +66,11 @@ public:
|
||||||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
|
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||||
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );
|
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );
|
||||||
|
|
||||||
void Draw3D( EDA_3D_CANVAS* glcanvas );
|
|
||||||
|
|
||||||
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
|
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
|
||||||
|
|
||||||
wxString GetClass() const
|
wxString GetClass() const
|
||||||
{
|
{
|
||||||
return wxT( "MGRAPHIC" );
|
return wxT( "MGRAPHIC" );
|
||||||
|
|
||||||
// return wxT( "EDGE" ); ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GetSelectMenuText() const;
|
wxString GetSelectMenuText() const;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -46,6 +46,7 @@ class EDA_DRAW_PANEL;
|
||||||
class D_PAD;
|
class D_PAD;
|
||||||
class BOARD;
|
class BOARD;
|
||||||
class MSG_PANEL_ITEM;
|
class MSG_PANEL_ITEM;
|
||||||
|
class CPolyPt;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,7 +243,60 @@ public:
|
||||||
GR_DRAWMODE aDrawMode,
|
GR_DRAWMODE aDrawMode,
|
||||||
const wxPoint& aOffset = ZeroOffset );
|
const wxPoint& aOffset = ZeroOffset );
|
||||||
|
|
||||||
void Draw3D( EDA_3D_CANVAS* glcanvas );
|
/**
|
||||||
|
* function ReadandInsert3DComponentShape
|
||||||
|
* read the 3D component shape(s) of the footprint (physical shape)
|
||||||
|
* and insert mesh in gl list
|
||||||
|
*/
|
||||||
|
void ReadAndInsert3DComponentShape( EDA_3D_CANVAS* glcanvas );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function TransformPadsShapesWithClearanceToPolygon
|
||||||
|
* generate pads shapes on layer aLayer as polygons,
|
||||||
|
* and adds these polygons to aCornerBuffer
|
||||||
|
* Useful to generate a polygonal representation of a footprint
|
||||||
|
* in 3D view and plot functions, when a full polygonal approach is needed
|
||||||
|
* @param aLayer = the current layer: pads on this layer are considered
|
||||||
|
* @param aCornerBuffer = the buffer to store polygons
|
||||||
|
* @param aInflateValue = an additionnal size to add to pad shapes
|
||||||
|
* aInflateValue = 0 to have the exact pad size
|
||||||
|
* @param aCircleToSegmentsCount = number of segments to generate a circle
|
||||||
|
* @param aCorrectionFactor = the correction to apply to a circle radius
|
||||||
|
* to approximate a circle by the polygon.
|
||||||
|
* if aCorrectionFactor = 1.0, the polygon is inside the circle
|
||||||
|
* the radius of circle approximated by segments is
|
||||||
|
* initial radius * aCorrectionFactor
|
||||||
|
*/
|
||||||
|
void TransformPadsShapesWithClearanceToPolygon( LAYER_NUM aLayer,
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function TransformGraphicShapesWithClearanceToPolygonSet
|
||||||
|
* generate shapes of graphic items (outlines) on layer aLayer as polygons,
|
||||||
|
* and adds these polygons to aCornerBuffer
|
||||||
|
* Useful to generate a polygonal representation of a footprint
|
||||||
|
* in 3D view and plot functions, when a full polygonal approach is needed
|
||||||
|
* @param aLayer = the current layer: items on this layer are considered
|
||||||
|
* @param aCornerBuffer = the buffer to store polygons
|
||||||
|
* @param aInflateValue = a value to inflate shapes
|
||||||
|
* aInflateValue = 0 to have the exact shape size
|
||||||
|
* @param aCircleToSegmentsCount = number of segments to generate a circle
|
||||||
|
* @param aCorrectionFactor = the correction to apply to a circle radius
|
||||||
|
* to approximate a circle by the polygon.
|
||||||
|
* if aCorrectionFactor = 1.0, the polygon is inside the circle
|
||||||
|
* the radius of circle approximated by segments is
|
||||||
|
* initial radius * aCorrectionFactor
|
||||||
|
*/
|
||||||
|
void TransformGraphicShapesWithClearanceToPolygonSet(
|
||||||
|
LAYER_NUM aLayer,
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DrawEdgesOnly
|
* Function DrawEdgesOnly
|
||||||
|
|
|
@ -223,7 +223,7 @@ public:
|
||||||
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor );
|
double aCorrectionFactor ) const;;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetClearance
|
* Function GetClearance
|
||||||
|
@ -274,8 +274,6 @@ public:
|
||||||
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
|
||||||
GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
|
GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );
|
||||||
|
|
||||||
void Draw3D( EDA_3D_CANVAS* glcanvas );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DrawShape
|
* Function DrawShape
|
||||||
* basic function to draw a pad.
|
* basic function to draw a pad.
|
||||||
|
@ -300,6 +298,43 @@ public:
|
||||||
*/
|
*/
|
||||||
void BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotation ) const;
|
void BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue, int aRotation ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BuildPadShapePolygon
|
||||||
|
* Build the Corner list of the polygonal shape,
|
||||||
|
* depending on shape, extra size (clearance ...) pad and orientation
|
||||||
|
* This function is similar to TransformShapeWithClearanceToPolygon,
|
||||||
|
* but the difference is BuildPadShapePolygon creates a polygon shape exactly
|
||||||
|
* similar to pad shape, which a size inflated by aInflateValue
|
||||||
|
* and TransformShapeWithClearanceToPolygon creates a more complex shape (for instance
|
||||||
|
* a rectangular pad is converted in a rectangulr shape with ronded corners)
|
||||||
|
* @param aCornerBuffer = a buffer to fill.
|
||||||
|
* @param aInflateValue = the clearance or margin value.
|
||||||
|
* value > 0: inflate, < 0 deflate, = 0 : no change
|
||||||
|
* the clearance can have different values for x and y directions
|
||||||
|
* (relative to the pad)
|
||||||
|
* @param aSegmentsPerCircle = number of segments to approximate a circle
|
||||||
|
* (used for round and oblong shapes only (16 to 32 is a good value)
|
||||||
|
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
||||||
|
* the pad size when the circle is approximated by segments
|
||||||
|
*/
|
||||||
|
void BuildPadShapePolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
wxSize aInflateValue, int aSegmentsPerCircle,
|
||||||
|
double aCorrectionFactor ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function BuildPadDrillShapePolygon
|
||||||
|
* Build the Corner list of the polygonal drill shape,
|
||||||
|
* depending on shape pad hole and orientation
|
||||||
|
* @param aCornerBuffer = a buffer to fill.
|
||||||
|
* @param aInflateValue = the clearance or margin value.
|
||||||
|
* value > 0: inflate, < 0 deflate, = 0 : no change
|
||||||
|
* @param aSegmentsPerCircle = number of segments to approximate a circle
|
||||||
|
* (used for round and oblong shapes only(16 to 32 is a good value)
|
||||||
|
* @return false if the pad has no hole, true otherwise
|
||||||
|
*/
|
||||||
|
bool BuildPadDrillShapePolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aInflateValue, int aSegmentsPerCircle ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function BuildSegmentFromOvalShape
|
* Function BuildSegmentFromOvalShape
|
||||||
* Has meaning only for OVAL (and ROUND) pads
|
* Has meaning only for OVAL (and ROUND) pads
|
||||||
|
|
|
@ -482,7 +482,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
||||||
GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
|
GRLine( aClipBox, aDC, holepos.x - dx0, holepos.y - dx0,
|
||||||
holepos.x + dx0, holepos.y + dx0, 0, nc_color );
|
holepos.x + dx0, holepos.y + dx0, 0, nc_color );
|
||||||
|
|
||||||
if( m_layerMask & LAYER_BACK ) // Draw /
|
if( m_layerMask & LAYER_BACK ) // Draw /
|
||||||
GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
|
GRLine( aClipBox, aDC, holepos.x + dx0, holepos.y - dx0,
|
||||||
holepos.x - dx0, holepos.y + dx0, 0, nc_color );
|
holepos.x - dx0, holepos.y + dx0, 0, nc_color );
|
||||||
}
|
}
|
||||||
|
@ -552,8 +552,8 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
||||||
{
|
{
|
||||||
// tsize reserve room for marges and segments thickness
|
// tsize reserve room for marges and segments thickness
|
||||||
tsize = ( tsize * 7 ) / 10;
|
tsize = ( tsize * 7 ) / 10;
|
||||||
DrawGraphicHaloText( aDrawInfo.m_DrawPanel, aDC, tpos,
|
DrawGraphicHaloText( aDrawInfo.m_DrawPanel, aDC, tpos,
|
||||||
aDrawInfo.m_Color, BLACK, WHITE,
|
aDrawInfo.m_Color, BLACK, WHITE,
|
||||||
buffer, t_angle,
|
buffer, t_angle,
|
||||||
wxSize( tsize , tsize ), GR_TEXT_HJUSTIFY_CENTER,
|
wxSize( tsize , tsize ), GR_TEXT_HJUSTIFY_CENTER,
|
||||||
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
|
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
|
||||||
|
@ -579,8 +579,8 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
|
||||||
|
|
||||||
// tsize reserve room for marges and segments thickness
|
// tsize reserve room for marges and segments thickness
|
||||||
tsize = ( tsize * 7 ) / 10;
|
tsize = ( tsize * 7 ) / 10;
|
||||||
DrawGraphicHaloText( aDrawInfo.m_DrawPanel, aDC, tpos,
|
DrawGraphicHaloText( aDrawInfo.m_DrawPanel, aDC, tpos,
|
||||||
aDrawInfo.m_Color, BLACK, WHITE,
|
aDrawInfo.m_Color, BLACK, WHITE,
|
||||||
m_ShortNetname, t_angle,
|
m_ShortNetname, t_angle,
|
||||||
wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
|
wxSize( tsize, tsize ), GR_TEXT_HJUSTIFY_CENTER,
|
||||||
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
|
GR_TEXT_VJUSTIFY_CENTER, tsize / 7, false, false );
|
||||||
|
@ -632,46 +632,48 @@ int D_PAD::BuildSegmentFromOvalShape(wxPoint& aSegStart, wxPoint& aSegEnd,
|
||||||
void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue,
|
void D_PAD::BuildPadPolygon( wxPoint aCoord[4], wxSize aInflateValue,
|
||||||
int aRotation ) const
|
int aRotation ) const
|
||||||
{
|
{
|
||||||
if( (GetShape() != PAD_RECT) && (GetShape() != PAD_TRAPEZOID) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxSize delta;
|
wxSize delta;
|
||||||
wxSize halfsize;
|
wxSize halfsize;
|
||||||
|
|
||||||
halfsize.x = m_Size.x >> 1;
|
halfsize.x = m_Size.x >> 1;
|
||||||
halfsize.y = m_Size.y >> 1;
|
halfsize.y = m_Size.y >> 1;
|
||||||
|
|
||||||
// For rectangular shapes, inflate is easy
|
switch( GetShape() )
|
||||||
if( GetShape() == PAD_RECT )
|
|
||||||
{
|
{
|
||||||
halfsize += aInflateValue;
|
case PAD_RECT:
|
||||||
|
// For rectangular shapes, inflate is easy
|
||||||
|
halfsize += aInflateValue;
|
||||||
|
|
||||||
// Verify if do not deflate more than than size
|
// Verify if do not deflate more than than size
|
||||||
// Only possible for inflate negative values.
|
// Only possible for inflate negative values.
|
||||||
if( halfsize.x < 0 )
|
if( halfsize.x < 0 )
|
||||||
halfsize.x = 0;
|
halfsize.x = 0;
|
||||||
|
|
||||||
if( halfsize.y < 0 )
|
if( halfsize.y < 0 )
|
||||||
halfsize.y = 0;
|
halfsize.y = 0;
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
{
|
|
||||||
// Trapezoidal pad: verify delta values
|
|
||||||
delta.x = ( m_DeltaSize.x >> 1 );
|
|
||||||
delta.y = ( m_DeltaSize.y >> 1 );
|
|
||||||
|
|
||||||
// be sure delta values are not to large
|
case PAD_TRAPEZOID:
|
||||||
if( (delta.x < 0) && (delta.x <= -halfsize.y) )
|
// Trapezoidal pad: verify delta values
|
||||||
delta.x = -halfsize.y + 1;
|
delta.x = ( m_DeltaSize.x >> 1 );
|
||||||
|
delta.y = ( m_DeltaSize.y >> 1 );
|
||||||
|
|
||||||
if( (delta.x > 0) && (delta.x >= halfsize.y) )
|
// be sure delta values are not to large
|
||||||
delta.x = halfsize.y - 1;
|
if( (delta.x < 0) && (delta.x <= -halfsize.y) )
|
||||||
|
delta.x = -halfsize.y + 1;
|
||||||
|
|
||||||
if( (delta.y < 0) && (delta.y <= -halfsize.x) )
|
if( (delta.x > 0) && (delta.x >= halfsize.y) )
|
||||||
delta.y = -halfsize.x + 1;
|
delta.x = halfsize.y - 1;
|
||||||
|
|
||||||
if( (delta.y > 0) && (delta.y >= halfsize.x) )
|
if( (delta.y < 0) && (delta.y <= -halfsize.x) )
|
||||||
delta.y = halfsize.x - 1;
|
delta.y = -halfsize.x + 1;
|
||||||
|
|
||||||
|
if( (delta.y > 0) && (delta.y >= halfsize.x) )
|
||||||
|
delta.y = halfsize.x - 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // is used only for rect and trap. pads
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the basic rectangular or trapezoid shape
|
// Build the basic rectangular or trapezoid shape
|
||||||
|
|
|
@ -82,21 +82,36 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
* Function TransformBoundingBoxWithClearanceToPolygon
|
||||||
* Convert the track shape to a closed polygon
|
* Convert the text bounding box to a rectangular polygon
|
||||||
|
* depending on the text orientation, the bounding box
|
||||||
|
* is not always horizontal or vertical
|
||||||
* Used in filling zones calculations
|
* Used in filling zones calculations
|
||||||
* Circles and arcs are approximated by segments
|
* Circles and arcs are approximated by segments
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
* @param aClearanceValue = the clearance around the pad
|
* @param aClearanceValue = the clearance around the text bounding box
|
||||||
|
* to the real clearance value (usually near from 1.0)
|
||||||
|
*/
|
||||||
|
void TransformBoundingBoxWithClearanceToPolygon(
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aClearanceValue ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformShapeWithClearanceToPolygonSet
|
||||||
|
* Convert the text shape to a set of polygons (one by segment)
|
||||||
|
* Used in 3D viewer
|
||||||
|
* Circles and arcs are approximated by segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aClearanceValue = the clearance around the text
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
||||||
* clearance when the circle is approximated by segment bigger or equal
|
* clearance when the circle is approximated by segment bigger or equal
|
||||||
* to the real clearance value (usually near from 1.0)
|
* to the real clearance value (usually near from 1.0)
|
||||||
*/
|
*/
|
||||||
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void TransformShapeWithClearanceToPolygonSet( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor );
|
double aCorrectionFactor ) const;
|
||||||
|
|
||||||
wxString GetSelectMenuText() const;
|
wxString GetSelectMenuText() const;
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ public:
|
||||||
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
int aClearanceValue,
|
int aClearanceValue,
|
||||||
int aCircleToSegmentsCount,
|
int aCircleToSegmentsCount,
|
||||||
double aCorrectionFactor );
|
double aCorrectionFactor ) const;
|
||||||
/**
|
/**
|
||||||
* Function SetDrill
|
* Function SetDrill
|
||||||
* sets the drill value for vias.
|
* sets the drill value for vias.
|
||||||
|
|
|
@ -263,19 +263,40 @@ public:
|
||||||
*/
|
*/
|
||||||
bool HitTestFilledArea( const wxPoint& aRefPos ) const;
|
bool HitTestFilledArea( const wxPoint& aRefPos ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function BuildFilledPolysListData
|
* Function TransformSolidAreasShapesToPolygonSet
|
||||||
* Build m_FilledPolysList data from real outlines (m_Poly)
|
* Convert solid areas full shapes to polygon set
|
||||||
* in order to have drawable (and plottable) filled polygons
|
* (the full shape is the polygon area with a thick outline)
|
||||||
* drawable filled polygons are polygons without hole
|
* Used in 3D view
|
||||||
* @param aPcb: the current board (can be NULL for non copper zones)
|
* Arcs (ends of segments) are approximated by segments
|
||||||
* @param aCornerBuffer: A reference to a buffer to put polygon corners, or NULL
|
* @param aCornerBuffer = a buffer to store the polygons
|
||||||
* if NULL (default), uses m_FilledPolysList and fill current zone.
|
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
||||||
* @return number of polygons
|
* @param aCorrectionFactor = the correction to apply to arcs radius to roughly
|
||||||
* This function does not add holes for pads and tracks but calls
|
* keep arc radius when approximated by segments
|
||||||
* AddClearanceAreasPolygonsToPolysList() to do that for copper layers
|
|
||||||
*/
|
*/
|
||||||
int BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer = NULL );
|
void TransformSolidAreasShapesToPolygonSet( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aCircleToSegmentsCount,
|
||||||
|
double aCorrectionFactor );
|
||||||
|
/**
|
||||||
|
* Function BuildFilledSolidAreasPolygons
|
||||||
|
* Build the filled solid areas data from real outlines (stored in m_Poly)
|
||||||
|
* The solid areas can be more thna one on copper layers, and do not have holes
|
||||||
|
( holes are linked by overlapping segments to the main outline)
|
||||||
|
* in order to have drawable (and plottable) filled polygons
|
||||||
|
* @param aPcb: the current board (can be NULL for non copper zones)
|
||||||
|
* @param aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
|
||||||
|
* if NULL (default:
|
||||||
|
* - m_FilledPolysList is used to store solid areas polygons.
|
||||||
|
* - on copper layers, tracks and other items shapes of other nets are
|
||||||
|
* removed from solid areas
|
||||||
|
* if not null:
|
||||||
|
* Only the zone outline (with holes, if any) are stored in aCornerBuffer
|
||||||
|
* with holes linked. Therfore only one polygon is created
|
||||||
|
* @return true if OK, false if the solid areas cannot be calculated
|
||||||
|
* This function calls AddClearanceAreasPolygonsToPolysList()
|
||||||
|
* to add holes for pads and tracks and other items not in net.
|
||||||
|
*/
|
||||||
|
bool BuildFilledSolidAreasPolygons( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer = NULL );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CopyPolygonsFromKiPolygonListToFilledPolysList
|
* Function CopyPolygonsFromKiPolygonListToFilledPolysList
|
||||||
|
@ -296,15 +317,31 @@ public:
|
||||||
* Function AddClearanceAreasPolygonsToPolysList
|
* Function AddClearanceAreasPolygonsToPolysList
|
||||||
* Add non copper areas polygons (pads and tracks with clearance)
|
* Add non copper areas polygons (pads and tracks with clearance)
|
||||||
* to a filled copper area
|
* to a filled copper area
|
||||||
* used in BuildFilledPolysListData when calculating filled areas in a zone
|
* used in BuildFilledSolidAreasPolygons when calculating filled areas in a zone
|
||||||
* Non copper areas are pads and track and their clearance area
|
* Non copper areas are pads and track and their clearance area
|
||||||
* The filled copper area must be computed before
|
* The filled copper area must be computed before
|
||||||
* BuildFilledPolysListData() call this function just after creating the
|
* BuildFilledSolidAreasPolygons() call this function just after creating the
|
||||||
* filled copper area polygon (without clearance areas
|
* filled copper area polygon (without clearance areas
|
||||||
* @param aPcb: the current board
|
* @param aPcb: the current board
|
||||||
*/
|
*/
|
||||||
void AddClearanceAreasPolygonsToPolysList( BOARD* aPcb );
|
void AddClearanceAreasPolygonsToPolysList( BOARD* aPcb );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TransformOutlinesShapeWithClearanceToPolygon
|
||||||
|
* Convert the outlines shape to a polygon with no holes
|
||||||
|
* inflated (optional) by max( aClearanceValue, the zone clearance)
|
||||||
|
* (holes are linked to external outline by overlapping segments)
|
||||||
|
* Used in filling zones calculations
|
||||||
|
* Circles (vias) and arcs (ends of tracks) are approximated by segments
|
||||||
|
* @param aCornerBuffer = a buffer to store the polygon
|
||||||
|
* @param aClearanceValue = the clearance around the pad
|
||||||
|
* @param aAddClearance = true to add a clearance area to the polygon
|
||||||
|
* false to create the outline polygon.
|
||||||
|
*/
|
||||||
|
void TransformOutlinesShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aClearanceValue,
|
||||||
|
bool aAddClearance );
|
||||||
/**
|
/**
|
||||||
* Function HitTestForCorner
|
* Function HitTestForCorner
|
||||||
* tests if the given wxPoint near a corner
|
* tests if the given wxPoint near a corner
|
||||||
|
@ -446,26 +483,7 @@ public:
|
||||||
m_Poly->SetHatchStyle( aStyle );
|
m_Poly->SetHatchStyle( aStyle );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformShapeWithClearanceToPolygon
|
|
||||||
* Convert the track shape to a closed polygon
|
|
||||||
* Used in filling zones calculations
|
|
||||||
* Circles (vias) and arcs (ends of tracks) are approximated by segments
|
|
||||||
* @param aCornerBuffer = a buffer to store the polygon
|
|
||||||
* @param aClearanceValue = the clearance around the pad
|
|
||||||
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
|
|
||||||
* @param aCorrectionFactor = the correction to apply to circles radius to keep
|
|
||||||
* @param aAddClearance = true to add a clearance area to the polygon
|
|
||||||
* false to create the outline polygon.
|
|
||||||
* clearance when the circle is approximated by segment bigger or equal
|
|
||||||
* to the real clearance value (usually near from 1.0)
|
|
||||||
*/
|
|
||||||
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
|
||||||
int aClearanceValue,
|
|
||||||
int aCircleToSegmentsCount,
|
|
||||||
double aCorrectionFactor,
|
|
||||||
bool aAddClearance );
|
|
||||||
/**
|
|
||||||
* Function IsSame
|
* Function IsSame
|
||||||
* tests if 2 zones are equivalent:
|
* tests if 2 zones are equivalent:
|
||||||
* 2 zones are equivalent if they have same parameters and same outlines
|
* 2 zones are equivalent if they have same parameters and same outlines
|
||||||
|
|
|
@ -156,14 +156,14 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
|
||||||
|
|
||||||
PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness );
|
PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness );
|
||||||
|
|
||||||
for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER;
|
for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER;
|
||||||
layer <= LAST_NON_COPPER_LAYER; ++layer )
|
layer <= LAST_NON_COPPER_LAYER; ++layer )
|
||||||
{
|
{
|
||||||
m_LayerSelectionCtrl->Append( m_parent->GetBoard()->GetLayerName( layer ) );
|
m_LayerSelectionCtrl->Append( m_parent->GetBoard()->GetLayerName( layer ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
LAYER_NUM layer = m_Item->GetLayer();
|
LAYER_NUM layer = m_Item->GetLayer();
|
||||||
|
|
||||||
// It has to be an aux layer
|
// It has to be an aux layer
|
||||||
if ( layer < FIRST_NON_COPPER_LAYER )
|
if ( layer < FIRST_NON_COPPER_LAYER )
|
||||||
layer = FIRST_NON_COPPER_LAYER;
|
layer = FIRST_NON_COPPER_LAYER;
|
||||||
|
|
|
@ -134,7 +134,7 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LAYER_MSK aLayerMask,
|
||||||
// compatibility):
|
// compatibility):
|
||||||
for( SEGZONE* seg = aBoard->m_Zone; seg != NULL; seg = seg->Next() )
|
for( SEGZONE* seg = aBoard->m_Zone; seg != NULL; seg = seg->Next() )
|
||||||
{
|
{
|
||||||
if( ( GetLayerMask( seg->GetLayer() ) & aLayerMask ) == 0 )
|
if( ( GetLayerMask( seg->GetLayer() ) & aLayerMask ) == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
|
aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
|
||||||
|
@ -515,53 +515,16 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
double correction = 1.0 / cos( M_PI / circleToSegmentsCount );
|
double correction = 1.0 / cos( M_PI / circleToSegmentsCount );
|
||||||
|
|
||||||
// Plot pads
|
// Plot pads
|
||||||
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
|
// add shapes with exact size
|
||||||
{
|
module->TransformPadsShapesWithClearanceToPolygon( layer,
|
||||||
if( (pad->GetLayerMask() & aLayerMask) == 0 )
|
initialPolys, 0,
|
||||||
continue;
|
circleToSegmentsCount, correction );
|
||||||
|
// add shapes inflated by aMinThickness/2
|
||||||
int clearance = pad->GetSolderMaskMargin();
|
module->TransformPadsShapesWithClearanceToPolygon( layer,
|
||||||
int margin = clearance + inflate;
|
bufferPolys, inflate,
|
||||||
|
circleToSegmentsCount, correction );
|
||||||
// For rect and trap. pads, use a polygon with the same shape
|
|
||||||
// (i.e. with no rounded corners)
|
|
||||||
if( (pad->GetShape() == PAD_RECT) || (pad->GetShape() == PAD_TRAPEZOID) )
|
|
||||||
{
|
|
||||||
wxPoint coord[4];
|
|
||||||
CPolyPt corner;
|
|
||||||
pad->BuildPadPolygon( coord, wxSize( margin, margin ),
|
|
||||||
pad->GetOrientation() );
|
|
||||||
for( int ii = 0; ii < 4; ii++ )
|
|
||||||
{
|
|
||||||
coord[ii] += pad->ReturnShapePos();
|
|
||||||
corner.x = coord[ii].x;
|
|
||||||
corner.y = coord[ii].y;
|
|
||||||
corner.end_contour = (ii == 3);
|
|
||||||
bufferPolys.push_back( corner );
|
|
||||||
}
|
|
||||||
pad->BuildPadPolygon( coord, wxSize( clearance, clearance ),
|
|
||||||
pad->GetOrientation() );
|
|
||||||
for( int ii = 0; ii < 4; ii++ )
|
|
||||||
{
|
|
||||||
coord[ii] += pad->ReturnShapePos();
|
|
||||||
corner.x = coord[ii].x;
|
|
||||||
corner.y = coord[ii].y;
|
|
||||||
corner.end_contour = (ii == 3);
|
|
||||||
initialPolys.push_back( corner );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pad->TransformShapeWithClearanceToPolygon( bufferPolys, clearance + inflate,
|
|
||||||
circleToSegmentsCount,
|
|
||||||
correction );
|
|
||||||
pad->TransformShapeWithClearanceToPolygon( initialPolys, clearance,
|
|
||||||
circleToSegmentsCount,
|
|
||||||
correction );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
|
// Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
|
||||||
|
@ -608,9 +571,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
if( zone->GetLayer() != layer )
|
if( zone->GetLayer() != layer )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zone->TransformShapeWithClearanceToPolygon( bufferPolys,
|
zone->TransformOutlinesShapeWithClearanceToPolygon( bufferPolys,
|
||||||
inflate, circleToSegmentsCount,
|
inflate, true );
|
||||||
correction, true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now:
|
// Now:
|
||||||
|
|
|
@ -38,8 +38,24 @@
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <zones.h>
|
#include <zones.h>
|
||||||
|
|
||||||
|
/* Build the filled solid areas data from real outlines (stored in m_Poly)
|
||||||
|
* The solid areas can be more than one on copper layers, and do not have holes
|
||||||
|
( holes are linked by overlapping segments to the main outline)
|
||||||
|
* aPcb: the current board (can be NULL for non copper zones)
|
||||||
|
* aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
|
||||||
|
* if NULL:
|
||||||
|
* - m_FilledPolysList is used to store solid areas polygons.
|
||||||
|
* - on copper layers, tracks and other items shapes of other nets are
|
||||||
|
* removed from solid areas
|
||||||
|
* if not null:
|
||||||
|
* Only the zone outline (with holes, if any) are stored in aCornerBuffer
|
||||||
|
* with holes linked. Therfore only one polygon is created
|
||||||
|
* This function calls AddClearanceAreasPolygonsToPolysList()
|
||||||
|
* to add holes for pads and tracks and other items not in net.
|
||||||
|
*/
|
||||||
|
|
||||||
int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer )
|
bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb,
|
||||||
|
std::vector <CPolyPt>* aCornerBuffer )
|
||||||
{
|
{
|
||||||
if( aCornerBuffer == NULL )
|
if( aCornerBuffer == NULL )
|
||||||
m_FilledPolysList.clear();
|
m_FilledPolysList.clear();
|
||||||
|
|
|
@ -112,7 +112,7 @@ int PCB_EDIT_FRAME::Fill_Zone( ZONE_CONTAINER* aZone )
|
||||||
|
|
||||||
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
||||||
|
|
||||||
aZone->BuildFilledPolysListData( GetBoard() );
|
aZone->BuildFilledSolidAreasPolygons( GetBoard() );
|
||||||
|
|
||||||
OnModify();
|
OnModify();
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
|
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <zones.h>
|
#include <zones.h>
|
||||||
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
|
|
||||||
extern void BuildUnconnectedThermalStubsPolygonList( std::vector<CPolyPt>& aCornerBuffer,
|
extern void BuildUnconnectedThermalStubsPolygonList( std::vector<CPolyPt>& aCornerBuffer,
|
||||||
|
@ -80,10 +81,6 @@ extern void CreateThermalReliefPadPolygon( std::vector<CPolyPt>& aCornerBuffer,
|
||||||
double aCorrectionFactor,
|
double aCorrectionFactor,
|
||||||
int aThermalRot );
|
int aThermalRot );
|
||||||
|
|
||||||
// Exported function
|
|
||||||
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
|
|
||||||
KI_POLYGON_SET& aKiPolyList );
|
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
static int s_thermalRot = 450; // angle of stubs in thermal reliefs for round pads
|
static int s_thermalRot = 450; // angle of stubs in thermal reliefs for round pads
|
||||||
|
|
||||||
|
@ -100,13 +97,13 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
|
||||||
/**
|
/**
|
||||||
* Function AddClearanceAreasPolygonsToPolysList
|
* Function AddClearanceAreasPolygonsToPolysList
|
||||||
* Supports a min thickness area constraint.
|
* Supports a min thickness area constraint.
|
||||||
* Add non copper areas polygons (pads and tracks with clearence)
|
* Add non copper areas polygons (pads and tracks with clearance)
|
||||||
* to the filled copper area found
|
* to the filled copper area found
|
||||||
* in BuildFilledPolysListData after calculating filled areas in a zone
|
* in BuildFilledPolysListData after calculating filled areas in a zone
|
||||||
* Non filled copper areas are pads and track and their clearance areas
|
* Non filled copper areas are pads and track and their clearance areas
|
||||||
* The filled copper area must be computed just before.
|
* The filled copper area must be computed just before.
|
||||||
* BuildFilledPolysListData() call this function just after creating the
|
* BuildFilledPolysListData() call this function just after creating the
|
||||||
* filled copper area polygon (without clearence areas
|
* filled copper area polygon (without clearance areas)
|
||||||
* to do that this function:
|
* to do that this function:
|
||||||
* 1 - Creates the main outline (zone outline) using a correction to shrink the resulting area
|
* 1 - Creates the main outline (zone outline) using a correction to shrink the resulting area
|
||||||
* with m_ZoneMinThickness/2 value.
|
* with m_ZoneMinThickness/2 value.
|
||||||
|
@ -329,17 +326,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
case PCB_LINE_T:
|
case PCB_LINE_T:
|
||||||
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
|
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
|
||||||
cornerBufferPolysToSubstract,
|
cornerBufferPolysToSubstract,
|
||||||
zone_clearance,
|
zone_clearance, s_CircleToSegmentsCount, s_Correction );
|
||||||
s_CircleToSegmentsCount,
|
|
||||||
s_Correction );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PCB_TEXT_T:
|
case PCB_TEXT_T:
|
||||||
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygon(
|
( (TEXTE_PCB*) item )->TransformBoundingBoxWithClearanceToPolygon(
|
||||||
cornerBufferPolysToSubstract,
|
cornerBufferPolysToSubstract, zone_clearance );
|
||||||
zone_clearance,
|
|
||||||
s_CircleToSegmentsCount,
|
|
||||||
s_Correction );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -379,10 +371,9 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
clearance = m_ZoneMinThickness / 2;
|
clearance = m_ZoneMinThickness / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
zone->TransformShapeWithClearanceToPolygon(
|
zone->TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
cornerBufferPolysToSubstract,
|
cornerBufferPolysToSubstract,
|
||||||
clearance, s_CircleToSegmentsCount,
|
clearance, addclearance );
|
||||||
s_Correction, addclearance );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove thermal symbols
|
// Remove thermal symbols
|
||||||
|
@ -468,103 +459,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
cornerBufferPolysToSubstract.clear();
|
cornerBufferPolysToSubstract.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
|
|
||||||
KI_POLYGON_SET& aKiPolyList )
|
|
||||||
{
|
|
||||||
unsigned ii;
|
|
||||||
|
|
||||||
std::vector<KI_POLY_POINT> cornerslist;
|
|
||||||
|
|
||||||
int polycount = 0;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aCornersBuffer.size(); ii++ )
|
|
||||||
{
|
|
||||||
if( aCornersBuffer[ii].end_contour )
|
|
||||||
polycount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
aKiPolyList.reserve( polycount );
|
|
||||||
|
|
||||||
for( unsigned icnt = 0; icnt < aCornersBuffer.size(); )
|
|
||||||
{
|
|
||||||
KI_POLYGON poly;
|
|
||||||
cornerslist.clear();
|
|
||||||
|
|
||||||
for( ii = icnt; ii < aCornersBuffer.size(); ii++ )
|
|
||||||
{
|
|
||||||
cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) );
|
|
||||||
|
|
||||||
if( aCornersBuffer[ii].end_contour )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
|
||||||
aKiPolyList.push_back( poly );
|
|
||||||
icnt = ii + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ZONE_CONTAINER::CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList )
|
void ZONE_CONTAINER::CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList )
|
||||||
{
|
{
|
||||||
m_FilledPolysList.clear();
|
m_FilledPolysList.clear();
|
||||||
|
CopyPolygonsFromKiPolygonListToPolysList( aKiPolyList, m_FilledPolysList );
|
||||||
for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ )
|
|
||||||
{
|
|
||||||
KI_POLYGON& poly = aKiPolyList[ii];
|
|
||||||
CPolyPt corner( 0, 0, false );
|
|
||||||
|
|
||||||
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
|
||||||
{
|
|
||||||
KI_POLY_POINT point = *(poly.begin() + jj);
|
|
||||||
corner.x = point.x();
|
|
||||||
corner.y = point.y();
|
|
||||||
corner.end_contour = false;
|
|
||||||
m_FilledPolysList.push_back( corner );
|
|
||||||
}
|
|
||||||
|
|
||||||
corner.end_contour = true;
|
|
||||||
m_FilledPolysList.pop_back();
|
|
||||||
m_FilledPolysList.push_back( corner );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ZONE_CONTAINER::CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList )
|
void ZONE_CONTAINER::CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList )
|
||||||
{
|
{
|
||||||
unsigned corners_count = m_FilledPolysList.size();
|
AddPolygonCornersToKiPolygonList( m_FilledPolysList, aKiPolyList );
|
||||||
unsigned ic = 0;
|
|
||||||
|
|
||||||
int polycount = 0;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < corners_count; ii++ )
|
|
||||||
{
|
|
||||||
const CPolyPt& corner = m_FilledPolysList[ii];
|
|
||||||
|
|
||||||
if( corner.end_contour )
|
|
||||||
polycount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
aKiPolyList.reserve( polycount );
|
|
||||||
std::vector<KI_POLY_POINT> cornerslist;
|
|
||||||
|
|
||||||
while( ic < corners_count )
|
|
||||||
{
|
|
||||||
cornerslist.clear();
|
|
||||||
KI_POLYGON poly;
|
|
||||||
{
|
|
||||||
while( ic < corners_count )
|
|
||||||
{
|
|
||||||
const CPolyPt& corner = m_FilledPolysList[ic++];
|
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
|
||||||
|
|
||||||
if( corner.end_contour )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
|
||||||
|
|
||||||
aKiPolyList.push_back( poly );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2013 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,6 +39,81 @@
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <zones.h>
|
#include <zones.h>
|
||||||
|
|
||||||
|
/* Function TransformOutlinesShapeWithClearanceToPolygon
|
||||||
|
* Convert the zone filled areas polygons to polygons
|
||||||
|
* inflated (optional) by max( aClearanceValue, the zone clearance)
|
||||||
|
* and copy them in aCornerBuffer
|
||||||
|
* param aClearanceValue = the clearance around polygons
|
||||||
|
* param aAddClearance = true to add a clearance area to the polygon
|
||||||
|
* false to create the outline polygon.
|
||||||
|
*/
|
||||||
|
void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
|
std::vector <CPolyPt>& aCornerBuffer,
|
||||||
|
int aClearanceValue, bool aAddClearance )
|
||||||
|
{
|
||||||
|
// Creates the zone outlines polygon (with linked holes if any)
|
||||||
|
std::vector <CPolyPt> zoneOutines;
|
||||||
|
BuildFilledSolidAreasPolygons( NULL, &zoneOutines );
|
||||||
|
|
||||||
|
// add clearance to outline
|
||||||
|
int clearance = 0;
|
||||||
|
if( aAddClearance )
|
||||||
|
{
|
||||||
|
clearance = GetClearance();
|
||||||
|
if( aClearanceValue > clearance )
|
||||||
|
clearance = aClearanceValue;
|
||||||
|
}
|
||||||
|
// Calculate the polygon with clearance
|
||||||
|
// holes are linked to the main outline, so only one polygon should be created.
|
||||||
|
KI_POLYGON_SET polyset_zone_solid_areas;
|
||||||
|
std::vector<KI_POLY_POINT> cornerslist;
|
||||||
|
unsigned ic = 0;
|
||||||
|
unsigned corners_count = zoneOutines.size();
|
||||||
|
while( ic < corners_count )
|
||||||
|
{
|
||||||
|
cornerslist.clear();
|
||||||
|
KI_POLYGON poly;
|
||||||
|
{
|
||||||
|
for( ; ic < corners_count; ic++ )
|
||||||
|
{
|
||||||
|
CPolyPt* corner = &zoneOutines[ic];
|
||||||
|
cornerslist.push_back( KI_POLY_POINT( corner->x, corner->y ) );
|
||||||
|
if( corner->end_contour )
|
||||||
|
{
|
||||||
|
ic++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
||||||
|
polyset_zone_solid_areas.push_back( poly );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
polyset_zone_solid_areas += clearance;
|
||||||
|
|
||||||
|
// Put the resulting polygon in aCornerBuffer corners list
|
||||||
|
for( unsigned ii = 0; ii < polyset_zone_solid_areas.size(); ii++ )
|
||||||
|
{
|
||||||
|
KI_POLYGON& poly = polyset_zone_solid_areas[ii];
|
||||||
|
CPolyPt corner( 0, 0, false );
|
||||||
|
|
||||||
|
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
||||||
|
{
|
||||||
|
KI_POLY_POINT point = *(poly.begin() + jj);
|
||||||
|
corner.x = point.x();
|
||||||
|
corner.y = point.y();
|
||||||
|
corner.end_contour = false;
|
||||||
|
aCornerBuffer.push_back( corner );
|
||||||
|
}
|
||||||
|
|
||||||
|
corner.end_contour = true;
|
||||||
|
aCornerBuffer.pop_back();
|
||||||
|
aCornerBuffer.push_back( corner );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function BuildUnconnectedThermalStubsPolygonList
|
* Function BuildUnconnectedThermalStubsPolygonList
|
||||||
|
|
|
@ -66,7 +66,7 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
|
||||||
{
|
{
|
||||||
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
|
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
|
||||||
if( m_ZoneDescriptorList[ia]->GetLayer() == layer )
|
if( m_ZoneDescriptorList[ia]->GetLayer() == layer )
|
||||||
m_ZoneDescriptorList[ia]->BuildFilledPolysListData( this );
|
m_ZoneDescriptorList[ia]->BuildFilledSolidAreasPolygons( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for bad areas: all zones must have more than 2 corners:
|
// Test for bad areas: all zones must have more than 2 corners:
|
||||||
|
|
Loading…
Reference in New Issue