KiCommand discussion and development - Easy pcbnew command line; 4.07 & 5.1.5/.6

Major update to KiCommand, changing how it loads so it should show up in External Plugins… menu more reliably. Also added to the KiCommand Wiki showing how to create tracks and lines (DRAWSEGMENTS). Still working toward easy assignment of nets to tracks. Added some more tests to verify installation, and updated the README.md in the github repo. Please let me know if you see any issues.

Updated KiCommand to include four new commands for dealing with tracks and nets: setnetcode, setnetname, getnetcodefromname, and getallnetnames.

KiCommand has a fairly complete list of commands and each of these commands is defined by a command string. You can use the see command to view how they are defined. For example:

  • ’getnetcodefromname see 'setnetcode see - will show you how those two commands are built from other KiCommand commands.

Another update to KiCommand.

  • showparams now instead of “showparam”: to be consistent with drawparams and params commands.
  • New tests for some geometry and drawing commands.
  • round has been fixed to handle a closed loop of drawsegments.
  • rotate now works on arcs appropriately, and should handle all EDA_ITEMs.
  • list. - make a list of lists from a single list.
  • callargs now extends either args or objects to the length of the longest list.
  • These two changes enable the ability to list all layernames with the following command:
  • board list 0,64,1 range list. GetLayerName callargs - list all layer names from 0 to 63.

KiCommand now has numerous unit tests that test both KiCommand and the underlying Python commands. There are a bunch of extra commands and some changes to the help text and categories. Let me know if there’s anything unexpected.

Work continues on expanding support for nets and netclasses. Support for netclass commands will be uploaded soon.

Major update to KiCommand to include net and netclass commands. I haven’t tested the set* commands, but the get* commands work well.

I’ve tried to standardize on get* command using an argument, while commands that are nouns (like netnamemap, netcodemap, tracks, etc) retrieve board-wide lists/maps of objects. To do this, a few commands have changed, and there are perhaps a few holdover commands that still need updating.

Through all of this, one command seemed out of place: matchreference was renamed to filterrefregex (filter reference regular expression) and a corresponding filtervalregex added to complement. The filter* commands filter the objectlist provided as an argument based on matching criteria also provided as an argument.

Development continues, and comments, discussion, or questions are welcome.

In my attempt to be very flexible in handling lists, where functions operate seamlessly on the elements of a list, I’ve run into an ambiguity. I’ve recently extended call and callargs to work on lists where you can supply a list of objects and/or a list of arguments and/or a list of functions, and it works well. For example:

  • netclassmap Default sindex GetClearance,GetTrackWidth,GetViaDiameter,GetViaDrill,GetuViaDiameter,GetuViaDrill,GetDiffPairWidth,GetDiffPairGap split call - return as a list, each of the listed values from the netclassptr object.

The detection of a list is determined by identifying an iterator. If it is an iterator, it is considered a list. With this detection, a dictionary is identified as a ‘list’ because it has an iterator. This makes it more difficult to directly call dictionary functions, such as keys() or values().

The solution is either to surround the dictionary with list and delist to get past the detection mechanism, or to redefine the new call and callargs functions into call. and callargs., which indicate an element-by-element function. Then redefine the call and callargs to not operate on lists element by element.

I’m trying to keep in mind that KiCommand is primarily an interactive command line and determine what is most useful in that context.

While I decide how to proceed, comments are welcome.

Edit: Maybe I could add calld and callargsd to indicate “direct”, where I ignore the iterator status of the objectlist. My main problem is that I like the ease of use of handling lists automatically, and I want that to be the “default” for unadorned functions.

Hi @HiGreg, i wonder if i can use your KiCommand to highlight all “equal” components in PCBnew?
So for example if i wanted to highlight all resistors with value 1k and 0603 package could i use something like

show all r 1k 0603 

or can i alter specific attributes of a footprint with it like the “lock” with something like

lock all fp

I’ve read the wiki and your read.me but you talk a lot about data types and stuff but it’s not quite clear to me if and how i could achieve the two examples from above.
If this is off topic, tell me and i open a new thread.

This is exactly on topic. First thing to note is that KiCommand is stack based, so arguments occur before the command. You can get all 1k resistors by using either a regular expression or a string match. Let’s walk through the demo board available in the kicad install directory (share/kicad/demos/complex_hierarchy). Load that board then try the following:

  • modules getvaltext print - this will print the value text of all modules

on the demo board, I see:

[u’CONN_2’, u’CONN_2’, u’CONN_2’, u’CONN_2’, u’CONN_2’, u’CONN_2’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4148’, u’1N4007’, u’15nF’, u’4.7nF’, u’150nF’, u’150nF’, u’820pF’, u’15nF’, u’4.7nF’, u’820pF’, u’LM358N’, u’ICL7660’, u’LM358N’, u’5,6K’, u’220K’, u’1K’, u’1K’, u’47’, u’220K’, u’47’, u’220K’, u’47’, u’220K’, u’470’, u’4,7K’, u’22K’, u’22K’, u’1K’, u’1K’, u’5,6K’, u’4,7K’, u’220K’, u’470’, u’220K’, u’47’, u’22K’, u’1K’, u’22K’, u’1K’, u’47uF’, u’47uF/20V’, u’47uF/63V’, u’10uF’, u’10uF’, u’MPAS92’, u’MPAS42’, u’MPAS92’, u’MPAS42’, u’MPAS92’, u’MPAS42’, u’MPAS92’, u’MPAS42’, u’4,7K’, u’4,7K’, u’78L05’]

  • modules getreftext print - print the reference text of all modules

Result:

[u’P5’, u’P6’, u’P3’, u’P4’, u’P2’, u’P1’, u’D9’, u’D4’, u’D6’, u’D7’, u’D3’, u’D2’, u’D8’, u’D5’, u’D1’, u’C3’, u’C4’, u’C14’, u’C12’, u’C5’, u’C6’, u’C7’, u’C8’, u’U3’, u’U1’, u’U4’, u’R20’, u’R22’, u’R23’, u’R24’, u’R25’, u’R26’, u’R27’, u’R28’, u’R5’, u’R4’, u’R3’, u’R21’, u’R17’, u’R7’, u’R8’, u’R9’, u’R10’, u’R11’, u’R12’, u’R13’, u’R14’, u’R15’, u’R16’, u’R18’, u’R6’, u’R19’, u’C1’, u’C2’, u’C9’, u’C10’, u’C11’, u’Q1’, u’Q2’, u’Q3’, u’Q4’, u’Q5’, u’Q6’, u’Q7’, u’Q8’, u’RV1’, u’RV2’, u’U2’]

The next one is a little tricky. Getting the path of the footprint. Try this:

  • clear modules GetFPID call GetLibItemName call '__str__ call print - get the name of the footprint

One of the items here is named “R_Axial_DIN0204_L3.6mm_D1.6mm_P7.62mm_Horizontal”, which seems to indicate its size (but it’s not guaranteed).

Now that we know a little bit about the board, we can start to hone our command to get only the desired modules.

Using some commands to filter on the name and value, assuming resistors start with “R”:

  • modules R.* filterrefregex 1K filtervalregex print - filter on modules with reference beginning with R and value of 1K

But we want to make sure we get the 0603, so let’s assume that string is in the footprint path.

  • copy GetFPID call GetLibItemName call '__str__ call - get the library name

We’ll call the following command string the module selection command. It’s a combination of all the above:

clear modules R.* filterrefregex 1K filtervalregex copy GetFPID call GetLibItemName call '__str__ call .*0204.* regex filter

That’s the command we’ll use to find the modules. You’ll want to change that to 0603 instead of 0204. Then we need to get or set their Lock status. There’s not a built in KiCommand to lock a footprint, but we can drop into the python function.

Execute the above module selection command to get all the modules desired. Then execute only one of the following.

Execute the module selection command, then:

  • IsLocked call - get the Locked status of modules

Execute the module selection command, then:

  • true SetLocked callargs - set the Locked status of modules

Finally, check that it worked. Execute the module selection command, then:

  • IsLocked call - get the Locked status of modules

Edit:

I just pushed some new commands for your use case: getlocked, setlocked, clearlocked, getfootprintname and filterfpregex.

The locked commands mirror get/set/clear visible, but don’t exactly match the Python commands underneath (SetLocked/IsLocked).

Example:

  • modules R.* filterrefregex 1K filtervalregex .*0603.* filterfpregex copy setlocked getlocked print - get modules matching each of the three criteria, set the locked status, then retrieve the locked status and print out the result. Should result in a list of “True” values.
3 Likes

Thank you for this extensive post. I sadly will have no time to proceed with this until the end of next week, but I’ll come back and report a bit about my experience once I’m done.

A bit of background on my use case:
i assemble PCBs in small batches like 1-5 pieces, by hand. So i use the PCB file as reference for assembly but keep selecting anything in PCBnew but the whole footprint, that’s quite annoying and the reason why i want to lock them. It’s also very useful to be able to show all equal components so i don’t have to search for the bag with the 1k resistor 25 times :wink:

@Detzi, whether or not this can be done with KiCommand, I would recommend trying the InteractiveHtmlBom plugin for hand assembly. It’s meant exactly for your use case.

4 Likes

KiCommand has been tested on pre release 5.1.6 (April 20) on Windows and no changes were necessary. There is one test (the now command) that occasionally fails, but the test will be fixed in the next release.

In the last couple of releases of KiCommand, there has been much work on making command consistent, along with updates to call and callargs that will be useful to users. Please feel free to reach out with comments, questions, or suggestions.

DRAWSEGMENT considerations?

In an attempt to unify the creation of DRAWSEGMENTs of all types,
KiCommand could use a few different approaches.

In general, the approaches would include a command with arguments. There would be two goals:

  1. Fairly easy command-line creation of new segments.
  2. (possibly) allow the extraction of segment definition, modify some of the parameters, then create a new segment with the modified parameters.

Let’s talk about the possible methods of creating a new DRAWSEGMENT. To do that, we’ll first talk about the different DRAWSEGMENTs that exist. There are 6 within the source code, and 4 that are accessible from the GUI.

  1. Line (S_SEGMENT)
  2. Polygon (S_POLYGON)
  3. Bezier Curve (S_CURVE)
  4. Circle (S_CIRCLE)
  5. Arc (S_ARC)
  6. Rectangle (S_RECT)

Only the bolded DRAWSEGMENT types are available from the GUI, so we’ll focus on those. Specifying Line and Polygon is fairly straightforward and are easily described by the end points and vertex points, respectively.

Arc and circle are a little different, and they have multiple ways that might be desired to specify the points. One of these methods, for each type, is also the native method for creating the DRAWSEGMENT within Python.

Methods for specifying circle. I’ll also supply a shorthand name for each method. All points and dimensions would be specified in native units.

  1. CircleP CenterPoint, StartPoint (a point on the circle) - this is the native method to create a circle.
  2. CircleR CenterPoint, Radius
  3. CircleC CirclePoint1, CirclePoint2, Radius (+/- indicates direction, CW/CCW or RW/LW, make sure this matches Angle direction)

Methods for specifying an arc.

  1. ArcA StartPoint, CenterPoint, AngleDegrees (+/- indicates direction) - this is the native method to create an arc.
  2. ArcP StartPoint, EndPoint, CenterPoint
  3. ArcR StartPoint, EndPoint, RadiusNative (+/- indicates direction, CW/CCW or RW/LW, make sure this matches Angle direction)

In addition to the numbers that specify points and dimensions, there are additional paramters that might be useful to specify: thickness and layer. These are normally specified in KiCommand for all new elements through the draw parameters. Draw parameters allows you to specify the thickness and layer for all subsequent draw commands. The layer used for drawing allows the possibility that the same element commands can create either DRAWSEGMENTs or TRACKS, depending on whether or not the layer is a copper layer.

One basic question on command structure is: should the command itself specify the DRAWSEGMENT type, or should the DRAWSEGMENT type be a parameter? To allow for the possibility of extracting an existing DRAWSEGMENT’s specification, it probably makes more sense to extract the type as well. This way, when extracting several DRAWSEGMENTs at one time, the exact type of DRAWSEGMENT is included in the results.

This could result in two possible commands:

  • getsegment - returns SegmentType,ArgX,…
  • newsegment - takes a single (list) argument SegmentType,Argx,…

Where segment type is one of the strings: Line, Polygon, ArcA, ArcP, ArcR, CircleP, CircleR, CircleC. Perhaps obviously, getsegment would by definition return only ArcA, or CircleP (the native methods of specifying). However, this would preclude being able to get, for example, the Circle radius, manipulating that, and drawing a new DRAWSEGMENT.

I should definitely allow specifying the thickness and layer with the draw parameters, as this would become tedious in use not to. It might be interesting to allow layer and thickness to be specified by parameter as well.

Open questions:

  1. Should SegmentType be specified by argument within the segment list, a parameter outside the segment list, or a different command for each type?
  2. Should Layer and Thickness be optional parameters, or parameters using a different command?
  3. Should points within the parameters be specified linearly or though nested lists (X, Y points)?

The answers depend on exactly the use cases I’m trying to develop for. Perhaps I’ll generate the use cases in a subsequent post.

Does anyone have any opinions or additional considerations?

Developing this idea further.

I have basic code put together that can take an argument string and put together a list of segments. The flexibility will allow a wide variety of ways of specifying the drawsegments.

I think it’s also prudent to change the order of some arguments for Arc and Circle drawsegments.

  1. Center, if specified, is first.
  2. Radius or Angle, if specified, is last.
  3. That means any points on the segment are specified “in the middle.”
  4. All arguments can be in arbitrarily-nested lists. This might often be paired x/y points in their own list. It won’t matter how their paired or nested.
  5. Any number of numeric arguments can be specified after the segmenttype string to indicate more than one segment definition (except for polygon or (new) polyline).
  6. All numeric arguments can be specified as float, int, or string. If strings are used, they can be comma separated. Strings are converted to floats. (I might consider converting number strings without a decimal point to integers.)
  7. If not done already, i’ll Modify arithmetic operators to pass through strings (such as segment type) so you can operate on the numbers in a segment specification without affecting the segment type. It will just “pass through” unmodified.

Also, I’m trying to figure out the Arc and Circle suffix letter to be consistent between them.

More updates to come.

Here are the (proposed) general rules for circles and arcs. It’s a way to unify the specification of circles and arcs and is more consistent for both, with a defined order of arguments. Hopefully this will be easier to remember.

The two/three letters are the arguments expected. “O” is a point on the drawing.

  • “C”: specified by C(O)N (N=A or R)
  • “P”: specified by points CO(O)
  • “R”: specified by OOR
  1. CircleC CR CenterPoint, Radius

  2. CircleP CO CenterPoint, StartPoint

  3. CircleR OOR CirclePoint1, CirclePoint2, +/-Radius

  4. ArcC COA CenterPoint, StartPoint, Angle

  5. ArcP COO CenterPoint, StartPoint, EndPoint

  6. ArcR OOR StartPoint, EndPoint, +/-Radius

First, the options spell out the (hopefully easy to remember) acronym “CPR”. The P and R suffixes are very consistent in the arguments specified, but the C is a little odd. You might be able to remember that C indicates to specify a number (angle or radius) also.

I’m playing around with zones and polygons and formulating how KiCommand should handle the variety of functions. I’ve discovered that through the KiCAD GUI, it is possible to create a DRAWSEGMENT of any type on any layer, including copper. Doing so on copper does not allow adding a NET since an object mut be derived from BOARD_CONNECTED_TYPE, such as TRACK, VIA, ARC (which themselves are derived from TRACK), and ZONE_CONTAINER, among others. It is not clear to me what the utility of a DRAWSEGMENT on a copper layer is, but it seems prudent to support it.

Because DRAWSEGMENTs can be on copper, we cannot distinguish automatically the intent of the user when creating segments on copper. Older KiCommand commands assume that if a line segment is drawn on copper, it is intended to be a track. New commands will not carry this assumption forward. The command will specifically indicate the destination object, whether DRAWSEGMENT, TRACK, or ZONE_CONTAINER.

Here’s what I’m thinking:

  • newdrawing - will create a DRAWSEGMENT of specified shape on the active layer (from drawparams)
  • newzone - will create a ZONE_CONTAINER of specified shape on the active layer (from drawparams)
  • newtrack - will create TRACK, ARC, or ZONE based on the specified shape (Line/Polyline->TRACK, Arc/Circle->ARC, Polygon->ZONE) on the active layer, which must be copper. When created, TRACKs have the default net (0/’’).

I had to create a place to indicate units. With the way it was working (angle being an argument for some shapes), it was not convenient to specify the shape and use the existing mm command to convert units because the angle would be “converted” (and then be horribly wrong). So I added the ability to specify units inline. The following commands are examples of how it’s working. These command just use straight lists of numbers. The ArcC shape uses the arc angle as its last argument. The angle does not get converted to the units specified (mm), but all other points do get converted to native units from mm.

Line,mm,20,10,22,12 split newdrawing refresh
ArcC,mm,20,10,22,12,90 split newdrawing refresh
ArcM,mm,22,12,20,12.8,18,12 split newdrawing refresh
CircleP,mm,-10,-10,5 split newdrawing refresh
Polygon,mm,30,0,30,1,25,1 split newdrawing refresh
Bezier,mm,30,0,30,1,25,1 split newdrawing refresh

I’m calling the above string description a “geom”. A “geom” can also be a list with wxPoints or pairs of x/y coordinates within the specification (wxPoints must already be in native units). There will be a way to get the “geom” of objects using getgeom command on a list of objects. geoms are more fully described in post 73.

Bezier Curves are interesting because I don’t think you can create them through the GUI, but you can create them in Python, and coming soon, KiCommand. After they are created, they can be manipulated in the GUI. It also looks like there is only one type of Bezier Curve: a 4-point Bezier Curve with the Start Point, Control Point 1, Control Point 2, and End Point.

Here’s a variety of shapes, some of which were created with KiCommand. Note the Bezier Curve in yellow in the upper right.

1 Like

Geom summary to date

A geom consists of a list of values used to specify one or more geometrical shapes. The list is easily generated manually, or can be extracted from existing objects such as DRAWSEGMENTs, TRACKs, and ZONEs. There are five commands that use a geom and a wide variety of shape types to cover each of the shape types within a DRAWSEGMENT. The same geom specification can be used to generate TRACKs and ZONEs.

Commands that use geom

  • getgeom - extract the geometries into an easy-to-read list called a “geom”. This will (currently) lose some information of the object, such as thickness, corner smoothing, and layer. The output of getgeom is not a string but instead a list of strings, wxPoints, and numbers.
  • getgeomstring - extract the geometries into an easy-to-read string called a “geom”. This is suitable for cut and paste operations to duplicate the shape of an object (excluding some object parameters such as thickness and layer). This can take a list of objects or a list of geoms.
  • newdrawing - will create a DRAWSEGMENT of specified shape on the active layer (from drawparams)
  • newzone - will create a ZONE_CONTAINER of specified shape on the active layer (from drawparams). If the zone is on copper, it will have the default net (0/’’).
  • newtrack - will create TRACK, ARC, or ZONE based on the specified shape (Line/Polyline->TRACK, Arc/Circle->ARC, Polygon->ZONE) on the active layer, which must be copper. When created, TRACKs have the default net (0/’’).

General Rules for geom specification

  • A geom consists of a list of values. The first value is a shapetype, the second and optional value is a unit, followed by points and numbers (collectively, “arguments”) that specify the shape. geoms can be specified successively in the same list.
  • All arguments can be listed as a comma-separated string to make specifications easy to enter by hand. Currently you would use the split command after your comma-separated string, but this requirement might be removed.
  • All arguments can be in arbitrarily-nested lists. This might often be paired x/y points in their own list. It won’t matter how they’re paired or nested.
  • In the specification of a geom, you can put a unit string after the shape type. Units are one of mm, mil, mils, native, or nm. This affects all parameters except for angles and numbers already specified as wxPoints. It is presumed that actual wxPoints would have come from getgeom.
  • Any number of numeric argument “sets” can be specified after the segmenttype string to indicate more than one segment/object (except for polygon or (new) polyline).
  • All numeric arguments can be specified as float, int, or string. If strings are used, they can be comma separated. Strings are converted to floats. (I might consider converting number strings without a decimal point to integers.)
  • Center, if specified, is first.
  • If Start and End are both specified, Start is before End.
  • Radius or Angle, if specified, is last.
  • Arithmetic operators are modified to pass through strings (such as segment type) so you can operate on the numbers in a segment specification without affecting the segment type. It will just “pass through” unmodified.

Argument Key:

  • C - is the center point of an arc or circle.
  • B - is a control point on a Bezier curve.
  • O - is a point on the drawing.
  • R - is a radius of an arc or circle.
  • A - is an angle of an arc.
  • S - is a start point on drawing.
  • E - is a end point on drawing.
  • P - is a point

Circle and Arc Suffix Key:

  • “C”: specified by C(O)N (N=A or R)
  • “R”: specified by OOR
  • “O”: specified by all points on the drawing.
  • “P”: specified by points CO(O)

All geoms:

The one-to-four letters after the shape name are the arguments expected based on the “Argument Key.”

Line SE StartPoint, EndPoint
Bezier SBBE StartPoint, ControlPoint1, ControlPoint2, EndPoint
Polygon P a sequence of vertex points
Polyline P a sequence of vertix points.
CircleC CR CenterPoint, Radius
CircleR OOR CirclePoint1, CirclePoint2, +/-Radius
CircleO OOO StartPoint, CirclePoint1, CirclePoint2
CircleP CO CenterPoint, StartPoint
ArcC COA CenterPoint, StartPoint, Angle
ArcR OOR StartPoint, EndPoint, +/-Radius
ArcO OOO StartPoint, MidPoint, EndPoint. Although this indicates "Mid" point, any point on the arc will suffice.
ArcP COO CenterPoint, StartPoint, EndPoint

Note that for all geoms, you can repeat sets of arguments for another shape of the same type. To specify this, just continue listing arguments.

  • Line,Units,Start1,End1,Start2,End2,Start3,End3,Start4,End4

This is different than Polyline, which creates segemnts identical to Line, but chains them together and only requires a list of vertex/points.

  • Polyline,mm,P1,P2,P3,P4

That will create segments:

  • P1,P2
  • P2,P3
  • P3,P4

Note that Polyline is not necessarily a closed area, you need to repeat P1 at the end of the point list if you want it closed. Whereas,

  • Polygon,mm,P1,P2,P3,P4

will create a closed polygon with specified vertices, with P4 connected to P1.

Example Commands:

Line,mm,20,10,22,12 split newdrawing refresh
ArcC,mm,20,10,22,12,90 split newdrawing refresh
ArcM,mm,22,12,20,12.8,18,12 split newdrawing refresh
CircleP,mm,-10,-10,5 split newdrawing refresh
Polygon,mm,30,0,30,1,25,1 split newdrawing refresh
Bezier,mm,30,0,30,1,25,1 split newdrawing refresh

Additional Thoughts

Polygons for DRAWSEGMENTs and ZONEs are treated differently by KiCAD. A ZONE treats vertices as the outside boundary, with corners rounded within those bounds based on a parameter that geoms don’t currently preserve. DRAWSEGMENTs and TRACKs (and Polylines) treat vertices as the midpoint of the drawn line, with material/layer extending beyond the points by the thickness. It’s not clear yet how/if KiCommand should handle conversion of these shapes so that ZONEs and DRAWSEGMENT Polygons turn out identical.

I’m thinking about how to add VIAs inline, so that you could specify an entire connected track. Something like “Via,[Type],Drill,ToLayerName” that you could place in the midst of a Polyline and it would make a Via connecting the current layer to the ToLayerName and set that layer is the “current layer” to continue the Polyline. I’m also considering how to add *drawparameters" so thickness or layer can be modified inline as well, perhaps those can be modifications to the current geom or current and future geoms until changed, based on the name of the parameter.

I also want to support DRAWSEGMENTS, TRACKS, ZONE_CONTAINER and ZONE_CONTAINERS in the midst of geom strings, that way you can copy any existing shape from or to a drawing, track, or zone.

That’s all I have for now. This represents my current thoughts and is subject to change. I’ll modify the Tutorial/Wiki with updated information when applicable. This is not currently released as of the time of this writing, but being developed for the next release of KiCommand.

@HiGreg
First thanks for this awesome tool!!
I’m using KC 5.1.6 Modern Toolset on a mac. In case anyone else on a mac has trouble getting KiCommand installed (like I did), putting it under ~/Library/Preferences/kicad/scripting/plugins/ worked for me.

Here’s a couple things I’ve noted so far:

  1. There is no default location during KiCad install (macOS) for the Demos folder, so kicommand.test fails finding the demo projects. Maybe for the mac use ~/Library/Application Support/kicad/demos ?
  2. If the popup KiCommand window is closed, then unable to restart KiCommand window without first closing the pcbnew window.
  3. When using the GRID command on a selected trace, only the Start point X Y points are snapped to the grid. The End point X Y points retain their previous values.

Thank you for the feedback!

  1. I don’t have experience running KiCAD on a Mac, so I really appreciate your finding out the demo projects’ location.

  2. I’ll look into the window not coming back.

  3. You’re right. At the time that command was written, I only took into account DRAWSEGMENTs, and not TRACKs. I’ll fix this in the next release. If you want to fix it now, you can edit line 792 of kicommand.py from

    if isinstance(seg, pcbnew.DRAWSEGMENT):

To

if isinstance(seg, (pcbnew.DRAWSEGMENT, pcbnew.TRACK) ):

@HiGreg
Wow! Thanks for the quick response.

  1. The Demos folder doesn’t get installed anywhere during KiCad installation on the mac, I was just suggesting a location. Open for any other convenient location.

  2. Thanks for looking into the window return problem.

  3. YES!!! It appears (from a quick test) that tracks (and vias) are now snapped correctly. What a great time saver!!

1 Like