PNS for component placement
Description
We should support a "push and shove router" type system for component placement in PcbNew.
There could be four modes:
- Ignore collisions (same as how placement works today)
- Highlight collisions
- Prevent collisions
- Shove components
Collisions would be determined by intersecting component courtyards.
The modes are pretty self-explanatory and would work similarly to the PNS trace router.
In "highlight collisions" mode, colliding components would be highlighted the same way that we currently highlight colliding pads/traces when "dragging" components.
In "prevent collisions" mode, components would be like rigid bodies, preventing moving a component in a way that its courtyard intersects with any other.
The "shove components" mode is the trickiest, and maybe doesn't need to be part of an initial implementation.
A useful algorithm for shoving components is to only allow the shove to go "1 level deep": if you push component A into component B, component B moves out of the way (i.e. along the closest cardinal direction to the vector away from the collision point). But if component B then collides with component C, it should stop. This prevents excessive shoves from rippling through the board while still being useful for some operations (e.g. shoving a decoupling cap out of the way, until it collides against a big IC, which would not move since it is component C in the above description)
KiCad Version
Application: Pcbnew
Version: (5.99.0-2904-gf20fe7180), release build
Libraries:
wxWidgets 3.1.3
libcurl/7.68.0-DEV Schannel zlib/1.2.11
Platform: Windows 10 (build 19041), 64-bit edition, 64 bit, Little endian, wxMSW
Build Info:
Date: Aug 20 2020 21:20:04
wxWidgets: 3.1.3 (wchar_t,STL containers)
Boost: 1.73.0
Curl: 7.68.0-DEV
Compiler: Visual C++ 1927 without C++ ABI
Build settings:
KICAD_SCRIPTING=OFF
KICAD_SCRIPTING_MODULES=OFF
KICAD_SCRIPTING_PYTHON3=OFF
KICAD_SCRIPTING_WXPYTHON=OFF
KICAD_SCRIPTING_WXPYTHON_PHOENIX=OFF
KICAD_SCRIPTING_ACTION_MENU=OFF
BUILD_GITHUB_PLUGIN=ON
KICAD_SPICE=OFF