KiCad PCB EDA Suite
class_board_item.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
10  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
11  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, you may find one here:
25  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
26  * or you may search the http://www.gnu.org website for the version 2 license,
27  * or you may write to the Free Software Foundation, Inc.,
28  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29  */
30 
31 #include <fctsys.h>
32 #include <common.h>
33 #include <pcbnew.h>
34 #include <wx/debug.h>
35 
36 #include <class_board.h>
37 #include <string>
38 
39 wxString BOARD_ITEM::ShowShape( STROKE_T aShape )
40 {
41  switch( aShape )
42  {
43  case S_SEGMENT: return _( "Line" );
44  case S_RECT: return _( "Rect" );
45  case S_ARC: return _( "Arc" );
46  case S_CIRCLE: return _( "Circle" );
47  case S_CURVE: return _( "Bezier Curve" );
48  case S_POLYGON: return _( "Polygon" );
49  default: return wxT( "??" );
50  }
51 }
52 
53 
55 {
57  wxASSERT( list );
58 
59  if( list )
60  list->Remove( this );
61 }
62 
63 
65 {
66  if( Type() == PCB_T )
67  return (BOARD*) this;
68 
69  BOARD_ITEM* parent = GetParent();
70 
71  if( parent )
72  return parent->GetBoard();
73 
74  return NULL;
75 }
76 
77 
78 wxString BOARD_ITEM::GetLayerName() const
79 {
80  BOARD* board = GetBoard();
81 
82  if( board )
83  return board->GetLayerName( m_Layer );
84 
85  // If no parent, return standard name
87 }
88 
89 
90 std::string BOARD_ITEM::FormatInternalUnits( int aValue )
91 {
92 #if 1
93 
94  char buf[50];
95  int len;
96  double mm = aValue / IU_PER_MM;
97 
98  if( mm != 0.0 && fabs( mm ) <= 0.0001 )
99  {
100  len = sprintf( buf, "%.10f", mm );
101 
102  while( --len > 0 && buf[len] == '0' )
103  buf[len] = '\0';
104 
105  if( buf[len] == '.' )
106  buf[len] = '\0';
107  else
108  ++len;
109  }
110  else
111  {
112  len = sprintf( buf, "%.10g", mm );
113  }
114 
115  return std::string( buf, len );
116 
117 #else
118 
119  // Assume aValue is in nanometers, and that we want the result in millimeters,
120  // and that int is 32 bits wide. Then perform an alternative algorithm.
121  // Can be used to verify that the above algorithm is correctly generating text.
122  // Convert aValue into an integer string, then insert a decimal point manually.
123  // Results are the same as above general purpose algorithm.
124 
125  wxASSERT( sizeof(int) == 4 );
126 
127  if( aValue == 0 )
128  return std::string( 1, '0' );
129  else
130  {
131  char buf[50];
132  int len = sprintf( buf, aValue > 0 ? "%06d" : "%07d", aValue ); // optionally pad w/leading zeros
133 
134  std::string ret( buf, len );
135 
136  std::string::iterator it = ret.end() - 1; // last byte
137 
138  // insert '.' at 6 positions from end, dividing by 10e6 (a million), nm => mm
139  std::string::iterator decpoint = ret.end() - 6;
140 
141  // truncate trailing zeros, up to decimal point position
142  for( ; *it=='0' && it >= decpoint; --it )
143  ret.erase( it ); // does not invalidate iterators it or decpoint
144 
145  if( it >= decpoint )
146  {
147  ret.insert( decpoint, '.' );
148 
149  // decpoint is invalidated here, after insert()
150 
151 #if 1 // want a leading zero when decimal point is in first position?
152  if( ret[0] == '.' )
153  {
154  // insert leading zero ahead of decimal point.
155  ret.insert( ret.begin(), '0' );
156  }
157  else if( ret[0]=='-' && ret[1]=='.' )
158  {
159  ret.insert( ret.begin() + 1, '0' );
160  }
161 #endif
162  }
163 
164  return ret;
165  }
166 
167 #endif
168 }
169 
170 
171 std::string BOARD_ITEM::FormatAngle( double aAngle )
172 {
173  char temp[50];
174 
175  int len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 );
176 
177  return std::string( temp, len );
178 }
179 
180 
181 std::string BOARD_ITEM::FormatInternalUnits( const wxPoint& aPoint )
182 {
183  return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y );
184 }
185 
186 
187 std::string BOARD_ITEM::FormatInternalUnits( const VECTOR2I& aPoint )
188 {
189  return FormatInternalUnits( aPoint.x ) + " " + FormatInternalUnits( aPoint.y );
190 }
191 
192 
193 std::string BOARD_ITEM::FormatInternalUnits( const wxSize& aSize )
194 {
195  return FormatInternalUnits( aSize.GetWidth() ) + " " + FormatInternalUnits( aSize.GetHeight() );
196 }
197 
198 
199 void BOARD_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
200 {
201  // Basic fallback
202  aCount = 1;
203  aLayers[0] = m_Layer;
204 }
205 
206 
207 int BOARD_ITEM::getTrailingInt( const wxString& aStr )
208 {
209  int number = 0;
210  int base = 1;
211 
212  // Trim and extract the trailing numeric part
213  int index = aStr.Len() - 1;
214  while( index >= 0 )
215  {
216  const char chr = aStr.GetChar( index );
217 
218  if( chr < '0' || chr > '9' )
219  break;
220 
221  number += ( chr - '0' ) * base;
222  base *= 10;
223  index--;
224  }
225 
226  return number;
227 }
228 
229 
230 int BOARD_ITEM::getNextNumberInSequence( const std::set<int>& aSeq, bool aFillSequenceGaps)
231 {
232  if( aSeq.empty() )
233  return 1;
234 
235  // By default go to the end of the sequence
236  int candidate = *aSeq.rbegin();
237 
238  // Filling in gaps in pad numbering
239  if( aFillSequenceGaps )
240  {
241  // start at the beginning
242  candidate = *aSeq.begin();
243 
244  for( auto it : aSeq )
245  {
246  if( it - candidate > 1 )
247  break;
248 
249  candidate = it;
250  }
251  }
252 
253  ++candidate;
254 
255  return candidate;
256 }
257 
258 
260 {
261  auto parent = GetParent();
262 
263  if( parent && GetList() )
264  parent->Remove( this );
265 
266  delete this;
267 }
268 
269 
271 {
272 
273 }
274 
276  int aClearanceValue,
277  int aCircleToSegmentsCount,
278  double aCorrectionFactor,
279  bool ignoreLineWidth ) const
280 {
281  wxASSERT_MSG( false, "Called TransformShapeWithClearanceToPolygon() on unsupported BOARD_ITEM." );
282 };
DHEAD * GetList() const
Definition: base_struct.h:212
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
BOARD_ITEM_CONTAINER * GetParent() const
static wxString ShowShape(STROKE_T aShape)
Function ShowShape converts the enum STROKE_T integer value to a wxString.
Definition: typeinfo.h:85
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
Class BOARD to handle a board.
polygon (not yet used for tracks, but could be in microwave apps)
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on...
void DeleteStructure()
Function DeleteStructure deletes this object after UnLink()ing it from its owner if it has one...
virtual void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, int aClearanceValue, int aCircleToSegmentsCount, double aCorrectionFactor, bool ignoreLineWidth=false) const
Function TransformShapeWithClearanceToPolygon Convert the item shape to a closed polygon Used in fill...
usual segment : line with rounded ends
virtual void UnLink()
Function UnLink detaches this object from its owner.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
static int getNextNumberInSequence(const std::set< int > &aSeq, bool aFillSequenceGaps)
static std::string FormatInternalUnits(int aValue)
Function FormatInternalUnits converts aValue from board internal units to a string appropriate for wr...
PCB_LAYER_ID m_Layer
virtual void SwapData(BOARD_ITEM *aImage)
Swap data between aItem and aImage.
segment with non rounded ends
static std::string FormatAngle(double aAngle)
Function FormatAngle converts aAngle from board units to a string appropriate for writing to file...
Class SHAPE_POLY_SET.
Arcs (with rounded ends)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
STROKE_T
Enum STROKE_T is the set of shapes for segments (graphic segments and tracks) which are often in the ...
Bezier Curve.
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:171
static int getTrailingInt(const wxString &aStr)
The common library.
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
static wxString GetStandardLayerName(PCB_LAYER_ID aLayerId)
Function GetStandardLayerName returns an "English Standard" name of a PCB layer when given aLayerNumb...
Definition: class_board.h:659