diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index fa9d124afc..b97701bd75 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -58,10 +58,10 @@ extern void CheckGLError(); */ static bool Is3DLayerEnabled( int aLayer ); - /* returns the Z orientation parmeter 1.0 or -1.0 for aLayer + /* returns the Z orientation parameter 1.0 or -1.0 for aLayer * Z orientation is 1.0 for all layers but "back" layers: * LAYER_N_BACK , ADHESIVE_N_BACK, SOLDERPASTE_N_BACK ), SILKSCREEN_N_BACK - * used to calculate the Z orientation parmeter for glNormal3f + * used to calculate the Z orientation parameter for glNormal3f */ static GLfloat Get3DLayer_Z_Orientation( int aLayer ); @@ -110,6 +110,7 @@ void EDA_3D_CANVAS::Redraw( bool finish ) } glFlush(); + if( finish ) glFinish(); @@ -193,6 +194,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() case PCB_LINE_T: { DRAWSEGMENT* segment = (DRAWSEGMENT*) PtStruct; + if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( segment->GetLayer() ) ) Draw3D_DrawSegment( segment ); } @@ -201,6 +203,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() case PCB_TEXT_T: { TEXTE_PCB* text = (TEXTE_PCB*) PtStruct; + if( Is3DLayerEnabled( text->GetLayer() ) ) Draw3D_DrawText( text ); } @@ -258,9 +261,9 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone ) else { // segments are used to fill areas - for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ ) - Draw3D_SolidSegment( aZone->m_FillSegmList[iseg].m_Start, - aZone->m_FillSegmList[iseg].m_End, + for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ ) + Draw3D_SolidSegment( aZone->FillSegments()[iseg].m_Start, + aZone->FillSegments()[iseg].m_End, aZone->GetMinThickness(), thickness, zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); } @@ -426,6 +429,7 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM ) SetGLColor( gridcolor ); else SetGLColor( gridcolor_marker ); + double delta = ii * aGriSizeMM * IU_PER_MM * scale; if( delta <= zmax ) @@ -505,8 +509,9 @@ void EDA_3D_CANVAS::Draw3D_Via( SEGVIA* via ) glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); Draw3D_ZaxisCylinder( via->GetStart(), (outer_radius + inner_radius)/2, - thickness, outer_radius - inner_radius, - zpos - (thickness/2), biu_to_3Dunits ); + thickness, outer_radius - inner_radius, + zpos - (thickness/2), biu_to_3Dunits ); + if( layer >= top_layer ) break; } @@ -559,8 +564,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) default: Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), - segment->GetWidth(), thickness, - zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); + segment->GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; } } @@ -593,8 +598,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) default: Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), - segment->GetWidth(), thickness, - zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); + segment->GetWidth(), thickness, + zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); break; } } @@ -607,12 +612,13 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment ) // so they are static. int s_Text3DWidth, s_Text3DZPos, s_thickness; + // This is a call back function, used by DrawGraphicText to draw the 3D text shape: static void Draw3dTextSegm( int x0, int y0, int xf, int yf ) { Draw3D_SolidSegment( wxPoint( x0, y0), wxPoint( xf, yf ), - s_Text3DWidth, s_thickness, s_Text3DZPos, - g_Parm_3D_Visu.m_BiuTo3Dunits ); + s_Text3DWidth, s_thickness, s_Text3DZPos, + g_Parm_3D_Visu.m_BiuTo3Dunits ); } @@ -681,6 +687,7 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE] ) { double zpos; + if( IsFlipped() ) zpos = g_Parm_3D_Visu.GetModulesZcoord3DIU( true ); else @@ -716,6 +723,7 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) } EDA_ITEM* Struct = m_Drawings; + for( ; Struct != NULL; Struct = Struct->Next() ) { switch( Struct->Type() ) @@ -760,6 +768,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) MODULE* module = (MODULE*) m_Parent; CPolyPt corner; + for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) { corner.x = m_PolyPoints[ii].x; @@ -798,7 +807,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas ) case S_CIRCLE: { int radius = KiROUND( hypot( double(m_Start.x - m_End.x), - double(m_Start.y - m_End.y) ) + double(m_Start.y - m_End.y) ) ); Draw3D_ZaxisCylinder( m_Start, radius, thickness, GetWidth(), @@ -953,12 +962,13 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) SetGLColor( g_ColorsSettings.GetLayerColor( layer ) ); int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); int ring_radius = (m_Size.x + m_Drill.x) / 4; + if( thickness == 0 ) glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); Draw3D_ZaxisCylinder(shape_pos, ring_radius, - thickness, ( m_Size.x - m_Drill.x) / 2, - zpos - (thickness/2), scale ); + thickness, ( m_Size.x - m_Drill.x) / 2, + zpos - (thickness/2), scale ); } break; @@ -967,6 +977,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) { wxPoint ends_offset; int width; + if( m_Size.x > m_Size.y ) // Horizontal ellipse { ends_offset.x = ( m_Size.x - m_Size.y ) / 2; @@ -982,9 +993,12 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) wxPoint start = shape_pos + ends_offset; wxPoint end = shape_pos - ends_offset; TransformRoundedEndsSegmentToPolygon( polyPadShape, start, end, slice, width ); + if( hasHole ) - polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), holecornersBuffer.end() ); + polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), + holecornersBuffer.end() ); } + break; case PAD_RECT: @@ -993,14 +1007,17 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) wxPoint coord[5]; BuildPadPolygon( coord, wxSize(0,0), m_Orient ); for( int ii = 0; ii < 4; ii ++ ) + { CPolyPt pt( coord[ii].x + shape_pos.x, coord[ii].y+ shape_pos.y ); polyPadShape.push_back( pt ); } + polyPadShape.back().end_contour = true; if( hasHole ) - polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), holecornersBuffer.end() ); + polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), + holecornersBuffer.end() ); } break; @@ -1028,16 +1045,16 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) // If not hole: draw a single polygon int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); + if( hasHole ) { Draw3D_SolidHorizontalPolygonWithHoles( polyPadShape, zpos, - thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); + thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } - else { Draw3D_SolidHorizontalPolyPolygons( polyPadShape, zpos, - thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); + thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } } } @@ -1047,6 +1064,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas ) bool Is3DLayerEnabled( int aLayer ) { int flg = -1; + // see if layer needs to be shown // check the flags switch (aLayer) @@ -1067,6 +1085,7 @@ bool Is3DLayerEnabled( int aLayer ) flg=g_Parm_3D_Visu.FL_ECO2; break; } + // the layer was not a layer with a flag, so show it if( flg < 0 ) return true; diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index 4fcd3e9163..96df5f941a 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -39,9 +39,6 @@ #include #include -#ifndef DEFAULT_SIZE_TEXT -# define DEFAULT_SIZE_TEXT 50 -#endif #define EDA_DRAWBASE #include diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 33446d8f6c..0f59228954 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -36,10 +36,8 @@ // Conversion to application internal units defined at build time. #if defined( PCBNEW ) #include -#define MILS_TO_IU( x ) ( x * IU_PER_MILS ); #elif defined( EESCHEMA ) #include -#define MILS_TO_IU( x ) ( x ) #else #error "Cannot resolve units formatting due to no definition of EESCHEMA or PCBNEW." #endif @@ -346,7 +344,8 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl aFormatter->Print( aNestLevel+1, "(effects" ); if( ( m_Size.x != Mils2iu( DEFAULT_SIZE_TEXT ) ) - || ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) ) || m_Bold || m_Italic ) + || ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) ) + || ( m_Thickness != 0 ) || m_Bold || m_Italic ) { aFormatter->Print( 0, " (font" ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a467d82cdf..1a77fe35a2 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1628,12 +1628,14 @@ D_PAD* BOARD::GetPad( std::vector& aPadList, const wxPoint& aPosition, i int delta = aPadList.size(); int idx = 0; // Starting index is the beginning of list + while( delta ) { // Calculate half size of remaining interval to test. // Ensure the computed value is not truncated (too small) if( (delta & 1) && ( delta > 1 ) ) delta++; + delta /= 2; D_PAD* pad = aPadList[idx]; @@ -1651,8 +1653,10 @@ D_PAD* BOARD::GetPad( std::vector& aPadList, const wxPoint& aPosition, i for( int ii = idx+1; ii <= idxmax; ii++ ) { pad = aPadList[ii]; + if( pad->GetPosition() != aPosition ) break; + if( (aLayerMask & pad->GetLayerMask()) != 0 ) return pad; } @@ -1660,8 +1664,10 @@ D_PAD* BOARD::GetPad( std::vector& aPadList, const wxPoint& aPosition, i for( int ii = idx-1 ;ii >=0; ii-- ) { pad = aPadList[ii]; + if( pad->GetPosition() != aPosition ) break; + if( (aLayerMask & pad->GetLayerMask()) != 0 ) return pad; } @@ -1675,12 +1681,14 @@ D_PAD* BOARD::GetPad( std::vector& aPadList, const wxPoint& aPosition, i if(pad->GetPosition().y < aPosition.y) // Must search after this item { idx += delta; + if( idx > idxmax ) idx = idxmax; } else // Must search before this item { idx -= delta; + if( idx < 0 ) idx = 0; } @@ -1688,12 +1696,14 @@ D_PAD* BOARD::GetPad( std::vector& aPadList, const wxPoint& aPosition, i else if( pad->GetPosition().x < aPosition.x ) // Must search after this item { idx += delta; + if( idx > idxmax ) idx = idxmax; } else // Must search before this item { idx -= delta; + if( idx < 0 ) idx = 0; } @@ -2202,6 +2212,106 @@ void BOARD::SetTrackWidthIndex( unsigned aIndex ) } +ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, + int aLayer, wxPoint aStartPointPosition, int aHatch ) +{ + ZONE_CONTAINER* new_area = InsertArea( aNetcode, + m_ZoneDescriptorList.size( ) - 1, + aLayer, aStartPointPosition.x, + aStartPointPosition.y, aHatch ); + + if( aNewZonesList ) + { + ITEM_PICKER picker( new_area, UR_NEW ); + aNewZonesList->PushItem( picker ); + } + + return new_area; +} + + +void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove ) +{ + if( area_to_remove == NULL ) + return; + + if( aDeletedList ) + { + ITEM_PICKER picker( area_to_remove, UR_DELETED ); + aDeletedList->PushItem( picker ); + Remove( area_to_remove ); // remove from zone list, but does not delete it + } + else + { + Delete( area_to_remove ); + } +} + + +ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ) +{ + ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); + + new_area->SetNet( netcode ); + new_area->SetLayer( layer ); + new_area->SetTimeStamp( GetNewTimeStamp() ); + + if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) ) + m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area ); + else + m_ZoneDescriptorList.push_back( new_area ); + + new_area->Outline()->Start( layer, x, y, hatch ); + return new_area; +} + + +bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAINER* aCurrArea ) +{ + CPolyLine* curr_polygon = aCurrArea->Outline(); + + // mark all areas as unmodified except this one, if modified + for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) + m_ZoneDescriptorList[ia]->SetFlags( 0 ); + + aCurrArea->SetFlags( 1 ); + + if( curr_polygon->IsPolygonSelfIntersecting() ) + { + std::vector* pa = new std::vector; + curr_polygon->UnHatch(); + int n_poly = aCurrArea->Outline()->NormalizeAreaOutlines( pa ); + + // If clipping has created some polygons, we must add these new copper areas. + if( n_poly > 1 ) + { + ZONE_CONTAINER* NewArea; + + for( int ip = 1; ip < n_poly; ip++ ) + { + // create new copper area and copy poly into it + CPolyLine* new_p = (*pa)[ip - 1]; + NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(), + wxPoint(0, 0), CPolyLine::NO_HATCH ); + + // remove the poly that was automatically created for the new area + // and replace it with a poly from NormalizeAreaOutlines + delete NewArea->Outline(); + NewArea->SetOutline( new_p ); + NewArea->Outline()->Hatch(); + NewArea->SetFlags( 1 ); + } + } + + delete pa; + } + + curr_polygon->Hatch(); + + return true; +} + + #if defined(DEBUG) void BOARD::Show( int nestLevel, std::ostream& os ) const diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 7d8b558ba6..abad85ec46 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -1109,8 +1109,7 @@ public: * @return true if changes are made * Also sets areas->utility1 flags if areas are modified */ - bool NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, - ZONE_CONTAINER* aCurrArea ); + bool NormalizeAreaPolygon( PICKED_ITEMS_LIST* aNewZonesList, ZONE_CONTAINER* aCurrArea ); /** * Function OnAreaPolygonModified @@ -1136,8 +1135,8 @@ public: * @return true if some areas modified */ bool CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, - int aNetCode, - bool aUseUtility ); + int aNetCode, + bool aUseUtility ); /** * Function RemoveArea diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 36f1b489b5..2d598130b0 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -164,7 +164,8 @@ void ZONE_CONTAINER::SetNet( int aNetCode ) } -void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) +void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, + const wxPoint& offset ) { if( DC == NULL ) return; @@ -293,7 +294,8 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, CornersTypeBuffer.push_back( (char) corner->m_utility ); - if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it + // the last corner of a filled area is found: draw it + if( (corner->end_contour) || (ic == imax) ) { /* Draw the current filled area: draw segments outline first * Curiously, draw segments outline first and after draw filled polygons @@ -318,7 +320,8 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, int x1 = CornersBuffer[ie].x; int y1 = CornersBuffer[ie].y; - if( CornersTypeBuffer[ie] == 0 ) // Draw only basic outlines, not extra segments + // Draw only basic outlines, not extra segments. + if( CornersTypeBuffer[ie] == 0 ) { if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) GRCSegm( panel->GetClipBox(), DC, diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 7c07df3fc4..2ef1f34b9a 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -159,11 +159,11 @@ public: int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const; /** - * Function Test_For_Copper_Island_And_Remove__Insulated_Islands + * Function TestForCopperIslandAndRemoveInsulatedIslands * Remove insulated copper islands found in m_FilledPolysList. * @param aPcb = the board to analyze */ - void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb ); + void TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb ); /** * Function CalculateSubAreaBoundaryBox @@ -239,6 +239,20 @@ public: int GetMinThickness() const { return m_ZoneMinThickness; } void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; } + int GetSelectedCorner() const { return m_CornerSelection; } + void SetSelectedCorner( int aCorner ) { m_CornerSelection = aCorner; } + + int GetFlags() const { return utility; } + void SetFlags( int aFlags ) { utility = aFlags; } + + std::vector & FillSegments() { return m_FillSegmList; } + const std::vector & FillSegments() const { return m_FillSegmList; } + + CPolyLine* Outline() { return m_Poly; } + const CPolyLine* Outline() const { return const_cast< CPolyLine* >( m_Poly ); } + + void SetOutline( CPolyLine* aOutline ) { m_Poly = aOutline; } + /** @copydoc EDA_ITEM::HitTest(const wxPoint&) */ virtual bool HitTest( const wxPoint& aPosition ); @@ -277,7 +291,7 @@ public: * Copy polygons from m_FilledPolysList to aKiPolyList * @param aKiPolyList = a KI_POLYGON_SET to fill by polygons. */ - void CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList ); + void CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList ); /** * Function AddClearanceAreasPolygonsToPolysList @@ -327,14 +341,14 @@ public: int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true ); /** - * Function Fill_Zone_Areas_With_Segments + * Function FillZoneAreasWithSegments * Fill sub areas in a zone with segments with m_ZoneMinThickness width * A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness. * all intersecting points with the horizontal infinite line and polygons to fill are calculated * a list of SEGZONE items is built, line per line * @return number of segments created */ - int Fill_Zone_Areas_With_Segments(); + int FillZoneAreasWithSegments(); /** * Function UnFill @@ -554,23 +568,10 @@ public: #endif - CPolyLine* m_Poly; // outlines - - // For corner moving, corner index to drag, or -1 if no selection. - int m_CornerSelection; - - int utility; // flags used in polygon calculations - - /* set of segments used to fill area, when fill zone by segment is used. - * ( m_FillMode == 1 ) - * in this case segments have m_ZoneMinThickness width - */ - std::vector m_FillSegmList; - - private: - wxString m_Netname; // Net Name - CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly + CPolyLine* m_Poly; ///< Outline of the zone. + wxString m_Netname; ///< Name of the net assigned to the zone. + CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly int m_cornerSmoothingType; unsigned int m_cornerRadius; @@ -613,6 +614,17 @@ private: /// How to fill areas: 0 => use filled polygons, 1 => fill with segments. int m_FillMode; + /// The index of the corner being moved or -1 if no corner is selected. + int m_CornerSelection; + + int utility; ///< Flags used in polygon calculations. + + + /** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used. + * In this case the segments have #m_ZoneMinThickness width. + */ + std::vector m_FillSegmList; + /* 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 diff --git a/pcbnew/class_zone_settings.cpp b/pcbnew/class_zone_settings.cpp index 3ac38639ba..af0d0e5d44 100644 --- a/pcbnew/class_zone_settings.cpp +++ b/pcbnew/class_zone_settings.cpp @@ -51,9 +51,9 @@ ZONE_SETTINGS::ZONE_SETTINGS() // ARC_APPROX_SEGMENTS_COUNT_LOW_DEF // or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments - // tickness of the gap in thermal reliefs: + // thickness of the gap in thermal reliefs: m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL ); - // tickness of the copper bridge in thermal reliefs: + // thickness of the copper bridge in thermal reliefs: m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL ); m_PadConnection = THERMAL_PAD; // How pads are covered by copper in zone @@ -115,10 +115,10 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c aTarget.SetPriority( m_ZonePriority ); aTarget.SetNet( m_NetcodeSelection ); aTarget.SetLayer( m_CurrentZone_Layer ); - aTarget.m_Poly->SetLayer( m_CurrentZone_Layer ); + aTarget.Outline()->SetLayer( m_CurrentZone_Layer ); } // call SetHatch last, because hatch lines will be rebuilt, // using new parameters values - aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true ); + aTarget.Outline()->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true ); } diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 7a8ab50e44..67d1194022 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -44,6 +44,7 @@ #include #include +#include void DRC::ShowDialog() @@ -148,16 +149,6 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) } -/** - * Function Drc - * tests the outline segment starting at CornerIndex and returns the result and displays the error - * in the status panel only if one exists. - * Test Edge inside other areas - * Test Edge too close other areas - * @param aArea The areaparent which contains the corner. - * @param aCornerIndex The starting point of the segment to test. - * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK - */ int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex ) { updatePointers(); @@ -173,11 +164,6 @@ int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex ) } -/** - * Function RunTests - * will actually run all the tests specified with a previous call to - * SetSettings() - */ void DRC::RunTests( wxTextCtrl* aMessages ) { // Ensure ratsnest is up to date: @@ -227,6 +213,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) aMessages->AppendText( _( "Track clearances...\n" ) ); wxSafeYield(); } + testTracks( true ); // Before testing segments and unconnected, refill all zones: @@ -295,7 +282,7 @@ void DRC::ListUnconnectedPads() void DRC::updatePointers() { - // update my pointers, m_mainWindow is the only unchangable one + // update my pointers, m_mainWindow is the only unchangeable one m_pcb = m_mainWindow->GetBoard(); if( m_ui ) // Use diag list boxes only in DRC dialog @@ -466,12 +453,6 @@ void DRC::testPad2Pad() } -#include -/* Function testTracks - * performs the DRC on all tracks. - * because this test can take a while, a progress bar can be displayed - * (Note: it is shown only if there are many tracks) - */ void DRC::testTracks( bool aShowProgressBar ) { wxProgressDialog * progressDialog = NULL; @@ -482,28 +463,32 @@ void DRC::testTracks( bool aShowProgressBar ) count++; int deltamax = count/delta; + if( aShowProgressBar && deltamax > 3 ) { progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString, - deltamax, m_mainWindow, - wxPD_AUTO_HIDE | wxPD_CAN_ABORT ); + deltamax, m_mainWindow, + wxPD_AUTO_HIDE | wxPD_CAN_ABORT ); progressDialog->Update( 0, wxEmptyString ); } int ii = 0; count = 0; + for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) { if ( ii++ > delta ) { ii = 0; count++; + if( progressDialog ) { if( !progressDialog->Update( count, wxEmptyString ) ) break; // Aborted by user } } + if( !doTrackDrc( segm, segm->Next(), true ) ) { wxASSERT( m_currentMarker ); @@ -511,6 +496,7 @@ void DRC::testTracks( bool aShowProgressBar ) m_currentMarker = 0; } } + if( progressDialog ) progressDialog->Destroy(); } @@ -528,6 +514,7 @@ void DRC::testUnconnected() return; wxString msg; + for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii ) { RATSNEST_ITEM& rat = m_pcb->m_FullRatsnest[ii]; @@ -596,7 +583,8 @@ void DRC::testKeepoutAreas() if( segm->GetLayer() != area->GetLayer() ) continue; - if( area->m_Poly->Distance( segm->GetStart(), segm->GetEnd(), segm->GetWidth() ) == 0 ) + if( area->Outline()->Distance( segm->GetStart(), segm->GetEnd(), + segm->GetWidth() ) == 0 ) { m_currentMarker = fillMarker( segm, NULL, DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); @@ -612,7 +600,7 @@ void DRC::testKeepoutAreas() if( ! ((SEGVIA*)segm)->IsOnLayer( area->GetLayer() ) ) continue; - if( area->m_Poly->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) + if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) { m_currentMarker = fillMarker( segm, NULL, DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); @@ -625,12 +613,7 @@ void DRC::testKeepoutAreas() } } -/* - * Function doTrackKeepoutDrc - * tests the current segment or via. - * aRefSeg is the segment to test - * return true if no DRC err - */ + bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) { // Test keepout areas for vias, tracks and pads inside keepout areas @@ -649,7 +632,8 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( aRefSeg->GetLayer() != area->GetLayer() ) continue; - if( area->m_Poly->Distance( aRefSeg->GetStart(), aRefSeg->GetEnd(), aRefSeg->GetWidth() ) == 0 ) + if( area->Outline()->Distance( aRefSeg->GetStart(), aRefSeg->GetEnd(), + aRefSeg->GetWidth() ) == 0 ) { m_currentMarker = fillMarker( aRefSeg, NULL, DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); @@ -664,7 +648,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) if( ! ((SEGVIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) continue; - if( area->m_Poly->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) + if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) { m_currentMarker = fillMarker( aRefSeg, NULL, DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index 087c82ba76..a1b0f61443 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1487,17 +1487,18 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics ) CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; - zone->m_Poly->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch ); + zone->Outline()->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch ); zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) ); zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) ); zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) ); - zone->m_Poly->CloseLastContour(); + zone->Outline()->CloseLastContour(); // this is not my fault: - zone->m_Poly->SetHatch( outline_hatch, - Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), - true ); + zone->Outline()->SetHatch( outline_hatch, + Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ), + true ); } + m_xpath->pop(); } @@ -2488,18 +2489,19 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals ) // the ZONE_CONTAINER API needs work, as you can see: if( first ) { - zone->m_Poly->Start( layer, kicad_x( v.x ), kicad_y( v.y ), outline_hatch ); + zone->Outline()->Start( layer, kicad_x( v.x ), kicad_y( v.y ), + outline_hatch ); first = false; } else zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) ); } - zone->m_Poly->CloseLastContour(); + zone->Outline()->CloseLastContour(); - zone->m_Poly->SetHatch( outline_hatch, - Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), - true ); + zone->Outline()->SetHatch( outline_hatch, + Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ), + true ); // clearances, etc. zone->SetArcSegmentCount( 32 ); // @todo: should be a constructor default? diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 31e2c41f89..74fad5c15a 100755 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -518,7 +518,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); m_canvas->SetAutoPanRequest( true ); - Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->m_CornerSelection, false ); + Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), false ); break; } @@ -527,7 +527,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) m_canvas->MoveCursorToCrossHair(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); m_canvas->SetAutoPanRequest( true ); - Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->m_CornerSelection ); + Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->GetSelectedCorner() ); break; } @@ -551,11 +551,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) * and start move the new corner */ zone_cont->Draw( m_canvas, &dc, GR_XOR ); - zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y ); - zone_cont->m_CornerSelection++; + zone_cont->Outline()->InsertCorner( zone_cont->GetSelectedCorner(), pos.x, pos.y ); + zone_cont->SetSelectedCorner( zone_cont->GetSelectedCorner() + 1 ); zone_cont->Draw( m_canvas, &dc, GR_XOR ); m_canvas->SetAutoPanRequest( true ); - Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->m_CornerSelection, true ); + Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), true ); break; } diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 52b8d6eb10..5687d8ec78 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1323,7 +1323,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const } m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(), - FMT_IU( aZone->m_Poly->GetHatchPitch() ).c_str() ); + FMT_IU( aZone->Outline()->GetHatchPitch() ).c_str() ); if( aZone->GetPriority() > 0 ) m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() ); @@ -1405,7 +1405,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, ")\n" ); - const std::vector< CPolyPt >& cv = aZone->m_Poly->m_CornersList; + const std::vector< CPolyPt >& cv = aZone->Outline()->m_CornersList; int newLine = 0; if( cv.size() ) @@ -1501,7 +1501,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const } // Save the filling segments list - const std::vector< SEGMENT >& segs = aZone->m_FillSegmList; + const std::vector< SEGMENT >& segs = aZone->FillSegments(); if( segs.size() ) { diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index c785c07e8e..b3a26ad4bc 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -2167,14 +2167,14 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() int flag = intParse( data ); if( !sawCorner ) - zc->m_Poly->Start( zc->GetLayer(), x, y, outline_hatch ); + zc->Outline()->Start( zc->GetLayer(), x, y, outline_hatch ); else zc->AppendCorner( wxPoint( x, y ) ); sawCorner = true; if( flag ) - zc->m_Poly->CloseLastContour(); + zc->Outline()->CloseLastContour(); } else if( TESTLINE( "ZInfo" ) ) // general info found @@ -2368,9 +2368,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() BIU ex = biuParse( data, &data ); BIU ey = biuParse( data ); - zc->m_FillSegmList.push_back( SEGMENT( - wxPoint( sx, sy ), - wxPoint( ex, ey ) ) ); + zc->FillSegments().push_back( SEGMENT( wxPoint( sx, sy ), wxPoint( ex, ey ) ) ); } } @@ -2397,9 +2395,9 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER() // Hatch here, after outlines corners are read // Set hatch here, after outlines corners are read - zc->m_Poly->SetHatch( outline_hatch, - Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ), - true ); + zc->Outline()->SetHatch( outline_hatch, + Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ), + true ); m_board->Add( zc.release() ); } @@ -3682,7 +3680,8 @@ 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->m_CornersList; + const CPOLY_PTS& cv = me->Outline()->m_CornersList; + for( CPOLY_PTS::const_iterator it = cv.begin(); it != cv.end(); ++it ) { fprintf( m_fp, "ZCorner %s %d\n", @@ -3710,7 +3709,8 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const typedef std::vector< SEGMENT > SEGMENTS; // Save the filling segments list - const SEGMENTS& segs = me->m_FillSegmList; + const SEGMENTS& segs = me->FillSegments(); + if( segs.size() ) { fprintf( m_fp, "$FILLSEGMENTS\n" ); diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index faf7546293..d0504f2931 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -61,7 +61,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) BOARD_ITEM* item = GetCurItem(); - m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block coomand when clicking on menu + m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block command when clicking on menu // If a command or a block is in progress: // Put the Cancel command (if needed) and the End command @@ -167,13 +167,14 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) if( !flags ) aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE, - _( "Auto Place Module" ) ); + _( "Automatically Place Module" ) ); } if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { if( !flags ) - aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, _( "Autoroute Module" ) ); + aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, + _( "Automatically Route Module" ) ); } break; @@ -205,7 +206,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) if( item->GetLayer() > LAST_COPPER_LAYER ) AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER, - _( "Delete All Drawing on Layer" ), KiBitmap( delete_xpm ) ); + _( "Delete All Drawings on Layer" ), KiBitmap( delete_xpm ) ); } break; @@ -377,7 +378,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) { wxMenu* commands = new wxMenu; AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS, - _( "Glob Move and Place" ), KiBitmap( move_xpm ) ); + _( "Global Move and Place" ), KiBitmap( move_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES, _( "Unlock All Modules" ), KiBitmap( unlocked_xpm ) ); AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES, @@ -387,9 +388,12 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) _( "Move All Modules" ), KiBitmap( move_xpm ) ); commands->Append( ID_POPUP_PCB_AUTOMOVE_NEW_MODULES, _( "Move New Modules" ) ); commands->AppendSeparator(); - commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, _( "Autoplace All Modules" ) ); - commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, _( "Autoplace New Modules" ) ); - commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, _( "Autoplace Next Module" ) ); + commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, + _( "Automatically Place All Modules" ) ); + commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, + _( "Automatically Place New Modules" ) ); + commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, + _( "Automatically Place Next Module" ) ); commands->AppendSeparator(); AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES, _( "Orient All Modules" ), KiBitmap( rotate_module_pos_xpm ) ); @@ -403,16 +407,15 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR, _( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) ); commands->AppendSeparator(); - commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, _( "Autoroute All Modules" ) ); + commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, + _( "Automatically Route All Modules" ) ); commands->AppendSeparator(); commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) ); aPopMenu->AppendSeparator(); } - msg = AddHotkeyName( _( "Begin Track" ), - g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); - AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, - msg, KiBitmap( add_tracks_xpm ) ); + msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); + AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) ); if( locate_track ) AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), @@ -574,7 +577,7 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu ) { PopMenu->AppendSeparator(); AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE, - _( "Global Tracks and Vias Edition" ), KiBitmap( width_track_via_xpm ) ); + _( "Edit All Tracks and Vias" ), KiBitmap( width_track_via_xpm ) ); } // Add lock/unlock flags menu: @@ -671,14 +674,15 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* msg = AddHotkeyName( _( "Move Zone" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES, msg, KiBitmap( move_xpm ) ); - msg = AddHotkeyName( _( "Edit Zone Params" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); + msg = AddHotkeyName( _( "Edit Zone Properties" ), g_Board_Editor_Hokeys_Descr, + HK_EDIT_ITEM ); AddMenuItem( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS, msg, KiBitmap( edit_xpm ) ); zones_menu->AppendSeparator(); - if( edge_zone->m_CornerSelection >= 0 && - edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) ) + if( edge_zone->GetSelectedCorner() >= 0 && + edge_zone->Outline()->IsCutoutContour( edge_zone->GetSelectedCorner() ) ) AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT, _( "Delete Cutout" ), KiBitmap( delete_xpm ) ); @@ -727,7 +731,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg, KiBitmap( edit_module_xpm ) ); AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT, - _( "Edit with ModEdit" ), + _( "Edit with Module Editor" ), KiBitmap( module_editor_xpm ) ); sub_menu_footprint->AppendSeparator(); msg = AddHotkeyName( _( "Delete Module" ), @@ -832,8 +836,8 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu ) KiBitmap( export_options_pad_xpm ) ); AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS, - _( "Global Pads Edition" ), - _( "Copy this pad settings to all pads in this footprint (or similar footprints)" ), + _( "Edit All Pads" ), + _( "Copy this pad's settings to all pads in this footprint (or similar footprints)" ), KiBitmap( global_options_pad_xpm ) ); sub_menu_Pad->AppendSeparator(); @@ -841,8 +845,8 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu ) if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) { - menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Autoroute Pad" ) ); - menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Autoroute Net" ) ); + menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Automatically Route Pad" ) ); + menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Automatically Route Net" ) ); } MODULE* module = (MODULE*) Pad->GetParent(); @@ -907,7 +911,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPo /** * Function Append_Track_Width_List * creates a wxMenu * which shows the last used track widths and via diameters - * @return a pointeur to the menu + * @return a pointer to the menu */ static wxMenu* Append_Track_Width_List( BOARD* aBoard ) { @@ -938,7 +942,7 @@ static wxMenu* Append_Track_Width_List( BOARD* aBoard ) msg.Printf( _( "Track %s" ), GetChars( value ) ); if( ii == 0 ) - msg << _( " (use NetClass)" ); + msg << _( " uses NetClass" ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true ); } @@ -959,11 +963,11 @@ static wxMenu* Append_Track_Width_List( BOARD* aBoard ) } else { - msg.Printf( _( "Via %s; (drl %s)" ), GetChars( value ), GetChars( drill ) ); + msg.Printf( _( "Via %s, drill %s" ), GetChars( value ), GetChars( drill ) ); } if( ii == 0 ) - msg << _( " (use NetClass)" ); + msg << _( " uses NetClass" ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true ); } diff --git a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp index 064e1eabec..d64f626bf9 100644 --- a/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp +++ b/pcbnew/pcad2kicadpcb_plugin/pcb_polygon.cpp @@ -177,8 +177,8 @@ void PCB_POLYGON::AddToBoard() // add outline int outline_hatch = CPolyLine::DIAGONAL_EDGE; - zone->m_Poly->Start( m_KiCadLayer, KiROUND( m_outline[i]->x ), - KiROUND( m_outline[i]->y ), outline_hatch ); + zone->Outline()->Start( m_KiCadLayer, KiROUND( m_outline[i]->x ), + KiROUND( m_outline[i]->y ), outline_hatch ); for( i = 1; i < (int) m_outline.GetCount(); i++ ) { @@ -186,15 +186,15 @@ void PCB_POLYGON::AddToBoard() KiROUND( m_outline[i]->y ) ) ); } - zone->m_Poly->CloseLastContour(); + zone->Outline()->CloseLastContour(); zone->SetZoneClearance( m_width ); zone->SetPriority( m_priority ); - zone->m_Poly->SetHatch( outline_hatch, - Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), - true ); + zone->Outline()->SetHatch( outline_hatch, + Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ), + true ); if ( m_objType == wxT( 'K' ) ) { diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 856216291d..41c058383b 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -2666,7 +2666,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR ) } // Set hatch here, after outlines corners are read - zone->m_Poly->SetHatch( hatchStyle, hatchPitch, true ); + zone->Outline()->SetHatch( hatchStyle, hatchPitch, true ); } if( pts.size() ) diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index 0768fd303f..0c89c03bf0 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -1,5 +1,29 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + /** * @file pcbnew/pcbplot.h + * @brief Board plot function definition file. */ #ifndef PCBPLOT_H_ @@ -46,8 +70,8 @@ class BOARD; class BRDITEMS_PLOTTER: public PCB_PLOT_PARAMS { PLOTTER* m_plotter; - BOARD* m_board; - int m_layerMask; + BOARD* m_board; + int m_layerMask; public: @@ -62,7 +86,7 @@ public: /** * @return a 'width adjustment' for the postscript engine * (useful for controlling toner bleeding during direct transfer) - * addded to track width and via/pads size + * added to track width and via/pads size */ int getFineWidthAdj() { @@ -71,12 +95,22 @@ public: else return 0; } + // Basic functions to plot a board item void SetLayerMask( int aLayerMask ){ m_layerMask = aLayerMask; } void Plot_Edges_Modules(); void Plot_1_EdgeModule( EDGE_MODULE* aEdge ); void PlotTextModule( TEXTE_MODULE* aTextMod, EDA_COLOR_T aColor ); + + /* + * Plot field of a module (footprint) + * Reference, Value, and other fields are plotted only if + * the corresponding option is enabled + * Invisible text fields are plotted only if PlotInvisibleText option is set + * usually they are not plotted. + */ bool PlotAllTextsModule( MODULE* aModule ); + void PlotDimension( DIMENSION* Dimension ); void PlotPcbTarget( PCB_TARGET* PtMire ); void PlotFilledAreas( ZONE_CONTAINER* aZone ); @@ -134,7 +168,7 @@ PLOTTER* StartPlotBoard( BOARD* aBoard, /** * Function PlotOneBoardLayer * main function to plot one copper or technical layer. - * It prepare options and calls the specilized plot function, + * It prepare options and calls the specialized plot function, * according to the layer type * @param aBoard = the board to plot * @param aPlotter = the plotter to use @@ -154,8 +188,8 @@ void PlotOneBoardLayer( BOARD* aBoard, PLOTTER* aPlotter, int aLayer, * @param aLayerMask = the mask to define the layers to plot * @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only * - * aPlotOpt has 3 important options to controle this plot, - * which are set, depending on the layer typpe to plot + * aPlotOpt has 3 important options to control this plot, + * which are set, depending on the layer type to plot * SetEnablePlotVia( bool aEnable ) * aEnable = true to plot vias, false to skip vias (has meaning * only for solder mask layers). @@ -188,7 +222,7 @@ void PlotSilkScreen( BOARD* aBoard, PLOTTER* aPlotter, long aLayerMask, * @param aOutputDir = the wxFileName to modify * (contains the absolute or relative to the board path * @param aBoardFilename = the board full filename - * @param aMessageBox = a wxMessageBox to show meesage (can be NULL) + * @param aMessageBox = a wxMessageBox to show message (can be NULL) */ bool EnsureOutputDirectory( wxFileName* aOutputDir, const wxString& aBoardFilename, @@ -207,9 +241,9 @@ bool EnsureOutputDirectory( wxFileName* aOutputDir, * @param aExtension = the file extension */ void BuildPlotFileName( wxFileName* aFilename, - const wxString& aOutputDir, - const wxString& aSuffix, - const wxString& aExtension ); + const wxString& aOutputDir, + const wxString& aSuffix, + const wxString& aExtension ); // PLOTGERB.CPP void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize ); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index bde880b43b..d2d9091a9d 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -54,12 +54,6 @@ */ -/* Function getColor - * return the layer colorfrom the layer id - * White color is special: cannot be seen on a white paper - * and in B&W mode, is plotted as white but other colors are plotted in BLACK - * so the returned color is LIGHTGRAY when the layer color is WHITE - */ EDA_COLOR_T BRDITEMS_PLOTTER::getColor( int aLayer ) { EDA_COLOR_T color = m_board->GetLayerColor( aLayer ); @@ -68,12 +62,7 @@ EDA_COLOR_T BRDITEMS_PLOTTER::getColor( int aLayer ) return color; } -/* - * Plot a pad. - * unlike other items, a pad had not a specific color, - * and be drawn as a non filled item although the plot mode is filled - * color and plot mode are needed by this function - */ + void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode ) { wxPoint shape_pos = aPad->ReturnShapePos(); @@ -90,7 +79,7 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T case PAD_OVAL: m_plotter->FlashPadOval( shape_pos, aPad->GetSize(), - aPad->GetOrientation(), aPlotMode ); + aPad->GetOrientation(), aPlotMode ); break; case PAD_TRAPEZOID: @@ -98,25 +87,19 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T wxPoint coord[4]; aPad->BuildPadPolygon( coord, wxSize(0,0), 0 ); m_plotter->FlashPadTrapez( shape_pos, coord, - aPad->GetOrientation(), aPlotMode ); + aPad->GetOrientation(), aPlotMode ); } break; case PAD_RECT: default: m_plotter->FlashPadRect( shape_pos, aPad->GetSize(), - aPad->GetOrientation(), aPlotMode ); + aPad->GetOrientation(), aPlotMode ); break; } } -/* - * Plot field of a module (footprint) - * Reference, Value, and other fields are plotted only if - * the corresponding option is enabled - * Invisible text fields are plotted only if PlotInvisibleText option is set - * usually they are not plotted. - */ + bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) { // see if we want to plot VALUE and REF fields @@ -221,8 +204,7 @@ void BRDITEMS_PLOTTER::PlotBoardGraphicItems() } } -void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, - EDA_COLOR_T aColor ) +void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, EDA_COLOR_T aColor ) { wxSize size; wxPoint pos; @@ -230,6 +212,7 @@ void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, if( aColor == WHITE ) aColor = LIGHTGRAY; + m_plotter->SetColor( aColor ); // calculate some text parameters : @@ -323,6 +306,7 @@ void BRDITEMS_PLOTTER::PlotPcbTarget( PCB_TARGET* aMire ) draw.SetLayer( aMire->GetLayer() ); draw.SetStart( aMire->GetPosition() ); radius = aMire->GetSize() / 3; + if( aMire->GetShape() ) // shape X radius = aMire->GetSize() / 2; @@ -410,55 +394,53 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge ) break; case S_ARC: - { - radius = (int) hypot( (double) ( end.x - pos.x ), + { + radius = (int) hypot( (double) ( end.x - pos.x ), (double) ( end.y - pos.y ) ); - double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x ); + double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x ); - double endAngle = startAngle + aEdge->GetAngle(); + double endAngle = startAngle + aEdge->GetAngle(); - if ( ( GetFormat() == PLOT_FORMAT_DXF ) && - ( m_layerMask & ( SILKSCREEN_LAYER_BACK | DRAW_LAYER | COMMENT_LAYER ) ) ) - m_plotter->ThickArc( pos, -startAngle, -endAngle, radius, - thickness, GetMode() ); - else - m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, - thickness, GetMode() ); - } - break; + if ( ( GetFormat() == PLOT_FORMAT_DXF ) && + ( m_layerMask & ( SILKSCREEN_LAYER_BACK | DRAW_LAYER | COMMENT_LAYER ) ) ) + m_plotter->ThickArc( pos, -startAngle, -endAngle, radius, thickness, GetMode() ); + else + m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetMode() ); + } + break; case S_POLYGON: + { + const std::vector& polyPoints = aEdge->GetPolyPoints(); + + if( polyPoints.size() <= 1 ) // Malformed polygon + break; + + // We must compute true coordinates from m_PolyList + // which are relative to module position, orientation 0 + MODULE* module = aEdge->GetParentModule(); + + std::vector< wxPoint > cornerList; + + cornerList.reserve( polyPoints.size() ); + + for( unsigned ii = 0; ii < polyPoints.size(); ii++ ) { - const std::vector& polyPoints = aEdge->GetPolyPoints(); + wxPoint corner = polyPoints[ii]; - if( polyPoints.size() <= 1 ) // Malformed polygon - break; - - // We must compute true coordinates from m_PolyList - // which are relative to module position, orientation 0 - MODULE* module = aEdge->GetParentModule(); - - std::vector< wxPoint > cornerList; - - cornerList.reserve( polyPoints.size() ); - - for( unsigned ii = 0; ii < polyPoints.size(); ii++ ) + if( module ) { - wxPoint corner = polyPoints[ii]; - - if( module ) - { - RotatePoint( &corner, module->GetOrientation() ); - corner += module->GetPosition(); - } - - cornerList.push_back( corner ); + RotatePoint( &corner, module->GetOrientation() ); + corner += module->GetPosition(); } - m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness ); + cornerList.push_back( corner ); } - break; + + m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness ); + } + break; } } @@ -566,10 +548,10 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone ) } else // We are using areas filled by { // segments: plot them ) - for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ ) + for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ ) { - wxPoint start = aZone->m_FillSegmList[iseg].m_Start; - wxPoint end = aZone->m_FillSegmList[iseg].m_End; + wxPoint start = aZone->FillSegments()[iseg].m_Start; + wxPoint end = aZone->FillSegments()[iseg].m_End; m_plotter->ThickSegment( start, end, aZone->GetMinThickness(), GetMode() ); @@ -644,8 +626,8 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg ) for( unsigned i = 1; i < bezierPoints.size(); i++ ) m_plotter->ThickSegment( bezierPoints[i - 1], - bezierPoints[i], - thickness, GetMode() ); + bezierPoints[i], + thickness, GetMode() ); } break; @@ -654,6 +636,7 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg ) } } + /** Helper function to plot a single drill mark. It compensate and clamp * the drill mark size depending on the current plot options */ @@ -669,6 +652,7 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_SHAPE_T aDrillShape, // Round holes only have x diameter, slots have both aDrillSize.x -= getFineWidthAdj(); aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 ); + if( aDrillShape == PAD_OVAL ) { aDrillSize.y -= getFineWidthAdj(); @@ -679,12 +663,7 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_SHAPE_T aDrillShape, m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetMode() ); } -/* Function PlotDrillMarks - * Draw a drill mark for pads and vias. - * Must be called after all drawings, because it - * redraw the drill mark on a pad or via, as a negative (i.e. white) shape in - * FILLED plot mode (for PS and PDF outputs) - */ + void BRDITEMS_PLOTTER::PlotDrillMarks() { /* If small drills marks were requested prepare a clamp value to pass @@ -711,9 +690,8 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() if( pts->Type() != PCB_VIA_T ) continue; - plotOneDrillMark(PAD_CIRCLE, - pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ), - wxSize( pts->GetWidth(), 0 ), 0, small_drill ); + plotOneDrillMark( PAD_CIRCLE, pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ), + wxSize( pts->GetWidth(), 0 ), 0, small_drill ); } for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() ) @@ -724,9 +702,9 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() continue; plotOneDrillMark( pad->GetDrillShape(), - pad->GetPosition(), pad->GetDrillSize(), - pad->GetSize(), pad->GetOrientation(), - small_drill ); + pad->GetPosition(), pad->GetDrillSize(), + pad->GetSize(), pad->GetOrientation(), + small_drill ); } } diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index 5e57a1a503..1faabd2388 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1171,16 +1171,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->m_CornersList.size(); + int count = item->Outline()->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->m_CornersList[ndx].x, - item->m_Poly->m_CornersList[ndx].y ); + wxPoint point( item->Outline()->m_CornersList[ndx].x, + item->Outline()->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->m_CornersList[ndx].end_contour ) + if( item->Outline()->m_CornersList[ndx].end_contour ) break; } @@ -1190,7 +1190,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->m_CornersList[ndx-1].end_contour ) + if( item->Outline()->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( plane ); plane->AddWindow( window ); @@ -1204,8 +1204,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->m_CornersList[ndx].x, - item->m_Poly->m_CornersList[ndx].y ); + wxPoint point(item->Outline()->m_CornersList[ndx].x, + item->Outline()->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } @@ -1246,16 +1246,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->m_CornersList.size(); + int count = item->Outline()->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->m_CornersList[ndx].x, - item->m_Poly->m_CornersList[ndx].y ); + wxPoint point( item->Outline()->m_CornersList[ndx].x, + item->Outline()->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->m_CornersList[ndx].end_contour ) + if( item->Outline()->m_CornersList[ndx].end_contour ) break; } @@ -1265,7 +1265,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->m_CornersList[ndx-1].end_contour ) + if( item->Outline()->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( keepout ); keepout->AddWindow( window ); @@ -1279,8 +1279,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->m_CornersList[ndx].x, - item->m_Poly->m_CornersList[ndx].y ); + wxPoint point(item->Outline()->m_CornersList[ndx].x, + item->Outline()->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 904940ab4e..b767aed295 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -38,23 +38,7 @@ #include #include -/* Local functions */ -/* Local variables */ - - -/** - * Function BuildFilledPolysListData - * Build m_FilledPolysList data from real outlines (m_Poly) - * in order to have drawable (and plottable) filled polygons - * drawable filled polygons are polygons without hole - * @param aPcb: the current board (can be NULL for non copper zones) - * @param aCornerBuffer: A reference to a buffer to put polygon corners, or NULL - * if NULL (default), uses m_FilledPolysList and fill current zone. - * @return number of polygons - * This function does not add holes for pads and tracks but calls - * AddClearanceAreasPolygonsToPolysList() to do that for copper layers - */ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector * aCornerBuffer ) { if( aCornerBuffer == NULL ) @@ -125,12 +109,13 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); } if ( m_FillMode ) // if fill mode uses segments, create them: - Fill_Zone_Areas_With_Segments( ); + FillZoneAreasWithSegments( ); } return 1; } + // Sort function to build filled zones static bool SortByXValues( const int& a, const int &b) { @@ -138,22 +123,14 @@ static bool SortByXValues( const int& a, const int &b) } -/** - * Function Fill_Zone_Areas_With_Segments - * Fill sub areas in a zone with segments with m_ZoneMinThickness width - * A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness. - * all intersecting points with the horizontal infinite line and polygons to fill are calculated - * a list of SEGZONE items is built, line per line - * @return number of segments created - */ -int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() +int ZONE_CONTAINER::FillZoneAreasWithSegments() { int ics, ice; int count = 0; std::vector x_coordinates; bool error = false; - int istart, iend; // index od the starting and the endif corner of one filled area in m_FilledPolysList + int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList int margin = m_ZoneMinThickness * 2 / 10; int minwidth = Mils2iu( 2 ); @@ -165,6 +142,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() m_FillSegmList.clear(); istart = 0; int end_list = m_FilledPolysList.size()-1; + for( int ic = 0; ic <= end_list; ic++ ) { CPolyPt* corner = &m_FilledPolysList[ic]; @@ -181,10 +159,12 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() { // find all intersection points of an infinite line with polyline sides x_coordinates.clear(); + for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) { if ( m_FilledPolysList[ice].m_utility ) continue; + int seg_startX = m_FilledPolysList[ics].x; int seg_startY = m_FilledPolysList[ics].y; int seg_endX = m_FilledPolysList[ice].x; @@ -202,20 +182,25 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() /* at this point refy is between seg_startY and seg_endY * see if an horizontal line at Y = refy is intersecting this segment */ - // calculate the x position of the intersection of this segment and the infinite line - // this is more easier if we move the X,Y axis origin to the segment start point: + // calculate the x position of the intersection of this segment and the + // infinite line this is more easier if we move the X,Y axis origin to + // the segment start point: seg_endX -= seg_startX; seg_endY -= seg_startY; double newrefy = (double) (refy - seg_startY); double intersec_x; + if ( seg_endY == 0 ) // horizontal segment on the same line: skip continue; - // Now calculate the x intersection coordinate of the horizontal line at y = newrefy - // and the segment from (0,0) to (seg_endX,seg_endY) - // with the horizontal line at the new refy position - // the line slope is slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY - // and the x pos relative to the new origin is intersec_x = refy/slope = refy * inv_slope - // Note: because horizontal segments are already tested and skipped, slope exists (seg_end_y not O) + + // Now calculate the x intersection coordinate of the horizontal line at + // y = newrefy and the segment from (0,0) to (seg_endX,seg_endY) with the + // horizontal line at the new refy position the line slope is: + // slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY + // and the x pos relative to the new origin is: + // intersec_x = refy/slope = refy * inv_slope + // Note: because horizontal segments are already tested and skipped, slope + // exists (seg_end_y not O) double inv_slope = (double)seg_endX / seg_endY; intersec_x = newrefy * inv_slope; x_coordinates.push_back((int) intersec_x + seg_startX); diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index b734b655d1..c931dc5d09 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -126,7 +126,7 @@ void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone ) if( success ) { zoneSettings.ExportSetting( *newZone ); - newZone->m_Poly->Hatch(); + newZone->Outline()->Hatch(); s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); @@ -176,7 +176,7 @@ int PCB_EDIT_FRAME::Delete_LastCreatedCorner( wxDC* DC ) if( zone->GetNumCorners() > 2 ) { - zone->m_Poly->DeleteCorner( zone->GetNumCorners() - 1 ); + zone->Outline()->DeleteCorner( zone->GetNumCorners() - 1 ); if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); @@ -239,11 +239,11 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone, // Prepare copy of old zones, for undo/redo. // if the corner is new, remove it from list, save and insert it in list - int cx = aZone->m_Poly->GetX( corner_id ); - int cy = aZone->m_Poly->GetY( corner_id ); + int cx = aZone->Outline()->GetX( corner_id ); + int cy = aZone->Outline()->GetY( corner_id ); if ( IsNewCorner ) - aZone->m_Poly->DeleteCorner( corner_id ); + aZone->Outline()->DeleteCorner( corner_id ); s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems(); @@ -252,7 +252,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone, aZone->GetLayer() ); if ( IsNewCorner ) - aZone->m_Poly->InsertCorner(corner_id-1, cx, cy ); + aZone->Outline()->InsertCorner(corner_id-1, cx, cy ); aZone->SetFlags( IN_EDIT ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, @@ -269,7 +269,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC, int corner_id ) { aZone->SetFlags( IS_DRAGGED ); - aZone->m_CornerSelection = corner_id; + aZone->SetSelectedCorner( corner_id ); m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, Abort_Zone_Move_Corner_Or_Outlines ); s_CursorLastPosition = s_CornerInitialPosition = GetScreen()->GetCrossHairPosition(); @@ -358,7 +358,7 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone ) { OnModify(); - if( aZone->m_Poly->GetNumCorners() <= 3 ) + if( aZone->Outline()->GetNumCorners() <= 3 ) { m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() ); @@ -382,9 +382,8 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone ) s_AuxiliaryList.ClearListAndDeleteItems(); s_PickedList. ClearListAndDeleteItems(); - SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), - aZone->GetLayer() ); - aZone->m_Poly->DeleteCorner( aZone->m_CornerSelection ); + SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() ); + aZone->Outline()->DeleteCorner( aZone->GetSelectedCorner() ); // modify zones outlines according to the new aZone shape GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); @@ -438,12 +437,12 @@ void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC ) { if( s_CornerIsNew ) { - zone->m_Poly->DeleteCorner( zone->m_CornerSelection ); + zone->Outline()->DeleteCorner( zone->GetSelectedCorner() ); } else { wxPoint pos = s_CornerInitialPosition; - zone->m_Poly->MoveCorner( zone->m_CornerSelection, pos.x, pos.y ); + zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y ); } } @@ -489,7 +488,7 @@ void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC* } else { - zone->m_Poly->MoveCorner( zone->m_CornerSelection, pos.x, pos.y ); + zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y ); } zone->Draw( aPanel, aDC, GR_XOR ); @@ -651,10 +650,10 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC ) zoneInfo.ExportSetting( *zone ); - zone->m_Poly->Start( zoneInfo.m_CurrentZone_Layer, - GetScreen()->GetCrossHairPosition().x, - GetScreen()->GetCrossHairPosition().y, - zone->GetHatchStyle() ); + zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer, + GetScreen()->GetCrossHairPosition().x, + GetScreen()->GetCrossHairPosition().y, + zone->GetHatchStyle() ); zone->AppendCorner( GetScreen()->GetCrossHairPosition() ); @@ -715,7 +714,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC ) } // Remove the last corner if is is at the same location as the prevoius corner - zone->m_Poly->RemoveNullSegments(); + zone->Outline()->RemoveNullSegments(); // Validate the current edge: int icorner = zone->GetNumCorners() - 1; @@ -752,7 +751,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC ) // Put new zone in list if( !s_CurrentZone ) { - zone->m_Poly->CloseLastContour(); // Close the current corner list + zone->Outline()->CloseLastContour(); // Close the current corner list GetBoard()->Add( zone ); GetBoard()->m_CurrentZoneContour = NULL; @@ -767,7 +766,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC ) s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) ); } - s_CurrentZone->m_Poly->CloseLastContour(); // Close the current corner list + s_CurrentZone->Outline()->CloseLastContour(); // Close the current corner list zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list. zone = s_CurrentZone; } @@ -924,7 +923,7 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone ) void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone ) { - int ncont = aZone->m_Poly->GetContour( aZone->m_CornerSelection ); + int ncont = aZone->Outline()->GetContour( aZone->GetSelectedCorner() ); EDA_RECT dirty = aZone->GetBoundingBox(); @@ -943,7 +942,7 @@ void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone ) else { SaveCopyInUndoList( aZone, UR_CHANGED ); - aZone->m_Poly->RemoveContour( ncont ); + aZone->Outline()->RemoveContour( ncont ); } m_canvas->RefreshDrawingRect( dirty ); 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 835f49bdb8..6003f99c33 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -437,7 +437,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // Remove insulated islands: if( GetNet() > 0 ) - Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); + TestForCopperIslandAndRemoveInsulatedIslands( aPcb ); // Now we remove all unused thermal stubs. cornerBufferPolysToSubstract.clear(); @@ -462,7 +462,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); if( GetNet() > 0 ) - Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); + TestForCopperIslandAndRemoveInsulatedIslands( aPcb ); } cornerBufferPolysToSubstract.clear(); diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index f898be0d3e..e113f7a61a 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -113,9 +113,9 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) // Compare outlines wxASSERT( m_Poly ); // m_Poly == NULL Should never happen - wxASSERT( aZoneToCompare.m_Poly ); + wxASSERT( aZoneToCompare.Outline() ); - if( m_Poly->m_CornersList != aZoneToCompare.m_Poly->m_CornersList ) // Compare vector + if( Outline()->m_CornersList != aZoneToCompare.Outline()->m_CornersList ) // Compare vector return false; return true; diff --git a/pcbnew/zones_polygons_insulated_copper_islands.cpp b/pcbnew/zones_polygons_insulated_copper_islands.cpp index 61a8435531..2b1cfa9369 100644 --- a/pcbnew/zones_polygons_insulated_copper_islands.cpp +++ b/pcbnew/zones_polygons_insulated_copper_islands.cpp @@ -38,12 +38,7 @@ #include -/** - * Function Test_For_Copper_Island_And_Remove__Insulated_Islands - * Remove insulated copper islands found in m_FilledPolysList. - * @param aPcb = the board to analyse - */ -void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD * aPcb ) +void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb ) { if( m_FilledPolysList.size() == 0 ) return; @@ -124,15 +119,6 @@ void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD } -/** - * Function CalculateSubAreaBoundaryBox - * Calculates the bounding box of a a filled area ( list of CPolyPt ) - * use m_FilledPolysList as list of CPolyPt (that are the corners of one or more polygons or - * filled areas ) - * @return an EDA_RECT as bounding box - * @param aIndexStart = index of the first corner of a polygon (filled area) in m_FilledPolysList - * @param aIndexEnd = index of the last corner of a polygon in m_FilledPolysList - */ EDA_RECT ZONE_CONTAINER::CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd ) { CPolyPt start_point, end_point; diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index d7b44c3eec..ff9b736a3b 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -45,149 +45,9 @@ #define STRAIGHT 0 // To be remove after math_for_graphics code cleanup -/** - * Function AddArea - * Add an empty copper area to board areas list - * @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful - * in undo commands) can be NULL - * @param aNetcode = the necode of the copper area (0 = no net) - * @param aLayer = the layer of area - * @param aStartPointPosition = position of the first point of the polygon outline of this area - * @param aHatch = hacth option - * @return pointer to the new area - */ -ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, - int aLayer, wxPoint aStartPointPosition, int aHatch ) -{ - ZONE_CONTAINER* new_area = InsertArea( aNetcode, - m_ZoneDescriptorList.size( ) - 1, - aLayer, aStartPointPosition.x, - aStartPointPosition.y, aHatch ); - if( aNewZonesList ) - { - ITEM_PICKER picker( new_area, UR_NEW ); - aNewZonesList->PushItem( picker ); - } - return new_area; -} - - -/** - * Function RemoveArea - * remove copper area from net, and put it in a deleted list (if exists) - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo - * commands) can be NULL - * @param area_to_remove = area to delete or put in deleted list - */ -void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove ) -{ - if( area_to_remove == NULL ) - return; - - if( aDeletedList ) - { - ITEM_PICKER picker( area_to_remove, UR_DELETED ); - aDeletedList->PushItem( picker ); - Remove( area_to_remove ); // remove from zone list, but does not delete it - } - else - { - Delete( area_to_remove ); - } -} - - -/** - * Function InsertArea - * add empty copper area to net, inserting after m_ZoneDescriptorList[iarea] - * @return pointer to the new area - */ -ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ) -{ - ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); - - new_area->SetNet( netcode ); - new_area->SetLayer( layer ); - new_area->SetTimeStamp( GetNewTimeStamp() ); - - if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) ) - m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area ); - else - m_ZoneDescriptorList.push_back( new_area ); - - new_area->m_Poly->Start( layer, x, y, hatch ); - return new_area; -} - - -/** - * Function NormalizeAreaPolygon - * Process an area that has been modified, by normalizing its polygon against itself. - * i.e. convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s) - * This may change the number and order of copper areas in the net. - * @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new created areas - * @param aCurrArea = the zone to process - * @return true if changes are made - * Also sets areas->utility1 flags if areas are modified - */ -bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, - ZONE_CONTAINER* aCurrArea ) -{ - CPolyLine* curr_polygon = aCurrArea->m_Poly; - - // mark all areas as unmodified except this one, if modified - for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) - m_ZoneDescriptorList[ia]->utility = 0; - - aCurrArea->utility = 1; - - if( curr_polygon->IsPolygonSelfIntersecting() ) - { - std::vector* pa = new std::vector; - curr_polygon->UnHatch(); - int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa ); - - // If clipping has created some polygons, we must add these new copper areas. - if( n_poly > 1 ) - { - ZONE_CONTAINER* NewArea; - - for( int ip = 1; ip < n_poly; ip++ ) - { - // create new copper area and copy poly into it - CPolyLine* new_p = (*pa)[ip - 1]; - NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(), - wxPoint(0, 0), CPolyLine::NO_HATCH ); - - // remove the poly that was automatically created for the new area - // and replace it with a poly from NormalizeAreaOutlines - delete NewArea->m_Poly; - NewArea->m_Poly = new_p; - NewArea->m_Poly->Hatch(); - NewArea->utility = 1; - } - } - delete pa; - } - - curr_polygon->Hatch(); - - return true; -} - - -/** - * Process an area that has been modified, by normalizing its polygon - * and merging the intersecting polygons for any other areas on the same net. - * This may change the number and order of copper areas in the net. - * @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas - * (useful in undo commands can be NULL - * @param modified_area = area to test - * @return true if some areas modified - */ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, - ZONE_CONTAINER* modified_area ) + ZONE_CONTAINER* modified_area ) { // clip polygon against itself bool modified = NormalizeAreaPolygon( aModifiedZonesList, modified_area ); @@ -225,18 +85,8 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, } -/** - * Function CombineAllAreasInNet - * Checks all copper areas in net for intersections, combining them if found - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful - * in undo commands can be NULL - * @param aNetCode = net to consider - * @param aUseUtility : if true, don't check areas if both utility flags are 0 - * Sets utility flag = 1 for any areas modified - * @return true if some areas modified - */ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, - bool aUseUtility ) + bool aUseUtility ) { if( m_ZoneDescriptorList.size() <= 1 ) return false; @@ -247,11 +97,12 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) { ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; + if( curr_area->GetNet() != aNetCode ) continue; // legal polygon - CRect b1 = curr_area->m_Poly->GetCornerBounds(); + CRect b1 = curr_area->Outline()->GetCornerBounds(); bool mod_ia1 = false; for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) @@ -270,12 +121,13 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, if( curr_area->GetLayer() != area2->GetLayer() ) continue; - CRect b2 = area2->m_Poly->GetCornerBounds(); + CRect b2 = area2->Outline()->GetCornerBounds(); + if( !( b1.left > b2.right || b1.right < b2.left || b1.bottom > b2.top || b1.top < b2.bottom ) ) { // check area2 against curr_area - if( curr_area->utility || area2->utility || aUseUtility == false ) + if( curr_area->GetFlags() || area2->GetFlags() || aUseUtility == false ) { bool ret = TestAreaIntersection( curr_area, area2 ); @@ -299,11 +151,6 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, } -/** - * Function TestAreaIntersections - * Check for intersection of a given copper area with other areas in same net - * @param area_to_test = area to compare to all other areas in the same net - */ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) { for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) @@ -336,22 +183,14 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) } -/** - * Function TestAreaIntersection - * Test for intersection of 2 copper areas - * area_to_test must be after area_ref in m_ZoneDescriptorList - * @param area_ref = area reference - * @param area_to_test = area to compare for intersection calculations - * @return : false if no intersection, true if intersection - */ bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ) { // see if areas are on same layer if( area_ref->GetLayer() != area_to_test->GetLayer() ) return false; - CPolyLine* poly1 = area_ref->m_Poly; - CPolyLine* poly2 = area_to_test->m_Poly; + CPolyLine* poly1 = area_ref->Outline(); + CPolyLine* poly2 = area_to_test->Outline(); // test bounding rects CRect b1 = poly1->GetCornerBounds(); @@ -443,20 +282,8 @@ bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area } -/** - * Function CombineAreas - * Merge 2 copper areas (which are expected intersecting) - * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas - * (useful for undo command) - * @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 : true if area_to_combine is combined with area_ref (and therefore be deleted) - */ - bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, - ZONE_CONTAINER* area_to_combine ) + ZONE_CONTAINER* area_to_combine ) { if( area_ref == area_to_combine ) { @@ -467,8 +294,8 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ // polygons intersect, combine them 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 ); + CopyPolysListToKiPolygonWithHole( area_ref->Outline()->m_CornersList, areaRefPoly ); + CopyPolysListToKiPolygonWithHole( area_to_combine->Outline()->m_CornersList, areaToMergePoly ); KI_POLYGON_WITH_HOLES_SET mergedOutlines; mergedOutlines.push_back( areaRefPoly ); @@ -488,47 +315,48 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ return false; areaRefPoly = mergedOutlines[0]; - area_ref->m_Poly->RemoveAllContours(); + area_ref->Outline()->RemoveAllContours(); KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin(); + // create area with external contour: Recreate only area edges, NOT holes - area_ref->m_Poly->Start( area_ref->GetLayer(), corner->x(), corner->y(), - area_ref->m_Poly->GetHatchStyle() ); + area_ref->Outline()->Start( area_ref->GetLayer(), corner->x(), corner->y(), + area_ref->Outline()->GetHatchStyle() ); + while( ++corner != areaRefPoly.end() ) { - area_ref->m_Poly->AppendCorner( corner->x(), corner->y() ); + area_ref->Outline()->AppendCorner( corner->x(), corner->y() ); } - area_ref->m_Poly->CloseLastContour(); + area_ref->Outline()->CloseLastContour(); // 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() ) { - area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() ); + area_ref->Outline()->AppendCorner( hole_corner->x(), hole_corner->y() ); hole_corner++; } - area_ref->m_Poly->CloseLastContour(); + + area_ref->Outline()->CloseLastContour(); hole++; } RemoveArea( aDeletedList, area_to_combine ); - area_ref->utility = 1; - area_ref->m_Poly->Hatch(); + area_ref->SetFlags( 1 ); + area_ref->Outline()->Hatch(); return true; } -/* Tests area outlines for DRC: areas inside other areas or too close. - * aArea_To_Examine: area to compare with other areas, - * or if NULL then all areas are compared to all others. - */ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine, bool aCreate_Markers ) { @@ -713,15 +541,6 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E } -/* tests a segment in ZONE_CONTAINER * aArea: - * Test Edge inside other areas - * Test Edge too close other areas - * aArea is the current area. - * aCornerIndex is the index of the first corner (starting point) - * of the edge segment to test. - * return false if DRC error or true if OK - */ - bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) { if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer @@ -733,7 +552,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->m_CornersList[aCornerIndex].end_contour == false + if( aArea->Outline()->m_CornersList[aCornerIndex].end_contour == false && aCornerIndex < (aArea->GetNumCorners() - 1) ) { end = aArea->GetCornerPosition( aCornerIndex + 1 ); @@ -746,7 +565,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) while( ii >= 0 ) { - if( aArea->m_Poly->m_CornersList[ii].end_contour ) + if( aArea->Outline()->m_CornersList[ii].end_contour ) break; end = aArea->GetCornerPosition( ii ); @@ -783,7 +602,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) zone_clearance = 1; // test for ending line inside area_to_test - if( area_to_test->m_Poly->TestPointInside( end.x, end.y ) ) + if( area_to_test->Outline()->TestPointInside( end.x, end.y ) ) { // COPPERAREA_COPPERAREA error: corner inside copper area m_currentMarker = fillMarker( aArea, end, @@ -798,26 +617,26 @@ 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->GetContoursCount(); icont2++ ) + for( int icont2 = 0; icont2 < area_to_test->Outline()->GetContoursCount(); icont2++ ) { - int ic_start2 = area_to_test->m_Poly->GetContourStart( icont2 ); - int ic_end2 = area_to_test->m_Poly->GetContourEnd( icont2 ); + int ic_start2 = area_to_test->Outline()->GetContourStart( icont2 ); + int ic_end2 = area_to_test->Outline()->GetContourEnd( icont2 ); for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) { - int bx1 = area_to_test->m_Poly->GetX( ic2 ); - int by1 = area_to_test->m_Poly->GetY( ic2 ); + int bx1 = area_to_test->Outline()->GetX( ic2 ); + int by1 = area_to_test->Outline()->GetY( ic2 ); int bx2, by2; if( ic2 == ic_end2 ) { - bx2 = area_to_test->m_Poly->GetX( ic_start2 ); - by2 = area_to_test->m_Poly->GetY( ic_start2 ); + bx2 = area_to_test->Outline()->GetX( ic_start2 ); + by2 = area_to_test->Outline()->GetY( ic_start2 ); } else { - bx2 = area_to_test->m_Poly->GetX( ic2 + 1 ); - by2 = area_to_test->m_Poly->GetY( ic2 + 1 ); + bx2 = area_to_test->Outline()->GetX( ic2 + 1 ); + by2 = area_to_test->Outline()->GetY( ic2 + 1 ); } int x, y; // variables containing the intersecting point coordinates