Commit 4ac7dd58 authored by jean-pierre charras's avatar jean-pierre charras

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.
parent 0e903dba
...@@ -100,7 +100,8 @@ public: ...@@ -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: ...@@ -111,47 +112,16 @@ public:
m_draw3dOffset.y = aPosY; m_draw3dOffset.y = aPosY;
} }
void DrawGrid( double aGriSizeMM );
/**
* 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 * Function BuildBoard3DView
* draws a 3D segment (line, arc or circle). * Called by CreateDrawGL_List()
* Fills the OpenGL draw list with board items draw list.
*/ */
void Draw3D_DrawSegment( DRAWSEGMENT* segment ); void BuildBoard3DView();
/** void DrawGrid( double aGriSizeMM );
* Function Draw3D_Zone void Draw3DViaHole( SEGVIA * aVia );
* draw all solid areas in aZone void Draw3DPadHole( D_PAD * aPad );
* @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()
}; };
......
This diff is collapsed.
...@@ -32,6 +32,82 @@ ...@@ -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, ...@@ -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 ...@@ -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 @@ ...@@ -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, ...@@ -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
...@@ -214,7 +214,7 @@ public: ...@@ -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;
......
/* /*
* 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 @@ ...@@ -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: ...@@ -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;
......
/* /*
* 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; ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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, ...@@ -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
{ case PAD_TRAPEZOID:
// Trapezoidal pad: verify delta values // Trapezoidal pad: verify delta values
delta.x = ( m_DeltaSize.x >> 1 ); delta.x = ( m_DeltaSize.x >> 1 );
delta.y = ( m_DeltaSize.y >> 1 ); delta.y = ( m_DeltaSize.y >> 1 );
// be sure delta values are not to large // be sure delta values are not to large
if( (delta.x < 0) && (delta.x <= -halfsize.y) ) if( (delta.x < 0) && (delta.x <= -halfsize.y) )
delta.x = -halfsize.y + 1; delta.x = -halfsize.y + 1;
if( (delta.x > 0) && (delta.x >= halfsize.y) ) if( (delta.x > 0) && (delta.x >= halfsize.y) )
delta.x = halfsize.y - 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;
if( (delta.y > 0) && (delta.y >= halfsize.x) ) default: // is used only for rect and trap. pads
delta.y = halfsize.x - 1; return;
} }
// Build the basic rectangular or trapezoid shape // Build the basic rectangular or trapezoid shape
......
...@@ -82,21 +82,36 @@ public: ...@@ -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: ...@@ -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: ...@@ -263,19 +263,40 @@ public:
*/ */
bool HitTestFilledArea( const wxPoint& aRefPos ) const; bool HitTestFilledArea( const wxPoint& aRefPos ) const;
/**
* 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
* @param aCornerBuffer = a buffer to store the polygons
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to arcs radius to roughly
* keep arc radius when approximated by segments
*/
void TransformSolidAreasShapesToPolygonSet( std::vector <CPolyPt>& aCornerBuffer,
int aCircleToSegmentsCount,
double aCorrectionFactor );
/** /**
* Function BuildFilledPolysListData * Function BuildFilledSolidAreasPolygons
* Build m_FilledPolysList data from real outlines (m_Poly) * 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 * in order to have drawable (and plottable) filled polygons
* drawable filled polygons are polygons without hole
* @param aPcb: the current board (can be NULL for non copper zones) * @param aPcb: the current board (can be NULL for non copper zones)
* @param aCornerBuffer: A reference to a buffer to put polygon corners, or NULL * @param aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
* if NULL (default), uses m_FilledPolysList and fill current zone. * if NULL (default:
* @return number of polygons * - m_FilledPolysList is used to store solid areas polygons.
* This function does not add holes for pads and tracks but calls * - on copper layers, tracks and other items shapes of other nets are
* AddClearanceAreasPolygonsToPolysList() to do that for copper layers * removed from solid areas
*/ * if not null:
int BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer = 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: ...@@ -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: ...@@ -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( ) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 ) ...@@ -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 @@ ...@@ -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, ...@@ -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 ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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, ...@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment