Commit 99b90d2f authored by jean-pierre charras's avatar jean-pierre charras

More work on a better support of polygons in Kicad (code cleaning).

parent ef5f1b9e
...@@ -561,15 +561,15 @@ void LIB_ARC::BeginEdit( int aEditMode, const wxPoint aPosition ) ...@@ -561,15 +561,15 @@ void LIB_ARC::BeginEdit( int aEditMode, const wxPoint aPosition )
// Drag either the start, end point or the outline // Drag either the start, end point or the outline
if( HitTestPoints( m_ArcStart, aPosition, MINIMUM_SELECTION_DISTANCE ) ) if( HitTestPoints( m_ArcStart, aPosition, MINIMUM_SELECTION_DISTANCE ) )
{ {
m_editSelectPoint = START; m_editSelectPoint = ARC_STATUS_START;
} }
else if( HitTestPoints( m_ArcEnd, aPosition, MINIMUM_SELECTION_DISTANCE ) ) else if( HitTestPoints( m_ArcEnd, aPosition, MINIMUM_SELECTION_DISTANCE ) )
{ {
m_editSelectPoint = END; m_editSelectPoint = ARC_STATUS_END;
} }
else else
{ {
m_editSelectPoint = OUTLINE; m_editSelectPoint = ARC_STATUS_OUTLINE;
} }
m_editState = 0; m_editState = 0;
...@@ -619,12 +619,12 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition ) ...@@ -619,12 +619,12 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition )
wxPoint newCenterPoint, startPos, endPos; wxPoint newCenterPoint, startPos, endPos;
// Choose the point of the arc to be adjusted // Choose the point of the arc to be adjusted
if( m_editSelectPoint == START ) if( m_editSelectPoint == ARC_STATUS_START )
{ {
startPos = aPosition; startPos = aPosition;
endPos = m_ArcEnd; endPos = m_ArcEnd;
} }
else if( m_editSelectPoint == END ) else if( m_editSelectPoint == ARC_STATUS_END )
{ {
endPos = aPosition; endPos = aPosition;
startPos = m_ArcStart; startPos = m_ArcStart;
...@@ -658,7 +658,7 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition ) ...@@ -658,7 +658,7 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition )
newCenterPoint = m_Pos; newCenterPoint = m_Pos;
} }
if( m_editSelectPoint == START || m_editSelectPoint == END ) if( m_editSelectPoint == ARC_STATUS_START || m_editSelectPoint == ARC_STATUS_END )
{ {
// Compute the new center point when the start/end points are modified // Compute the new center point when the start/end points are modified
wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2, wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2,
......
...@@ -37,15 +37,15 @@ class TRANSFORM; ...@@ -37,15 +37,15 @@ class TRANSFORM;
class LIB_ARC : public LIB_ITEM class LIB_ARC : public LIB_ITEM
{ {
enum SELECT_T enum SELECT_T // When creating an arc: status of arc
{ {
START, ARC_STATUS_START,
END, ARC_STATUS_END,
OUTLINE, ARC_STATUS_OUTLINE,
}; };
int m_Radius; int m_Radius;
int m_t1; /* First radius angle of the arc in 0.1 degrees. */ int m_t1; // First radius angle of the arc in 0.1 degrees.
int m_t2; /* Second radius angle of the arc in 0.1 degrees. */ int m_t2; /* Second radius angle of the arc in 0.1 degrees. */
wxPoint m_ArcStart; wxPoint m_ArcStart;
wxPoint m_ArcEnd; /* Arc end position. */ wxPoint m_ArcEnd; /* Arc end position. */
......
...@@ -1302,12 +1302,12 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) ...@@ -1302,12 +1302,12 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
g_CurrentTrackList.PushBack( newTrack ); g_CurrentTrackList.PushBack( newTrack );
} }
g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, START ); g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, FLG_START );
if( g_FirstTrackSegment->start ) if( g_FirstTrackSegment->start )
g_FirstTrackSegment->SetState( BEGIN_ONPAD, ON ); g_FirstTrackSegment->SetState( BEGIN_ONPAD, ON );
g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, END ); g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, FLG_END );
if( g_CurrentTrackSegment->end ) if( g_CurrentTrackSegment->end )
g_CurrentTrackSegment->SetState( END_ONPAD, ON ); g_CurrentTrackSegment->SetState( END_ONPAD, ON );
......
...@@ -1681,7 +1681,7 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint ) ...@@ -1681,7 +1681,7 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint )
int aLayerMask = GetLayerMask( aTrace->GetLayer() ); int aLayerMask = GetLayerMask( aTrace->GetLayer() );
if( aEndPoint == START ) if( aEndPoint == FLG_START )
{ {
aPosition = aTrace->m_Start; aPosition = aTrace->m_Start;
} }
...@@ -2271,7 +2271,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS ...@@ -2271,7 +2271,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
aSegment->end = newTrack; aSegment->end = newTrack;
aSegment->SetState( END_ONPAD, OFF ); aSegment->SetState( END_ONPAD, OFF );
D_PAD * pad = GetPad( newTrack, START ); D_PAD * pad = GetPad( newTrack, FLG_START );
if ( pad ) if ( pad )
{ {
......
...@@ -1282,7 +1282,7 @@ TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) ...@@ -1282,7 +1282,7 @@ TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint )
int ii; int ii;
int max_dist; int max_dist;
if( aEndPoint == START ) if( aEndPoint == FLG_START )
position = m_Start; position = m_Start;
else else
position = m_End; position = m_End;
......
...@@ -613,7 +613,7 @@ private: ...@@ -613,7 +613,7 @@ private:
/* set of filled polygons used to draw a zone as a filled area. /* set of filled polygons used to draw a zone as a filled area.
* from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole * from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole
* (they are* all in one piece) In very simple cases m_FilledPolysList is same * (they are all in one piece) In very simple cases m_FilledPolysList is same
* as m_Poly. In less simple cases (when m_Poly has holes) m_FilledPolysList is * as m_Poly. In less simple cases (when m_Poly has holes) m_FilledPolysList is
* a polygon equivalent to m_Poly, without holes but with extra outline segment * a polygon equivalent to m_Poly, without holes but with extra outline segment
* connecting "holes" with external main outline. In complex cases an outline * connecting "holes" with external main outline. In complex cases an outline
......
...@@ -272,7 +272,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) ...@@ -272,7 +272,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
if( (type_end & START_ON_PAD ) == 0 ) if( (type_end & START_ON_PAD ) == 0 )
{ {
other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, START ); other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_START );
if( other == NULL ) // Test a connection to zones if( other == NULL ) // Test a connection to zones
{ {
...@@ -306,7 +306,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) ...@@ -306,7 +306,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
segment->SetState( BUSY, ON ); segment->SetState( BUSY, ON );
SEGVIA* via = (SEGVIA*) other; SEGVIA* via = (SEGVIA*) other;
other = via->GetTrace( aFrame->GetBoard()->m_Track, NULL, START ); other = via->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_START );
if( other == NULL ) if( other == NULL )
{ {
...@@ -327,7 +327,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) ...@@ -327,7 +327,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
// if not connected to a pad, test if segment's END is connected to another track // if not connected to a pad, test if segment's END is connected to another track
if( (type_end & END_ON_PAD ) == 0 ) if( (type_end & END_ON_PAD ) == 0 )
{ {
other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, END ); other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_END );
if( other == NULL ) // Test a connection to zones if( other == NULL ) // Test a connection to zones
{ {
...@@ -362,7 +362,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) ...@@ -362,7 +362,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
segment->SetState( BUSY, ON ); segment->SetState( BUSY, ON );
SEGVIA* via = (SEGVIA*) other; SEGVIA* via = (SEGVIA*) other;
other = via->GetTrace( aFrame->GetBoard()->m_Track, NULL, END ); other = via->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_END );
if( other == NULL ) if( other == NULL )
{ {
...@@ -486,7 +486,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -486,7 +486,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// search for a possible point that connects on the START point of the segment // search for a possible point that connects on the START point of the segment
for( segStart = segment->Next(); ; ) for( segStart = segment->Next(); ; )
{ {
segStart = segment->GetTrace( segStart, NULL, START ); segStart = segment->GetTrace( segStart, NULL, FLG_START );
if( segStart ) if( segStart )
{ {
...@@ -500,7 +500,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -500,7 +500,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// We must have only one segment connected // We must have only one segment connected
segStart->SetState( BUSY, ON ); segStart->SetState( BUSY, ON );
other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, START ); other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_START );
segStart->SetState( BUSY, OFF ); segStart->SetState( BUSY, OFF );
if( other == NULL ) if( other == NULL )
...@@ -514,7 +514,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -514,7 +514,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
if( flag ) // We have the starting point of the segment is connected to an other segment if( flag ) // We have the starting point of the segment is connected to an other segment
{ {
segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), segment, segStart, segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), segment, segStart,
START ); FLG_START );
if( segDelete ) if( segDelete )
{ {
...@@ -526,7 +526,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -526,7 +526,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// search for a possible point that connects on the END point of the segment: // search for a possible point that connects on the END point of the segment:
for( segEnd = segment->Next(); ; ) for( segEnd = segment->Next(); ; )
{ {
segEnd = segment->GetTrace( segEnd, NULL, END ); segEnd = segment->GetTrace( segEnd, NULL, FLG_END );
if( segEnd ) if( segEnd )
{ {
...@@ -538,7 +538,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -538,7 +538,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// We must have only one segment connected // We must have only one segment connected
segEnd->SetState( BUSY, ON ); segEnd->SetState( BUSY, ON );
other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, END ); other = segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_END );
segEnd->SetState( BUSY, OFF ); segEnd->SetState( BUSY, OFF );
if( other == NULL ) if( other == NULL )
...@@ -554,7 +554,8 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) ...@@ -554,7 +554,8 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
if( flag & 2 ) // We have the ending point of the segment is connected to an other segment if( flag & 2 ) // We have the ending point of the segment is connected to an other segment
{ {
segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), segment, segEnd, END ); segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(),
segment, segEnd, FLG_END );
if( segDelete ) if( segDelete )
{ {
...@@ -643,7 +644,7 @@ TRACK* MergeColinearSegmentIfPossible( BOARD* aPcb, TRACK* aTrackRef, TRACK* aCa ...@@ -643,7 +644,7 @@ TRACK* MergeColinearSegmentIfPossible( BOARD* aPcb, TRACK* aTrackRef, TRACK* aCa
* (this function) is called when there is only 2 connected segments, * (this function) is called when there is only 2 connected segments,
*and if this point is not on a pad, it can be removed and the 2 segments will be merged *and if this point is not on a pad, it can be removed and the 2 segments will be merged
*/ */
if( aEndType == START ) if( aEndType == FLG_START )
{ {
// We must not have a pad, which is a always terminal point for a track // We must not have a pad, which is a always terminal point for a track
if( aPcb->GetPadFast( aTrackRef->m_Start, aTrackRef->ReturnMaskLayer() ) ) if( aPcb->GetPadFast( aTrackRef->m_Start, aTrackRef->ReturnMaskLayer() ) )
...@@ -712,7 +713,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() ...@@ -712,7 +713,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
} }
else else
{ {
other = segment->GetTrace( GetBoard()->m_Track, NULL, START ); other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START );
if( other ) if( other )
net_code_s = other->GetNet(); net_code_s = other->GetNet();
...@@ -730,7 +731,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() ...@@ -730,7 +731,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
} }
else else
{ {
other = segment->GetTrace( GetBoard()->m_Track, NULL, END ); other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END );
if( other ) if( other )
net_code_e = other->GetNet(); net_code_e = other->GetNet();
...@@ -871,14 +872,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame ) ...@@ -871,14 +872,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame )
if( aFrame->GetCanvas()->GetAbortRequest() ) if( aFrame->GetCanvas()->GetAbortRequest() )
return; return;
pad = aFrame->GetBoard()->GetPad( segment, START ); pad = aFrame->GetBoard()->GetPad( segment, FLG_START );
if( pad ) if( pad )
{ {
// test if the track start point is not exactly starting on the pad // test if the track start point is not exactly starting on the pad
if( segment->m_Start != pad->GetPosition() ) if( segment->m_Start != pad->GetPosition() )
{ {
if( segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, START ) == NULL ) if( segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_START ) == NULL )
{ {
TRACK* newTrack = (TRACK*) segment->Clone(); TRACK* newTrack = (TRACK*) segment->Clone();
...@@ -893,14 +894,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame ) ...@@ -893,14 +894,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame )
} }
} }
pad = aFrame->GetBoard()->GetPad( segment, END ); pad = aFrame->GetBoard()->GetPad( segment, FLG_END );
if( pad ) if( pad )
{ {
// test if the track end point is not exactly on the pad // test if the track end point is not exactly on the pad
if( segment->m_End != pad->GetPosition() ) if( segment->m_End != pad->GetPosition() )
{ {
if( segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, END ) == NULL ) if( segment->GetTrace( aFrame->GetBoard()->m_Track, NULL, FLG_END ) == NULL )
{ {
TRACK* newTrack = (TRACK*)segment->Clone(); TRACK* newTrack = (TRACK*)segment->Clone();
......
...@@ -263,7 +263,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) ...@@ -263,7 +263,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
newTrack->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); newTrack->SetState( BEGIN_ONPAD | END_ONPAD, OFF );
D_PAD* pad = GetBoard()->GetPad( previousTrack, END ); D_PAD* pad = GetBoard()->GetPad( previousTrack, FLG_END );
if( pad ) if( pad )
{ {
...@@ -1042,7 +1042,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList ) ...@@ -1042,7 +1042,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList )
while( track != NULL ) while( track != NULL )
{ {
TRACK* next_track = track->Next(); TRACK* next_track = track->Next();
LockPoint = pcb->GetPad( track, END ); LockPoint = pcb->GetPad( track, FLG_END );
if( LockPoint ) if( LockPoint )
{ {
......
...@@ -887,7 +887,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ...@@ -887,7 +887,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
s_StartSegmentPresent = s_EndSegmentPresent = true; s_StartSegmentPresent = s_EndSegmentPresent = true;
if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) ) if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) )
TrackToStartPoint = track->GetTrace( GetBoard()->m_Track, NULL, START ); TrackToStartPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_START );
// Test if more than one segment is connected to this point // Test if more than one segment is connected to this point
if( TrackToStartPoint ) if( TrackToStartPoint )
...@@ -895,14 +895,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ...@@ -895,14 +895,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
TrackToStartPoint->SetState( BUSY, ON ); TrackToStartPoint->SetState( BUSY, ON );
if( ( TrackToStartPoint->Type() == PCB_VIA_T ) if( ( TrackToStartPoint->Type() == PCB_VIA_T )
|| track->GetTrace( GetBoard()->m_Track, NULL, START ) ) || track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ) )
error = true; error = true;
TrackToStartPoint->SetState( BUSY, OFF ); TrackToStartPoint->SetState( BUSY, OFF );
} }
if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) ) if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) )
TrackToEndPoint = track->GetTrace( GetBoard()->m_Track, NULL, END ); TrackToEndPoint = track->GetTrace( GetBoard()->m_Track, NULL, FLG_END );
// Test if more than one segment is connected to this point // Test if more than one segment is connected to this point
if( TrackToEndPoint ) if( TrackToEndPoint )
...@@ -910,7 +910,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ...@@ -910,7 +910,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
TrackToEndPoint->SetState( BUSY, ON ); TrackToEndPoint->SetState( BUSY, ON );
if( (TrackToEndPoint->Type() == PCB_VIA_T) if( (TrackToEndPoint->Type() == PCB_VIA_T)
|| track->GetTrace( GetBoard()->m_Track, NULL, END ) ) || track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ) )
error = true; error = true;
TrackToEndPoint->SetState( BUSY, OFF ); TrackToEndPoint->SetState( BUSY, OFF );
......
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
#define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select #define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select
#define START 0 /* Flag used in locate routines */ #define FLG_START 0 // Flag used in locate routines
#define END 1 #define FLG_END 1 // Flag used in locate routines
#define DIM_ANCRE_MODULE 3 /* Anchor size (footprint center) */ #define DIM_ANCRE_MODULE 3 /* Anchor size (footprint center) */
#define DIM_ANCRE_TEXTE 2 /* Anchor size (Text center) */ #define DIM_ANCRE_TEXTE 2 /* Anchor size (Text center) */
......
...@@ -89,39 +89,12 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt> ...@@ -89,39 +89,12 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>
break; break;
} }
m_smoothedPoly->MakeKboolPoly( -1, -1, NULL, true );
int count = 0;
while( m_smoothedPoly->GetKboolEngine()->StartPolygonGet() )
{
CPolyPt corner( 0, 0, false );
while( m_smoothedPoly->GetKboolEngine()->PolygonHasMorePoints() )
{
corner.x = (int) m_smoothedPoly->GetKboolEngine()->GetPolygonXPoint();
corner.y = (int) m_smoothedPoly->GetKboolEngine()->GetPolygonYPoint();
corner.end_contour = false;
if( aCornerBuffer )
aCornerBuffer->push_back( corner );
else
m_FilledPolysList.push_back( corner );
count++;
}
corner.end_contour = true;
if( aCornerBuffer ) if( aCornerBuffer )
{ ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList,
aCornerBuffer->pop_back(); *aCornerBuffer );
aCornerBuffer->push_back( corner );
}
else else
{ ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList,
m_FilledPolysList.pop_back(); m_FilledPolysList );
m_FilledPolysList.push_back( corner );
}
m_smoothedPoly->GetKboolEngine()->EndPolygonGet();
}
m_smoothedPoly->FreeKboolEngine();
/* 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
*/ */
...@@ -134,7 +107,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt> ...@@ -134,7 +107,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>
Fill_Zone_Areas_With_Segments( ); Fill_Zone_Areas_With_Segments( );
} }
return count; return 1;
} }
// Sort function to build filled zones // Sort function to build filled zones
......
...@@ -524,10 +524,6 @@ int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, ...@@ -524,10 +524,6 @@ int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone,
corner.x = point.x(); corner.x = point.x();
corner.y = point.y(); corner.y = point.y();
corner.end_contour = false; corner.end_contour = false;
// Flag this corner if starting a hole connection segment:
// This is used by draw functions to draw only useful segments (and not extra segments)
// corner.utility = (aBoolengine->GetPolygonPointEdgeType() == KB_FALSE_EDGE) ? 1 : 0;
polysList.push_back( corner ); polysList.push_back( corner );
count++; count++;
} }
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
*/ */
#include <fctsys.h> #include <fctsys.h>
#include <polygons_defs.h>
#include <common.h> #include <common.h>
#include <confirm.h> #include <confirm.h>
#include <class_undoredo_container.h> #include <class_undoredo_container.h>
...@@ -779,58 +778,6 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ ...@@ -779,58 +778,6 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
return 1; return 1;
} }
/**
* Function CopyPolysListToKiPolygonWithHole
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
*
* @param aPolysList = the list of corners of contours
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
*/
void CopyPolysListToKiPolygonWithHole( const std::vector<CPolyPt>& aPolysList,
KI_POLYGON_WITH_HOLES& aPolygoneWithHole )
{
unsigned corners_count = aPolysList.size();
std::vector<KI_POLY_POINT> cornerslist;
KI_POLYGON poly;
// Enter main outline: this is the first contour
unsigned ic = 0;
while( ic < corners_count )
{
const CPolyPt& corner = aPolysList[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
aPolygoneWithHole.set( cornerslist.begin(), cornerslist.end() );
// Enter holes: they are next contours (when exist)
if( ic < corners_count )
{
KI_POLYGON_SET holePolyList;
while( ic < corners_count )
{
cornerslist.clear();
while( ic < corners_count )
{
const CPolyPt& corner = aPolysList[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
holePolyList.push_back( poly );
}
aPolygoneWithHole.set_holes( holePolyList.begin(), holePolyList.end() );
}
}
/** /**
* Function CombineAreas * Function CombineAreas
......
...@@ -29,10 +29,12 @@ CPolyLine::CPolyLine() ...@@ -29,10 +29,12 @@ CPolyLine::CPolyLine()
CPolyLine::~CPolyLine() CPolyLine::~CPolyLine()
{ {
UnHatch(); UnHatch();
if( m_Kbool_Poly_Engine ) if( m_Kbool_Poly_Engine )
delete m_Kbool_Poly_Engine; delete m_Kbool_Poly_Engine;
} }
/** /**
* Function armBoolEng * Function armBoolEng
* Initialise parameters used in kbool * Initialise parameters used in kbool
...@@ -56,11 +58,11 @@ static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); ...@@ -56,11 +58,11 @@ static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false );
* @param bRetainArcs == true, try to retain arcs in polys * @param bRetainArcs == true, try to retain arcs in polys
* @return number of external contours, or -1 if error * @return number of external contours, or -1 if error
*/ */
int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, bool bRetainArcs ) int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool bRetainArcs )
{ {
std::vector<CArc> arc_array; std::vector<CArc> arc_array;
std::vector <void*> hole_array; // list of holes std::vector <void*> hole_array; // list of holes
std::vector<int> * hole; // used to store corners for a given hole std::vector<int>* hole; // used to store corners for a given hole
CPolyLine* polyline; CPolyLine* polyline;
int n_ext_cont = 0; // CPolyLine count int n_ext_cont = 0; // CPolyLine count
...@@ -71,9 +73,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -71,9 +73,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
* True holes are combined if possible * True holes are combined if possible
*/ */
if( bRetainArcs ) if( bRetainArcs )
MakeKboolPoly( -1, -1, &arc_array ); MakeKboolPoly( &arc_array );
else else
MakeKboolPoly( -1, -1, NULL ); MakeKboolPoly( NULL );
UnHatch(); UnHatch();
...@@ -92,6 +94,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -92,6 +94,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
{ {
hole = new std::vector<int>; hole = new std::vector<int>;
hole_array.push_back( hole ); hole_array.push_back( hole );
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // store hole while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // store hole
{ {
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
...@@ -108,11 +111,13 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -108,11 +111,13 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
m_CornersList.clear(); m_CornersList.clear();
m_SideStyle.clear(); m_SideStyle.clear();
bool first = true; bool first = true;
while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) while( m_Kbool_Poly_Engine->PolygonHasMorePoints() )
{ {
// foreach point in the polygon // foreach point in the polygon
int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
if( first ) if( first )
{ {
first = false; first = false;
...@@ -131,10 +136,12 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -131,10 +136,12 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
polyline = new CPolyLine; // create new poly polyline = new CPolyLine; // create new poly
aExtraPolyList->push_back( polyline ); // put it in array aExtraPolyList->push_back( polyline ); // put it in array
bool first = true; 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 x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint();
int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint();
if( first ) if( first )
{ {
first = false; first = false;
...@@ -153,8 +160,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -153,8 +160,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// now add cutouts to the corresponding CPolyLine(s) // now add cutouts to the corresponding CPolyLine(s)
for( unsigned ii = 0; ii < hole_array.size(); ii++ ) for( unsigned ii = 0; ii < hole_array.size(); ii++ )
{ {
hole = (std::vector<int> *)hole_array[ii]; hole = (std::vector<int>*)hole_array[ii];
polyline = NULL; polyline = NULL;
if( n_ext_cont == 1 ) if( n_ext_cont == 1 )
{ {
polyline = this; polyline = this;
...@@ -166,6 +174,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -166,6 +174,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// so we test only the first corner // so we test only the first corner
int x = (*hole)[0]; int x = (*hole)[0];
int y = (*hole)[1]; int y = (*hole)[1];
if( TestPointInside( x, y ) ) if( TestPointInside( x, y ) )
polyline = this; polyline = this;
else if( aExtraPolyList ) else if( aExtraPolyList )
...@@ -204,76 +213,21 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo ...@@ -204,76 +213,21 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// free hole list // free hole list
for( unsigned ii = 0; ii < hole_array.size(); ii++ ) for( unsigned ii = 0; ii < hole_array.size(); ii++ )
delete (std::vector<int> *)hole_array[ii]; delete (std::vector<int>*)hole_array[ii];
return n_ext_cont; return n_ext_cont;
} }
/**
* Function AddPolygonsToBoolEng
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* @param arc_array: arc converted to poly segments (NULL if not exists)
* @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 aStart_contour,
int aEnd_contour,
std::vector<CArc> * arc_array )
{
int count = 0;
if( (aGroup != GROUP_A) && (aGroup != GROUP_B ) )
return 0; //Error !
/* Convert the current polyline contour to a kbool polygon: */
MakeKboolPoly( aStart_contour, aEnd_contour, arc_array );
/* 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 * Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour * fill a kbool engine with a closed polyline contour
* approximates arcs with multiple straight-line segments * approximates arcs with multiple straight-line segments
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* combining intersecting contours if possible * combining intersecting contours if possible
* @param arc_array : return corners computed from arcs approximations in arc_array * @param arc_array : return corners computed from arcs approximations in arc_array
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
* @return error: 0 if Ok, 1 if error * @return error: 0 if Ok, 1 if error
*/ */
int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<CArc> * arc_array, int CPolyLine::MakeKboolPoly( std::vector<CArc>* arc_array )
bool aConvertHoles )
{ {
if( m_Kbool_Poly_Engine ) if( m_Kbool_Poly_Engine )
{ {
...@@ -281,65 +235,40 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -281,65 +235,40 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
m_Kbool_Poly_Engine = NULL; m_Kbool_Poly_Engine = NULL;
} }
int polycount = GetContoursCount(); if( !GetClosed() )
if( !GetClosed() && (aStart_contour == (polycount - 1) || aStart_contour == -1) )
return 1; // error return 1; // error
int n_arcs = 0; int n_arcs = 0;
int polycount = GetContoursCount();
int last_contour = polycount - 1;
int first_contour = aStart_contour;
int last_contour = aEnd_contour;
if( aStart_contour == -1 )
{
first_contour = 0;
last_contour = polycount - 1;
}
if( aEnd_contour == -1 )
{
last_contour = polycount - 1;
}
if( arc_array ) if( arc_array )
arc_array->clear(); arc_array->clear();
int iarc = 0; int iarc = 0;
for( int icont = first_contour; icont<=last_contour; icont++ )
for( int icont = 0; icont<=last_contour; icont++ )
{ {
// Fill a kbool engine for this contour, // Fill a kbool engine for this contour,
// and combine it with previous contours // and combine it with previous contours
Bool_Engine* booleng = new Bool_Engine(); Bool_Engine* booleng = new Bool_Engine();
armBoolEng( booleng, aConvertHoles ); 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 // first, calculate number of vertices in contour
int n_vertices = 0; int n_vertices = 0;
int ic_st = GetContourStart( icont ); int ic_st = GetContourStart( icont );
int ic_end = GetContourEnd( icont ); int ic_end = GetContourEnd( icont );
if( !booleng->StartPolygonAdd( GROUP_B ) ) if( !booleng->StartPolygonAdd( GROUP_B ) )
{ {
wxASSERT( 0 ); wxASSERT( 0 );
return 1; //error return 1; // error
} }
for( int ic = ic_st; ic<=ic_end; ic++ ) for( int ic = ic_st; ic<=ic_end; ic++ )
{ {
int style = m_SideStyle[ic]; int style = m_SideStyle[ic];
if( style == STRAIGHT ) if( style == STRAIGHT )
n_vertices++; n_vertices++;
else else
...@@ -353,12 +282,14 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -353,12 +282,14 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
// now enter this contour to booleng // now enter this contour to booleng
int ivtx = 0; int ivtx = 0;
for( int ic = ic_st; ic<=ic_end; ic++ ) for( int ic = ic_st; ic<=ic_end; ic++ )
{ {
int style = m_SideStyle[ic]; int style = m_SideStyle[ic];
int x1 = m_CornersList[ic].x; int x1 = m_CornersList[ic].x;
int y1 = m_CornersList[ic].y; int y1 = m_CornersList[ic].y;
int x2, y2; int x2, y2;
if( ic < ic_end ) if( ic < ic_end )
{ {
x2 = m_CornersList[ic + 1].x; x2 = m_CornersList[ic + 1].x;
...@@ -369,6 +300,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -369,6 +300,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
x2 = m_CornersList[ic_st].x; x2 = m_CornersList[ic_st].x;
y2 = m_CornersList[ic_st].y; y2 = m_CornersList[ic_st].y;
} }
if( style == STRAIGHT ) if( style == STRAIGHT )
{ {
booleng->AddPoint( x1, y1 ); booleng->AddPoint( x1, y1 );
...@@ -382,6 +314,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -382,6 +314,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
double xo, yo, theta1, theta2, a, b; double xo, yo, theta1, theta2, a, b;
a = fabs( (double) (x1 - x2) ); a = fabs( (double) (x1 - x2) );
b = fabs( (double) (y1 - y2) ); b = fabs( (double) (y1 - y2) );
if( style == CPolyLine::ARC_CW ) if( style == CPolyLine::ARC_CW )
{ {
// clockwise arc (ie.quadrant of ellipse) // clockwise arc (ie.quadrant of ellipse)
...@@ -463,16 +396,19 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -463,16 +396,19 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
arc_array->push_back( new_arc ); arc_array->push_back( new_arc );
iarc++; iarc++;
} }
for( int is = 0; is<n; is++ ) for( int is = 0; is<n; is++ )
{ {
double theta = theta1 + ( (theta2 - theta1) * (double) is ) / n; double theta = theta1 + ( (theta2 - theta1) * (double) is ) / n;
double x = xo + a* cos( theta ); double x = xo + a* cos( theta );
double y = yo + b* sin( theta ); double y = yo + b* sin( theta );
if( is == 0 ) if( is == 0 )
{ {
x = x1; x = x1;
y = y1; y = y1;
} }
booleng->AddPoint( x, y ); booleng->AddPoint( x, y );
ivtx++; ivtx++;
} }
...@@ -494,7 +430,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -494,7 +430,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
* Others polygons are substract to the outline and corners will be ordered counter clockwise * Others polygons are substract to the outline and corners will be ordered counter clockwise
* by the kbool engine * by the kbool engine
*/ */
if( aStart_contour <= 0 && icont != 0 ) // substract hole to outside ( if the outline contour is take in account) if( icont != 0 ) // substract hole to outside ( if the outline contour is take in account)
{ {
booleng->Do_Operation( BOOL_A_SUB_B ); booleng->Do_Operation( BOOL_A_SUB_B );
} }
...@@ -506,6 +442,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< ...@@ -506,6 +442,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
// now use result as new polygon (delete the old one if exists) // now use result as new polygon (delete the old one if exists)
if( m_Kbool_Poly_Engine ) if( m_Kbool_Poly_Engine )
delete m_Kbool_Poly_Engine; delete m_Kbool_Poly_Engine;
m_Kbool_Poly_Engine = booleng; m_Kbool_Poly_Engine = booleng;
} }
...@@ -529,16 +466,16 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -529,16 +466,16 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
// DGRID is only meant to make fractional parts of input data which // DGRID is only meant to make fractional parts of input data which
/* /*
The input data scaled up with DGrid is related to the accuracy the user has in his input data. * The input data scaled up with DGrid is related to the accuracy the user has in his input data.
User data with a minimum accuracy of 0.001, means set the DGrid to 1000. * User data with a minimum accuracy of 0.001, means set the DGrid to 1000.
The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid * The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid
everything smaller than 1/DGrid is rounded. * everything smaller than 1/DGrid is rounded.
*
DGRID is only meant to make fractional parts of input data which can be * DGRID is only meant to make fractional parts of input data which can be
doubles, part of the integers used in vertexes within the boolean algorithm. * doubles, part of the integers used in vertexes within the boolean algorithm.
And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy. * And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy.
Within the algorithm all input data is multiplied with DGRID, and the result * Within the algorithm all input data is multiplied with DGRID, and the result
is rounded to an integer. * is rounded to an integer.
*/ */
double DGRID = 1000.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example) double DGRID = 1000.0; // round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// kbool uses DGRID to convert float user units to integer // kbool uses DGRID to convert float user units to integer
...@@ -548,7 +485,7 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -548,7 +485,7 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
// but choose DGRID = 1000.0 solves some filling problems // but choose DGRID = 1000.0 solves some filling problems
// (perhaps because this allows a better precision in kbool internal calculations // (perhaps because this allows a better precision in kbool internal calculations
double MARGE = 1.0/DGRID; // snap with in this range points to lines in the intersection routines double MARGE = 1.0 / DGRID; // snap with in this range points to lines in the intersection routines
// should always be >= 1/DGRID a MARGE >= 10/DGRID is ok // should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
// this is also used to remove small segments and to decide when // this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 ) // two segments are in line. ( initial value = 0.001 )
...@@ -565,18 +502,19 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -565,18 +502,19 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
/* /*
Grid makes sure that the integer data used within the algorithm has room for extra intersections * Grid makes sure that the integer data used within the algorithm has room for extra intersections
smaller than the smallest number within the input data. * smaller than the smallest number within the input data.
The input data scaled up with DGrid is related to the accuracy the user has in his input data. * The input data scaled up with DGrid is related to the accuracy the user has in his input data.
Another scaling with Grid is applied on top of it to create space in the integer number for * Another scaling with Grid is applied on top of it to create space in the integer number for
even smaller numbers. * even smaller numbers.
*/ */
int GRID = (int) ( 10000.0 / DGRID ); // initial value = 10000 in kbool example but we use int GRID = (int) ( 10000.0 / DGRID ); // initial value = 10000 in kbool example but we use
// 10000/DGRID because the scaling is made by DGRID // 10000/DGRID because the scaling is made by DGRID
// on integer pcbnew units and the global scaling // on integer pcbnew units and the global scaling
// ( GRID*DGRID) must be < 30000 to avoid overflow // ( GRID*DGRID) must be < 30000 to avoid overflow
// in calculations (made in long long in kbool) // in calculations (made in long long in kbool)
if ( GRID <= 1 ) // Cannot be null! if( GRID <= 1 ) // Cannot be null!
GRID = 1; GRID = 1;
aBooleng->SetMarge( MARGE ); aBooleng->SetMarge( MARGE );
...@@ -606,7 +544,7 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) ...@@ -606,7 +544,7 @@ void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
} }
int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetainArcs ) int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* pa, bool bRetainArcs )
{ {
return NormalizeWithKbool( pa, bRetainArcs ); return NormalizeWithKbool( pa, bRetainArcs );
} }
...@@ -615,13 +553,14 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetain ...@@ -615,13 +553,14 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetain
// Restore arcs to a polygon where they were replaced with steps // Restore arcs to a polygon where they were replaced with steps
// If pa != NULL, also use polygons in pa array // If pa != NULL, also use polygons in pa array
// //
int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa ) int CPolyLine::RestoreArcs( std::vector<CArc>* arc_array, std::vector<CPolyLine*>* pa )
{ {
// get poly info // get poly info
int n_polys = 1; int n_polys = 1;
if( pa ) if( pa )
n_polys += pa->size(); n_polys += pa->size();
CPolyLine* poly; CPolyLine* poly;
// undraw polys and clear m_utility flag for all corners // undraw polys and clear m_utility flag for all corners
...@@ -631,7 +570,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -631,7 +570,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly = this; poly = this;
else else
poly = (*pa)[ip - 1]; poly = (*pa)[ip - 1];
poly->UnHatch(); poly->UnHatch();
for( int ic = 0; ic<poly->GetNumCorners(); ic++ ) for( int ic = 0; ic<poly->GetNumCorners(); ic++ )
poly->SetUtility( ic, 0 ); poly->SetUtility( ic, 0 );
...@@ -642,6 +583,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -642,6 +583,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
bool bFound; bool bFound;
int arc_start = 0; int arc_start = 0;
int arc_end = 0; int arc_end = 0;
for( unsigned iarc = 0; iarc<arc_array->size(); iarc++ ) for( unsigned iarc = 0; iarc<arc_array->size(); iarc++ )
{ {
int arc_xi = (*arc_array)[iarc].xi; int arc_xi = (*arc_array)[iarc].xi;
...@@ -659,28 +601,37 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -659,28 +601,37 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly = this; poly = this;
else else
poly = (*pa)[ip - 1]; poly = (*pa)[ip - 1];
int polycount = poly->GetContoursCount(); int polycount = poly->GetContoursCount();
for( int icont = 0; icont < polycount; icont++ ) for( int icont = 0; icont < polycount; icont++ )
{ {
int ic_start = poly->GetContourStart( icont ); int ic_start = poly->GetContourStart( icont );
int ic_end = poly->GetContourEnd( icont ); int ic_end = poly->GetContourEnd( icont );
if( (ic_end - ic_start) > n_steps ) if( (ic_end - ic_start) > n_steps )
{ {
for( int ic = ic_start; ic<=ic_end; ic++ ) for( int ic = ic_start; ic<=ic_end; ic++ )
{ {
int ic_next = ic + 1; int ic_next = ic + 1;
if( ic_next > ic_end ) if( ic_next > ic_end )
ic_next = ic_start; ic_next = ic_start;
int xi = poly->GetX( ic ); int xi = poly->GetX( ic );
int yi = poly->GetY( ic ); int yi = poly->GetY( ic );
if( xi == arc_xi && yi == arc_yi ) if( xi == arc_xi && yi == arc_yi )
{ {
// test for forward arc // test for forward arc
int ic2 = ic + n_steps; int ic2 = ic + n_steps;
if( ic2 > ic_end ) if( ic2 > ic_end )
ic2 = ic2 - ic_end + ic_start - 1; ic2 = ic2 - ic_end + ic_start - 1;
int xf = poly->GetX( ic2 ); int xf = poly->GetX( ic2 );
int yf = poly->GetY( ic2 ); int yf = poly->GetY( ic2 );
if( xf == arc_xf && yf == arc_yf ) if( xf == arc_xf && yf == arc_yf )
{ {
// arc from ic to ic2 // arc from ic to ic2
...@@ -692,10 +643,13 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -692,10 +643,13 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
{ {
// try reverse arc // try reverse arc
ic2 = ic - n_steps; ic2 = ic - n_steps;
if( ic2 < ic_start ) if( ic2 < ic_start )
ic2 = ic2 - ic_start + ic_end + 1; ic2 = ic2 - ic_start + ic_end + 1;
xf = poly->GetX( ic2 ); xf = poly->GetX( ic2 );
yf = poly->GetY( ic2 ); yf = poly->GetY( ic2 );
if( xf == arc_xf && yf == arc_yf ) if( xf == arc_xf && yf == arc_yf )
{ {
// arc from ic2 to ic // arc from ic2 to ic
...@@ -705,6 +659,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -705,6 +659,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
style = 3 - style; style = 3 - style;
} }
} }
if( bFound ) if( bFound )
{ {
poly->m_SideStyle[arc_start] = style; poly->m_SideStyle[arc_start] = style;
...@@ -714,7 +669,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -714,7 +669,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
{ {
if( i > ic_end ) if( i > ic_end )
i = ic_start; i = ic_start;
poly->SetUtility( i, 1 ); poly->SetUtility( i, 1 );
if( i == ic_end ) if( i == ic_end )
i = ic_start; i = ic_start;
else else
...@@ -724,10 +681,12 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -724,10 +681,12 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
break; break;
} }
} }
if( bFound ) if( bFound )
break; break;
} }
} }
if( bFound ) if( bFound )
break; break;
} }
...@@ -744,6 +703,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine ...@@ -744,6 +703,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly = this; poly = this;
else else
poly = (*pa)[ip - 1]; poly = (*pa)[ip - 1];
for( int ic = poly->GetNumCorners() - 1; ic>=0; ic-- ) for( int ic = poly->GetNumCorners() - 1; ic>=0; ic-- )
{ {
if( poly->GetUtility( ic ) ) if( poly->GetUtility( ic ) )
...@@ -795,8 +755,10 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw ) ...@@ -795,8 +755,10 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
// add entries for new corner and side // add entries for new corner and side
m_CornersList.push_back( poly_pt ); m_CornersList.push_back( poly_pt );
m_SideStyle.push_back( style ); m_SideStyle.push_back( style );
if( m_CornersList.size() > 0 && !m_CornersList[m_CornersList.size() - 1].end_contour ) if( m_CornersList.size() > 0 && !m_CornersList[m_CornersList.size() - 1].end_contour )
m_SideStyle[m_CornersList.size() - 1] = style; m_SideStyle[m_CornersList.size() - 1] = style;
if( bDraw ) if( bDraw )
Hatch(); Hatch();
} }
...@@ -810,9 +772,11 @@ void CPolyLine::Close( int style, bool bDraw ) ...@@ -810,9 +772,11 @@ void CPolyLine::Close( int style, bool bDraw )
{ {
wxASSERT( 0 ); wxASSERT( 0 );
} }
UnHatch(); UnHatch();
m_SideStyle[m_CornersList.size() - 1] = style; m_SideStyle[m_CornersList.size() - 1] = style;
m_CornersList[m_CornersList.size() - 1].end_contour = true; m_CornersList[m_CornersList.size() - 1].end_contour = true;
if( bDraw ) if( bDraw )
Hatch(); Hatch();
} }
...@@ -852,14 +816,17 @@ void CPolyLine::DeleteCorner( int ic, bool bDraw ) ...@@ -852,14 +816,17 @@ void CPolyLine::DeleteCorner( int ic, bool bDraw )
// closed contour // closed contour
m_CornersList.erase( m_CornersList.begin() + ic ); m_CornersList.erase( m_CornersList.begin() + ic );
m_SideStyle.erase( m_SideStyle.begin() + ic ); m_SideStyle.erase( m_SideStyle.begin() + ic );
if( ic == iend ) if( ic == iend )
m_CornersList[ic - 1].end_contour = true; m_CornersList[ic - 1].end_contour = true;
} }
if( bClosed && GetContourSize( icont ) < 3 ) if( bClosed && GetContourSize( icont ) < 3 )
{ {
// delete the entire contour // delete the entire contour
RemoveContour( icont ); RemoveContour( icont );
} }
if( bDraw ) if( bDraw )
Hatch(); Hatch();
} }
...@@ -880,6 +847,7 @@ void CPolyLine::RemoveContour( int icont ) ...@@ -880,6 +847,7 @@ void CPolyLine::RemoveContour( int icont )
int iend = GetContourEnd( icont ); int iend = GetContourEnd( icont );
int polycount = GetContoursCount(); int polycount = GetContoursCount();
if( icont == 0 && polycount == 1 ) if( icont == 0 && polycount == 1 )
{ {
// remove the only contour // remove the only contour
...@@ -900,6 +868,7 @@ void CPolyLine::RemoveContour( int icont ) ...@@ -900,6 +868,7 @@ void CPolyLine::RemoveContour( int icont )
m_SideStyle.erase( m_SideStyle.begin() + ic ); m_SideStyle.erase( m_SideStyle.begin() + ic );
} }
} }
Hatch(); Hatch();
} }
...@@ -915,6 +884,7 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) ...@@ -915,6 +884,7 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
} }
int polycount = GetContoursCount(); int polycount = GetContoursCount();
for( int contour = 0; contour < polycount; contour++ ) for( int contour = 0; contour < polycount; contour++ )
{ {
unsigned int startIndex = GetContourStart( contour ); unsigned int startIndex = GetContourStart( contour );
...@@ -935,8 +905,8 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) ...@@ -935,8 +905,8 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
} }
else else
{ {
xa = m_CornersList[index-1].x - x1; xa = m_CornersList[index - 1].x - x1;
ya = m_CornersList[index-1].y - y1; ya = m_CornersList[index - 1].y - y1;
} }
if( index == endIndex ) if( index == endIndex )
...@@ -946,33 +916,34 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) ...@@ -946,33 +916,34 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
} }
else else
{ {
xb = m_CornersList[index+1].x - x1; xb = m_CornersList[index + 1].x - x1;
yb = m_CornersList[index+1].y - y1; yb = m_CornersList[index + 1].y - y1;
} }
unsigned int lena = (unsigned int)sqrt( (double)(xa*xa + ya*ya) ); unsigned int lena = (unsigned int) sqrt( (double) (xa * xa + ya * ya) );
unsigned int lenb = (unsigned int)sqrt( (double)(xb*xb + yb*yb) ); unsigned int lenb = (unsigned int) sqrt( (double) (xb * xb + yb * yb) );
unsigned int distance = aDistance; unsigned int distance = aDistance;
// Chamfer one half of an edge at most // Chamfer one half of an edge at most
if( 0.5*lena < distance ) if( 0.5 * lena < distance )
distance = (unsigned int)(0.5*(double)lena); distance = (unsigned int) (0.5 * (double) lena);
if( 0.5*lenb < distance ) if( 0.5 * lenb < distance )
distance = (unsigned int)(0.5*(double)lenb); distance = (unsigned int) (0.5 * (double) lenb);
nx = (int) ( (double) (distance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); nx = (int) ( (double) (distance * xa) / sqrt( (double) (xa * xa + ya * ya) ) );
ny = (int) ( (double) (distance*ya)/sqrt( (double) (xa*xa + ya*ya) ) ); ny = (int) ( (double) (distance * ya) / sqrt( (double) (xa * xa + ya * ya) ) );
if( index == startIndex ) if( index == startIndex )
newPoly->Start( GetLayer(), x1 + nx, y1 + ny, GetHatchStyle() ); newPoly->Start( GetLayer(), x1 + nx, y1 + ny, GetHatchStyle() );
else else
newPoly->AppendCorner( x1 + nx, y1 + ny ); newPoly->AppendCorner( x1 + nx, y1 + ny );
nx = (int) ( (double) (distance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); nx = (int) ( (double) (distance * xb) / sqrt( (double) (xb * xb + yb * yb) ) );
ny = (int) ( (double) (distance*yb)/sqrt( (double) (xb*xb + yb*yb) ) ); ny = (int) ( (double) (distance * yb) / sqrt( (double) (xb * xb + yb * yb) ) );
newPoly->AppendCorner( x1 + nx, y1 + ny ); newPoly->AppendCorner( x1 + nx, y1 + ny );
} }
newPoly->Close(); newPoly->Close();
} }
...@@ -991,6 +962,7 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) ...@@ -991,6 +962,7 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
} }
int polycount = GetContoursCount(); int polycount = GetContoursCount();
for( int contour = 0; contour < polycount; contour++ ) for( int contour = 0; contour < polycount; contour++ )
{ {
unsigned int startIndex = GetContourStart( contour ); unsigned int startIndex = GetContourStart( contour );
...@@ -998,7 +970,6 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) ...@@ -998,7 +970,6 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
for( unsigned int index = startIndex; index <= endIndex; index++ ) for( unsigned int index = startIndex; index <= endIndex; index++ )
{ {
int x1, y1; // Current vertex int x1, y1; // Current vertex
long long xa, ya; // Previous vertex long long xa, ya; // Previous vertex
long long xb, yb; // Next vertex long long xb, yb; // Next vertex
...@@ -1014,8 +985,8 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) ...@@ -1014,8 +985,8 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
} }
else else
{ {
xa = m_CornersList[index-1].x - x1; xa = m_CornersList[index - 1].x - x1;
ya = m_CornersList[index-1].y - y1; ya = m_CornersList[index - 1].y - y1;
} }
if( index == endIndex ) if( index == endIndex )
...@@ -1025,40 +996,40 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) ...@@ -1025,40 +996,40 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
} }
else else
{ {
xb = m_CornersList[index+1].x - x1; xb = m_CornersList[index + 1].x - x1;
yb = m_CornersList[index+1].y - y1; yb = m_CornersList[index + 1].y - y1;
} }
double lena = sqrt( (double) (xa*xa + ya*ya) ); double lena = sqrt( (double) (xa * xa + ya * ya) );
double lenb = sqrt( (double) (xb*xb + yb*yb) ); double lenb = sqrt( (double) (xb * xb + yb * yb) );
double cosine = ( xa*xb + ya*yb )/( lena*lenb ); double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
unsigned int radius = aRadius; unsigned int radius = aRadius;
double denom = sqrt( 2.0/( 1+cosine )-1 ); double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
// Limit rounding distance to one half of an edge // Limit rounding distance to one half of an edge
if( 0.5*lena*denom < radius ) if( 0.5 * lena * denom < radius )
radius = (unsigned int)(0.5*lena*denom); radius = (unsigned int) (0.5 * lena * denom);
if( 0.5*lenb*denom < radius ) if( 0.5 * lenb * denom < radius )
radius = (unsigned int)(0.5*lenb*denom); radius = (unsigned int) (0.5 * lenb * denom);
// Calculate fillet arc absolute center point (xc, yx) // Calculate fillet arc absolute center point (xc, yx)
double k = radius / sqrt( .5*( 1-cosine ) ); double k = radius / sqrt( .5 * ( 1 - cosine ) );
double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); ( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
double xc = x1 + k*( xa/lena + xb/lenb )/lenab; double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
double yc = y1 + k*( ya/lena + yb/lenb )/lenab; double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
// Calculate arc start and end vectors // Calculate arc start and end vectors
k = radius / sqrt( 2/( 1+cosine )-1 ); k = radius / sqrt( 2 / ( 1 + cosine ) - 1 );
double xs = x1 + k*xa/lena - xc; double xs = x1 + k * xa / lena - xc;
double ys = y1 + k*ya/lena - yc; double ys = y1 + k * ya / lena - yc;
double xe = x1 + k*xb/lenb - xc; double xe = x1 + k * xb / lenb - xc;
double ye = y1 + k*yb/lenb - yc; double ye = y1 + k * yb / lenb - yc;
// Cosine of arc angle // Cosine of arc angle
double argument = ( xs*xe + ys*ye ) / ( radius*radius ); double argument = ( xs * xe + ys * ye ) / ( radius * radius );
if( argument < -1 ) // Just in case... if( argument < -1 ) // Just in case...
argument = -1; argument = -1;
...@@ -1068,37 +1039,42 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) ...@@ -1068,37 +1039,42 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
double arcAngle = acos( argument ); double arcAngle = acos( argument );
// Calculate the number of segments // Calculate the number of segments
double tempSegments = (double)aSegments * ( arcAngle / ( 2*M_PI ) ); double tempSegments = (double) aSegments * ( arcAngle / ( 2 * M_PI ) );
if( tempSegments - (int)tempSegments > 0 ) if( tempSegments - (int) tempSegments > 0 )
tempSegments++; tempSegments++;
unsigned int segments = (unsigned int) tempSegments; unsigned int segments = (unsigned int) tempSegments;
double deltaAngle = arcAngle / segments; double deltaAngle = arcAngle / segments;
double startAngle = atan2( -ys, xs ); double startAngle = atan2( -ys, xs );
// Flip arc for inner corners // Flip arc for inner corners
if( xa*yb - ya*xb <= 0 ) if( xa * yb - ya * xb <= 0 )
deltaAngle *= -1; deltaAngle *= -1;
nx = xc + xs + 0.5; nx = xc + xs + 0.5;
ny = yc + ys + 0.5; ny = yc + ys + 0.5;
if( index == startIndex ) if( index == startIndex )
newPoly->Start( GetLayer(), (int)nx, (int)ny, GetHatchStyle() ); newPoly->Start( GetLayer(), (int) nx, (int) ny, GetHatchStyle() );
else else
newPoly->AppendCorner( (int)nx, (int)ny ); newPoly->AppendCorner( (int) nx, (int) ny );
unsigned int nVertices = 0; unsigned int nVertices = 0;
for( unsigned int j = 0; j < segments; j++ ) for( unsigned int j = 0; j < segments; j++ )
{ {
nx = xc + cos( startAngle + (j+1)*deltaAngle )*radius + 0.5; nx = xc + cos( startAngle + (j + 1) * deltaAngle ) * radius + 0.5;
ny = yc - sin( startAngle + (j+1)*deltaAngle )*radius + 0.5; ny = yc - sin( startAngle + (j + 1) * deltaAngle ) * radius + 0.5;
newPoly->AppendCorner( (int)nx, (int)ny ); newPoly->AppendCorner( (int) nx, (int) ny );
nVertices++; nVertices++;
} }
} }
newPoly->Close(); newPoly->Close();
} }
return newPoly; return newPoly;
} }
...@@ -1127,6 +1103,7 @@ void CPolyLine::RemoveAllContours( void ) ...@@ -1127,6 +1103,7 @@ void CPolyLine::RemoveAllContours( void )
void CPolyLine::InsertCorner( int ic, int x, int y ) void CPolyLine::InsertCorner( int ic, int x, int y )
{ {
UnHatch(); UnHatch();
if( (unsigned) (ic) >= m_CornersList.size() ) if( (unsigned) (ic) >= m_CornersList.size() )
{ {
m_CornersList.push_back( CPolyPt( x, y ) ); m_CornersList.push_back( CPolyPt( x, y ) );
...@@ -1146,6 +1123,7 @@ void CPolyLine::InsertCorner( int ic, int x, int y ) ...@@ -1146,6 +1123,7 @@ void CPolyLine::InsertCorner( int ic, int x, int y )
m_CornersList[ic].end_contour = false; m_CornersList[ic].end_contour = false;
} }
} }
Hatch(); Hatch();
} }
...@@ -1182,6 +1160,7 @@ CRect CPolyLine::GetCornerBounds() ...@@ -1182,6 +1160,7 @@ CRect CPolyLine::GetCornerBounds()
r.left = r.bottom = INT_MAX; r.left = r.bottom = INT_MAX;
r.right = r.top = INT_MIN; r.right = r.top = INT_MIN;
for( unsigned i = 0; i<m_CornersList.size(); i++ ) for( unsigned i = 0; i<m_CornersList.size(); i++ )
{ {
r.left = min( r.left, m_CornersList[i].x ); r.left = min( r.left, m_CornersList[i].x );
...@@ -1202,6 +1181,7 @@ CRect CPolyLine::GetCornerBounds( int icont ) ...@@ -1202,6 +1181,7 @@ CRect CPolyLine::GetCornerBounds( int icont )
r.right = r.top = INT_MIN; r.right = r.top = INT_MIN;
int istart = GetContourStart( icont ); int istart = GetContourStart( icont );
int iend = GetContourEnd( icont ); int iend = GetContourEnd( icont );
for( int i = istart; i<=iend; i++ ) for( int i = istart; i<=iend; i++ )
{ {
r.left = min( r.left, m_CornersList[i].x ); r.left = min( r.left, m_CornersList[i].x );
...@@ -1240,8 +1220,11 @@ int CPolyLine::GetContoursCount() ...@@ -1240,8 +1220,11 @@ int CPolyLine::GetContoursCount()
if( m_CornersList[ic].end_contour ) if( m_CornersList[ic].end_contour )
ncont++; ncont++;
if( !m_CornersList[m_CornersList.size() - 1].end_contour ) if( !m_CornersList[m_CornersList.size() - 1].end_contour )
ncont++; ncont++;
return ncont; return ncont;
} }
...@@ -1266,11 +1249,13 @@ int CPolyLine::GetContourStart( int icont ) ...@@ -1266,11 +1249,13 @@ int CPolyLine::GetContourStart( int icont )
return 0; return 0;
int ncont = 0; int ncont = 0;
for( unsigned i = 0; i<m_CornersList.size(); i++ ) for( unsigned i = 0; i<m_CornersList.size(); i++ )
{ {
if( m_CornersList[i].end_contour ) if( m_CornersList[i].end_contour )
{ {
ncont++; ncont++;
if( ncont == icont ) if( ncont == icont )
return i + 1; return i + 1;
} }
...@@ -1290,12 +1275,14 @@ int CPolyLine::GetContourEnd( int icont ) ...@@ -1290,12 +1275,14 @@ int CPolyLine::GetContourEnd( int icont )
return m_CornersList.size() - 1; return m_CornersList.size() - 1;
int ncont = 0; int ncont = 0;
for( unsigned i = 0; i<m_CornersList.size(); i++ ) for( unsigned i = 0; i<m_CornersList.size(); i++ )
{ {
if( m_CornersList[i].end_contour ) if( m_CornersList[i].end_contour )
{ {
if( ncont == icont ) if( ncont == icont )
return i; return i;
ncont++; ncont++;
} }
} }
...@@ -1315,6 +1302,7 @@ void CPolyLine::SetSideStyle( int is, int style ) ...@@ -1315,6 +1302,7 @@ void CPolyLine::SetSideStyle( int is, int style )
{ {
UnHatch(); UnHatch();
wxPoint p1, p2; wxPoint p1, p2;
if( is == (int) (m_CornersList.size() - 1) ) if( is == (int) (m_CornersList.size() - 1) )
{ {
p1.x = m_CornersList[m_CornersList.size() - 1].x; p1.x = m_CornersList[m_CornersList.size() - 1].x;
...@@ -1329,10 +1317,12 @@ void CPolyLine::SetSideStyle( int is, int style ) ...@@ -1329,10 +1317,12 @@ void CPolyLine::SetSideStyle( int is, int style )
p2.x = m_CornersList[is + 1].x; p2.x = m_CornersList[is + 1].x;
p2.y = m_CornersList[is + 1].y; p2.y = m_CornersList[is + 1].y;
} }
if( p1.x == p2.x || p1.y == p2.y ) if( p1.x == p2.x || p1.y == p2.y )
m_SideStyle[is] = STRAIGHT; m_SideStyle[is] = STRAIGHT;
else else
m_SideStyle[is] = style; m_SideStyle[is] = style;
Hatch(); Hatch();
} }
...@@ -1359,6 +1349,8 @@ bool sort_ends_by_descending_X( const wxPoint& ref, const wxPoint& tst ) ...@@ -1359,6 +1349,8 @@ bool sort_ends_by_descending_X( const wxPoint& ref, const wxPoint& tst )
{ {
return tst.x < ref.x; return tst.x < ref.x;
} }
void CPolyLine::Hatch() void CPolyLine::Hatch()
{ {
m_HatchLines.clear(); m_HatchLines.clear();
...@@ -1374,20 +1366,25 @@ void CPolyLine::Hatch() ...@@ -1374,20 +1366,25 @@ void CPolyLine::Hatch()
int max_x = m_CornersList[0].x; int max_x = m_CornersList[0].x;
int min_y = m_CornersList[0].y; int min_y = m_CornersList[0].y;
int max_y = m_CornersList[0].y; int max_y = m_CornersList[0].y;
for( unsigned ic = 1; ic < m_CornersList.size(); ic++ ) for( unsigned ic = 1; ic < m_CornersList.size(); ic++ )
{ {
if( m_CornersList[ic].x < min_x ) if( m_CornersList[ic].x < min_x )
min_x = m_CornersList[ic].x; min_x = m_CornersList[ic].x;
if( m_CornersList[ic].x > max_x ) if( m_CornersList[ic].x > max_x )
max_x = m_CornersList[ic].x; max_x = m_CornersList[ic].x;
if( m_CornersList[ic].y < min_y ) if( m_CornersList[ic].y < min_y )
min_y = m_CornersList[ic].y; min_y = m_CornersList[ic].y;
if( m_CornersList[ic].y > max_y ) if( m_CornersList[ic].y > max_y )
max_y = m_CornersList[ic].y; max_y = m_CornersList[ic].y;
} }
// Calculate spacing betwwen 2 hatch lines // Calculate spacing betwwen 2 hatch lines
int spacing; int spacing;
if( m_hatchStyle == DIAGONAL_EDGE ) if( m_hatchStyle == DIAGONAL_EDGE )
spacing = m_hatchPitch; spacing = m_hatchPitch;
else else
...@@ -1401,6 +1398,7 @@ void CPolyLine::Hatch() ...@@ -1401,6 +1398,7 @@ void CPolyLine::Hatch()
int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1 int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
double slope = 0.707106 * slope_flag; // 45 degrees slope double slope = 0.707106 * slope_flag; // 45 degrees slope
int max_a, min_a; int max_a, min_a;
if( slope_flag == 1 ) if( slope_flag == 1 )
{ {
max_a = (int) (max_y - slope * min_x); max_a = (int) (max_y - slope * min_x);
...@@ -1411,6 +1409,7 @@ void CPolyLine::Hatch() ...@@ -1411,6 +1409,7 @@ void CPolyLine::Hatch()
max_a = (int) (max_y - slope * max_x); max_a = (int) (max_y - slope * max_x);
min_a = (int) (min_y - slope * min_x); min_a = (int) (min_y - slope * min_x);
} }
min_a = (min_a / spacing) * spacing; min_a = (min_a / spacing) * spacing;
// calculate an offset depending on layer number, // calculate an offset depending on layer number,
...@@ -1427,7 +1426,7 @@ void CPolyLine::Hatch() ...@@ -1427,7 +1426,7 @@ void CPolyLine::Hatch()
static std::vector <wxPoint> pointbuffer; static std::vector <wxPoint> pointbuffer;
pointbuffer.clear(); pointbuffer.clear();
pointbuffer.reserve(MAXPTS+2); pointbuffer.reserve( MAXPTS + 2 );
for( int a = min_a; a < max_a; a += spacing ) for( int a = min_a; a < max_a; a += spacing )
{ {
...@@ -1439,10 +1438,12 @@ void CPolyLine::Hatch() ...@@ -1439,10 +1438,12 @@ void CPolyLine::Hatch()
// we skip this line (should not occur) // we skip this line (should not occur)
pointbuffer.clear(); pointbuffer.clear();
int i_start_contour = 0; int i_start_contour = 0;
for( int ic = 0; ic<nc; ic++ ) for( int ic = 0; ic<nc; ic++ )
{ {
double x, y, x2, y2; double x, y, x2, y2;
int ok; int ok;
if( m_CornersList[ic].end_contour || ( ic == (int) (m_CornersList.size() - 1) ) ) if( m_CornersList[ic].end_contour || ( ic == (int) (m_CornersList.size() - 1) ) )
{ {
ok = FindLineSegmentIntersection( a, slope, ok = FindLineSegmentIntersection( a, slope,
...@@ -1461,16 +1462,19 @@ void CPolyLine::Hatch() ...@@ -1461,16 +1462,19 @@ void CPolyLine::Hatch()
m_SideStyle[ic], m_SideStyle[ic],
&x, &y, &x2, &y2 ); &x, &y, &x2, &y2 );
} }
if( ok ) if( ok )
{ {
wxPoint point( (int) x, (int) y); wxPoint point( (int) x, (int) y );
pointbuffer.push_back( point ); pointbuffer.push_back( point );
} }
if( ok == 2 ) if( ok == 2 )
{ {
wxPoint point( (int) x2, (int) y2); wxPoint point( (int) x2, (int) y2 );
pointbuffer.push_back( point ); pointbuffer.push_back( point );
} }
if( pointbuffer.size() >= MAXPTS ) // overflow if( pointbuffer.size() >= MAXPTS ) // overflow
{ {
wxASSERT( 0 ); wxASSERT( 0 );
...@@ -1495,6 +1499,7 @@ void CPolyLine::Hatch() ...@@ -1495,6 +1499,7 @@ void CPolyLine::Hatch()
for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 ) for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
{ {
double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x; double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
// Push only one line for diagonal hatch, // Push only one line for diagonal hatch,
// or for small lines < twice the line len // or for small lines < twice the line len
// else push 2 small lines // else push 2 small lines
...@@ -1546,19 +1551,21 @@ bool CPolyLine::TestPointInside( int px, int py ) ...@@ -1546,19 +1551,21 @@ bool CPolyLine::TestPointInside( int px, int py )
// if inside 2 contours (the main outline + an hole), it is outside the poly. // if inside 2 contours (the main outline + an hole), it is outside the poly.
int polycount = GetContoursCount(); int polycount = GetContoursCount();
bool inside = false; bool inside = false;
for( int icont = 0; icont < polycount; icont++ ) for( int icont = 0; icont < polycount; icont++ )
{ {
int istart = GetContourStart( icont ); int istart = GetContourStart( icont );
int iend = GetContourEnd( icont ); int iend = GetContourEnd( icont );
// Test this polygon: // Test this polygon:
if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py) ) // test point inside the current polygon if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) ) // test point inside the current polygon
inside = not inside; inside = not inside;
} }
return inside; return inside;
} }
// copy data from another poly, but don't draw it // copy data from another poly, but don't draw it
// //
void CPolyLine::Copy( CPolyLine* src ) void CPolyLine::Copy( CPolyLine* src )
...@@ -1585,6 +1592,7 @@ bool CPolyLine::IsCutoutContour( int icont ) ...@@ -1585,6 +1592,7 @@ bool CPolyLine::IsCutoutContour( int icont )
if( ncont == 0 ) // the first contour is the main outline, not an hole if( ncont == 0 ) // the first contour is the main outline, not an hole
return false; return false;
return true; return true;
} }
...@@ -1592,6 +1600,7 @@ bool CPolyLine::IsCutoutContour( int icont ) ...@@ -1592,6 +1600,7 @@ bool CPolyLine::IsCutoutContour( int icont )
void CPolyLine::MoveOrigin( int x_off, int y_off ) void CPolyLine::MoveOrigin( int x_off, int y_off )
{ {
UnHatch(); UnHatch();
for( int ic = 0; ic < GetNumCorners(); ic++ ) for( int ic = 0; ic < GetNumCorners(); ic++ )
{ {
SetX( ic, GetX( ic ) + x_off ); SetX( ic, GetX( ic ) + x_off );
...@@ -1647,23 +1656,27 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n ...@@ -1647,23 +1656,27 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
Close( STRAIGHT ); Close( STRAIGHT );
} }
// Bezier Support // Bezier Support
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3) void CPolyLine::AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3 )
{ {
std::vector<wxPoint> bezier_points; std::vector<wxPoint> bezier_points;
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3); bezier_points = Bezier2Poly( x1, y1, x2, y2, x3, y3 );
for( unsigned int i = 0; i < bezier_points.size() ; i++)
AppendCorner( bezier_points[i].x, bezier_points[i].y); for( unsigned int i = 0; i < bezier_points.size(); i++ )
AppendCorner( bezier_points[i].x, bezier_points[i].y );
} }
void CPolyLine::AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
void CPolyLine::AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 )
{ {
std::vector<wxPoint> bezier_points; std::vector<wxPoint> bezier_points;
bezier_points = Bezier2Poly(x1,y1,x2,y2,x3,y3,x4,y4); bezier_points = Bezier2Poly( x1, y1, x2, y2, x3, y3, x4, y4 );
for( unsigned int i = 0; i < bezier_points.size() ; i++)
AppendCorner( bezier_points[i].x, bezier_points[i].y); for( unsigned int i = 0; i < bezier_points.size(); i++ )
AppendCorner( bezier_points[i].x, bezier_points[i].y );
} }
...@@ -1717,8 +1730,10 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) ...@@ -1717,8 +1730,10 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
CPolyLine::STRAIGHT, aWidth, CPolyLine::STRAIGHT, aWidth,
1, // min clearance, should be > 0 1, // min clearance, should be > 0
NULL, NULL ); NULL, NULL );
if( distance > d ) if( distance > d )
distance = d; distance = d;
if( distance <= 0 ) if( distance <= 0 )
return 0; return 0;
} }
...@@ -1727,6 +1742,7 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) ...@@ -1727,6 +1742,7 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
return distance; return distance;
} }
/* /*
* Function Distance * Function Distance
* Calculates the distance between a point and polygon (with holes): * Calculates the distance between a point and polygon (with holes):
...@@ -1775,6 +1791,7 @@ int CPolyLine::Distance( const wxPoint& aPoint ) ...@@ -1775,6 +1791,7 @@ int CPolyLine::Distance( const wxPoint& aPoint )
if( distance > d ) if( distance > d )
distance = d; distance = d;
if( distance <= 0 ) if( distance <= 0 )
return 0; return 0;
} }
...@@ -1782,3 +1799,152 @@ int CPolyLine::Distance( const wxPoint& aPoint ) ...@@ -1782,3 +1799,152 @@ int CPolyLine::Distance( const wxPoint& aPoint )
return distance; return distance;
} }
/**
* Function CopyPolysListToKiPolygonWithHole
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
*
* @param aPolysList = the list of corners of contours
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
*/
void CopyPolysListToKiPolygonWithHole( const std::vector<CPolyPt>& aPolysList,
KI_POLYGON_WITH_HOLES& aPolygoneWithHole )
{
unsigned corners_count = aPolysList.size();
std::vector<KI_POLY_POINT> cornerslist;
KI_POLYGON poly;
// Enter main outline: this is the first contour
unsigned ic = 0;
while( ic < corners_count )
{
const CPolyPt& corner = aPolysList[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
aPolygoneWithHole.set( cornerslist.begin(), cornerslist.end() );
// Enter holes: they are next contours (when exist)
if( ic < corners_count )
{
KI_POLYGON_SET holePolyList;
while( ic < corners_count )
{
cornerslist.clear();
while( ic < corners_count )
{
const CPolyPt& corner = aPolysList[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
holePolyList.push_back( poly );
}
aPolygoneWithHole.set_holes( holePolyList.begin(), holePolyList.end() );
}
}
/**
* Function ConvertPolysListWithHolesToOnePolygon
* converts the outline contours aPolysListWithHoles with holes to one polygon
* with no holes (only one contour)
* holes are linked to main outlines by overlap segments, to give only one polygon
*
* @param aPolysListWithHoles = the list of corners of contours (haing holes
* @param aOnePolyList = a polygon with no holes
*/
void ConvertPolysListWithHolesToOnePolygon( const std::vector<CPolyPt>& aPolysListWithHoles,
std::vector<CPolyPt>& aOnePolyList )
{
unsigned corners_count = aPolysListWithHoles.size();
int polycount = 0;
for( unsigned ii = 0; ii < corners_count; ii++ )
{
const CPolyPt& corner = aPolysListWithHoles[ii];
if( corner.end_contour )
polycount++;
}
// If polycount<= 1, there is no holes found.
if( polycount<= 1 )
{
aOnePolyList = aPolysListWithHoles;
return;
}
// Holes are found: convert them to only one polygon with overlap segments
KI_POLYGON_SET polysholes;
KI_POLYGON_SET mainpoly;
KI_POLYGON poly_tmp;
std::vector<KI_POLY_POINT> cornerslist;
corners_count = aPolysListWithHoles.size();
unsigned ic = 0;
// enter main outline
while( ic < corners_count )
{
const CPolyPt& corner = aPolysListWithHoles[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
bpl::set_points( poly_tmp, cornerslist.begin(), cornerslist.end() );
mainpoly.push_back( poly_tmp );
while( ic < corners_count )
{
cornerslist.clear();
{
while( ic < corners_count )
{
const CPolyPt& corner = aPolysListWithHoles[ic++];
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
if( corner.end_contour )
break;
}
bpl::set_points( poly_tmp, cornerslist.begin(), cornerslist.end() );
polysholes.push_back( poly_tmp );
}
}
mainpoly -= polysholes;
// copy polygon with no holes to destination
// We should have only one polygon in list
wxASSERT( mainpoly.size() != 1 );
{
KI_POLYGON& poly_nohole = mainpoly[0];
CPolyPt corner( 0, 0, false );
for( unsigned jj = 0; jj < poly_nohole.size(); jj++ )
{
KI_POLY_POINT point = *(poly_nohole.begin() + jj);
corner.x = point.x();
corner.y = point.y();
corner.end_contour = false;
aOnePolyList.push_back( corner );
}
corner.end_contour = true;
aOnePolyList.pop_back();
aOnePolyList.push_back( corner );
}
}
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
#include <kbool/include/kbool/booleng.h> #include <kbool/include/kbool/booleng.h>
#include <pad_shapes.h> #include <pad_shapes.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h> // for wxPoint definition
#include <polygons_defs.h>
// inflection modes for DS_LINE and DS_LINE_VERTEX, used in math_for_graphics.cpp // inflection modes for DS_LINE and DS_LINE_VERTEX, used in math_for_graphics.cpp
enum enum {
{
IM_NONE = 0, IM_NONE = 0,
IM_90_45, IM_90_45,
IM_45_90, IM_45_90,
...@@ -44,11 +45,12 @@ public: ...@@ -44,11 +45,12 @@ public:
wxPoint m_End; wxPoint m_End;
CSegment() { }; CSegment() { };
CSegment( const wxPoint & aStart, const wxPoint & aEnd ) CSegment( const wxPoint& aStart, const wxPoint& aEnd )
{ {
m_Start = aStart; m_Start = aStart;
m_End = aEnd; m_End = aEnd;
} }
CSegment( int x0, int y0, int x1, int y1 ) CSegment( int x0, int y0, int x1, int y1 )
{ {
m_Start.x = x0; m_Start.y = y0; m_Start.x = x0; m_Start.y = y0;
...@@ -77,8 +79,8 @@ public: ...@@ -77,8 +79,8 @@ public:
wxPoint( aX, aY ), end_contour( aEnd ), m_utility( aUtility ) wxPoint( aX, aY ), end_contour( aEnd ), m_utility( aUtility )
{} {}
/// Pure copy constructor is here to dis-ambiguate from the // / Pure copy constructor is here to dis-ambiguate from the
/// specialized CPolyPt( const wxPoint& ) constructor version below. // / specialized CPolyPt( const wxPoint& ) constructor version below.
CPolyPt( const CPolyPt& aPt ) : CPolyPt( const CPolyPt& aPt ) :
wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), m_utility( aPt.m_utility ) wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), m_utility( aPt.m_utility )
{} {}
...@@ -91,10 +93,10 @@ public: ...@@ -91,10 +93,10 @@ public:
bool end_contour; bool end_contour;
int m_utility; int m_utility;
bool operator == (const CPolyPt& cpt2 ) const bool operator ==( const CPolyPt& cpt2 ) const
{ return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); } { return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); }
bool operator != (CPolyPt& cpt2 ) const bool operator !=( CPolyPt& cpt2 ) const
{ return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); } { return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); }
}; };
...@@ -177,6 +179,7 @@ public: ...@@ -177,6 +179,7 @@ public:
int GetUtility( int ic ) { return m_CornersList[ic].m_utility; }; int GetUtility( int ic ) { return m_CornersList[ic].m_utility; };
void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; }; void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; };
int GetSideStyle( int is ); int GetSideStyle( int is );
int GetHatchPitch() { return m_hatchPitch; } int GetHatchPitch() { return m_hatchPitch; }
int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
...@@ -184,59 +187,38 @@ public: ...@@ -184,59 +187,38 @@ public:
void SetHatch( int hatch, int pitch ) void SetHatch( int hatch, int pitch )
{ {
SetHatchPitch( pitch ); SetHatchPitch( pitch );
m_hatchStyle = (enum hatch_style ) hatch; m_hatchStyle = (enum hatch_style) hatch;
Hatch(); Hatch();
} }
void SetX( int ic, int x ); void SetX( int ic, int x );
void SetY( int ic, int y ); void SetY( int ic, int y );
void SetEndContour( int ic, bool end_contour ); void SetEndContour( int ic, bool end_contour );
void SetSideStyle( int is, int style ); void SetSideStyle( int is, int style );
void SetHatchStyle( enum hatch_style style ) void SetHatchStyle( enum hatch_style style )
{ {
m_hatchStyle = style; m_hatchStyle = style;
} }
void SetHatchPitch( int pitch ) { m_hatchPitch = pitch; } void SetHatchPitch( int pitch ) { m_hatchPitch = pitch; }
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa = NULL ); int RestoreArcs( std::vector<CArc>* arc_array, std::vector<CPolyLine*>* pa = NULL );
int NormalizeAreaOutlines( std::vector<CPolyLine*> * pa = NULL, int NormalizeAreaOutlines( std::vector<CPolyLine*>* pa = NULL,
bool bRetainArcs = false ); bool bRetainArcs = false );
// KBOOL functions // KBOOL functions
/**
* Function AddPolygonsToBoolEng
* and edges contours to a kbool engine, preparing a boolean op between polygons
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* @param arc_array: arc connverted to poly (NULL if not exists)
* @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,
int aStart_contour = -1,
int aEnd_contour = -1,
std::vector<CArc> * arc_array = NULL );
/** /**
* Function MakeKboolPoly * Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour * fill a kbool engine with a closed polyline contour
* approximates arcs with multiple straight-line segments * approximates arcs with multiple straight-line segments
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* combining intersecting contours if possible * combining intersecting contours if possible
* @param arc_array : return data on arcs in arc_array * @param arc_array : return data on arcs in arc_array
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
* @return error: 0 if Ok, 1 if error * @return error: 0 if Ok, 1 if error
*/ */
int MakeKboolPoly( int aStart_contour = -1, int MakeKboolPoly( std::vector<CArc>* arc_array = NULL );
int aEnd_contour = -1,
std::vector<CArc> * arc_array = NULL,
bool aConvertHoles = false);
/** /**
* Function NormalizeWithKbool * Function NormalizeWithKbool
...@@ -250,22 +232,11 @@ public: ...@@ -250,22 +232,11 @@ public:
* @param bRetainArcs == false, try to retain arcs in polys * @param bRetainArcs == false, try to retain arcs in polys
* @return number of external contours, or -1 if error * @return number of external contours, or -1 if error
*/ */
int NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, bool bRetainArcs ); int NormalizeWithKbool( std::vector<CPolyLine*>* aExtraPolyList, bool bRetainArcs );
/**
* Function GetKboolEngine
* @return the current used Kbool Engine (after normalization using kbool)
*/
Bool_Engine* GetKboolEngine( ) { return m_Kbool_Poly_Engine; }
/**
* Function FreeKboolEngine
* delete the current used Kbool Engine (free memory after normalization using kbool)
*/
void FreeKboolEngine( ) { delete m_Kbool_Poly_Engine; m_Kbool_Poly_Engine = NULL; }
// Bezier Support // Bezier Support
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3); void AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3 );
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4); void AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );
/** /**
* Function Distance * Function Distance
...@@ -296,11 +267,33 @@ private: ...@@ -296,11 +267,33 @@ private:
// for DIAGONAL_FULL, the pitch is twice this value // for DIAGONAL_FULL, the pitch is twice this value
int m_utility; // a flag used in some calculations int m_utility; // a flag used in some calculations
Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data
public: public:
std::vector <CPolyPt> m_CornersList; // array of points for corners std::vector <CPolyPt> m_CornersList; // array of points for corners
std::vector <int> m_SideStyle; // array of styles for sides std::vector <int> m_SideStyle; // array of styles for sides
std::vector <CSegment> m_HatchLines; // hatch lines showing the polygon area std::vector <CSegment> m_HatchLines; // hatch lines showing the polygon area
}; };
/**
* Function CopyPolysListToKiPolygonWithHole
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
*
* @param aPolysList = the list of corners of contours
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
*/
void CopyPolysListToKiPolygonWithHole( const std::vector<CPolyPt>& aPolysList,
KI_POLYGON_WITH_HOLES& aPolygoneWithHole );
/**
* Function ConvertPolysListWithHolesToOnePolygon
* converts the outline contours aPolysListWithHoles with holes to one polygon
* with no holes (only one contour)
* holes are linked to main outlines by overlap segments, to give only one polygon
*
* @param aPolysListWithHoles = the list of corners of contours (haing holes
* @param aOnePolyList = a polygon with no holes
*/
void ConvertPolysListWithHolesToOnePolygon( const std::vector<CPolyPt>& aPolysListWithHoles,
std::vector<CPolyPt>& aOnePolyList );
#endif // #ifndef POLYLINE_H #endif // #ifndef POLYLINE_H
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