diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 0c0a6b05d8..36e2bcea1c 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -305,7 +305,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() { CPolyPt* endcorner = &polysList[ic]; - if( begincorner->utility == 0 ) + if( begincorner->m_utility == 0 ) { // Draw only basic outlines, not extra segments dummysegment.m_Start.x = begincorner->x; @@ -318,7 +318,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() if( (endcorner->end_contour) || (ic == imax) ) { // the last corner of a filled area is found: draw it - if( endcorner->utility == 0 ) + if( endcorner->m_utility == 0 ) { // Draw only basic outlines, not extra segments dummysegment.m_Start.x = endcorner->x; diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index f1fcb5f319..489b7a07eb 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -561,15 +561,15 @@ void LIB_ARC::BeginEdit( int aEditMode, const wxPoint aPosition ) // Drag either the start, end point or the outline 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 ) ) { - m_editSelectPoint = END; + m_editSelectPoint = ARC_STATUS_END; } else { - m_editSelectPoint = OUTLINE; + m_editSelectPoint = ARC_STATUS_OUTLINE; } m_editState = 0; @@ -619,12 +619,12 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition ) wxPoint newCenterPoint, startPos, endPos; // Choose the point of the arc to be adjusted - if( m_editSelectPoint == START ) + if( m_editSelectPoint == ARC_STATUS_START ) { startPos = aPosition; endPos = m_ArcEnd; } - else if( m_editSelectPoint == END ) + else if( m_editSelectPoint == ARC_STATUS_END ) { endPos = aPosition; startPos = m_ArcStart; @@ -658,7 +658,7 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition ) 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 wxPoint middlePoint = wxPoint( (startPos.x + endPos.x) / 2, diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index ab179a98ef..139c55335a 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -37,15 +37,15 @@ class TRANSFORM; class LIB_ARC : public LIB_ITEM { - enum SELECT_T + enum SELECT_T // When creating an arc: status of arc { - START, - END, - OUTLINE, + ARC_STATUS_START, + ARC_STATUS_END, + ARC_STATUS_OUTLINE, }; 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. */ wxPoint m_ArcStart; wxPoint m_ArcEnd; /* Arc end position. */ diff --git a/pcb_calculator/bitmaps/Thumbs.db b/pcb_calculator/bitmaps/Thumbs.db deleted file mode 100644 index a26a0e272b..0000000000 Binary files a/pcb_calculator/bitmaps/Thumbs.db and /dev/null differ diff --git a/pcbnew/autorouter/solve.cpp b/pcbnew/autorouter/solve.cpp index c3c00a2c0a..17f9ae35f6 100644 --- a/pcbnew/autorouter/solve.cpp +++ b/pcbnew/autorouter/solve.cpp @@ -1302,12 +1302,12 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) 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 ) 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 ) g_CurrentTrackSegment->SetState( END_ONPAD, ON ); diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index 10d03071a3..47a8bbd736 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -167,19 +167,19 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector // Calculate the polygon with clearance and holes // holes are linked to the main outline, so only one polygon should be created. - KPolygonSet polyset_zone_solid_areas; - std::vector cornerslist; + KI_POLYGON_SET polyset_zone_solid_areas; + std::vector cornerslist; unsigned ic = 0; unsigned corners_count = zoneOutines.size(); while( ic < corners_count ) { cornerslist.clear(); - KPolygon poly; + KI_POLYGON poly; { for( ; ic < corners_count; ic++ ) { CPolyPt* corner = &zoneOutines[ic]; - cornerslist.push_back( KPolyPoint( corner->x, corner->y ) ); + cornerslist.push_back( KI_POLY_POINT( corner->x, corner->y ) ); if( corner->end_contour ) { ic++; @@ -197,12 +197,12 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector // Put the resultng polygon in buffer for( unsigned ii = 0; ii < polyset_zone_solid_areas.size(); ii++ ) { - KPolygon& poly = polyset_zone_solid_areas[ii]; + KI_POLYGON& poly = polyset_zone_solid_areas[ii]; CPolyPt corner( 0, 0, false ); for( unsigned jj = 0; jj < poly.size(); jj++ ) { - KPolyPoint point = *(poly.begin() + jj); + KI_POLY_POINT point = *(poly.begin() + jj); corner.x = point.x(); corner.y = point.y(); corner.end_contour = false; diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a495faf219..2da338f002 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1681,7 +1681,7 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint ) int aLayerMask = GetLayerMask( aTrace->GetLayer() ); - if( aEndPoint == START ) + if( aEndPoint == FLG_START ) { aPosition = aTrace->m_Start; } @@ -2271,7 +2271,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS aSegment->end = newTrack; aSegment->SetState( END_ONPAD, OFF ); - D_PAD * pad = GetPad( newTrack, START ); + D_PAD * pad = GetPad( newTrack, FLG_START ); if ( pad ) { diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 788072f471..120a64e398 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -1282,7 +1282,7 @@ TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint ) int ii; int max_dist; - if( aEndPoint == START ) + if( aEndPoint == FLG_START ) position = m_Start; else position = m_End; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index d67142aaa8..d79c1e4ffc 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -210,7 +210,7 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const { seg_start = GetCornerPosition( ic ) + offset; - if( m_Poly->corner[ic].end_contour == false && ic < GetNumCorners() - 1 ) + if( m_Poly->m_CornersList[ic].end_contour == false && ic < GetNumCorners() - 1 ) { seg_end = GetCornerPosition( ic + 1 ) + offset; } @@ -306,7 +306,7 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, CornersBuffer.push_back( coord ); - CornersTypeBuffer.push_back( (char) corner->utility ); + CornersTypeBuffer.push_back( (char) corner->m_utility ); if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it { @@ -432,13 +432,13 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in int yi = GetCornerPosition( ic ).y; int xf, yf; - if( m_Poly->corner[ic].end_contour == false && ic < icmax ) + if( m_Poly->m_CornersList[ic].end_contour == false && ic < icmax ) { is_close_segment = false; xf = GetCornerPosition( ic + 1 ).x; yf = GetCornerPosition( ic + 1 ).y; - if( (m_Poly->corner[ic + 1].end_contour) || (ic == icmax - 1) ) + if( (m_Poly->m_CornersList[ic + 1].end_contour) || (ic == icmax - 1) ) current_gr_mode = GR_XOR; else current_gr_mode = draw_mode; @@ -507,12 +507,12 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) int min_dist = MIN_DIST_IN_MILS*IU_PER_MILS; wxPoint delta; - unsigned lim = m_Poly->corner.size(); + unsigned lim = m_Poly->m_CornersList.size(); for( unsigned item_pos = 0; item_pos < lim; item_pos++ ) { - delta.x = refPos.x - m_Poly->corner[item_pos].x; - delta.y = refPos.y - m_Poly->corner[item_pos].y; + delta.x = refPos.x - m_Poly->m_CornersList[item_pos].x; + delta.y = refPos.y - m_Poly->m_CornersList[item_pos].y; // Calculate a distance: int dist = MAX( abs( delta.x ), abs( delta.y ) ); @@ -530,7 +530,7 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) { - unsigned lim = m_Poly->corner.size(); + unsigned lim = m_Poly->m_CornersList.size(); m_CornerSelection = -1; // Set to not found @@ -547,7 +547,7 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) * the last segment of the current outline starts at current corner, and ends * at the first corner of the outline */ - if( m_Poly->corner[item_pos].end_contour || end_segm >= lim ) + if( m_Poly->m_CornersList[item_pos].end_contour || end_segm >= lim ) { unsigned tmp = first_corner_pos; first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline @@ -557,10 +557,10 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) /* test the dist between segment and ref point */ int dist = (int) GetPointToLineSegmentDistance( refPos.x, refPos.y, - m_Poly->corner[item_pos].x, - m_Poly->corner[item_pos].y, - m_Poly->corner[end_segm].x, - m_Poly->corner[end_segm].y ); + m_Poly->m_CornersList[item_pos].x, + m_Poly->m_CornersList[item_pos].y, + m_Poly->m_CornersList[end_segm].x, + m_Poly->m_CornersList[end_segm].y ); if( dist < min_dist ) { @@ -703,7 +703,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame ) msg = board->GetLayerName( m_Layer ); frame->AppendMsgPanel( _( "Layer" ), msg, BROWN ); - msg.Printf( wxT( "%d" ), (int) m_Poly->corner.size() ); + msg.Printf( wxT( "%d" ), (int) m_Poly->m_CornersList.size() ); frame->AppendMsgPanel( _( "Corners" ), msg, BLUE ); if( m_FillMode ) @@ -730,7 +730,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame ) void ZONE_CONTAINER::Move( const wxPoint& offset ) { /* move outlines */ - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); } @@ -761,7 +761,7 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset ) SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); // Move the end point of the selected edge: - if( m_Poly->corner[ii].end_contour || ii == GetNumCorners() - 1 ) + if( m_Poly->m_CornersList[ii].end_contour || ii == GetNumCorners() - 1 ) { int icont = m_Poly->GetContour( ii ); ii = m_Poly->GetContourStart( icont ); @@ -781,13 +781,13 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle ) { wxPoint pos; - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { - pos.x = m_Poly->corner[ii].x; - pos.y = m_Poly->corner[ii].y; + pos.x = m_Poly->m_CornersList[ii].x; + pos.y = m_Poly->m_CornersList[ii].y; RotatePoint( &pos, centre, angle ); - m_Poly->corner[ii].x = pos.x; - m_Poly->corner[ii].y = pos.y; + m_Poly->m_CornersList[ii].x = pos.x; + m_Poly->m_CornersList[ii].y = pos.y; } m_Poly->Hatch(); @@ -820,11 +820,11 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre ) void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref ) { - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { - m_Poly->corner[ii].y -= mirror_ref.y; - NEGATE( m_Poly->corner[ii].y ); - m_Poly->corner[ii].y += mirror_ref.y; + m_Poly->m_CornersList[ii].y -= mirror_ref.y; + NEGATE( m_Poly->m_CornersList[ii].y ); + m_Poly->m_CornersList[ii].y += mirror_ref.y; } m_Poly->Hatch(); diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index e6e33cc06b..048125c9c2 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -613,7 +613,7 @@ private: /* 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 - * (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 * a polygon equivalent to m_Poly, without holes but with extra outline segment * connecting "holes" with external main outline. In complex cases an outline diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 4f22db1182..b93b88081f 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -272,7 +272,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) 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 { @@ -306,7 +306,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) segment->SetState( BUSY, ON ); 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 ) { @@ -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( (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 { @@ -362,7 +362,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame ) segment->SetState( BUSY, ON ); 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 ) { @@ -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 for( segStart = segment->Next(); ; ) { - segStart = segment->GetTrace( segStart, NULL, START ); + segStart = segment->GetTrace( segStart, NULL, FLG_START ); if( segStart ) { @@ -500,7 +500,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) // We must have only one segment connected 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 ); if( other == NULL ) @@ -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 { segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), segment, segStart, - START ); + FLG_START ); if( segDelete ) { @@ -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: for( segEnd = segment->Next(); ; ) { - segEnd = segment->GetTrace( segEnd, NULL, END ); + segEnd = segment->GetTrace( segEnd, NULL, FLG_END ); if( segEnd ) { @@ -538,7 +538,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame ) // We must have only one segment connected 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 ); if( other == NULL ) @@ -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 { - segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), segment, segEnd, END ); + segDelete = MergeColinearSegmentIfPossible( aFrame->GetBoard(), + segment, segEnd, FLG_END ); if( segDelete ) { @@ -643,7 +644,7 @@ TRACK* MergeColinearSegmentIfPossible( BOARD* aPcb, TRACK* aTrackRef, TRACK* aCa * (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 */ - if( aEndType == START ) + if( aEndType == FLG_START ) { // We must not have a pad, which is a always terminal point for a track if( aPcb->GetPadFast( aTrackRef->m_Start, aTrackRef->ReturnMaskLayer() ) ) @@ -712,7 +713,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, START ); + other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_START ); if( other ) net_code_s = other->GetNet(); @@ -730,7 +731,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks() } else { - other = segment->GetTrace( GetBoard()->m_Track, NULL, END ); + other = segment->GetTrace( GetBoard()->m_Track, NULL, FLG_END ); if( other ) net_code_e = other->GetNet(); @@ -871,14 +872,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame ) if( aFrame->GetCanvas()->GetAbortRequest() ) return; - pad = aFrame->GetBoard()->GetPad( segment, START ); + pad = aFrame->GetBoard()->GetPad( segment, FLG_START ); if( pad ) { // test if the track start point is not exactly starting on the pad 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(); @@ -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 ) { // test if the track end point is not exactly on the pad 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(); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 472e1ca18d..b43eeacf44 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -263,7 +263,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC ) newTrack->SetState( BEGIN_ONPAD | END_ONPAD, OFF ); - D_PAD* pad = GetBoard()->GetPad( previousTrack, END ); + D_PAD* pad = GetBoard()->GetPad( previousTrack, FLG_END ); if( pad ) { @@ -1042,7 +1042,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST& aTrackList ) while( track != NULL ) { TRACK* next_track = track->Next(); - LockPoint = pcb->GetPad( track, END ); + LockPoint = pcb->GetPad( track, FLG_END ); if( LockPoint ) { diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 9387c24cc3..0c14255698 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1059,7 +1059,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, ")\n" ); - const std::vector< CPolyPt >& cv = aZone->m_Poly->corner; + const std::vector< CPolyPt >& cv = aZone->m_Poly->m_CornersList; int newLine = 0; if( cv.size() ) diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 028b2f9248..77618154a4 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -3609,7 +3609,7 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const typedef std::vector< CPolyPt > CPOLY_PTS; // Save the corner list - const CPOLY_PTS& cv = me->m_Poly->corner; + const CPOLY_PTS& cv = me->m_Poly->m_CornersList; for( CPOLY_PTS::const_iterator it = cv.begin(); it != cv.end(); ++it ) { fprintf( m_fp, "ZCorner %s %d\n", @@ -3623,12 +3623,12 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const { fprintf( m_fp, "$POLYSCORNERS\n" ); - for( CPOLY_PTS::const_iterator it = fv.begin(); it != fv.end(); ++it ) + for( CPOLY_PTS::const_iterator it = fv.begin(); it != fv.end(); ++it ) { fprintf( m_fp, "%s %d %d\n", fmtBIUPair( it->x, it->y ).c_str(), it->end_contour, - it->utility ); + it->m_utility ); } fprintf( m_fp, "$endPOLYSCORNERS\n" ); diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index b72387ccfe..c58c4fdbc4 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -887,7 +887,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC s_StartSegmentPresent = s_EndSegmentPresent = true; 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 if( TrackToStartPoint ) @@ -895,14 +895,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToStartPoint->SetState( BUSY, ON ); if( ( TrackToStartPoint->Type() == PCB_VIA_T ) - || track->GetTrace( GetBoard()->m_Track, NULL, START ) ) + || track->GetTrace( GetBoard()->m_Track, NULL, FLG_START ) ) error = true; TrackToStartPoint->SetState( BUSY, OFF ); } 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 if( TrackToEndPoint ) @@ -910,7 +910,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC TrackToEndPoint->SetState( BUSY, ON ); if( (TrackToEndPoint->Type() == PCB_VIA_T) - || track->GetTrace( GetBoard()->m_Track, NULL, END ) ) + || track->GetTrace( GetBoard()->m_Track, NULL, FLG_END ) ) error = true; TrackToEndPoint->SetState( BUSY, OFF ); diff --git a/pcbnew/pcbnew.h b/pcbnew/pcbnew.h index bc5df44334..78624ab4fd 100644 --- a/pcbnew/pcbnew.h +++ b/pcbnew/pcbnew.h @@ -25,8 +25,8 @@ #define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select -#define START 0 /* Flag used in locate routines */ -#define END 1 +#define FLG_START 0 // Flag used in locate routines +#define FLG_END 1 // Flag used in locate routines #define DIM_ANCRE_MODULE 3 /* Anchor size (footprint center) */ #define DIM_ANCRE_TEXTE 2 /* Anchor size (Text center) */ diff --git a/pcbnew/polygons_defs.h b/pcbnew/polygons_defs.h deleted file mode 100644 index 3d7640c8d8..0000000000 --- a/pcbnew/polygons_defs.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * file polygons_defs.h - * definitions to use boost::polygon in KiCad. - */ - -#ifndef _POLYGONS_DEFS_H_ -#define _POLYGONS_DEFS_H_ - -#include - -// Define some types used here from boost::polygon -namespace bpl = boost::polygon; // bpl = boost polygon library -using namespace bpl::operators; // +, -, =, ... - -typedef int coordinate_type; - -typedef bpl::polygon_data KPolygon; -typedef std::vector KPolygonSet; - -typedef bpl::point_data KPolyPoint; -#endif // #ifndef _POLYGONS_DEFS_H_ diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index be1a66e462..1a51b76aca 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1178,16 +1178,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->corner.size(); + int count = item->m_Poly->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point( item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->corner[ndx].end_contour ) + if( item->m_Poly->m_CornersList[ndx].end_contour ) break; } @@ -1197,7 +1197,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->corner[ndx-1].end_contour ) + if( item->m_Poly->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( plane ); plane->AddWindow( window ); @@ -1211,8 +1211,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point(item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } @@ -1253,16 +1253,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->corner.size(); + int count = item->m_Poly->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point( item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->corner[ndx].end_contour ) + if( item->m_Poly->m_CornersList[ndx].end_contour ) break; } @@ -1272,7 +1272,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->corner[ndx-1].end_contour ) + if( item->m_Poly->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( keepout ); keepout->AddWindow( window ); @@ -1286,8 +1286,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point(item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 539d6a0f0c..0a29804f28 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -89,39 +89,12 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector 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 ) - { - aCornerBuffer->pop_back(); - aCornerBuffer->push_back( corner ); - } - else - { - m_FilledPolysList.pop_back(); - m_FilledPolysList.push_back( corner ); - } - m_smoothedPoly->GetKboolEngine()->EndPolygonGet(); - } - - m_smoothedPoly->FreeKboolEngine(); - + if( aCornerBuffer ) + ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, + *aCornerBuffer ); + else + ConvertPolysListWithHolesToOnePolygon( m_smoothedPoly->m_CornersList, + m_FilledPolysList ); /* For copper layers, we now must add holes in the Polygon list. * holes are pads and tracks with their clearance area */ @@ -134,7 +107,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector Fill_Zone_Areas_With_Segments( ); } - return count; + return 1; } // Sort function to build filled zones @@ -188,7 +161,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() x_coordinates.clear(); for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) { - if ( m_FilledPolysList[ice].utility ) + if ( m_FilledPolysList[ice].m_utility ) continue; int seg_startX = m_FilledPolysList[ics].x; int seg_startY = m_FilledPolysList[ics].y; diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 487ce0110d..85d9012b4d 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -81,14 +81,14 @@ extern void CreateThermalReliefPadPolygon( std::vector& aCornerBuffer, int aThermalRot ); // Local Functions: helper function to calculate solid areas -static void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, - KPolygonSet& aKPolyList ); +static void AddPolygonCornersToKiPolygonList( std::vector & aCornersBuffer, + KI_POLYGON_SET& aKiPolyList ); -static int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ); +static int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ); -static int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ); +static int CopyPolygonsFromFilledPolysListToKiPolygonList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ); // Local Variables: @@ -148,8 +148,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) */ s_Correction = 1.0 / cos( 3.14159265 / s_CircleToSegmentsCount ); - // This KPolygonSet is the area(s) to fill, with m_ZoneMinThickness/2 - KPolygonSet polyset_zone_solid_areas; + // This KI_POLYGON_SET is the area(s) to fill, with m_ZoneMinThickness/2 + KI_POLYGON_SET polyset_zone_solid_areas; int margin = m_ZoneMinThickness / 2; /* First, creates the main polygon (i.e. the filled area using only one outline) @@ -160,7 +160,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) * the main polygon is stored in polyset_zone_solid_areas */ - CopyPolygonsFromFilledPolysListTotKPolygonList( this, polyset_zone_solid_areas ); + CopyPolygonsFromFilledPolysListToKiPolygonList( this, polyset_zone_solid_areas ); polyset_zone_solid_areas -= margin; if( polyset_zone_solid_areas.size() == 0 ) @@ -431,15 +431,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // Calculate now actual solid areas if( cornerBufferPolysToSubstract.size() > 0 ) { - KPolygonSet polyset_holes; - AddPolygonCornersToKPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + KI_POLYGON_SET polyset_holes; + AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); // Remove holes from initial area.: polyset_zone_solid_areas -= polyset_holes; } // put solid areas in m_FilledPolysList: m_FilledPolysList.clear(); - CopyPolygonsFromKPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); + CopyPolygonsFromKiPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); // Remove insulated islands: if( GetNet() > 0 ) @@ -455,13 +455,13 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // remove copper areas if( cornerBufferPolysToSubstract.size() ) { - KPolygonSet polyset_holes; - AddPolygonCornersToKPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + KI_POLYGON_SET polyset_holes; + AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); polyset_zone_solid_areas -= polyset_holes; // put these areas in m_FilledPolysList m_FilledPolysList.clear(); - CopyPolygonsFromKPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); + CopyPolygonsFromKiPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); if( GetNet() > 0 ) Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); @@ -470,12 +470,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) cornerBufferPolysToSubstract.clear(); } -void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, - KPolygonSet& aKPolyList ) +void AddPolygonCornersToKiPolygonList( std::vector & aCornersBuffer, + KI_POLYGON_SET& aKiPolyList ) { unsigned ii; - std::vector cornerslist; + std::vector cornerslist; int polycount = 0; @@ -485,49 +485,45 @@ void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, polycount++; } - aKPolyList.reserve( polycount ); + aKiPolyList.reserve( polycount ); for( unsigned icnt = 0; icnt < aCornersBuffer.size(); ) { - KPolygon poly; + KI_POLYGON poly; cornerslist.clear(); for( ii = icnt; ii < aCornersBuffer.size(); ii++ ) { - cornerslist.push_back( KPolyPoint( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) ); + cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) ); if( aCornersBuffer[ii].end_contour ) break; } bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); - aKPolyList.push_back( poly ); + aKiPolyList.push_back( poly ); icnt = ii + 1; } } -int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ) +int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ) { int count = 0; std::vector polysList; - for( unsigned ii = 0; ii < aKPolyList.size(); ii++ ) + for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ ) { - KPolygon& poly = aKPolyList[ii]; + KI_POLYGON& poly = aKiPolyList[ii]; CPolyPt corner( 0, 0, false ); for( unsigned jj = 0; jj < poly.size(); jj++ ) { - KPolyPoint point = *(poly.begin() + jj); + KI_POLY_POINT point = *(poly.begin() + jj); corner.x = point.x(); corner.y = point.y(); 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 ); count++; } @@ -542,10 +538,10 @@ int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, } -int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ) +int CopyPolygonsFromFilledPolysListToKiPolygonList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ) { - std::vector polysList = aZone->GetFilledPolysList(); + const std::vector& polysList = aZone->GetFilledPolysList(); unsigned corners_count = polysList.size(); int count = 0; unsigned ic = 0; @@ -554,35 +550,32 @@ int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, for( unsigned ii = 0; ii < corners_count; ii++ ) { - CPolyPt* corner = &polysList[ic]; + const CPolyPt& corner = polysList[ii]; - if( corner->end_contour ) + if( corner.end_contour ) polycount++; } - aKPolyList.reserve( polycount ); - std::vector cornerslist; + aKiPolyList.reserve( polycount ); + std::vector cornerslist; while( ic < corners_count ) { cornerslist.clear(); - KPolygon poly; + KI_POLYGON poly; { - for( ; ic < corners_count; ic++ ) + while( ic < corners_count ) { - CPolyPt* corner = &polysList[ic]; - cornerslist.push_back( KPolyPoint( corner->x, corner->y ) ); + const CPolyPt& corner = polysList[ic++]; + cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); count++; - if( corner->end_contour ) - { - ic++; + if( corner.end_contour ) break; - } } bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); - aKPolyList.push_back( poly ); + aKiPolyList.push_back( poly ); } } diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index d3971a44fd..7d13e3b6b4 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -115,7 +115,7 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) wxASSERT( m_Poly ); // m_Poly == NULL Should never happen wxASSERT( aZoneToCompare.m_Poly ); - if( m_Poly->corner != aZoneToCompare.m_Poly->corner ) // Compare vector + if( m_Poly->m_CornersList != aZoneToCompare.m_Poly->m_CornersList ) // Compare vector return false; return true; diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index d790a8eb9e..02a6652739 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -142,7 +142,7 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) // first, check for sides intersecting other sides, especially arcs bool bInt = false; bool bArcInt = false; - int n_cont = p->GetNumContours(); + int n_cont = p->GetContoursCount(); // make bounding rect for each contour std::vector cr; @@ -550,7 +550,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) continue; // test for intersecting segments - for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + for( int icont1 = 0; icont1GetContoursCount(); icont1++ ) { int is1 = poly1->GetContourStart( icont1 ); int ie1 = poly1->GetContourEnd( icont1 ); @@ -574,7 +574,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) style1 = poly1->GetSideStyle( ic1 ); - for( int icont2 = 0; icont2 < poly2->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < poly2->GetContoursCount(); icont2++ ) { int is2 = poly2->GetContourStart( icont2 ); int ie2 = poly2->GetContourEnd( icont2 ); @@ -668,7 +668,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ bool bInt = false; bool bArcInt = false; - for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + for( int icont1 = 0; icont1GetContoursCount(); icont1++ ) { int is1 = poly1->GetContourStart( icont1 ); int ie1 = poly1->GetContourEnd( icont1 ); @@ -692,7 +692,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ style1 = poly1->GetSideStyle( ic1 ); - for( int icont2 = 0; icont2GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2GetContoursCount(); icont2++ ) { int is2 = poly2->GetContourStart( icont2 ); int ie2 = poly2->GetContourEnd( icont2 ); @@ -781,142 +781,84 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ /** * Function CombineAreas - * If possible, combine 2 copper areas + * Merge 2 copper areas (which are expected intersecting) * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo * commands can be NULL - * @param area_ref = tje main area (zone) + * @param area_ref = the main area (zone) * @param area_to_combine = the zone that can be merged with area_ref * area_ref must be BEFORE area_to_combine * area_to_combine will be deleted, if areas are combined * @return : 0 if no intersection * 1 if intersection - * 2 if arcs intersect + * 2 if arcs intersect (Currently not supported) */ + int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine ) { if( area_ref == area_to_combine ) { wxASSERT( 0 ); + return 0; } // polygons intersect, combine them - std::vector arc_array1; - std::vector arc_array2; - bool keep_area_to_combine = false; +// std::vector arc_array1; +// std::vector arc_array2; + bool keep_area_to_combine = false; // TODO test if areas intersect - Bool_Engine* booleng = new Bool_Engine(); - ArmBoolEng( booleng ); + KI_POLYGON_WITH_HOLES areaRefPoly; + KI_POLYGON_WITH_HOLES areaToMergePoly; + CopyPolysListToKiPolygonWithHole( area_ref->m_Poly->m_CornersList, areaRefPoly ); + CopyPolysListToKiPolygonWithHole( area_to_combine->m_Poly->m_CornersList, areaToMergePoly ); - area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A, -1, -1 ); - area_to_combine->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_B, -1, -1 ); - booleng->Do_Operation( BOOL_OR ); + KI_POLYGON_WITH_HOLES_SET mergedOutlines; + mergedOutlines.push_back( areaRefPoly ); + 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; + + areaRefPoly = mergedOutlines[0]; + area_ref->m_Poly->RemoveAllContours(); + + KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin(); // create area with external contour: Recreate only area edges, NOT holes - if( booleng->StartPolygonGet() ) + area_ref->m_Poly->Start( area_ref->GetLayer(), corner->x(), corner->y(), + area_ref->m_Poly->GetHatchStyle() ); + while( ++corner != areaRefPoly.end() ) { - if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE ) + area_ref->m_Poly->AppendCorner( corner->x(), corner->y() ); + } + + area_ref->m_Poly->Close(); + + // add holes (set of polygons) + KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes(); + while( hole != areaRefPoly.end_holes() ) + { + KI_POLYGON::iterator_type hole_corner = hole->begin(); + // create area with external contour: Recreate only area edges, NOT holes + while( hole_corner != hole->end() ) { - DisplayError( NULL, wxT( "BOARD::CombineAreas() error: unexpected hole descriptor" ) ); + area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() ); + hole_corner++; } - - 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->Close(); + hole++; } - // Recreate the area_to_combine if a second polygon exists - // if not exists , the first poly contains the 2 initial polygons -#if 0 // TestAreaIntersection must be called before combine areas, so - // 2 intersecting areas are expected, and only one outline contour after combining areas - else - { - area_to_combine->m_Poly->RemoveAllContours(); - keep_area_to_combine = true; - - // create area with external contour: Recreate only area edges, NOT holes (todo..) - { - // foreach point in the polygon - bool first = true; - while( booleng->PolygonHasMorePoints() ) - { - int x = booleng->GetPolygonXPoint(); - int y = booleng->GetPolygonYPoint(); - - if( first ) - { - first = false; - area_to_combine->m_Poly->Start( area_ref->GetLayer(), x, y, - area_ref->m_Poly->GetHatchStyle() ); - } - else - { - area_to_combine->m_Poly->AppendCorner( x, y ); - } - } - - booleng->EndPolygonGet(); - area_to_combine->m_Poly->Close(); - } - } -#endif - - // 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->Close(); - booleng->EndPolygonGet(); - } if( !keep_area_to_combine ) 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->RestoreArcs( &arc_array1 ); +// area_ref->m_Poly->RestoreArcs( &arc_array2 ); area_ref->m_Poly->Hatch(); - delete booleng; + return 1; } @@ -1024,7 +966,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E } // now test spacing between areas - for( int icont = 0; icont < refSmoothedPoly->GetNumContours(); icont++ ) + for( int icont = 0; icont < refSmoothedPoly->GetContoursCount(); icont++ ) { int ic_start = refSmoothedPoly->GetContourStart( icont ); int ic_end = refSmoothedPoly->GetContourEnd( icont ); @@ -1048,7 +990,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E int astyle = refSmoothedPoly->GetSideStyle( ic ); - for( int icont2 = 0; icont2 < testSmoothedPoly->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < testSmoothedPoly->GetContoursCount(); icont2++ ) { int ic_start2 = testSmoothedPoly->GetContourStart( icont2 ); int ic_end2 = testSmoothedPoly->GetContourEnd( icont2 ); @@ -1128,7 +1070,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) wxPoint end; // Search the end point of the edge starting at aCornerIndex - if( aArea->m_Poly->corner[aCornerIndex].end_contour == false + if( aArea->m_Poly->m_CornersList[aCornerIndex].end_contour == false && aCornerIndex < (aArea->GetNumCorners() - 1) ) { end = aArea->GetCornerPosition( aCornerIndex + 1 ); @@ -1141,7 +1083,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) while( ii >= 0 ) { - if( aArea->m_Poly->corner[ii].end_contour ) + if( aArea->m_Poly->m_CornersList[ii].end_contour ) break; end = aArea->GetCornerPosition( ii ); @@ -1189,7 +1131,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) int ax2 = end.x; int ay2 = end.y; - for( int icont2 = 0; icont2 < area_to_test->m_Poly->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < area_to_test->m_Poly->GetContoursCount(); icont2++ ) { int ic_start2 = area_to_test->m_Poly->GetContourStart( icont2 ); int ic_end2 = area_to_test->m_Poly->GetContourEnd( icont2 ); diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 4630e9dbbc..57d6190edf 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -16,10 +16,10 @@ CPolyLine::CPolyLine() { - m_hatchStyle = NO_HATCH; - m_hatchPitch = 0; - m_Width = 0; - utility = 0; + m_hatchStyle = NO_HATCH; + m_hatchPitch = 0; + m_width = 0; + m_utility = 0; m_Kbool_Poly_Engine = NULL; } @@ -29,11 +29,23 @@ CPolyLine::CPolyLine() CPolyLine::~CPolyLine() { UnHatch(); + if( m_Kbool_Poly_Engine ) delete m_Kbool_Poly_Engine; } +/** + * Function armBoolEng + * Initialise parameters used in kbool + * @param aBooleng = pointer to the Bool_Engine to initialise + * @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) + */ +static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); + /** * Function NormalizeWithKbool * Use the Kbool Library to clip contours: if outlines are crossing, the self-crossing polygon @@ -46,11 +58,11 @@ CPolyLine::~CPolyLine() * @param bRetainArcs == true, try to retain arcs in polys * @return number of external contours, or -1 if error */ -int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, bool bRetainArcs ) +int CPolyLine::NormalizeWithKbool( std::vector* aExtraPolyList, bool bRetainArcs ) { std::vector arc_array; std::vector hole_array; // list of holes - std::vector * hole; // used to store corners for a given hole + std::vector* hole; // used to store corners for a given hole CPolyLine* polyline; int n_ext_cont = 0; // CPolyLine count @@ -61,9 +73,9 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo * True holes are combined if possible */ if( bRetainArcs ) - MakeKboolPoly( -1, -1, &arc_array ); + MakeKboolPoly( &arc_array ); else - MakeKboolPoly( -1, -1, NULL ); + MakeKboolPoly( NULL ); UnHatch(); @@ -82,10 +94,11 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo { hole = new std::vector; hole_array.push_back( hole ); + while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) // store hole { - int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); hole->push_back( x ); hole->push_back( y ); } @@ -95,14 +108,16 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo else if( n_ext_cont == 0 ) { // first external contour, replace this poly - corner.clear(); - side_style.clear(); + m_CornersList.clear(); + m_SideStyle.clear(); bool first = true; + while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) { // foreach point in the polygon - int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); - int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); + if( first ) { first = false; @@ -121,10 +136,12 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo polyline = new CPolyLine; // create new poly aExtraPolyList->push_back( polyline ); // put it in array bool first = true; + 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(); + int x = (int) m_Kbool_Poly_Engine->GetPolygonXPoint(); + int y = (int) m_Kbool_Poly_Engine->GetPolygonYPoint(); + if( first ) { first = false; @@ -143,8 +160,9 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo // now add cutouts to the corresponding CPolyLine(s) for( unsigned ii = 0; ii < hole_array.size(); ii++ ) { - hole = (std::vector *)hole_array[ii]; - polyline = NULL; + hole = (std::vector*)hole_array[ii]; + polyline = NULL; + if( n_ext_cont == 1 ) { polyline = this; @@ -154,8 +172,9 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo // find the polygon that contains this hole // testing one corner inside is enought because a hole is entirely inside the polygon // so we test only the first corner - int x = (*hole)[0]; - int y = (*hole)[1]; + int x = (*hole)[0]; + int y = (*hole)[1]; + if( TestPointInside( x, y ) ) polyline = this; else if( aExtraPolyList ) @@ -177,8 +196,8 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo { for( unsigned ii = 0; ii< (*hole).size(); ii++ ) { - int x = (*hole)[ii]; ii++; - int y = (*hole)[ii]; + int x = (*hole)[ii]; ii++; + int y = (*hole)[ii]; polyline->AppendCorner( x, y, STRAIGHT, false ); } @@ -194,76 +213,21 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo // free hole list for( unsigned ii = 0; ii < hole_array.size(); ii++ ) - delete (std::vector *)hole_array[ii]; + delete (std::vector*)hole_array[ii]; 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 * 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 * fill a kbool engine with a closed polyline contour * 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 * @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 */ -int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector * arc_array, - bool aConvertHoles ) +int CPolyLine::MakeKboolPoly( std::vector* arc_array ) { if( m_Kbool_Poly_Engine ) { @@ -271,65 +235,40 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< m_Kbool_Poly_Engine = NULL; } - int polycount = GetNumContours(); - - if( !GetClosed() && (aStart_contour == (polycount - 1) || aStart_contour == -1) ) + if( !GetClosed() ) return 1; // error 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 ) arc_array->clear(); + 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, // and combine it with previous contours Bool_Engine* booleng = new Bool_Engine(); - ArmBoolEng( booleng, aConvertHoles ); - - 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(); - } - } + armBoolEng( booleng, false ); // first, calculate number of vertices in contour int n_vertices = 0; - int ic_st = GetContourStart( icont ); - int ic_end = GetContourEnd( icont ); + int ic_st = GetContourStart( icont ); + int ic_end = GetContourEnd( icont ); + if( !booleng->StartPolygonAdd( GROUP_B ) ) { wxASSERT( 0 ); - return 1; //error + return 1; // error } + for( int ic = ic_st; ic<=ic_end; ic++ ) { - int style = side_style[ic]; + int style = m_SideStyle[ic]; + if( style == STRAIGHT ) n_vertices++; else @@ -343,22 +282,25 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< // now enter this contour to booleng int ivtx = 0; + for( int ic = ic_st; ic<=ic_end; ic++ ) { - int style = side_style[ic]; - int x1 = corner[ic].x; - int y1 = corner[ic].y; + int style = m_SideStyle[ic]; + int x1 = m_CornersList[ic].x; + int y1 = m_CornersList[ic].y; int x2, y2; + if( ic < ic_end ) { - x2 = corner[ic + 1].x; - y2 = corner[ic + 1].y; + x2 = m_CornersList[ic + 1].x; + y2 = m_CornersList[ic + 1].y; } else { - x2 = corner[ic_st].x; - y2 = corner[ic_st].y; + x2 = m_CornersList[ic_st].x; + y2 = m_CornersList[ic_st].y; } + if( style == STRAIGHT ) { booleng->AddPoint( x1, y1 ); @@ -367,44 +309,45 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< else { // style is arc_cw or arc_ccw - int n; // number of steps for arcs + int n; // number of steps for arcs n = CArc::ARC_STEPS; - double xo, yo, theta1, theta2, a, b; - a = fabs( (double) (x1 - x2) ); - b = fabs( (double) (y1 - y2) ); + double xo, yo, theta1, theta2, a, b; + a = fabs( (double) (x1 - x2) ); + b = fabs( (double) (y1 - y2) ); + if( style == CPolyLine::ARC_CW ) { // clockwise arc (ie.quadrant of ellipse) if( x2 > x1 && y2 > y1 ) { // first quadrant, draw second quadrant of ellipse - xo = x2; - yo = y1; - theta1 = M_PI; - theta2 = M_PI / 2.0; + xo = x2; + yo = y1; + theta1 = M_PI; + theta2 = M_PI / 2.0; } else if( x2 < x1 && y2 > y1 ) { // second quadrant, draw third quadrant of ellipse - xo = x1; - yo = y2; - theta1 = 3.0 * M_PI / 2.0; - theta2 = M_PI; + xo = x1; + yo = y2; + theta1 = 3.0 * M_PI / 2.0; + theta2 = M_PI; } else if( x2 < x1 && y2 < y1 ) { // third quadrant, draw fourth quadrant of ellipse - xo = x2; - yo = y1; - theta1 = 2.0 * M_PI; - theta2 = 3.0 * M_PI / 2.0; + xo = x2; + yo = y1; + theta1 = 2.0 * M_PI; + theta2 = 3.0 * M_PI / 2.0; } else { - xo = x1; // fourth quadrant, draw first quadrant of ellipse - yo = y2; - theta1 = M_PI / 2.0; - theta2 = 0.0; + xo = x1; // fourth quadrant, draw first quadrant of ellipse + yo = y2; + theta1 = M_PI / 2.0; + theta2 = 0.0; } } else @@ -412,31 +355,31 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< // counter-clockwise arc if( x2 > x1 && y2 > y1 ) { - xo = x1; // first quadrant, draw fourth quadrant of ellipse - yo = y2; - theta1 = 3.0 * M_PI / 2.0; - theta2 = 2.0 * M_PI; + xo = x1; // first quadrant, draw fourth quadrant of ellipse + yo = y2; + theta1 = 3.0 * M_PI / 2.0; + theta2 = 2.0 * M_PI; } else if( x2 < x1 && y2 > y1 ) { - xo = x2; // second quadrant - yo = y1; - theta1 = 0.0; - theta2 = M_PI / 2.0; + xo = x2; // second quadrant + yo = y1; + theta1 = 0.0; + theta2 = M_PI / 2.0; } else if( x2 < x1 && y2 < y1 ) { - xo = x1; // third quadrant - yo = y2; - theta1 = M_PI / 2.0; - theta2 = M_PI; + xo = x1; // third quadrant + yo = y2; + theta1 = M_PI / 2.0; + theta2 = M_PI; } else { - xo = x2; // fourth quadrant - yo = y1; - theta1 = M_PI; - theta2 = 3.0 * M_PI / 2.0; + xo = x2; // fourth quadrant + yo = y1; + theta1 = M_PI; + theta2 = 3.0 * M_PI / 2.0; } } @@ -446,23 +389,26 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< CArc new_arc; new_arc.style = style; new_arc.n_steps = n; - new_arc.xi = x1; - new_arc.yi = y1; - new_arc.xf = x2; - new_arc.yf = y2; + new_arc.xi = x1; + new_arc.yi = y1; + new_arc.xf = x2; + new_arc.yf = y2; arc_array->push_back( new_arc ); iarc++; } + for( int is = 0; isAddPoint( x, y ); ivtx++; } @@ -474,7 +420,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< wxASSERT( 0 ); } - // close list added to the bool engine + // close list added to the bool engine booleng->EndPolygonAdd(); /* now combine polygon to the previous polygons. @@ -484,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 * 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 ); } @@ -496,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) if( m_Kbool_Poly_Engine ) delete m_Kbool_Poly_Engine; + m_Kbool_Poly_Engine = booleng; } @@ -504,69 +451,70 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< /** - * Function ArmBoolEng + * Function armBoolEng * Initialise parameters used in kbool * @param aBooleng = pointer to the Bool_Engine to initialise * @param aConvertHoles = mode for holes when a boolean operation is made * true: in resulting polygon, holes are linked into outer contours by double overlapping segments * false: in resulting polygons, holes are not linked: they are separate polygons */ -void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) +void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) { // set some global vals to arm the boolean engine // input points are scaled up with GetDGrid() * GetGrid() // 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. - 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 - everything smaller than 1/DGrid is rounded. + /* + * 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. + * The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid + * everything smaller than 1/DGrid is rounded. + * + * 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. + * 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 + * 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) + // kbool uses DGRID to convert float user units to integer + // kbool unit = (int)(user unit * DGRID) + // Note: in kicad, coordinates are already integer so DGRID could be set to 1 + // we can choose 1.0, + // but choose DGRID = 1000.0 solves some filling problems +// (perhaps because this allows a better precision in kbool internal calculations - 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. - 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 - 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) - // kbool uses DGRID to convert float user units to integer - // kbool unit = (int)(user unit * DGRID) - // Note: in kicad, coordinates are already integer so DGRID could be set to 1 - // we can choose 1.0, - // but choose DGRID = 1000.0 solves some filling problems -// (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 - // should always be >= 1/DGRID a MARGE >= 10/DGRID is ok - // this is also used to remove small segments and to decide when - // two segments are in line. ( initial value = 0.001 ) - // For kicad we choose MARGE = 1/DGRID + 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 + // this is also used to remove small segments and to decide when + // two segments are in line. ( initial value = 0.001 ) + // For kicad we choose MARGE = 1/DGRID double CORRECTIONFACTOR = 0.0; // correct the polygons by this number: used in BOOL_CORRECTION operation // this operation shrinks a polygon if CORRECTIONFACTOR < 0 // or stretch it if CORRECTIONFACTOR > 0 // the size change is CORRECTIONFACTOR (holes are correctly handled) - double CORRECTIONABER = 1.0; // the accuracy for the rounded shapes used in correction - double ROUNDFACTOR = 1.5; // when will we round the correction shape to a circle - double SMOOTHABER = 10.0; // accuracy when smoothing a polygon - double MAXLINEMERGE = 1000.0; // leave as is, segments of this length in smoothen + double CORRECTIONABER = 1.0; // the accuracy for the rounded shapes used in correction + double ROUNDFACTOR = 1.5; // when will we round the correction shape to a circle + double SMOOTHABER = 10.0; // accuracy when smoothing a polygon + double MAXLINEMERGE = 1000.0; // leave as is, segments of this length in smoothen - /* - 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. - 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 - even smaller numbers. - */ - int GRID = (int) ( 10000.0 / DGRID ); // initial value = 10000 in kbool example but we use - // 10000/DGRID because the scaling is made by DGRID - // on integer pcbnew units and the global scaling - // ( GRID*DGRID) must be < 30000 to avoid overflow - // in calculations (made in long long in kbool) - if ( GRID <= 1 ) // Cannot be null! + /* + * 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. + * 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 + * even smaller numbers. + */ + int GRID = (int) ( 10000.0 / DGRID ); // initial value = 10000 in kbool example but we use + + // 10000/DGRID because the scaling is made by DGRID + // on integer pcbnew units and the global scaling + // ( GRID*DGRID) must be < 30000 to avoid overflow + // in calculations (made in long long in kbool) + if( GRID <= 1 ) // Cannot be null! GRID = 1; aBooleng->SetMarge( MARGE ); @@ -581,9 +529,9 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) if( aConvertHoles ) { -#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions - // SetAllowNonTopHoleLinking() exists only in kbool >= 2.1 - aBooleng->SetAllowNonTopHoleLinking( false ); // Default = true, but i have problems (filling errors) when true +#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions + // SetAllowNonTopHoleLinking() exists only in kbool >= 2.1 + aBooleng->SetAllowNonTopHoleLinking( false ); // Default = true, but i have problems (filling errors) when true #endif aBooleng->SetLinkHoles( true ); // holes will be connected by double overlapping segments aBooleng->SetOrientationEntryMode( false ); // all polygons are contours, not holes @@ -596,7 +544,7 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) } -int CPolyLine::NormalizeAreaOutlines( std::vector * pa, bool bRetainArcs ) +int CPolyLine::NormalizeAreaOutlines( std::vector* pa, bool bRetainArcs ) { return NormalizeWithKbool( pa, bRetainArcs ); } @@ -605,33 +553,37 @@ int CPolyLine::NormalizeAreaOutlines( std::vector * pa, bool bRetain // Restore arcs to a polygon where they were replaced with steps // If pa != NULL, also use polygons in pa array // -int CPolyLine::RestoreArcs( std::vector * arc_array, std::vector * pa ) +int CPolyLine::RestoreArcs( std::vector* arc_array, std::vector* pa ) { // get poly info int n_polys = 1; if( pa ) n_polys += pa->size(); + CPolyLine* poly; - // undraw polys and clear utility flag for all corners + // undraw polys and clear m_utility flag for all corners for( int ip = 0; ipUnHatch(); + for( int ic = 0; icGetNumCorners(); ic++ ) poly->SetUtility( ic, 0 ); - // clear utility flag + // clear m_utility flag } // find arcs and replace them - bool bFound; - int arc_start = 0; - int arc_end = 0; + bool bFound; + int arc_start = 0; + int arc_end = 0; + for( unsigned iarc = 0; iarcsize(); iarc++ ) { int arc_xi = (*arc_array)[iarc].xi; @@ -649,62 +601,77 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vectorGetNumContours(); + + int polycount = poly->GetContoursCount(); + for( int icont = 0; icont < polycount; icont++ ) { - int ic_start = poly->GetContourStart( icont ); - int ic_end = poly->GetContourEnd( icont ); + int ic_start = poly->GetContourStart( icont ); + int ic_end = poly->GetContourEnd( icont ); + if( (ic_end - ic_start) > n_steps ) { for( int ic = ic_start; ic<=ic_end; ic++ ) { int ic_next = ic + 1; + if( ic_next > ic_end ) ic_next = ic_start; - int xi = poly->GetX( ic ); - int yi = poly->GetY( ic ); + + int xi = poly->GetX( ic ); + int yi = poly->GetY( ic ); + if( xi == arc_xi && yi == arc_yi ) { // test for forward arc int ic2 = ic + n_steps; + if( ic2 > ic_end ) ic2 = ic2 - ic_end + ic_start - 1; - int xf = poly->GetX( ic2 ); - int yf = poly->GetY( ic2 ); + + int xf = poly->GetX( ic2 ); + int yf = poly->GetY( ic2 ); + if( xf == arc_xf && yf == arc_yf ) { // arc from ic to ic2 - bFound = true; - arc_start = ic; - arc_end = ic2; + bFound = true; + arc_start = ic; + arc_end = ic2; } else { // try reverse arc ic2 = ic - n_steps; + if( ic2 < ic_start ) ic2 = ic2 - ic_start + ic_end + 1; - xf = poly->GetX( ic2 ); - yf = poly->GetY( ic2 ); + + xf = poly->GetX( ic2 ); + yf = poly->GetY( ic2 ); + if( xf == arc_xf && yf == arc_yf ) { // arc from ic2 to ic - bFound = true; - arc_start = ic2; - arc_end = ic; - style = 3 - style; + bFound = true; + arc_start = ic2; + arc_end = ic; + style = 3 - style; } } + if( bFound ) { - poly->side_style[arc_start] = style; + poly->m_SideStyle[arc_start] = style; // mark corners for deletion from arc_start+1 to arc_end-1 for( int i = arc_start + 1; i!=arc_end; ) { if( i > ic_end ) i = ic_start; + poly->SetUtility( i, 1 ); + if( i == ic_end ) i = ic_start; else @@ -714,10 +681,12 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vector * arc_array, std::vectorGetNumCorners() - 1; ic>=0; ic-- ) { if( poly->GetUtility( ic ) ) @@ -751,26 +721,26 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vector 0 && !corner[corner.size() - 1].end_contour ) - side_style[corner.size() - 1] = style; + m_CornersList.push_back( poly_pt ); + m_SideStyle.push_back( style ); + + if( m_CornersList.size() > 0 && !m_CornersList[m_CornersList.size() - 1].end_contour ) + m_SideStyle[m_CornersList.size() - 1] = style; + if( bDraw ) Hatch(); } @@ -800,9 +772,11 @@ void CPolyLine::Close( int style, bool bDraw ) { wxASSERT( 0 ); } + UnHatch(); - side_style[corner.size() - 1] = style; - corner[corner.size() - 1].end_contour = true; + m_SideStyle[m_CornersList.size() - 1] = style; + m_CornersList[m_CornersList.size() - 1].end_contour = true; + if( bDraw ) Hatch(); } @@ -813,8 +787,8 @@ void CPolyLine::Close( int style, bool bDraw ) void CPolyLine::MoveCorner( int ic, int x, int y ) { UnHatch(); - corner[ic].x = x; - corner[ic].y = y; + m_CornersList[ic].x = x; + m_CornersList[ic].y = y; Hatch(); } @@ -824,32 +798,35 @@ void CPolyLine::MoveCorner( int ic, int x, int y ) void CPolyLine::DeleteCorner( int ic, bool bDraw ) { UnHatch(); - int icont = GetContour( ic ); - int istart = GetContourStart( icont ); - int iend = GetContourEnd( icont ); - bool bClosed = icont < GetNumContours() - 1 || GetClosed(); + int icont = GetContour( ic ); + int istart = GetContourStart( icont ); + int iend = GetContourEnd( icont ); + bool bClosed = icont < GetContoursCount() - 1 || GetClosed(); if( !bClosed ) { // open contour, must be last contour - corner.erase( corner.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); if( ic != istart ) - side_style.erase( side_style.begin() + ic - 1 ); + m_SideStyle.erase( m_SideStyle.begin() + ic - 1 ); } else { // closed contour - corner.erase( corner.begin() + ic ); - side_style.erase( side_style.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); + m_SideStyle.erase( m_SideStyle.begin() + ic ); + if( ic == iend ) - corner[ic - 1].end_contour = true; + m_CornersList[ic - 1].end_contour = true; } + if( bClosed && GetContourSize( icont ) < 3 ) { // delete the entire contour RemoveContour( icont ); } + if( bDraw ) Hatch(); } @@ -866,10 +843,11 @@ void CPolyLine::RemoveContour( int icont ) */ { UnHatch(); - int istart = GetContourStart( icont ); - int iend = GetContourEnd( icont ); + int istart = GetContourStart( icont ); + int iend = GetContourEnd( icont ); + + int polycount = GetContoursCount(); - int polycount = GetNumContours(); if( icont == 0 && polycount == 1 ) { // remove the only contour @@ -878,18 +856,19 @@ void CPolyLine::RemoveContour( int icont ) else if( icont == polycount - 1 ) { // remove last contour - corner.erase( corner.begin() + istart, corner.end() ); - side_style.erase( side_style.begin() + istart, side_style.end() ); + m_CornersList.erase( m_CornersList.begin() + istart, m_CornersList.end() ); + m_SideStyle.erase( m_SideStyle.begin() + istart, m_SideStyle.end() ); } else { // remove closed contour for( int ic = iend; ic>=istart; ic-- ) { - corner.erase( corner.begin() + ic ); - side_style.erase( side_style.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); + m_SideStyle.erase( m_SideStyle.begin() + ic ); } } + Hatch(); } @@ -904,65 +883,67 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) return newPoly; } - int polycount = GetNumContours(); + int polycount = GetContoursCount(); + for( int contour = 0; contour < polycount; contour++ ) { - unsigned int startIndex = GetContourStart( contour ); - unsigned int endIndex = GetContourEnd( contour ); + unsigned int startIndex = GetContourStart( contour ); + unsigned int endIndex = GetContourEnd( contour ); for( unsigned int index = startIndex; index <= endIndex; index++ ) { - int x1, y1, nx, ny; - long long xa, ya, xb, yb; + int x1, y1, nx, ny; + long long xa, ya, xb, yb; - x1 = corner[index].x; - y1 = corner[index].y; + x1 = m_CornersList[index].x; + y1 = m_CornersList[index].y; if( index == startIndex ) { - xa = corner[endIndex].x - x1; - ya = corner[endIndex].y - y1; + xa = m_CornersList[endIndex].x - x1; + ya = m_CornersList[endIndex].y - y1; } else { - xa = corner[index-1].x - x1; - ya = corner[index-1].y - y1; + xa = m_CornersList[index - 1].x - x1; + ya = m_CornersList[index - 1].y - y1; } if( index == endIndex ) { - xb = corner[startIndex].x - x1; - yb = corner[startIndex].y - y1; + xb = m_CornersList[startIndex].x - x1; + yb = m_CornersList[startIndex].y - y1; } else { - xb = corner[index+1].x - x1; - yb = corner[index+1].y - y1; + xb = m_CornersList[index + 1].x - x1; + yb = m_CornersList[index + 1].y - y1; } - unsigned int lena = (unsigned int)sqrt( (double)(xa*xa + ya*ya) ); - unsigned int lenb = (unsigned int)sqrt( (double)(xb*xb + yb*yb) ); - unsigned int distance = aDistance; + unsigned int lena = (unsigned int) sqrt( (double) (xa * xa + ya * ya) ); + unsigned int lenb = (unsigned int) sqrt( (double) (xb * xb + yb * yb) ); + unsigned int distance = aDistance; // Chamfer one half of an edge at most - if( 0.5*lena < distance ) - distance = (unsigned int)(0.5*(double)lena); + if( 0.5 * lena < distance ) + distance = (unsigned int) (0.5 * (double) lena); - if( 0.5*lenb < distance ) - distance = (unsigned int)(0.5*(double)lenb); + if( 0.5 * lenb < distance ) + distance = (unsigned int) (0.5 * (double) lenb); - nx = (int) ( (double) (distance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); - ny = (int) ( (double) (distance*ya)/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) ) ); if( index == startIndex ) newPoly->Start( GetLayer(), x1 + nx, y1 + ny, GetHatchStyle() ); else newPoly->AppendCorner( x1 + nx, y1 + ny ); - nx = (int) ( (double) (distance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); - ny = (int) ( (double) (distance*yb)/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) ) ); newPoly->AppendCorner( x1 + nx, y1 + ny ); } + newPoly->Close(); } @@ -980,115 +961,120 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) return newPoly; } - int polycount = GetNumContours(); + int polycount = GetContoursCount(); + for( int contour = 0; contour < polycount; contour++ ) { - unsigned int startIndex = GetContourStart( contour ); - unsigned int endIndex = GetContourEnd( contour ); + unsigned int startIndex = GetContourStart( contour ); + unsigned int endIndex = GetContourEnd( contour ); for( unsigned int index = startIndex; index <= endIndex; index++ ) { + int x1, y1; // Current vertex + long long xa, ya; // Previous vertex + long long xb, yb; // Next vertex + double nx, ny; - int x1, y1; // Current vertex - long long xa, ya; // Previous vertex - long long xb, yb; // Next vertex - double nx, ny; - - x1 = corner[index].x; - y1 = corner[index].y; + x1 = m_CornersList[index].x; + y1 = m_CornersList[index].y; if( index == startIndex ) { - xa = corner[endIndex].x - x1; - ya = corner[endIndex].y - y1; + xa = m_CornersList[endIndex].x - x1; + ya = m_CornersList[endIndex].y - y1; } else { - xa = corner[index-1].x - x1; - ya = corner[index-1].y - y1; + xa = m_CornersList[index - 1].x - x1; + ya = m_CornersList[index - 1].y - y1; } if( index == endIndex ) { - xb = corner[startIndex].x - x1; - yb = corner[startIndex].y - y1; + xb = m_CornersList[startIndex].x - x1; + yb = m_CornersList[startIndex].y - y1; } else { - xb = corner[index+1].x - x1; - yb = corner[index+1].y - y1; + xb = m_CornersList[index + 1].x - x1; + yb = m_CornersList[index + 1].y - y1; } - double lena = sqrt( (double) (xa*xa + ya*ya) ); - double lenb = sqrt( (double) (xb*xb + yb*yb) ); - double cosine = ( xa*xb + ya*yb )/( lena*lenb ); + double lena = sqrt( (double) (xa * xa + ya * ya) ); + double lenb = sqrt( (double) (xb * xb + yb * yb) ); + double cosine = ( xa * xb + ya * yb ) / ( lena * lenb ); - unsigned int radius = aRadius; - double denom = sqrt( 2.0/( 1+cosine )-1 ); + unsigned int radius = aRadius; + double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 ); // Limit rounding distance to one half of an edge - if( 0.5*lena*denom < radius ) - radius = (unsigned int)(0.5*lena*denom); + if( 0.5 * lena * denom < radius ) + radius = (unsigned int) (0.5 * lena * denom); - if( 0.5*lenb*denom < radius ) - radius = (unsigned int)(0.5*lenb*denom); + if( 0.5 * lenb * denom < radius ) + radius = (unsigned int) (0.5 * lenb * denom); // Calculate fillet arc absolute center point (xc, yx) - double k = radius / sqrt( .5*( 1-cosine ) ); - double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + - ( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); - double xc = x1 + k*( xa/lena + xb/lenb )/lenab; - double yc = y1 + k*( ya/lena + yb/lenb )/lenab; + double k = radius / sqrt( .5 * ( 1 - cosine ) ); + double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) + + ( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) ); + double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab; + double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab; // Calculate arc start and end vectors - k = radius / sqrt( 2/( 1+cosine )-1 ); - double xs = x1 + k*xa/lena - xc; - double ys = y1 + k*ya/lena - yc; - double xe = x1 + k*xb/lenb - xc; - double ye = y1 + k*yb/lenb - yc; + k = radius / sqrt( 2 / ( 1 + cosine ) - 1 ); + double xs = x1 + k * xa / lena - xc; + double ys = y1 + k * ya / lena - yc; + double xe = x1 + k * xb / lenb - xc; + double ye = y1 + k * yb / lenb - yc; // 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... argument = -1; else if( argument > 1 ) argument = 1; - double arcAngle = acos( argument ); + double arcAngle = acos( argument ); // 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++; - unsigned int segments = (unsigned int) tempSegments; - double deltaAngle = arcAngle / segments; - double startAngle = atan2( -ys, xs ); + unsigned int segments = (unsigned int) tempSegments; + + double deltaAngle = arcAngle / segments; + double startAngle = atan2( -ys, xs ); // Flip arc for inner corners - if( xa*yb - ya*xb <= 0 ) + if( xa * yb - ya * xb <= 0 ) deltaAngle *= -1; - nx = xc + xs + 0.5; - ny = yc + ys + 0.5; + nx = xc + xs + 0.5; + ny = yc + ys + 0.5; + if( index == startIndex ) - newPoly->Start( GetLayer(), (int)nx, (int)ny, GetHatchStyle() ); + newPoly->Start( GetLayer(), (int) nx, (int) ny, GetHatchStyle() ); else - newPoly->AppendCorner( (int)nx, (int)ny ); + newPoly->AppendCorner( (int) nx, (int) ny ); unsigned int nVertices = 0; + for( unsigned int j = 0; j < segments; j++ ) { - nx = xc + cos( startAngle + (j+1)*deltaAngle )*radius + 0.5; - ny = yc - sin( startAngle + (j+1)*deltaAngle )*radius + 0.5; - newPoly->AppendCorner( (int)nx, (int)ny ); + nx = xc + cos( startAngle + (j + 1) * deltaAngle ) * radius + 0.5; + ny = yc - sin( startAngle + (j + 1) * deltaAngle ) * radius + 0.5; + newPoly->AppendCorner( (int) nx, (int) ny ); nVertices++; } } + newPoly->Close(); } + return newPoly; } @@ -1103,8 +1089,8 @@ void CPolyLine::RemoveAllContours( void ) * Others params are not chnaged */ { - corner.clear(); - side_style.clear(); + m_CornersList.clear(); + m_SideStyle.clear(); } @@ -1117,25 +1103,27 @@ void CPolyLine::RemoveAllContours( void ) void CPolyLine::InsertCorner( int ic, int x, int y ) { UnHatch(); - if( (unsigned) (ic) >= corner.size() ) + + if( (unsigned) (ic) >= m_CornersList.size() ) { - corner.push_back( CPolyPt( x, y ) ); - side_style.push_back( STRAIGHT ); + m_CornersList.push_back( CPolyPt( x, y ) ); + m_SideStyle.push_back( STRAIGHT ); } else { - corner.insert( corner.begin() + ic + 1, CPolyPt( x, y ) ); - side_style.insert( side_style.begin() + ic + 1, STRAIGHT ); + m_CornersList.insert( m_CornersList.begin() + ic + 1, CPolyPt( x, y ) ); + m_SideStyle.insert( m_SideStyle.begin() + ic + 1, STRAIGHT ); } - if( (unsigned) (ic + 1) < corner.size() ) + if( (unsigned) (ic + 1) < m_CornersList.size() ) { - if( corner[ic].end_contour ) + if( m_CornersList[ic].end_contour ) { - corner[ic + 1].end_contour = true; - corner[ic].end_contour = false; + m_CornersList[ic + 1].end_contour = true; + m_CornersList[ic].end_contour = false; } } + Hatch(); } @@ -1150,7 +1138,7 @@ void CPolyLine::UnHatch() int CPolyLine::GetEndContour( int ic ) { - return corner[ic].end_contour; + return m_CornersList[ic].end_contour; } @@ -1158,10 +1146,10 @@ CRect CPolyLine::GetBounds() { CRect r = GetCornerBounds(); - r.left -= m_Width / 2; - r.right += m_Width / 2; - r.bottom -= m_Width / 2; - r.top += m_Width / 2; + r.left -= m_width / 2; + r.right += m_width / 2; + r.bottom -= m_width / 2; + r.top += m_width / 2; return r; } @@ -1172,12 +1160,13 @@ CRect CPolyLine::GetCornerBounds() r.left = r.bottom = INT_MAX; r.right = r.top = INT_MIN; - for( unsigned i = 0; i max_x ) - max_x = corner[ic].x; - if( corner[ic].y < min_y ) - min_y = corner[ic].y; - if( corner[ic].y > max_y ) - max_y = corner[ic].y; + if( m_CornersList[ic].x < min_x ) + min_x = m_CornersList[ic].x; + + if( m_CornersList[ic].x > max_x ) + max_x = m_CornersList[ic].x; + + if( m_CornersList[ic].y < min_y ) + min_y = m_CornersList[ic].y; + + if( m_CornersList[ic].y > max_y ) + max_y = m_CornersList[ic].y; } // Calculate spacing betwwen 2 hatch lines - int spacing; + int spacing; + if( m_hatchStyle == DIAGONAL_EDGE ) spacing = m_hatchPitch; else spacing = m_hatchPitch * 2; // set the "lenght" of hatch lines (the lenght on horizontal axis) - double hatch_line_len = m_hatchPitch; + double hatch_line_len = m_hatchPitch; // To have a better look, give a slope depending on the layer - int layer = GetLayer(); - int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1 - double slope = 0.707106 * slope_flag; // 45 degrees slope - int max_a, min_a; + int layer = GetLayer(); + int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1 + double slope = 0.707106 * slope_flag; // 45 degrees slope + int max_a, min_a; + if( slope_flag == 1 ) { - max_a = (int) (max_y - slope * min_x); - min_a = (int) (min_y - slope * max_x); + max_a = (int) (max_y - slope * min_x); + min_a = (int) (min_y - slope * max_x); } else { - max_a = (int) (max_y - slope * max_x); - min_a = (int) (min_y - slope * min_x); + max_a = (int) (max_y - slope * max_x); + min_a = (int) (min_y - slope * min_x); } + min_a = (min_a / spacing) * spacing; // calculate an offset depending on layer number, @@ -1409,7 +1418,7 @@ void CPolyLine::Hatch() min_a += offset; // now calculate and draw hatch lines - int nc = corner.size(); + int nc = m_CornersList.size(); // loop through hatch lines #define MAXPTS 200 // Usually we store only few values per one hatch line @@ -1417,7 +1426,7 @@ void CPolyLine::Hatch() static std::vector pointbuffer; pointbuffer.clear(); - pointbuffer.reserve(MAXPTS+2); + pointbuffer.reserve( MAXPTS + 2 ); for( int a = min_a; a < max_a; a += spacing ) { @@ -1429,38 +1438,43 @@ void CPolyLine::Hatch() // we skip this line (should not occur) pointbuffer.clear(); int i_start_contour = 0; + for( int ic = 0; ic= MAXPTS ) // overflow { wxASSERT( 0 ); @@ -1485,6 +1499,7 @@ void CPolyLine::Hatch() for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 ) { double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x; + // Push only one line for diagonal hatch, // or for small lines < twice the line len // else push 2 small lines @@ -1494,18 +1509,18 @@ void CPolyLine::Hatch() } else { - double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y; - double slope = dy / dx; + double dy = pointbuffer[ip + 1].y - pointbuffer[ip].y; + double slope = dy / dx; if( dx > 0 ) dx = hatch_line_len; else dx = -hatch_line_len; - double x1 = pointbuffer[ip].x + dx; - double x2 = pointbuffer[ip + 1].x - dx; - double y1 = pointbuffer[ip].y + dx * slope; - double y2 = pointbuffer[ip + 1].y - dx * slope; + double x1 = pointbuffer[ip].x + dx; + double x2 = pointbuffer[ip + 1].x - dx; + double y1 = pointbuffer[ip].y + dx * slope; + double y2 = pointbuffer[ip + 1].y - dx * slope; m_HatchLines.push_back( CSegment( pointbuffer[ip].x, pointbuffer[ip].y, @@ -1534,32 +1549,34 @@ bool CPolyLine::TestPointInside( int px, int py ) // if the tested point is inside only one contour, it is inside the whole polygon // (in fact inside the main outline, and outside all holes). // if inside 2 contours (the main outline + an hole), it is outside the poly. - int polycount = GetNumContours(); - bool inside = false; + int polycount = GetContoursCount(); + bool inside = false; + for( int icont = 0; icont < polycount; icont++ ) { - int istart = GetContourStart( icont ); - int iend = GetContourEnd( icont ); + int istart = GetContourStart( icont ); + int iend = GetContourEnd( icont ); // Test this polygon: - if( TestPointInsidePolygon( corner, 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; } return inside; } + // copy data from another poly, but don't draw it // void CPolyLine::Copy( CPolyLine* src ) { UnHatch(); - m_hatchStyle = src->m_hatchStyle; - m_hatchPitch = src->m_hatchPitch; + m_hatchStyle = src->m_hatchStyle; + m_hatchPitch = src->m_hatchPitch; // copy corners, using vector copy - corner = src->corner; + m_CornersList = src->m_CornersList; // copy side styles, using vector copy - side_style = src->side_style; + m_SideStyle = src->m_SideStyle; } @@ -1573,8 +1590,9 @@ bool CPolyLine::IsCutoutContour( int icont ) { int ncont = GetContour( 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 true; } @@ -1582,6 +1600,7 @@ bool CPolyLine::IsCutoutContour( int icont ) void CPolyLine::MoveOrigin( int x_off, int y_off ) { UnHatch(); + for( int ic = 0; ic < GetNumCorners(); ic++ ) { SetX( ic, GetX( ic ) + x_off ); @@ -1593,43 +1612,43 @@ void CPolyLine::MoveOrigin( int x_off, int y_off ) // Set various parameters: -// the calling function should UnHatch() before calling them, -// and Draw() after +// the calling function should UnHatch() before calling them, +// and Draw() after // void CPolyLine::SetX( int ic, int x ) { - corner[ic].x = x; + m_CornersList[ic].x = x; } void CPolyLine::SetY( int ic, int y ) { - corner[ic].y = y; + m_CornersList[ic].y = y; } void CPolyLine::SetEndContour( int ic, bool end_contour ) { - corner[ic].end_contour = end_contour; + m_CornersList[ic].end_contour = end_contour; } 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 r = sqrt( (double) (xi - xc) * (xi - xc) + (double) (yi - yc) * (yi - yc) ); // get angles of start and finish - double th_i = atan2( (double) (yi - yc), (double) (xi - xc) ); - double th_f = atan2( (double) (yf - yc), (double) (xf - xc) ); - double th_d = (th_f - th_i) / (num - 1); - double theta = th_i; + double th_i = atan2( (double) (yi - yc), (double) (xi - xc) ); + double th_f = atan2( (double) (yf - yc), (double) (xf - xc) ); + double th_d = (th_f - th_i) / (num - 1); + double theta = th_i; // generate arc for( int ic = 0; ic bezier_points; - 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); + 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 ); } -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 bezier_points; - 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); + 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 ); } @@ -1675,13 +1698,13 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) if( TestPointInside( aStart.x, aStart.y ) ) return 0; - int distance = INT_MAX; - int polycount = GetNumContours(); + int distance = INT_MAX; + int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { - int ic_start = GetContourStart( icont ); - int ic_end = GetContourEnd( icont ); + int ic_start = GetContourStart( icont ); + int ic_end = GetContourEnd( icont ); // now test spacing between area outline and segment for( int ic2 = ic_start; ic2 <= ic_end; ic2++ ) @@ -1705,10 +1728,12 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, bstyle, 0, aStart.x, aStart.y, aEnd.x, aEnd.y, CPolyLine::STRAIGHT, aWidth, - 1, // min clearance, should be > 0 + 1, // min clearance, should be > 0 NULL, NULL ); + if( distance > d ) distance = d; + if( distance <= 0 ) return 0; } @@ -1717,6 +1742,7 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) return distance; } + /* * Function Distance * Calculates the distance between a point and polygon (with holes): @@ -1731,13 +1757,13 @@ int CPolyLine::Distance( const wxPoint& aPoint ) if( TestPointInside( aPoint.x, aPoint.y ) ) return 0; - int distance = INT_MAX; - int polycount = GetNumContours(); + int distance = INT_MAX; + int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { - int ic_start = GetContourStart( icont ); - int ic_end = GetContourEnd( icont ); + int ic_start = GetContourStart( icont ); + int ic_end = GetContourEnd( icont ); // now test spacing between area outline and segment for( int ic2 = ic_start; ic2 <= ic_end; ic2++ ) @@ -1760,11 +1786,12 @@ int CPolyLine::Distance( const wxPoint& aPoint ) // Here we expect only straight lines for vertices // (no arcs, not yet supported in Pcbnew) int d = KiROUND( GetPointToLineSegmentDistance( aPoint.x, aPoint.y, - bx1, by1, bx2, by2 ) ); + bx1, by1, bx2, by2 ) ); if( distance > d ) distance = d; + if( distance <= 0 ) return 0; } @@ -1772,3 +1799,152 @@ int CPolyLine::Distance( const wxPoint& aPoint ) 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& aPolysList, + KI_POLYGON_WITH_HOLES& aPolygoneWithHole ) +{ + unsigned corners_count = aPolysList.size(); + + std::vector 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& aPolysListWithHoles, + std::vector& 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 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 ); + } +} diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index a27478dae4..4bf31a5213 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -19,11 +19,12 @@ #include #include -#include +#include // for wxPoint definition + +#include // inflection modes for DS_LINE and DS_LINE_VERTEX, used in math_for_graphics.cpp -enum -{ +enum { IM_NONE = 0, IM_90_45, IM_45_90, @@ -31,18 +32,6 @@ enum }; - -/** - * Function ArmBoolEng - * Initialise parameters used in kbool - * @param aBooleng = pointer to the Bool_Engine to initialise - * @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) - */ -void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); - class CRect { public: @@ -56,15 +45,16 @@ public: wxPoint m_End; CSegment() { }; - CSegment( const wxPoint & aStart, const wxPoint & aEnd ) + CSegment( const wxPoint& aStart, const wxPoint& aEnd ) { m_Start = aStart; - m_End = aEnd; + m_End = aEnd; } + CSegment( int x0, int y0, int x1, int y1 ) { - m_Start.x = x0; m_Start.y = y0; - m_End.x = x1; m_End.y = y1; + m_Start.x = x0; m_Start.y = y0; + m_End.x = x1; m_End.y = y1; } }; @@ -75,10 +65,10 @@ class CArc { public: enum { ARC_STEPS = 16 }; // arc approximation step is 16 segm / 90 degres - int style; - int xi, yi, xf, yf; - int n_steps; // number of straight-line segments in gpc_poly - bool bFound; + int style; + int xi, yi, xf, yf; + int n_steps; // number of straight-line segments in gpc_poly + bool bFound; }; @@ -86,27 +76,27 @@ class CPolyPt : public wxPoint { public: CPolyPt( int aX = 0, int aY = 0, bool aEnd = false, int aUtility = 0 ) : - wxPoint( aX, aY ), end_contour( aEnd ), utility( aUtility ) + wxPoint( aX, aY ), end_contour( aEnd ), m_utility( aUtility ) {} - /// Pure copy constructor is here to dis-ambiguate from the - /// specialized CPolyPt( const wxPoint& ) constructor version below. + // / Pure copy constructor is here to dis-ambiguate from the + // / specialized CPolyPt( const wxPoint& ) constructor version below. CPolyPt( const CPolyPt& aPt ) : - wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), utility( aPt.utility ) + wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), m_utility( aPt.m_utility ) {} CPolyPt( const wxPoint& aPoint ) : - wxPoint( aPoint ), end_contour( false ), utility( 0 ) + wxPoint( aPoint ), end_contour( false ), m_utility( 0 ) {} - bool end_contour; - int utility; + bool end_contour; + 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); } - bool operator != (CPolyPt& cpt2 ) const + bool operator !=( CPolyPt& cpt2 ) const { return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); } }; @@ -116,7 +106,7 @@ public: class CPolyLine { public: - enum side_style { STRAIGHT, ARC_CW, ARC_CCW }; // side styles + enum m_SideStyle { STRAIGHT, ARC_CW, ARC_CCW }; // side styles enum hatch_style { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles // constructors/destructor @@ -124,13 +114,13 @@ public: ~CPolyLine(); // functions for modifying polyline - void Start( int layer, int x, int y, int hatch ); - void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw = false ); - 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 RemoveContour( int icont ); + void Start( int layer, int x, int y, int hatch ); + void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw = false ); + 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 RemoveContour( int icont ); /** * Function Chamfer @@ -138,7 +128,7 @@ public: * @param aDistance is the chamfering distance. * @return CPolyLine* - Pointer to new polygon. */ - CPolyLine* Chamfer( unsigned int aDistance ); + CPolyLine* Chamfer( unsigned int aDistance ); /** * Function Fillet @@ -147,108 +137,88 @@ public: * @param aSegments is the number of segments / fillet. * @return CPolyLine* - Pointer to new polygon. */ - CPolyLine* Fillet( unsigned int aRadius, unsigned int aSegments ); + CPolyLine* Fillet( unsigned int aRadius, unsigned int aSegments ); - void RemoveAllContours( void ); + void RemoveAllContours( void ); // Remove or create hatch - void UnHatch(); - void Hatch(); + void UnHatch(); + void Hatch(); // Transform functions - void MoveOrigin( int x_off, int y_off ); + void MoveOrigin( int x_off, int y_off ); // misc. functions - CRect GetBounds(); - CRect GetCornerBounds(); - CRect GetCornerBounds( int icont ); - void Copy( CPolyLine* src ); - bool TestPointInside( int x, int y ); - bool IsCutoutContour( int icont ); - void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ); + CRect GetBounds(); + CRect GetCornerBounds(); + CRect GetCornerBounds( int icont ); + void Copy( CPolyLine* src ); + bool TestPointInside( int x, int y ); + bool IsCutoutContour( int icont ); + void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ); // access functions void SetLayer( int aLayer ) { m_layer = aLayer; } int GetLayer() { return m_layer; } - int GetNumCorners(); - int GetNumSides(); - int GetClosed(); - int GetNumContours(); - int GetContour( int ic ); - int GetContourStart( int icont ); - int GetContourEnd( int icont ); - int GetContourSize( int icont ); + int GetNumCorners(); + int GetNumSides(); + int GetClosed(); + int GetContoursCount(); + int GetContour( int ic ); + int GetContourStart( int icont ); + int GetContourEnd( int icont ); + int GetContourSize( int icont ); - int GetX( int ic ) const { return corner[ic].x; } - int GetY( int ic ) const { return corner[ic].y; } + int GetX( int ic ) const { return m_CornersList[ic].x; } + int GetY( int ic ) const { return m_CornersList[ic].y; } - const wxPoint& GetPos( int ic ) const { return corner[ic]; } + const wxPoint& GetPos( int ic ) const { return m_CornersList[ic]; } - int GetEndContour( int ic ); + int GetEndContour( int ic ); + + int GetUtility( int ic ) { return m_CornersList[ic].m_utility; }; + void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; }; + int GetSideStyle( int is ); - int GetUtility( int ic ) { return corner[ic].utility; }; - void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; - int GetSideStyle( int is ); 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 enum hatch_style GetHatchStyle() { return m_hatchStyle; } void SetHatch( int hatch, int pitch ) - { - SetHatchPitch( pitch ); - m_hatchStyle = (enum hatch_style ) hatch; - Hatch(); - } - void SetX( int ic, int x ); - void SetY( int ic, int y ); - void SetEndContour( int ic, bool end_contour ); - void SetSideStyle( int is, int style ); + { + SetHatchPitch( pitch ); + m_hatchStyle = (enum hatch_style) hatch; + Hatch(); + } + + void SetX( int ic, int x ); + void SetY( int ic, int y ); + void SetEndContour( int ic, bool end_contour ); + void SetSideStyle( int is, int style ); + void SetHatchStyle( enum hatch_style style ) - { - m_hatchStyle = style; - } + { + m_hatchStyle = style; + } + void SetHatchPitch( int pitch ) { m_hatchPitch = pitch; } - int RestoreArcs( std::vector * arc_array, std::vector * pa = NULL ); + int RestoreArcs( std::vector* arc_array, std::vector* pa = NULL ); - int NormalizeAreaOutlines( std::vector * pa = NULL, - bool bRetainArcs = false ); + int NormalizeAreaOutlines( std::vector* pa = NULL, + bool bRetainArcs = false ); // 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 * arc_array = NULL ); - /** * Function MakeKboolPoly * fill a kbool engine with a closed polyline contour * 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 * @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 */ - int MakeKboolPoly( int aStart_contour = -1, - int aEnd_contour = -1, - std::vector * arc_array = NULL, - bool aConvertHoles = false); + int MakeKboolPoly( std::vector* arc_array = NULL ); /** * Function NormalizeWithKbool @@ -262,22 +232,11 @@ public: * @param bRetainArcs == false, try to retain arcs in polys * @return number of external contours, or -1 if error */ - int NormalizeWithKbool( std::vector * 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; } + int NormalizeWithKbool( std::vector* aExtraPolyList, bool bRetainArcs ); // 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, int x4, int y4); + 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 ); /** * Function Distance @@ -286,7 +245,7 @@ public: * @return int = distance between the point and outline. * 0 if the point is inside */ - int Distance( const wxPoint& aPoint ); + int Distance( const wxPoint& aPoint ); /** * Function Distance @@ -297,22 +256,44 @@ public: * @return int = distance between the segment and outline. * 0 if segment intersects or is inside */ - int Distance( wxPoint aStart, wxPoint aEnd, int aWidth ); + int Distance( wxPoint aStart, wxPoint aEnd, int aWidth ); 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 - 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 - int utility; - Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data - + 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 + 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 + int m_utility; // a flag used in some calculations + Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data public: - std::vector corner; // array of points for corners - std::vector side_style; // array of styles for sides - std::vector m_HatchLines; // hatch lines + std::vector m_CornersList; // array of points for corners + std::vector m_SideStyle; // array of styles for sides + std::vector m_HatchLines; // hatch lines showing the polygon area }; -#endif // #ifndef POLYLINE_H +/** + * 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& 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& aPolysListWithHoles, + std::vector& aOnePolyList ); + +#endif // #ifndef POLYLINE_H diff --git a/polygon/polygons_defs.h b/polygon/polygons_defs.h new file mode 100644 index 0000000000..f9055c1cc6 --- /dev/null +++ b/polygon/polygons_defs.h @@ -0,0 +1,66 @@ +/* + * file polygons_defs.h + * definitions to use boost::polygon in KiCad. + */ + +#ifndef _POLYGONS_DEFS_H_ +#define _POLYGONS_DEFS_H_ + +#include + +// Define some types used here from boost::polygon +namespace bpl = boost::polygon; // bpl = boost polygon library +using namespace bpl::operators; // +, -, =, ... + +// Definitions needed by boost::polygon +typedef int coordinate_type; + +/** + * KI_POLYGON defines a single polygon ( boost::polygon_data type. + * When holes are created in a KPolygon, they are + * linked to main outline by overlapping segments, + * so there is always one polygon and one list of corners + * coordinates are int + */ +typedef bpl::polygon_data KI_POLYGON; + +/** + * KI_POLYGON_SET defines a set of single KI_POLYGON. + * A KI_POLYGON_SET is used to store a set of polygons + * when performing operations between 2 polygons + * or 2 sets of polygons + * The result of operations like and, xor... between 2 polygons + * is always stored in a KI_POLYGON_SET, because these operations + * can create many polygons + */ +typedef std::vector KI_POLYGON_SET; + +/** + * KI_POLY_POINT defines a point for boost::polygon. + * KI_POLY_POINT store x and y coordinates (int) + */ +typedef bpl::point_data KI_POLY_POINT; + +/** + * KI_POLYGON_WITH_HOLES defines a single polygon with holes + * When holes are created in a KI_POLYGON_WITH_HOLES, they are + * stored as separate single polygons, + * KI_POLYGON_WITH_HOLES store always one polygon for the external outline + * and one list of polygons (holes) which can be empty + */ +typedef bpl::polygon_with_holes_data KI_POLYGON_WITH_HOLES; + +/** + * KI_POLYGON_WITH_HOLES_SET defines a set of KI_POLYGON_WITH_HOLES. + * A KI_POLYGON_WITH_HOLES_SET is used to store a set of polygons with holes + * when performing operations between 2 polygons + * or 2 sets of polygons with holes + * The result of operations like and, xor... between 2 polygons with holes + * is always stored in a KI_POLYGON_WITH_HOLES_SET, because these operations + * can create many separate polygons with holespolygons + */ + +typedef std::vector KI_POLYGON_WITH_HOLES_SET; + + +#endif // #ifndef _POLYGONS_DEFS_H_