Fix issues in zones creation (DRC and merging) I created in 3658.1
This commit is contained in:
parent
1c9433fb31
commit
f96d557e73
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include <pcbnew.h>
|
||||
#include <zones.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
|
||||
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
|
||||
|
@ -912,7 +913,7 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
|
|||
AppendCorner( aPolygon[i] );
|
||||
}
|
||||
|
||||
m_Poly->Close();
|
||||
m_Poly->CloseLastContour();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -429,7 +429,7 @@ public:
|
|||
return m_Poly->GetHatchStyle();
|
||||
}
|
||||
|
||||
void SetHatchStyle( CPolyLine::hatch_style aStyle )
|
||||
void SetHatchStyle( CPolyLine::HATCH_STYLE aStyle )
|
||||
{
|
||||
m_Poly->SetHatchStyle( aStyle );
|
||||
}
|
||||
|
|
|
@ -99,7 +99,6 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
|
|||
aTarget.m_FillMode = m_FillMode;
|
||||
aTarget.m_ZoneClearance = m_ZoneClearance;
|
||||
aTarget.m_ZoneMinThickness = m_ZoneMinThickness;
|
||||
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ) );
|
||||
aTarget.m_ArcToSegmentsCount = m_ArcToSegmentsCount;
|
||||
aTarget.m_ThermalReliefGap = m_ThermalReliefGap;
|
||||
aTarget.m_ThermalReliefCopperBridge = m_ThermalReliefCopperBridge;
|
||||
|
@ -118,4 +117,8 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
|
|||
aTarget.SetLayer( m_CurrentZone_Layer );
|
||||
aTarget.m_Poly->SetLayer( m_CurrentZone_Layer );
|
||||
}
|
||||
|
||||
// call SetHatch last, because hatch lines will be rebuilt,
|
||||
// using new parameters values
|
||||
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true );
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <class_track.h>
|
||||
#include <class_zone.h>
|
||||
#include <class_marker_pcb.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
|
||||
/* compare 2 trapezoids (can be rectangle) and return true if distance > aDist
|
||||
|
|
|
@ -1404,17 +1404,18 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
|
|||
zone->SetLayer( layer );
|
||||
zone->SetNet( 0 );
|
||||
|
||||
int outline_hatch = CPolyLine::DIAGONAL_EDGE;
|
||||
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
|
||||
|
||||
zone->m_Poly->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
|
||||
zone->m_Poly->Close();
|
||||
zone->m_Poly->CloseLastContour();
|
||||
|
||||
// this is not my fault:
|
||||
zone->m_Poly->SetHatch( outline_hatch,
|
||||
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ) );
|
||||
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ),
|
||||
true );
|
||||
}
|
||||
m_xpath->pop();
|
||||
}
|
||||
|
@ -2360,7 +2361,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
|
|||
zone->SetNet( netCode );
|
||||
zone->SetNetName( netName );
|
||||
|
||||
int outline_hatch = CPolyLine::DIAGONAL_EDGE;
|
||||
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
|
||||
|
||||
bool first = true;
|
||||
for( CITER vi = it->second.begin(); vi != it->second.end(); ++vi )
|
||||
|
@ -2380,10 +2381,11 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
|
|||
zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
|
||||
}
|
||||
|
||||
zone->m_Poly->Close();
|
||||
zone->m_Poly->CloseLastContour();
|
||||
|
||||
zone->m_Poly->SetHatch( outline_hatch,
|
||||
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ) );
|
||||
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ),
|
||||
true );
|
||||
|
||||
// clearances, etc.
|
||||
zone->SetArcSegCount( 32 ); // @todo: should be a constructor default?
|
||||
|
|
|
@ -2109,7 +2109,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
{
|
||||
auto_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
|
||||
|
||||
int outline_hatch = CPolyLine::NO_HATCH;
|
||||
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::NO_HATCH;
|
||||
bool sawCorner = false;
|
||||
char buf[1024];
|
||||
|
||||
|
@ -2133,7 +2133,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
sawCorner = true;
|
||||
|
||||
if( flag )
|
||||
zc->m_Poly->Close();
|
||||
zc->m_Poly->CloseLastContour();
|
||||
}
|
||||
|
||||
else if( TESTLINE( "ZInfo" ) ) // general info found
|
||||
|
@ -2350,9 +2350,11 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
zc->SetNet( 0 );
|
||||
}
|
||||
|
||||
// Hatch here, after outlines corners are read
|
||||
// Set hatch here, after outlines corners are read
|
||||
zc->m_Poly->SetHatch( outline_hatch,
|
||||
Mils2iu( zc->m_Poly->GetDefaultHatchPitchMils() ) );
|
||||
Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ),
|
||||
true );
|
||||
|
||||
m_board->Add( zc.release() );
|
||||
}
|
||||
|
|
|
@ -2292,8 +2292,8 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
|
|||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
|
||||
wxT( " as ZONE_CONTAINER." ) );
|
||||
|
||||
int hatchStyle = CPolyLine::NO_HATCH; // Fix compile warning
|
||||
int hatchPitch = 0; // Fix compile warning
|
||||
CPolyLine::HATCH_STYLE hatchStyle = CPolyLine::NO_HATCH;
|
||||
int hatchPitch = Mils2iu( CPolyLine::GetDefaultHatchPitchMils() );
|
||||
wxPoint pt;
|
||||
T token;
|
||||
|
||||
|
@ -2587,7 +2587,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
|
|||
}
|
||||
|
||||
// Set hatch here, after outlines corners are read
|
||||
zone->m_Poly->SetHatch( hatchStyle, hatchPitch );
|
||||
zone->m_Poly->SetHatch( hatchStyle, hatchPitch, true );
|
||||
}
|
||||
|
||||
if( pts.size() )
|
||||
|
|
|
@ -679,8 +679,12 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
|
|||
if( !Drc_On || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) )
|
||||
{
|
||||
// Ok, we can add a new corner
|
||||
if( m_canvas->IsMouseCaptured() )
|
||||
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
|
||||
zone->AppendCorner( GetScreen()->GetCrossHairPosition() );
|
||||
SetCurItem( zone ); // calls DisplayInfo().
|
||||
if( m_canvas->IsMouseCaptured() )
|
||||
m_canvas->CallMouseCapture( DC, wxPoint(0,0), false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -738,7 +742,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
|
|||
// Put new zone in list
|
||||
if( !s_CurrentZone )
|
||||
{
|
||||
zone->m_Poly->Close(); // Close the current corner list
|
||||
zone->m_Poly->CloseLastContour(); // Close the current corner list
|
||||
GetBoard()->Add( zone );
|
||||
GetBoard()->m_CurrentZoneContour = NULL;
|
||||
|
||||
|
@ -753,7 +757,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
|
|||
s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) );
|
||||
}
|
||||
|
||||
s_CurrentZone->m_Poly->Close(); // Close the current corner list
|
||||
s_CurrentZone->m_Poly->CloseLastContour(); // Close the current corner list
|
||||
zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
|
||||
zone = s_CurrentZone;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <pcbnew.h>
|
||||
#include <drc_stuff.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
|
||||
static bool bDontShowSelfIntersectionArcsWarning;
|
||||
|
@ -311,19 +312,15 @@ int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
|
|||
str += wxT( "This may result in splitting the area.\n" );
|
||||
str += wxT( "If the area is complex, this may take a few seconds." );
|
||||
wxMessageBox( str );
|
||||
|
||||
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
|
||||
}
|
||||
}
|
||||
|
||||
//** TODO test for cutouts outside of area
|
||||
//** if( test == 1 )
|
||||
{
|
||||
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
|
||||
curr_polygon->UnHatch();
|
||||
int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
|
||||
|
||||
// i.e if clipping has created some polygons, we must add these new copper areas.
|
||||
// If clipping has created some polygons, we must add these new copper areas.
|
||||
if( n_poly > 1 )
|
||||
{
|
||||
ZONE_CONTAINER* NewArea;
|
||||
|
@ -803,10 +800,10 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
|
|||
}
|
||||
|
||||
// polygons intersect, combine them
|
||||
// std::vector<CArc> arc_array1;
|
||||
// std::vector<CArc> arc_array2;
|
||||
bool keep_area_to_combine = false; // TODO test if areas intersect
|
||||
// TODO: test here if areas intersect and combine only if so
|
||||
|
||||
#if 0
|
||||
// do not set to 1 (not fully working): only for me (JP. Charras) until this code is finished
|
||||
KI_POLYGON_WITH_HOLES areaRefPoly;
|
||||
KI_POLYGON_WITH_HOLES areaToMergePoly;
|
||||
CopyPolysListToKiPolygonWithHole( area_ref->m_Poly->m_CornersList, areaRefPoly );
|
||||
|
@ -814,14 +811,12 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
|
|||
|
||||
KI_POLYGON_WITH_HOLES_SET mergedOutlines;
|
||||
mergedOutlines.push_back( areaRefPoly );
|
||||
mergedOutlines += areaToMergePoly;
|
||||
mergedOutlines |= areaToMergePoly;
|
||||
|
||||
// We should have only one polygon with holes in mergedOutlines
|
||||
// or the 2 initial outlines do not intersect
|
||||
if( mergedOutlines.size() > 1 )
|
||||
return 0;
|
||||
// We can have more than one polygon with holes in mergedOutlines
|
||||
// depending on the complexity of outlines
|
||||
|
||||
areaRefPoly = mergedOutlines[0];
|
||||
areaRefPoly = mergedOutlines[0]; // TODO: read and create all created polygons
|
||||
area_ref->m_Poly->RemoveAllContours();
|
||||
|
||||
KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin();
|
||||
|
@ -833,7 +828,7 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
|
|||
area_ref->m_Poly->AppendCorner( corner->x(), corner->y() );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->Close();
|
||||
area_ref->m_Poly->CloseLastContour();
|
||||
|
||||
// add holes (set of polygons)
|
||||
KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes();
|
||||
|
@ -846,17 +841,83 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
|
|||
area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() );
|
||||
hole_corner++;
|
||||
}
|
||||
area_ref->m_Poly->Close();
|
||||
area_ref->m_Poly->CloseLastContour();
|
||||
hole++;
|
||||
}
|
||||
#else
|
||||
void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
|
||||
Bool_Engine* booleng = new Bool_Engine();
|
||||
armBoolEng( booleng );
|
||||
|
||||
area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A );
|
||||
area_to_combine->m_Poly->AddPolygonsToBoolEng(booleng, GROUP_B );
|
||||
booleng->Do_Operation( BOOL_OR );
|
||||
|
||||
if( !keep_area_to_combine )
|
||||
RemoveArea( aDeletedList, area_to_combine );
|
||||
// create area with external contour: Recreate only area edges, NOT holes
|
||||
if( booleng->StartPolygonGet() )
|
||||
{
|
||||
if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE )
|
||||
{
|
||||
DisplayError( NULL, wxT( "BOARD::CombineAreas() error: unexpected hole descriptor" ) );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->RemoveAllContours();
|
||||
|
||||
// foreach point in the polygon
|
||||
bool first = true;
|
||||
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = (int) booleng->GetPolygonXPoint();
|
||||
int y = (int) booleng->GetPolygonYPoint();
|
||||
|
||||
if( first )
|
||||
{
|
||||
first = false;
|
||||
area_ref->m_Poly->Start( area_ref->GetLayer(
|
||||
), x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||
}
|
||||
else
|
||||
{
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
}
|
||||
|
||||
booleng->EndPolygonGet();
|
||||
area_ref->m_Poly->CloseLastContour();
|
||||
}
|
||||
|
||||
// add holes
|
||||
bool show_error = true;
|
||||
|
||||
while( booleng->StartPolygonGet() )
|
||||
{
|
||||
// we expect all vertex are holes inside the main outline
|
||||
if( booleng->GetPolygonPointEdgeType() != KB_INSIDE_EDGE )
|
||||
{
|
||||
if( show_error ) // show this error only once, if happens
|
||||
DisplayError( NULL,
|
||||
wxT( "BOARD::CombineAreas() error: unexpected outside contour descriptor" ) );
|
||||
|
||||
show_error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
while( booleng->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = (int) booleng->GetPolygonXPoint();
|
||||
int y = (int) booleng->GetPolygonYPoint();
|
||||
area_ref->m_Poly->AppendCorner( x, y );
|
||||
}
|
||||
|
||||
area_ref->m_Poly->CloseLastContour();
|
||||
booleng->EndPolygonGet();
|
||||
}
|
||||
#endif
|
||||
|
||||
RemoveArea( aDeletedList, area_to_combine );
|
||||
|
||||
area_ref->utility = 1;
|
||||
// area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||
// area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
||||
area_ref->m_Poly->Hatch();
|
||||
|
||||
return 1;
|
||||
|
@ -917,6 +978,11 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
|||
// ZONE_CONTAINER::GetClearance().
|
||||
int zone2zoneClearance = Area_Ref->GetClearance( area_to_test );
|
||||
|
||||
// Keepout areas have no clearance, so set zone2zoneClearance to 1
|
||||
// ( zone2zoneClearance = 0 can create problems in test functions)
|
||||
if( Area_Ref->GetIsKeepout() )
|
||||
zone2zoneClearance = 1;
|
||||
|
||||
// test for some corners of Area_Ref inside area_to_test
|
||||
for( int ic = 0; ic < refSmoothedPoly->GetNumCorners(); ic++ )
|
||||
{
|
||||
|
@ -1114,6 +1180,11 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
|
|||
if( area_to_test->GetIsKeepout() != aArea->GetIsKeepout() )
|
||||
continue;
|
||||
|
||||
// For keepout, there is no clearance, so use a minimal value for it
|
||||
// use 1, not 0 as value to avoid some issues in tests
|
||||
if( area_to_test->GetIsKeepout() )
|
||||
zone_clearance = 1;
|
||||
|
||||
// test for ending line inside area_to_test
|
||||
if( area_to_test->m_Poly->TestPointInside( end.x, end.y ) )
|
||||
{
|
||||
|
@ -1159,7 +1230,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
|
|||
0,
|
||||
ax1, ay1, ax2, ay2, astyle,
|
||||
0,
|
||||
0,
|
||||
zone_clearance,
|
||||
&x, &y );
|
||||
|
||||
if( d < zone_clearance )
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
#include <PolyLine.h>
|
||||
#include <bezier_curves.h>
|
||||
#include <polygon_test_point_inside.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
CPolyLine::CPolyLine()
|
||||
{
|
||||
m_hatchStyle = NO_HATCH;
|
||||
m_hatchPitch = 0;
|
||||
m_layer = 0;
|
||||
m_width = 0;
|
||||
m_utility = 0;
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
|
@ -44,7 +46,7 @@ CPolyLine::~CPolyLine()
|
|||
* false: holes are not linked: in this mode contours are added clockwise
|
||||
* and polygons added counter clockwise are holes (default)
|
||||
*/
|
||||
static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
|
||||
void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
|
||||
|
||||
/**
|
||||
* Function NormalizeWithKbool
|
||||
|
@ -128,16 +130,19 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
|
|||
}
|
||||
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
Close();
|
||||
CloseLastContour();
|
||||
n_ext_cont++;
|
||||
}
|
||||
else if( aExtraPolyList ) // a new outside contour is found: create a new CPolyLine
|
||||
else if( aExtraPolyList ) // a new outside contour is found: create a new CPolyLine
|
||||
{
|
||||
polyline = new CPolyLine; // create new poly
|
||||
aExtraPolyList->push_back( polyline ); // put it in array
|
||||
polyline = new CPolyLine;
|
||||
polyline->SetLayer( GetLayer() );
|
||||
polyline->SetHatchStyle( GetHatchStyle() );
|
||||
polyline->SetHatchPitch( GetHatchPitch() );
|
||||
aExtraPolyList->push_back( polyline ); // put it in array
|
||||
bool first = true;
|
||||
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // read next external contour
|
||||
{
|
||||
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
|
@ -152,7 +157,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
|
|||
}
|
||||
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
polyline->Close( STRAIGHT, false );
|
||||
polyline->CloseLastContour();
|
||||
n_ext_cont++;
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +206,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
|
|||
polyline->AppendCorner( x, y, STRAIGHT, false );
|
||||
}
|
||||
|
||||
polyline->Close( STRAIGHT, false );
|
||||
polyline->CloseLastContour();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,6 +224,42 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function AddPolygonsToBoolEng
|
||||
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
|
||||
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
|
||||
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
|
||||
*/
|
||||
int CPolyLine::AddPolygonsToBoolEng( Bool_Engine* aBooleng, GroupType aGroup )
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
/* Convert the current polyline contour to a kbool polygon: */
|
||||
MakeKboolPoly();
|
||||
|
||||
/* add the resulting kbool set of polygons to the current kcool engine */
|
||||
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||
{
|
||||
if( aBooleng->StartPolygonAdd( GROUP_A ) )
|
||||
{
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
aBooleng->AddPoint( x, y );
|
||||
count++;
|
||||
}
|
||||
|
||||
aBooleng->EndPolygonAdd();
|
||||
}
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
}
|
||||
|
||||
delete m_Kbool_Poly_Engine;
|
||||
m_Kbool_Poly_Engine = NULL;
|
||||
|
||||
return count;
|
||||
}
|
||||
/**
|
||||
* Function MakeKboolPoly
|
||||
* fill a kbool engine with a closed polyline contour
|
||||
|
@ -247,13 +288,32 @@ int CPolyLine::MakeKboolPoly( std::vector<CArc>* arc_array )
|
|||
|
||||
int iarc = 0;
|
||||
|
||||
for( int icont = 0; icont<=last_contour; icont++ )
|
||||
for( int icont = 0; icont <= last_contour; icont++ )
|
||||
{
|
||||
// Fill a kbool engine for this contour,
|
||||
// and combine it with previous contours
|
||||
Bool_Engine* booleng = new Bool_Engine();
|
||||
armBoolEng( booleng, false );
|
||||
|
||||
if( m_Kbool_Poly_Engine ) // a previous contour exists. Put it in new engine
|
||||
{
|
||||
while( m_Kbool_Poly_Engine->StartPolygonGet() )
|
||||
{
|
||||
if( booleng->StartPolygonAdd( GROUP_A ) )
|
||||
{
|
||||
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
|
||||
{
|
||||
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
|
||||
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
|
||||
booleng->AddPoint( x, y );
|
||||
}
|
||||
|
||||
booleng->EndPolygonAdd();
|
||||
}
|
||||
m_Kbool_Poly_Engine->EndPolygonGet();
|
||||
}
|
||||
}
|
||||
|
||||
// first, calculate number of vertices in contour
|
||||
int n_vertices = 0;
|
||||
int ic_st = GetContourStart( icont );
|
||||
|
@ -735,7 +795,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc>* arc_array, std::vector<CPolyLine*
|
|||
void CPolyLine::Start( int layer, int x, int y, int hatch )
|
||||
{
|
||||
m_layer = layer;
|
||||
SetHatchStyle( (enum hatch_style) hatch );
|
||||
SetHatchStyle( (enum HATCH_STYLE) hatch );
|
||||
CPolyPt poly_pt( x, y );
|
||||
poly_pt.end_contour = false;
|
||||
|
||||
|
@ -766,19 +826,9 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
|
|||
|
||||
// close last polyline contour
|
||||
//
|
||||
void CPolyLine::Close( int style, bool bDraw )
|
||||
void CPolyLine::CloseLastContour()
|
||||
{
|
||||
if( GetClosed() )
|
||||
{
|
||||
wxASSERT( 0 );
|
||||
}
|
||||
|
||||
UnHatch();
|
||||
m_SideStyle[m_CornersList.size() - 1] = style;
|
||||
m_CornersList[m_CornersList.size() - 1].end_contour = true;
|
||||
|
||||
if( bDraw )
|
||||
Hatch();
|
||||
}
|
||||
|
||||
|
||||
|
@ -944,7 +994,7 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
|
|||
newPoly->AppendCorner( x1 + nx, y1 + ny );
|
||||
}
|
||||
|
||||
newPoly->Close();
|
||||
newPoly->CloseLastContour();
|
||||
}
|
||||
|
||||
return newPoly;
|
||||
|
@ -1072,7 +1122,7 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
|
|||
}
|
||||
}
|
||||
|
||||
newPoly->Close();
|
||||
newPoly->CloseLastContour();
|
||||
}
|
||||
|
||||
return newPoly;
|
||||
|
@ -1632,11 +1682,13 @@ void CPolyLine::SetEndContour( int ic, bool end_contour )
|
|||
m_CornersList[ic].end_contour = end_contour;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AppendArc adds segments to current contour to approximate the given arc
|
||||
*/
|
||||
void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num )
|
||||
{
|
||||
// get radius
|
||||
double r = sqrt( (double) (xi - xc) * (xi - xc) + (double) (yi - yc) * (yi - yc) );
|
||||
double radius = hypot( (double) (xi - xc), (double) (yi - yc) );
|
||||
|
||||
// get angles of start and finish
|
||||
double th_i = atan2( (double) (yi - yc), (double) (xi - xc) );
|
||||
|
@ -1645,15 +1697,15 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
|
|||
double theta = th_i;
|
||||
|
||||
// generate arc
|
||||
for( int ic = 0; ic<num; ic++ )
|
||||
for( int ic = 0; ic < num; ic++ )
|
||||
{
|
||||
int x = KiROUND( xc + r * cos( theta ) );
|
||||
int y = KiROUND( yc + r * sin( theta ) );
|
||||
int x = KiROUND( xc + radius * cos( theta ) );
|
||||
int y = KiROUND( yc + radius * sin( theta ) );
|
||||
AppendCorner( x, y, STRAIGHT, 0 );
|
||||
theta += th_d;
|
||||
}
|
||||
|
||||
Close( STRAIGHT );
|
||||
CloseLastContour();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,9 +58,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
class CArc
|
||||
{
|
||||
public:
|
||||
|
@ -107,7 +104,7 @@ class CPolyLine
|
|||
{
|
||||
public:
|
||||
enum m_SideStyle { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
|
||||
enum hatch_style { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
||||
enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
|
||||
|
||||
// constructors/destructor
|
||||
CPolyLine();
|
||||
|
@ -119,7 +116,7 @@ public:
|
|||
void InsertCorner( int ic, int x, int y );
|
||||
void DeleteCorner( int ic, bool bDraw = false );
|
||||
void MoveCorner( int ic, int x, int y );
|
||||
void Close( int style = STRAIGHT, bool bDraw = false );
|
||||
void CloseLastContour();
|
||||
void RemoveContour( int icont );
|
||||
|
||||
/**
|
||||
|
@ -155,6 +152,11 @@ public:
|
|||
void Copy( CPolyLine* src );
|
||||
bool TestPointInside( int x, int y );
|
||||
bool IsCutoutContour( int icont );
|
||||
|
||||
/**
|
||||
* Function AppendArc.
|
||||
* Adds segments to current contour to approximate the given arc
|
||||
*/
|
||||
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
|
||||
|
||||
// access functions
|
||||
|
@ -181,14 +183,15 @@ public:
|
|||
int GetSideStyle( int is );
|
||||
|
||||
int GetHatchPitch() { return m_hatchPitch; }
|
||||
int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
|
||||
static int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
|
||||
|
||||
enum hatch_style GetHatchStyle() { return m_hatchStyle; }
|
||||
void SetHatch( int hatch, int pitch )
|
||||
enum HATCH_STYLE GetHatchStyle() { return m_hatchStyle; }
|
||||
void SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch )
|
||||
{
|
||||
SetHatchPitch( pitch );
|
||||
m_hatchStyle = (enum hatch_style) hatch;
|
||||
Hatch();
|
||||
SetHatchPitch( aHatchPitch );
|
||||
m_hatchStyle = (enum HATCH_STYLE) aHatchStyle;
|
||||
if( aRebuildHatch )
|
||||
Hatch();
|
||||
}
|
||||
|
||||
void SetX( int ic, int x );
|
||||
|
@ -196,7 +199,7 @@ public:
|
|||
void SetEndContour( int ic, bool end_contour );
|
||||
void SetSideStyle( int is, int style );
|
||||
|
||||
void SetHatchStyle( enum hatch_style style )
|
||||
void SetHatchStyle( enum HATCH_STYLE style )
|
||||
{
|
||||
m_hatchStyle = style;
|
||||
}
|
||||
|
@ -210,6 +213,14 @@ public:
|
|||
|
||||
// KBOOL functions
|
||||
|
||||
/**
|
||||
* Function AddPolygonsToBoolEng
|
||||
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
|
||||
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
|
||||
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
|
||||
*/
|
||||
int AddPolygonsToBoolEng( Bool_Engine* aBooleng, GroupType aGroup );
|
||||
|
||||
/**
|
||||
* Function MakeKboolPoly
|
||||
* fill a kbool engine with a closed polyline contour
|
||||
|
@ -261,7 +272,7 @@ public:
|
|||
private:
|
||||
int m_layer; // layer to draw on
|
||||
int m_width; // lines width when drawing. Provided but not really used
|
||||
enum hatch_style m_hatchStyle; // hatch style, see enum above
|
||||
enum HATCH_STYLE m_hatchStyle; // hatch style, see enum above
|
||||
int m_hatchPitch; // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
|
||||
// and the len of eacvh segment
|
||||
// for DIAGONAL_FULL, the pitch is twice this value
|
||||
|
|
|
@ -9,9 +9,23 @@
|
|||
#include <fctsys.h>
|
||||
|
||||
#include <PolyLine.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
#define NM_PER_MIL 25400
|
||||
|
||||
typedef struct PointTag
|
||||
{
|
||||
double X,Y;
|
||||
} PointT;
|
||||
|
||||
typedef struct EllipseTag
|
||||
{
|
||||
PointT Center; /* ellipse center */
|
||||
double xrad, yrad; // radii on x and y
|
||||
double theta1, theta2; // start and end angle for arc
|
||||
} EllipseKH;
|
||||
|
||||
|
||||
double Distance( double x1, double y1, double x2, double y2 )
|
||||
{
|
||||
double dx = x1 - x2;
|
||||
|
@ -21,6 +35,13 @@ double Distance( double x1, double y1, double x2, double y2 )
|
|||
}
|
||||
|
||||
|
||||
static int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1=NULL, double * y1=NULL,
|
||||
double * x2=NULL, double * y2=NULL );
|
||||
static bool InRange( double x, double xi, double xf );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function TestLineHit
|
||||
* test for hit on line segment i.e. a point within a given distance from segment
|
||||
|
@ -862,26 +883,26 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
|
|||
|
||||
// Get clearance between 2 segments
|
||||
// Returns point in segment closest to other segment in x, y
|
||||
// in clearance > max_cl, just returns max_cl and doesn't return x,y
|
||||
// in clearance > max_cl, just returns max_cl+1 and doesn't return x,y
|
||||
//
|
||||
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1,
|
||||
int x2i, int y2i, int x2f, int y2f, int style2, int w2,
|
||||
int max_cl, int* x, int* y )
|
||||
{
|
||||
// check clearance between bounding rectangles
|
||||
int test = max_cl + w1 / 2 + w2 / 2;
|
||||
int min_dist = max_cl + ( (w1 + w2) / 2 );
|
||||
|
||||
if( min( x1i, x1f ) - max( x2i, x2f ) > test )
|
||||
return max_cl;
|
||||
if( min( x1i, x1f ) - max( x2i, x2f ) > min_dist )
|
||||
return max_cl+1;
|
||||
|
||||
if( min( x2i, x2f ) - max( x1i, x1f ) > test )
|
||||
return max_cl;
|
||||
if( min( x2i, x2f ) - max( x1i, x1f ) > min_dist )
|
||||
return max_cl+1;
|
||||
|
||||
if( min( y1i, y1f ) - max( y2i, y2f ) > test )
|
||||
return max_cl;
|
||||
if( min( y1i, y1f ) - max( y2i, y2f ) > min_dist )
|
||||
return max_cl+1;
|
||||
|
||||
if( min( y2i, y2f ) - max( y1i, y1f ) > test )
|
||||
return max_cl;
|
||||
if( min( y2i, y2f ) - max( y1i, y1f ) > min_dist )
|
||||
return max_cl+1;
|
||||
|
||||
if( style1 == CPolyLine::STRAIGHT && style1 == CPolyLine::STRAIGHT )
|
||||
{
|
||||
|
@ -890,7 +911,9 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
double dd;
|
||||
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
|
||||
x2i, y2i, x2f, y2f, &xx, &yy, &dd );
|
||||
int d = max( 0, (int) dd - w1 / 2 - w2 / 2 );
|
||||
int d = (int) dd - ( (w1 + w2) / 2 );
|
||||
if( d < 0 )
|
||||
d = 0;
|
||||
|
||||
if( x )
|
||||
*x = xx;
|
||||
|
@ -905,10 +928,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
// see if segments intersect
|
||||
double xr[2];
|
||||
double yr[2];
|
||||
test =
|
||||
int count =
|
||||
FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
|
||||
|
||||
if( test )
|
||||
if( count )
|
||||
{
|
||||
if( x )
|
||||
*x = (int) xr[0];
|
||||
|
|
|
@ -1,22 +1,5 @@
|
|||
// math stuff for graphics, from FreePCB
|
||||
|
||||
#ifndef abs
|
||||
#define abs(x) (((x) >=0) ? (x) : (-(x)))
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct PointTag
|
||||
{
|
||||
double X,Y;
|
||||
} PointT;
|
||||
|
||||
typedef struct EllipseTag
|
||||
{
|
||||
PointT Center; /* ellipse center */
|
||||
double xrad, yrad; // radii on x and y
|
||||
double theta1, theta2; // start and end angle for arc
|
||||
} EllipseKH;
|
||||
|
||||
|
||||
// math stuff for graphics
|
||||
bool Quadratic( double a, double b, double c, double *x1, double *x2 );
|
||||
|
@ -70,11 +53,5 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
|
|||
double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf );
|
||||
|
||||
double GetPointToLineDistance( double a, double b, int x, int y, double * xp=NULL, double * yp=NULL );
|
||||
bool InRange( double x, double xi, double xf );
|
||||
|
||||
double Distance( double x1, double y1, double x2, double y2 );
|
||||
|
||||
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
|
||||
double * x1=NULL, double * y1=NULL,
|
||||
double * x2=NULL, double * y2=NULL );
|
||||
|
||||
|
|
Loading…
Reference in New Issue