Commit f72aec25 authored by Maciej Suminski's avatar Maciej Suminski

Auto zone refilling after using the POINT_EDITOR.

Minor code cleaning.
parent b6e3b3a3
...@@ -358,19 +358,6 @@ public: ...@@ -358,19 +358,6 @@ public:
*/ */
bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const; bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const;
/**
* Function Fill_Zone
* Calculate the zone filling
* The zone outline is a frontier, and can be complex (with holes)
* The filling starts from starting points like pads, tracks.
* If exists the old filling is removed
* @param frame = reference to the main frame
* @param DC = current Device Context
* @param verbose = true to show error messages
* @return error level (0 = no error)
*/
int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true );
/** /**
* Function FillZoneAreasWithSegments * Function FillZoneAreasWithSegments
* Fill sub areas in a zone with segments with m_ZoneMinThickness width * Fill sub areas in a zone with segments with m_ZoneMinThickness width
......
...@@ -2339,7 +2339,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() ...@@ -2339,7 +2339,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
arcsegcount = 32; arcsegcount = 32;
zc->SetArcSegmentCount( arcsegcount ); zc->SetArcSegmentCount( arcsegcount );
zc->SetIsFilled( fillstate == 'S' ? true : false ); zc->SetIsFilled( fillstate == 'S' );
zc->SetThermalReliefGap( thermalReliefGap ); zc->SetThermalReliefGap( thermalReliefGap );
zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge ); zc->SetThermalReliefCopperBridge( thermalReliefCopperBridge );
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "selection_tool.h" #include "selection_tool.h"
#include "point_editor.h" #include "point_editor.h"
#include <wxPcbStruct.h>
#include <class_drawsegment.h> #include <class_drawsegment.h>
#include <class_zone.h> #include <class_zone.h>
...@@ -206,6 +207,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) ...@@ -206,6 +207,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
if( m_editPoints ) if( m_editPoints )
{ {
finishItem();
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_toolMgr->GetView()->Remove( m_editPoints.get() ); m_toolMgr->GetView()->Remove( m_editPoints.get() );
m_editPoints.reset(); m_editPoints.reset();
...@@ -326,6 +328,20 @@ void POINT_EDITOR::updateItem() const ...@@ -326,6 +328,20 @@ void POINT_EDITOR::updateItem() const
} }
void POINT_EDITOR::finishItem() const
{
EDA_ITEM* item = m_editPoints->GetParent();
if( item->Type() == PCB_ZONE_AREA_T )
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
if( zone->IsFilled() )
getEditFrame<PCB_EDIT_FRAME>()->Fill_Zone( zone );
}
}
void POINT_EDITOR::updatePoints() const void POINT_EDITOR::updatePoints() const
{ {
EDA_ITEM* item = m_editPoints->GetParent(); EDA_ITEM* item = m_editPoints->GetParent();
......
...@@ -69,6 +69,9 @@ private: ...@@ -69,6 +69,9 @@ private:
///> Updates item's points with edit points. ///> Updates item's points with edit points.
void updateItem() const; void updateItem() const;
///> Applies the last changes to the edited item.
void finishItem() const;
///> Updates edit points with item's points. ///> Updates edit points with item's points.
void updatePoints() const; void updatePoints() const;
......
...@@ -54,8 +54,7 @@ ...@@ -54,8 +54,7 @@
* to add holes for pads and tracks and other items not in net. * to add holes for pads and tracks and other items not in net.
*/ */
bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, CPOLYGONS_LIST* aCornerBuffer )
CPOLYGONS_LIST* aCornerBuffer )
{ {
if( aCornerBuffer == NULL ) if( aCornerBuffer == NULL )
m_FilledPolysList.RemoveAllContours(); m_FilledPolysList.RemoveAllContours();
...@@ -80,9 +79,11 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, ...@@ -80,9 +79,11 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb,
case ZONE_SETTINGS::SMOOTHING_CHAMFER: case ZONE_SETTINGS::SMOOTHING_CHAMFER:
m_smoothedPoly = m_Poly->Chamfer( m_cornerRadius ); m_smoothedPoly = m_Poly->Chamfer( m_cornerRadius );
break; break;
case ZONE_SETTINGS::SMOOTHING_FILLET: case ZONE_SETTINGS::SMOOTHING_FILLET:
m_smoothedPoly = m_Poly->Fillet( m_cornerRadius, m_ArcToSegmentsCount ); m_smoothedPoly = m_Poly->Fillet( m_cornerRadius, m_ArcToSegmentsCount );
break; break;
default: default:
m_smoothedPoly = new CPolyLine; m_smoothedPoly = new CPolyLine;
m_smoothedPoly->Copy( m_Poly ); m_smoothedPoly->Copy( m_Poly );
...@@ -90,18 +91,16 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, ...@@ -90,18 +91,16 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb,
} }
if( aCornerBuffer ) if( aCornerBuffer )
ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, *aCornerBuffer );
*aCornerBuffer );
else else
ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, m_FilledPolysList );
m_FilledPolysList );
/* For copper layers, we now must add holes in the Polygon list. /* For copper layers, we now must add holes in the Polygon list.
* holes are pads and tracks with their clearance area * holes are pads and tracks with their clearance area
* for non copper layers just recalculate the m_FilledPolysList * for non copper layers just recalculate the m_FilledPolysList
* with m_ZoneMinThickness taken in account * with m_ZoneMinThickness taken in account
*/ */
if( ! aCornerBuffer ) if( !aCornerBuffer )
{ {
if( IsOnCopperLayer() ) if( IsOnCopperLayer() )
AddClearanceAreasPolygonsToPolysList( aPcb ); AddClearanceAreasPolygonsToPolysList( aPcb );
...@@ -124,16 +123,19 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, ...@@ -124,16 +123,19 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb,
m_FilledPolysList.RemoveAllContours(); m_FilledPolysList.RemoveAllContours();
CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas );
} }
if ( m_FillMode ) // if fill mode uses segments, create them:
FillZoneAreasWithSegments( ); if( m_FillMode ) // if fill mode uses segments, create them:
FillZoneAreasWithSegments();
} }
m_IsFilled = true;
return 1; return 1;
} }
// Sort function to build filled zones // Sort function to build filled zones
static bool SortByXValues( const int& a, const int &b) static bool SortByXValues( const int& a, const int &b )
{ {
return a < b; return a < b;
} }
...@@ -141,13 +143,11 @@ static bool SortByXValues( const int& a, const int &b) ...@@ -141,13 +143,11 @@ static bool SortByXValues( const int& a, const int &b)
int ZONE_CONTAINER::FillZoneAreasWithSegments() int ZONE_CONTAINER::FillZoneAreasWithSegments()
{ {
int ics, ice; int ics, ice;
int count = 0; int count = 0;
std::vector <int> x_coordinates; std::vector <int> x_coordinates;
bool error = false; bool error = false;
int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList
int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList
int margin = m_ZoneMinThickness * 2 / 10; int margin = m_ZoneMinThickness * 2 / 10;
int minwidth = Mils2iu( 2 ); int minwidth = Mils2iu( 2 );
margin = std::max ( minwidth, margin ); margin = std::max ( minwidth, margin );
...@@ -157,28 +157,25 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() ...@@ -157,28 +157,25 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments()
// Read all filled areas in m_FilledPolysList // Read all filled areas in m_FilledPolysList
m_FillSegmList.clear(); m_FillSegmList.clear();
istart = 0; istart = 0;
int end_list = m_FilledPolysList.GetCornersCount()-1; int end_list = m_FilledPolysList.GetCornersCount() - 1;
for( int ic = 0; ic <= end_list; ic++ ) for( int ic = 0; ic <= end_list; ic++ )
{ {
CPolyPt* corner = &m_FilledPolysList[ic]; CPolyPt* corner = &m_FilledPolysList[ic];
if ( corner->end_contour || (ic == end_list) ) if ( corner->end_contour || ( ic == end_list ) )
{ {
iend = ic; iend = ic;
EDA_RECT rect = CalculateSubAreaBoundaryBox( istart, iend ); EDA_RECT rect = CalculateSubAreaBoundaryBox( istart, iend );
// Calculate the y limits of the zone // Calculate the y limits of the zone
int refy = rect.GetY(); for( int refy = rect.GetY(), endy = rect.GetBottom(); refy < endy; refy += step )
int endy = rect.GetBottom();
for( ; refy < endy; refy += step )
{ {
// find all intersection points of an infinite line with polyline sides // find all intersection points of an infinite line with polyline sides
x_coordinates.clear(); x_coordinates.clear();
for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ )
{ {
if ( m_FilledPolysList[ice].m_utility ) if( m_FilledPolysList[ice].m_utility )
continue; continue;
int seg_startX = m_FilledPolysList[ics].x; int seg_startX = m_FilledPolysList[ics].x;
...@@ -203,7 +200,7 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() ...@@ -203,7 +200,7 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments()
// the segment start point: // the segment start point:
seg_endX -= seg_startX; seg_endX -= seg_startX;
seg_endY -= seg_startY; seg_endY -= seg_startY;
double newrefy = (double) (refy - seg_startY); double newrefy = (double) ( refy - seg_startY );
double intersec_x; double intersec_x;
if ( seg_endY == 0 ) // horizontal segment on the same line: skip if ( seg_endY == 0 ) // horizontal segment on the same line: skip
...@@ -217,9 +214,9 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() ...@@ -217,9 +214,9 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments()
// intersec_x = refy/slope = refy * inv_slope // intersec_x = refy/slope = refy * inv_slope
// Note: because horizontal segments are already tested and skipped, slope // Note: because horizontal segments are already tested and skipped, slope
// exists (seg_end_y not O) // exists (seg_end_y not O)
double inv_slope = (double)seg_endX / seg_endY; double inv_slope = (double) seg_endX / seg_endY;
intersec_x = newrefy * inv_slope; intersec_x = newrefy * inv_slope;
x_coordinates.push_back((int) intersec_x + seg_startX); x_coordinates.push_back( (int) intersec_x + seg_startX );
} }
// A line scan is finished: build list of segments // A line scan is finished: build list of segments
...@@ -239,12 +236,12 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() ...@@ -239,12 +236,12 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments()
error = true; error = true;
} }
if ( error ) if( error )
break; break;
int iimax = x_coordinates.size()-1; int iimax = x_coordinates.size() - 1;
for (int ii = 0; ii < iimax; ii +=2 ) for( int ii = 0; ii < iimax; ii +=2 )
{ {
wxPoint seg_start, seg_end; wxPoint seg_start, seg_end;
count++; count++;
...@@ -257,16 +254,19 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments() ...@@ -257,16 +254,19 @@ int ZONE_CONTAINER::FillZoneAreasWithSegments()
} }
} //End examine segments in one area } //End examine segments in one area
if ( error ) if( error )
break; break;
istart = iend + 1; // istart points the first corner of the next area istart = iend + 1; // istart points the first corner of the next area
} // End find one end of outline } // End find one end of outline
if ( error ) if( error )
break; break;
} // End examine all areas } // End examine all areas
if( !error )
m_IsFilled = true;
return count; return count;
} }
......
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