KiCad PCB EDA Suite
pcb_expr_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 #include <cstdio>
26 #include <memory>
27 #include <board.h>
28 #include <track.h>
29 #include <geometry/shape_segment.h>
30 #include <pcb_expr_evaluator.h>
31 
35 
36 #include <drc/drc_engine.h>
37 #include <geometry/shape_circle.h>
38 
39 bool exprFromTo( LIBEVAL::CONTEXT* aCtx, void* self )
40 {
41  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
42  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
43  LIBEVAL::VALUE* result = aCtx->AllocValue();
44 
45  LIBEVAL::VALUE* argTo = aCtx->Pop();
46  LIBEVAL::VALUE* argFrom = aCtx->Pop();
47 
48  result->Set(0.0);
49  aCtx->Push( result );
50 
51  if(!item)
52  return false;
53 
54  auto ftCache = item->GetBoard()->GetConnectivity()->GetFromToCache();
55 
56  if( !ftCache )
57  {
58  wxLogWarning( "Attempting to call fromTo() with non-existent from-to cache, aborting...");
59  return true;
60  }
61 
62  if( ftCache->IsOnFromToPath( static_cast<BOARD_CONNECTED_ITEM*>( item ),
63  argFrom->AsString(), argTo->AsString() ) )
64  {
65  result->Set(1.0);
66  }
67 
68  return true;
69 }
70 
71 
72 static void existsOnLayer( LIBEVAL::CONTEXT* aCtx, void *self )
73 {
74  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
75  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
76 
77  LIBEVAL::VALUE* arg = aCtx->Pop();
78  LIBEVAL::VALUE* result = aCtx->AllocValue();
79 
80  result->Set( 0.0 );
81  aCtx->Push( result );
82 
83  if( !item )
84  return;
85 
86  if( !arg )
87  {
88  aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
89  wxT( "existsOnLayer()" ) ) );
90  return;
91  }
92 
93  wxString layerName = arg->AsString();
94  wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
95  bool anyMatch = false;
96 
97  for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
98  {
99  wxPGChoiceEntry& entry = layerMap[ii];
100 
101  if( entry.GetText().Matches( layerName ) )
102  {
103  anyMatch = true;
104 
105  if( item->IsOnLayer( ToLAYER_ID( entry.GetValue() ) ) )
106  {
107  result->Set( 1.0 );
108  return;
109  }
110  }
111  }
112 
113  if( !anyMatch )
114  aCtx->ReportError( wxString::Format( _( "Unrecognized layer '%s'" ), layerName ) );
115 }
116 
117 
118 static void isPlated( LIBEVAL::CONTEXT* aCtx, void* self )
119 {
120  LIBEVAL::VALUE* result = aCtx->AllocValue();
121 
122  result->Set( 0.0 );
123  aCtx->Push( result );
124 
125  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
126  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
127  PAD* pad = dynamic_cast<PAD*>( item );
128 
129  if( pad && pad->GetAttribute() == PAD_ATTRIB_PTH )
130  result->Set( 1.0 );
131 }
132 
133 
134 static void insideCourtyard( LIBEVAL::CONTEXT* aCtx, void* self )
135 {
136  PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
137  LIBEVAL::VALUE* arg = aCtx->Pop();
138  LIBEVAL::VALUE* result = aCtx->AllocValue();
139 
140  result->Set( 0.0 );
141  aCtx->Push( result );
142 
143  if( !arg )
144  {
145  aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
146  wxT( "insideCourtyard()" ) ) );
147  return;
148  }
149 
150  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
151  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
152  FOOTPRINT* footprint = nullptr;
153 
154  if( !item )
155  return;
156 
157  if( arg->AsString() == "A" )
158  {
159  footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 0 ) );
160  }
161  else if( arg->AsString() == "B" )
162  {
163  footprint = dynamic_cast<FOOTPRINT*>( context->GetItem( 1 ) );
164  }
165  else
166  {
167  for( FOOTPRINT* candidate : item->GetBoard()->Footprints() )
168  {
169  if( candidate->GetReference().Matches( arg->AsString() ) )
170  {
171  footprint = candidate;
172  break;
173  }
174  }
175  }
176 
177  if( footprint )
178  {
179  SHAPE_POLY_SET footprintCourtyard;
180 
181  if( footprint->IsFlipped() )
182  footprintCourtyard = footprint->GetPolyCourtyardBack();
183  else
184  footprintCourtyard = footprint->GetPolyCourtyardFront();
185 
186  SHAPE_POLY_SET testPoly;
187 
188  item->TransformShapeWithClearanceToPolygon( testPoly, context->GetLayer(), 0,
189  ARC_LOW_DEF, ERROR_INSIDE );
190  testPoly.BooleanIntersection( footprintCourtyard, SHAPE_POLY_SET::PM_FAST );
191 
192  if( testPoly.OutlineCount() )
193  result->Set( 1.0 );
194  }
195 }
196 
197 
198 static void insideArea( LIBEVAL::CONTEXT* aCtx, void* self )
199 {
200  PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
201  LIBEVAL::VALUE* arg = aCtx->Pop();
202  LIBEVAL::VALUE* result = aCtx->AllocValue();
203 
204  result->Set( 0.0 );
205  aCtx->Push( result );
206 
207  if( !arg )
208  {
209  aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
210  wxT( "insideArea()" ) ) );
211  return;
212  }
213 
214  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
215  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
216 
217  if( !item )
218  return;
219 
220  auto insideZone =
221  [&]( ZONE* zone ) -> bool
222  {
223  if( !zone )
224  return false;
225 
226  if( !zone->GetCachedBoundingBox().Intersects( item->GetBoundingBox() ) )
227  return false;
228 
229  if( item->GetFlags() & HOLE_PROXY )
230  {
231  if( item->Type() == PCB_PAD_T )
232  {
233  PAD* pad = static_cast<PAD*>( item );
234  const SHAPE_SEGMENT* holeShape = pad->GetEffectiveHoleShape();
235 
236  return zone->Outline()->Collide( holeShape );
237  }
238  else if( item->Type() == PCB_VIA_T )
239  {
240  VIA* via = static_cast<VIA*>( item );
241  const SHAPE_CIRCLE holeShape( via->GetPosition(), via->GetDrillValue() );
242 
243  return zone->Outline()->Collide( &holeShape );
244  }
245 
246  return false;
247  }
248 
249  if( item->Type() == PCB_FOOTPRINT_T )
250  {
251  FOOTPRINT* footprint = static_cast<FOOTPRINT*>( item );
252 
253  if( ( footprint->GetFlags() & MALFORMED_COURTYARDS ) != 0 )
254  {
255  aCtx->ReportError( _( "Footprint's courtyard is not a single, closed shape." ) );
256  return false;
257  }
258 
259  if( ( zone->GetLayerSet() & LSET::FrontMask() ).any() )
260  {
261  SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyardFront();
262 
263  if( courtyard.OutlineCount() == 0 )
264  {
265  aCtx->ReportError( _( "Footprint has no front courtyard." ) );
266  return false;
267  }
268  else
269  {
270  return zone->Outline()->Collide( &courtyard.Outline( 0 ) );
271  }
272  }
273 
274  if( ( zone->GetLayerSet() & LSET::BackMask() ).any() )
275  {
276  SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyardBack();
277 
278  if( courtyard.OutlineCount() == 0 )
279  {
280  aCtx->ReportError( _( "Footprint has no back courtyard." ) );
281  return false;
282  }
283  else
284  {
285  return zone->Outline()->Collide( &courtyard.Outline( 0 ) );
286  }
287  }
288 
289  return false;
290  }
291 
292 
293  std::shared_ptr<SHAPE> shape = item->GetEffectiveShape( context->GetLayer() );
294 
295  return zone->Outline()->Collide( shape.get() );
296  };
297 
298  if( arg->AsString() == "A" )
299  {
300  if( insideZone( dynamic_cast<ZONE*>( context->GetItem( 0 ) ) ) )
301  result->Set( 1.0 );
302  }
303  else if( arg->AsString() == "B" )
304  {
305  if( insideZone( dynamic_cast<ZONE*>( context->GetItem( 1 ) ) ) )
306  result->Set( 1.0 );
307  }
308  else if( KIID::SniffTest( arg->AsString() ) )
309  {
310  KIID target( arg->AsString() );
311 
312  for( ZONE* candidate : item->GetBoard()->Zones() )
313  {
314  // Only a single zone can match the UUID; exit once we find a match whether
315  // "inside" or not
316  if( candidate->m_Uuid == target )
317  {
318  if( insideZone( candidate ) )
319  result->Set( 1.0 );
320 
321  return;
322  }
323  }
324 
325  for( FOOTPRINT* footprint : item->GetBoard()->Footprints() )
326  {
327  for( ZONE* candidate : footprint->Zones() )
328  {
329  // Only a single zone can match the UUID; exit once we find a match whether
330  // "inside" or not
331  if( candidate->m_Uuid == target )
332  {
333  if( insideZone( candidate ) )
334  result->Set( 1.0 );
335 
336  return;
337  }
338  }
339  }
340  }
341  else // Match on zone name
342  {
343  for( ZONE* candidate : item->GetBoard()->Zones() )
344  {
345  if( candidate->GetZoneName().Matches( arg->AsString() ) )
346  {
347  // Many zones can match the name; exit only when we find an "inside"
348  if( insideZone( candidate ) )
349  {
350  result->Set( 1.0 );
351  return;
352  }
353  }
354  }
355 
356  for( FOOTPRINT* footprint : item->GetBoard()->Footprints() )
357  {
358  for( ZONE* candidate : footprint->Zones() )
359  {
360  // Many zones can match the name; exit only when we find an "inside"
361  if( candidate->GetZoneName().Matches( arg->AsString() ) )
362  {
363  if( insideZone( candidate ) )
364  {
365  result->Set( 1.0 );
366  return;
367  }
368  }
369  }
370  }
371  }
372 }
373 
374 
375 static void memberOf( LIBEVAL::CONTEXT* aCtx, void* self )
376 {
377  LIBEVAL::VALUE* arg = aCtx->Pop();
378  LIBEVAL::VALUE* result = aCtx->AllocValue();
379 
380  result->Set( 0.0 );
381  aCtx->Push( result );
382 
383  if( !arg )
384  {
385  aCtx->ReportError( wxString::Format( _( "Missing argument to '%s'" ),
386  wxT( "memberOf()" ) ) );
387  return;
388  }
389 
390  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
391  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
392 
393  if( !item )
394  return;
395 
396  PCB_GROUP* group = item->GetParentGroup();
397 
398  if( !group && item->GetParent() && item->GetParent()->Type() == PCB_FOOTPRINT_T )
399  group = item->GetParent()->GetParentGroup();
400 
401  while( group )
402  {
403  if( group->GetName().Matches( arg->AsString() ) )
404  {
405  result->Set( 1.0 );
406  return;
407  }
408 
409  group = group->GetParentGroup();
410  }
411 }
412 
413 
414 static void isMicroVia( LIBEVAL::CONTEXT* aCtx, void* self )
415 {
416  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
417  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
418  LIBEVAL::VALUE* result = aCtx->AllocValue();
419 
420  result->Set( 0.0 );
421  aCtx->Push( result );
422 
423  auto via = dyn_cast<VIA*>( item );
424 
425  if( via && via->GetViaType() == VIATYPE::MICROVIA )
426  {
427  result->Set ( 1.0 );
428  }
429 }
430 
431 
432 static void isBlindBuriedVia( LIBEVAL::CONTEXT* aCtx, void* self )
433 {
434  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
435  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
436  LIBEVAL::VALUE* result = aCtx->AllocValue();
437 
438  result->Set( 0.0 );
439  aCtx->Push( result );
440 
441  auto via = dyn_cast<VIA*>( item );
442 
443  if( via && via->GetViaType() == VIATYPE::BLIND_BURIED )
444  {
445  result->Set ( 1.0 );
446  }
447 }
448 
449 
450 static void isDiffPair( LIBEVAL::CONTEXT* aCtx, void* self )
451 {
452  PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
453  BOARD_ITEM* item = vref ? vref->GetObject( aCtx ) : nullptr;
454  LIBEVAL::VALUE* result = aCtx->AllocValue();
455 
456  result->Set( 0.0 );
457  aCtx->Push( result );
458 
459  if( item && item->IsConnected() )
460  {
461  NETINFO_ITEM* netinfo = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNet();
462  int dummy_p, dummy_n;
463 
464  if( netinfo && DRC_ENGINE::IsNetADiffPair( item->GetBoard(), netinfo, dummy_p, dummy_n ) )
465  result->Set( 1.0 );
466  }
467 }
468 
469 
471 {
473 }
474 
475 
477 {
478  m_funcs.clear();
479  RegisterFunc( "existsOnLayer('x')", existsOnLayer );
480  RegisterFunc( "isPlated()", isPlated );
481  RegisterFunc( "insideCourtyard('x')", insideCourtyard );
482  RegisterFunc( "insideArea('x')", insideArea );
483  RegisterFunc( "isMicroVia()", isMicroVia );
484  RegisterFunc( "isBlindBuriedVia()", isBlindBuriedVia );
485  RegisterFunc( "memberOf('x')", memberOf );
486  RegisterFunc( "fromTo('x','y')", exprFromTo );
487  RegisterFunc( "isDiffPair()", isDiffPair );
488 }
489 
490 
492 {
493  wxASSERT( dynamic_cast<const PCB_EXPR_CONTEXT*>( aCtx ) );
494 
495  const PCB_EXPR_CONTEXT* ctx = static_cast<const PCB_EXPR_CONTEXT*>( aCtx );
496  BOARD_ITEM* item = ctx->GetItem( m_itemIndex );
497  return item;
498 }
499 
500 
502 {
503 public:
505  LIBEVAL::VALUE( double( aLayer ) )
506  {};
507 
508  virtual bool EqualTo( const VALUE* b ) const override
509  {
510  // For boards with user-defined layer names there will be 2 entries for each layer
511  // in the ENUM_MAP: one for the canonical layer name and one for the user layer name.
512  // We need to check against both.
513 
514  wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
515  PCB_LAYER_ID layerId = ToLAYER_ID( (int) AsDouble() );
516 
517  for( unsigned ii = 0; ii < layerMap.GetCount(); ++ii )
518  {
519  wxPGChoiceEntry& entry = layerMap[ii];
520 
521  if( entry.GetValue() == layerId && entry.GetText().Matches( b->AsString() ) )
522  return true;
523  }
524 
525  return false;
526  }
527 };
528 
529 
531 {
532  if( m_itemIndex == 2 )
533  {
534  PCB_EXPR_CONTEXT* context = static_cast<PCB_EXPR_CONTEXT*>( aCtx );
535  return PCB_LAYER_VALUE( context->GetLayer() );
536  }
537 
538  BOARD_ITEM* item = const_cast<BOARD_ITEM*>( GetObject( aCtx ) );
539  auto it = m_matchingTypes.find( TYPE_HASH( *item ) );
540 
541  if( it == m_matchingTypes.end() )
542  {
543  // Don't force user to type "A.Type == 'via' && A.Via_Type == 'buried'" when the
544  // simplier "A.Via_Type == 'buried'" is perfectly clear. Instead, return an undefined
545  // value when the property doesn't appear on a particular object.
546 
547  return LIBEVAL::VALUE();
548  }
549  else
550  {
551  if( m_type == LIBEVAL::VT_NUMERIC )
552  return LIBEVAL::VALUE( (double) item->Get<int>( it->second ) );
553  else
554  {
555  wxString str;
556 
557  if( !m_isEnum )
558  {
559  str = item->Get<wxString>( it->second );
560  }
561  else
562  {
563  const wxAny& any = item->Get( it->second );
564  any.GetAs<wxString>( &str );
565  }
566 
567  if( str == "UNDEFINED" )
568  return LIBEVAL::VALUE();
569  else
570  return LIBEVAL::VALUE( str );
571  }
572  }
573 }
574 
575 
577 {
579 
580  return registry.Get( aName.Lower() );
581 }
582 
583 
584 std::unique_ptr<LIBEVAL::VAR_REF> PCB_EXPR_UCODE::CreateVarRef( const wxString& aVar,
585  const wxString& aField )
586 {
588  std::unique_ptr<PCB_EXPR_VAR_REF> vref;
589 
590  if( aVar == "A" )
591  vref = std::make_unique<PCB_EXPR_VAR_REF>( 0 );
592  else if( aVar == "B" )
593  vref = std::make_unique<PCB_EXPR_VAR_REF>( 1 );
594  else if( aVar == "L" )
595  vref = std::make_unique<PCB_EXPR_VAR_REF>( 2 );
596  else
597  return nullptr;
598 
599  if( aField.length() == 0 ) // return reference to base object
600  {
601  return std::move( vref );
602  }
603 
604  wxString field( aField );
605  field.Replace( "_", " " );
606 
607  for( const PROPERTY_MANAGER::CLASS_INFO& cls : propMgr.GetAllClasses() )
608  {
609  if( propMgr.IsOfType( cls.type, TYPE_HASH( BOARD_ITEM ) ) )
610  {
611  PROPERTY_BASE* prop = propMgr.GetProperty( cls.type, field );
612 
613  if( prop )
614  {
615  vref->AddAllowedClass( cls.type, prop );
616 
617  if( prop->TypeHash() == TYPE_HASH( int ) )
618  {
619  vref->SetType( LIBEVAL::VT_NUMERIC );
620  }
621  else if( prop->TypeHash() == TYPE_HASH( wxString ) )
622  {
623  vref->SetType( LIBEVAL::VT_STRING );
624  }
625  else if ( prop->HasChoices() )
626  { // it's an enum, we treat it as string
627  vref->SetType( LIBEVAL::VT_STRING );
628  vref->SetIsEnum ( true );
629  }
630  else
631  {
632  wxFAIL_MSG( "PCB_EXPR_UCODE::createVarRef: Unknown property type." );
633  }
634  }
635  }
636  }
637 
638  if( vref->GetType() == LIBEVAL::VT_UNDEFINED )
639  vref->SetType( LIBEVAL::VT_PARSE_ERROR );
640 
641  return std::move( vref );
642 }
643 
644 
646 {
647 public:
649  {
650  }
651 
652  virtual const std::vector<wxString>& GetSupportedUnits() const override
653  {
654  static const std::vector<wxString> pcbUnits = { "mil", "mm", "in" };
655 
656  return pcbUnits;
657  }
658 
659  virtual wxString GetSupportedUnitsMessage() const override
660  {
661  return _( "must be mm, in, or mil" );
662  }
663 
664  virtual double Convert( const wxString& aString, int unitId ) const override
665  {
666  double v = wxAtof( aString );
667 
668  switch( unitId )
669  {
670  case 0: return DoubleValueFromString( EDA_UNITS::MILS, aString );
671  case 1: return DoubleValueFromString( EDA_UNITS::MILLIMETRES, aString );
672  case 2: return DoubleValueFromString( EDA_UNITS::INCHES, aString );
673  default: return v;
674  }
675  };
676 };
677 
678 
680 {
681  m_unitResolver = std::make_unique<PCB_UNIT_RESOLVER>();
682 }
683 
684 
686 {
687  m_result = 0;
688 }
689 
691 {
692 }
693 
694 
695 bool PCB_EXPR_EVALUATOR::Evaluate( const wxString& aExpr )
696 {
697  PCB_EXPR_UCODE ucode;
698  PCB_EXPR_CONTEXT preflightContext( F_Cu );
699 
700  if( !m_compiler.Compile( aExpr.ToUTF8().data(), &ucode, &preflightContext ) )
701  return false;
702 
703  PCB_EXPR_CONTEXT evaluationContext( F_Cu );
704  LIBEVAL::VALUE* result = ucode.Run( &evaluationContext );
705 
706  if( result->GetType() == LIBEVAL::VT_NUMERIC )
707  m_result = KiROUND( result->AsDouble() );
708 
709  return true;
710 }
711 
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:101
BOARD_ITEM * GetItem(int index) const
Definition: track.h:354
virtual bool HasChoices() const
Returns true if this PROPERTY has a limited set of possible values.
Definition: property.h:215
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:64
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:55
int OutlineCount() const
Returns the number of outlines in the set
std::unique_ptr< UNIT_RESOLVER > m_unitResolver
ZONES & Zones()
Definition: board.h:289
SHAPE_POLY_SET & GetPolyCourtyardFront()
Used in DRC to test the courtyard area (a complex polygon)
Definition: footprint.h:665
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
Definition: board_item.h:86
virtual LIBEVAL::FUNC_CALL_REF CreateFuncCall(const wxString &aName) override
PCB_GROUP is a set of BOARD_ITEMs (i.e., without duplicates)
Definition: pcb_group.h:50
void RegisterFunc(const wxString &funcSignature, LIBEVAL::FUNC_CALL_REF funcPtr)
static void isDiffPair(LIBEVAL::CONTEXT *aCtx, void *self)
LIBEVAL::FUNC_CALL_REF Get(const wxString &name)
virtual size_t TypeHash() const =0
Returns type-id of the property type.
static ENUM_MAP< T > & Instance()
Definition: property.h:519
static void isPlated(LIBEVAL::CONTEXT *aCtx, void *self)
bool exprFromTo(LIBEVAL::CONTEXT *aCtx, void *self)
static int IsNetADiffPair(BOARD *aBoard, NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
const SHAPE_SEGMENT * GetEffectiveHoleShape() const
Function GetEffectiveHoleShape Returns a SHAPE object representing the pad's hole.
Definition: pcbnew/pad.cpp:270
class PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual wxString GetSupportedUnitsMessage() const override
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
Definition: lset.cpp:867
bool Compile(const wxString &aString, UCODE *aCode, CONTEXT *aPreflightContext)
std::map< wxString, LIBEVAL::FUNC_CALL_REF > m_funcs
SHAPE_POLY_SET & GetPolyCourtyardBack()
Definition: footprint.h:666
PROPERTY_BASE * GetProperty(TYPE_ID aType, const wxString &aProperty) const
Returns a property for a specific type.
PAD_ATTR_T GetAttribute() const
Definition: pad.h:348
Definition: kiid.h:44
PCB_LAYER_ID
A quick note on layer IDs:
PCB_EXPR_COMPILER m_compiler
VAR_TYPE_T GetType() const
std::function< void(CONTEXT *, void *)> FUNC_CALL_REF
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Function IsOnLayer tests to see if this object is on the given layer.
Definition: board_item.h:239
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Function Collide()
Definition: shape_circle.h:68
static void isBlindBuriedVia(LIBEVAL::CONTEXT *aCtx, void *self)
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: track.cpp:170
wxString GetName() const
Definition: pcb_group.h:65
LIBEVAL::VAR_TYPE_T m_type
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
static bool SniffTest(const wxString &aCandidate)
Definition: kiid.cpp:96
static void existsOnLayer(LIBEVAL::CONTEXT *aCtx, void *self)
FOOTPRINTS & Footprints()
Definition: board.h:283
wxAny Get(PROPERTY_BASE *aProperty)
Definition: inspectable.h:84
virtual std::unique_ptr< LIBEVAL::VAR_REF > CreateVarRef(const wxString &aVar, const wxString &aField) override
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:382
#define MALFORMED_COURTYARDS
Definition: eda_item.h:124
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
PCB_LAYER_VALUE(PCB_LAYER_ID aLayer)
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp
static void insideArea(LIBEVAL::CONTEXT *aCtx, void *self)
class FOOTPRINT, a footprint
Definition: typeinfo.h:89
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
#define HOLE_PROXY
Indicates the BOARD_ITEM is a proxy for its hole.
Definition: eda_item.h:127
bool IsFlipped() const
function IsFlipped
Definition: footprint.h:282
virtual LIBEVAL::VALUE GetValue(LIBEVAL::CONTEXT *aCtx) override
void ReportError(const wxString &aErrorMsg)
NETINFO_ITEM handles the data for a net.
Definition: netinfo.h:65
bool IsOfType(TYPE_ID aDerived, TYPE_ID aBase) const
Returns true if aDerived is inherited from aBase.
virtual double AsDouble() const
int GetNet() const
Function GetNet.
Definition: netinfo.h:223
static void memberOf(LIBEVAL::CONTEXT *aCtx, void *self)
#define _(s)
Definition: 3d_actions.cpp:33
virtual const wxString & AsString() const
static void insideCourtyard(LIBEVAL::CONTEXT *aCtx, void *self)
Plated through hole pad.
Definition: pad_shapes.h:80
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
bool Evaluate(const wxString &aExpr)
static void isMicroVia(LIBEVAL::CONTEXT *aCtx, void *self)
virtual double Convert(const wxString &aString, int unitId) const override
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Definition: lset.cpp:874
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
Definition: board_item.cpp:153
virtual const std::vector< wxString > & GetSupportedUnits() const override
CLASSES_INFO GetAllClasses()
virtual bool IsConnected() const
Function IsConnected() Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:146
Provides class metadata.
Definition: property_mgr.h:61
virtual bool EqualTo(const VALUE *b) const override
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
virtual void TransformShapeWithClearanceToPolygon(SHAPE_POLY_SET &aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Function TransformShapeWithClearanceToPolygon Convert the item shape to a closed polygon Used in fill...
Definition: board_item.cpp:129
VALUE * Run(CONTEXT *ctx)
virtual const EDA_RECT GetBoundingBox() const
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: eda_item.cpp:89
Definition: pad.h:59
double DoubleValueFromString(EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType)
Function DoubleValueFromString converts aTextValue to a double.
Definition: base_units.cpp:333
wxPoint GetPosition() const override
Definition: track.h:422
STATUS_FLAGS GetFlags() const
Definition: eda_item.h:222
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:179
bool Collide(const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const override
Function Collide()
Definition: shape_segment.h:59
void Push(VALUE *v)
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:898
void Set(double aValue)
BOARD_ITEM * GetObject(const LIBEVAL::CONTEXT *aCtx) const
PCB_LAYER_ID GetLayer() const
std::unordered_map< TYPE_ID, PROPERTY_BASE * > m_matchingTypes
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
static PCB_EXPR_BUILTIN_FUNCTIONS & Instance()