kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #27534
Re: Via Stitching
Hello Kristoffer,
I just made a new patch, with some modifications. I changed that GAL canvas
adding algorithm, so that it does not involve PNS any longer.
Cheers
Heikki
On Fri, Feb 3, 2017 at 5:33 PM, Kristoffer Ödmark <
kristofferodmark90@xxxxxxxxx> wrote:
> Hello!
>
> I wanted to try the patch, but I cannot apply it to current master branch,
> from which commit should I apply it or could you update the patch?
>
> - Kristoffer
>
> On 2017-01-25 09:40, Heikki Pulkkinen wrote:
>
>> Hi,
>>
>> My suggestion via stitching and its connectivity algorithm is ready to
>> use and it is working fine. Of course there might be some bugs. One of
>> the goal ideas is that It uses as much as possible current tested and
>> well working code, so do not have to test all again. I am going to
>> change that GAL canvas adding algorithm, so that it do not involve PNS.
>> But not soon.
>>
>> If you want to make new all connecting connectivity algorithm, it is
>> fine for me. I think that it would take longer than month to get all
>> ready, if you are going to make rework all, and still have same
>> usability and workability as user point of view.
>>
>> If You, or someone, are sill interested in my suggestion there is latest
>> full patch.
>>
>>
>> Regards
>>
>> Heikki
>>
>>
>>
>>
>>
>>
>> On Thu, Jan 19, 2017 at 12:38 PM, Maciej Sumiński
>> <maciej.suminski@xxxxxxx <mailto:maciej.suminski@xxxxxxx>> wrote:
>>
>> On 01/18/2017 02:35 PM, Wayne Stambaugh wrote:
>> > On 1/17/2017 12:14 PM, Heikki Pulkkinen wrote:
>> >> Hi Wayne,
>> >>
>> >> OK, I explain inside your text.
>> >>
>> >>
>> >> On Mon, Jan 16, 2017 at 11:09 PM, Wayne Stambaugh
>> <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> wrote:
>> >>
>> >> Heikki,
>> >>
>> >> What is the purpose of the "stitch" token added to the file
>> format?
>> >> Vias already have a netcode field so adding "stitch" to the
>> file format
>> >> seems to serve no purpose.
>> >>
>> >> It is there because there is some cases when that "stitch" via
>> lose it's
>> >> netcode when opening board. If via was stitch when saved, then it's
>> >> stitch code would be saved netcode and board is what it was when
>> saved.
>> >
>> > This is being addressed by work currently being done on the
>> connection
>> > algorithm (someone correct me if I'm wrong about this). Changing
>> the
>> > file format to fix a design flaw in the connection algorithm doesn't
>> > make sense other than it's an easier fix.
>> >
>> >>
>> >>
>> >> I would prefer that you avoid the term stitching. Vias could
>> just as
>> >> easily be thermal vias. I don't think the generic term via
>> is going to
>> >> confuse anyone. I would think most users placing vias for
>> purposes
>> >> other than trace routing understand the purpose of the vias.
>> >>
>> >> I agree that. That is better term of them. I change code so that
>> I use
>> >> thermal instead stitch and user point of view these are just vias.
>> >
>> > Just use the term "via". The designer knows the purpose of the via.
>> >
>> >>
>> >>
>> >> You are still automatically assigning via netcodes based on
>> placement.
>> >> We agreed (at least I thought we did) that this assumption is
>> dangerous
>> >> and that the user should be selecting the net assignment.
>> I'm OK if you
>> >> suggest to the user the best netcode based on the via
>> placement position
>> >> but under no circumstance should the code be selecting the
>> via netcode.
>> >>
>> >> It seems, that code is automatically assigning netcode, but it is
>> users
>> >> decide. When user selects connected layer pair and what layer is
>> main
>> >> connected layer, not even have to select that last one, user
>> selects
>> >> netcode in that main connected layer copper pours netcode. And
>> you see
>> >> instantly what you get. if there is no pour in main selected layer
>> in
>> >> that point, then you don't get any via. Simple.
>> >>
>> >> As a user I know what copper pours I want to connect together. And
>> I
>> >> know what these pours netcodes are. It is faster just pressing a
>> button,
>> >> than selecting every time netcode where connect. And if there is
>> no pour
>> >> to connect in that netcode you selected, it is just one
>> unconnected via
>> >> or it may have connected.
>> >>
>> >> I think that there is no need to make any selection box of that.
>> >
>> > This only true when there is only one possible connection between
>> a via
>> > and plane or trace. In this case, it would be acceptable to use
>> net of
>> > the only connection to the via. However, when there is more than
>> one
>> > net connect, how do you decide which net to use? You are going to
>> end
>> > up with unexpected behavior if you make assumptions in this case.
>> You
>> > wouldn't necessarily need to display a list of all of the nets,
>> only the
>> > nets that bisect the via.
>> >
>> >>
>> >>
>> >> There is some work currently going on with to fix some of the
>> issues
>> >> with the connection algorithm that may conflict with your
>> code. Please
>> >> make sure you check with the folks that are working on this
>> code. If
>> >> you are working on the connection algorithm, please let
>> Heikki know so
>> >> that we can avoid any conflicts.
>> >>
>> >> OK, wait that.
>> >
>> > Would whoever is working on that let Heikki know the current status.
>> > Perhaps some collaboration would be helpful to move this along.
>> >
>>
>> Heikki,
>>
>> We all want to have via stitching, and it is planned for v5. One
>> important thing is we need to rework the connectivity algorithm. While
>> doing so, we want to take the opportunity to add the code necessary to
>> handle stitching vias. Tom is working on this, I am going to join
>> soon,
>> and we expect to finish it in a month or so.
>>
>> As Wayne has already mentioned, we would rather avoid making stitching
>> vias a special type (m_stitch, m_zones fields, "stitch" tag in the
>> file
>> format).
>>
>> Once the connectivity algorithm is in place, the via placement tool is
>> trivial: simply add a via at a specific place and let the connectivity
>> algorithm handle the details. No need to involve the PNS router here.
>>
>> I think the code for displaying the via net names would be a good
>> addition.
>>
>> Regards,
>> Orson
>>
>> >>
>> >> Please configure your editor so that it doesn't leave
>> trailing white
>> >> space all over the source files. Your patch contains a bunch
>> of it
>> >>
>> >>
>> >> Cheers,
>> >>
>> >> Wayne
>> >>
>> >>
>> >> Who can tell me what to do with those trailing white spaces. I
>> use KDevelop.
>> >
>> > Does KDevelop support macros? If so, someone probably has written a
>> > macro to delete trailing white space. If not, you can always
>> write your
>> > own. The more painful option is to configure the editor to show
>> white
>> > space (most editors have this option) and clean it up manually
>> before
>> > you generate your patches.
>> >
>> >>
>> >> Cheers
>> >> Heikki
>> >>
>> >> On 1/9/2017 11:33 AM, Heikki Pulkkinen wrote:
>> >> > Hi
>> >> >
>> >> > I add netnames to stitch vias.
>> >> >
>> >> >
>> >> > Regards
>> >> >
>> >> >
>> >> > Heikki
>> >> >
>> >> > https://youtu.be/7FgmY8Uzgbg
>> >> >
>> >> >
>> >> > On Wed, Dec 21, 2016 at 3:15 PM, Heikki Pulkkinen
>> <hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> > <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>> wrote:
>> >> >
>> >> > Hi Wayne and others,
>> >> >
>> >> > It has been for a while. I was out of my faster
>> computer again.
>> >> > Mother board has to been put oven again.
>> >> > I think, that my suggestion of via stitching is now
>> quite robust.
>> >> > But it has to be tested more and some other than me.
>> Main idea has
>> >> > developed so, that VIA class has new property of that
>> stitching and
>> >> > it has to be saved on [.kicad_pcb] file too. Filling
>> pours is part
>> >> > of that how to connect vias and pours, so it has to be
>> done twice.
>> >> > And there is some new additions in shape_poly_set.cpp
>> and drc.cpp.
>> >> > They do not disturb other program. And of course I have
>> to add some
>> >> > little things in gal canvas too. I did not make any
>> class of
>> >> > stitching, just put them in own namespace, because
>> there is no data
>> >> > to hide. All stitch data is in VIA class. So, hope that
>> my idea is
>> >> > usable and it is worth of improve.
>> >> >
>> >> > Regards
>> >> >
>> >> > Heikki
>> >> >
>> >> > On Sun, Nov 13, 2016 at 8:03 PM, Wayne Stambaugh
>> >> > <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>> wrote:
>> >> >
>> >> > Hi Heikki,
>> >> >
>> >> > I appreciate any effort that you can make on this.
>> I really
>> >> > would like
>> >> > to get the via stitching code in before the stable
>> version
>> >> 5 pre
>> >> > release
>> >> > which I'm hoping to do at the beginning of 2017
>> before FOSDEM.
>> >> >
>> >> > Cheers,
>> >> >
>> >> > Wayne
>> >> >
>> >> >
>> >> > On 11/12/2016 12:35 PM, Heikki Pulkkinen wrote:
>> >> > > Hi Wayne,
>> >> > >
>> >> > > OK, I understand that. I look what can I do, but
>> I do
>> >> not promise
>> >> > > anything, very soon anyway. I am not familiar
>> with gal
>> >> canvas. I done
>> >> > > this to legacy canvas, because I know how it
>> works. Now
>> >> stitching works
>> >> > > in my tests quite well "of course". And it is
>> working my
>> >> needs.
>> >> > >
>> >> > > I try via stitching on gal, and it is partly
>> working.
>> >> Stitch via
>> >> > > placing and chain connection does not seems to
>> work. But
>> >> converting old
>> >> > > designs with pad->track->via... chain removing pad
>> >> connection from chain
>> >> > > converts vias as stitch vias when run track via
>> cleanup.
>> >> > >
>> >> > > I do some code cleaning and send it to look at as
>> soon
>> >> as possible. You
>> >> > > can use it or not, It is fine for me.
>> >> > >
>> >> > >
>> >> > > Regards
>> >> > >
>> >> > > Heikki
>> >> > >
>> >> > >
>> >> > > On Fri, Nov 11, 2016 at 10:16 PM, Wayne Stambaugh
>> >> <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>> wrote:
>> >> > >
>> >> > > Hi Heikki,
>> >> > >
>> >> > > I spoke to Tom this morning about your via
>> stitching work. He mentioned
>> >> > > that your via stitching work should be
>> developed for the gal canvas.
>> >> > > I'm not sure you are aware but I put a
>> moratorium on adding new features
>> >> > > to the legacy canvas earlier in the year.
>> This is because the legacy
>> >> > > canvas is going to be removed at some time in
>> the not too distant
>> >> > > future. I should have mentioned this sooner
>> but it really needs to be
>> >> > > done this way to be accepted into kicad. I
>> realize this is going to be
>> >> > > more work for you but it would have to be
>> done anyway. If you support
>> >> > > both canvases, I'm fine with that but the gal
>> canvas must be supported
>> >> > > for any new feature added to pcbnew.
>> >> > >
>> >> > > Thanks,
>> >> > >
>> >> > > Wayne
>> >> > >
>> >> > >
>> >> > > On 11/8/2016 3:35 AM, Heikki Pulkkinen wrote:
>> >> > > > Hi
>> >> > > >
>> >> > > > Now via->pour chain is recovering.
>> >> > > >
>> >> > > > Heikki
>> >> > > >
>> >> > > > https://youtu.be/HuViOfQmcrU
>> >> > > >
>> >> > > >
>> >> > > > On Mon, Nov 7, 2016 at 1:26 PM, Heikki
>> Pulkkinen <hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>> wrote:
>> >> > > >
>> >> > > > Hi,
>> >> > > >
>> >> > > > I made some new features. Now it is
>> possible chaining copper pours
>> >> > > > with Vias. This video show, how it
>> works at the moment.
>> >> > > >
>> >> > > >
>> >> > > > Heikki
>> >> > > >
>> >> > > > https://youtu.be/91tT626XnbM
>> >> > > >
>> >> > > > On Sat, Oct 29, 2016 at 7:58 AM, Heikki
>> Pulkkinen
>> >> > > > <hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>> wrote:
>> >> > > >
>> >> > > > Hi Wayne,
>> >> > > >
>> >> > > > I think that there is two places
>> when user is "wrong" wit
>> >> > > > his/her will. One is when there are
>> not at least two pours to
>> >> > > > connect with and second is that
>> there must be at least one pad
>> >> > > > in connection chain. If antennas
>> are user will, it is better
>> >> > > > create component. I might be wrong,
>> but that is how I think it.
>> >> > > > I did some experimental development
>> in my code which now keeps
>> >> > > > vias netcodes Steven's ideas way,
>> and take care of that there is
>> >> > > > connected pad. These two videos
>> show how that works. I try more
>> >> > > > other things when I am back home
>> again.
>> >> > > >
>> >> > > > Regards
>> >> > > >
>> >> > > > Heikki
>> >> > > >
>> >> > > > https://youtu.be/wXdVl4WXCJ8
>> >> > > > https://youtu.be/5qe-XnVJwXs
>> >> > > >
>> >> > > >
>> >> > > > 27.10.2016 1.47 "Wayne Stambaugh"
>> <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
>> >> > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>>>> kirjoitti:
>> >> > > >
>> >> > > > I'm just not comfortable with the
>> >> connection
>> >> > algorithm
>> >> > > > reassigning via
>> >> > > > net codes to a zone's net code
>> based
>> >> on the
>> >> > zone/via
>> >> > > > intersection. This
>> >> > > > puts the responsibility of the
>> >> connection on
>> >> > the project
>> >> > > > rather than the
>> >> > > > user. I'm OK if we suggest a
>> net when the
>> >> > user is placing
>> >> > > > vias but the
>> >> > > > user has the final say and the
>> via net
>> >> code
>> >> > does not
>> >> > > change
>> >> > > > unless the
>> >> > > > user explicitly changes it. I
>> don't
>> >> now how
>> >> > to make
>> >> > > it any
>> >> > > > clearer than
>> >> > > > that. Someone would have to
>> make a really
>> >> > impressive
>> >> > > > argument (read
>> >> > > > doctoral thesis) as to why we
>> should allow
>> >> > kicad to
>> >> > > determine
>> >> > > > connectivity rather than the
>> user.
>> >> > > >
>> >> > > > On 10/25/2016 1:54 AM, Heikki
>> >> Pulkkinen wrote:
>> >> > > > > Thanks Wayne to look at this
>> and Steven
>> >> > for asking about
>> >> > > > connection logic.
>> >> > > > >
>> >> > > > > It is good to try explain
>> what did you
>> >> > thought last
>> >> > > > summer. It clearer
>> >> > > > > things.
>> >> > > > >
>> >> > > > > There are main rule which
>> connects
>> >> top and
>> >> > bottom layer
>> >> > > > and second rule
>> >> > > > > connecting inner layers. And
>> now I think
>> >> > that main
>> >> > > rule is
>> >> > > > useless,
>> >> > > > > because second rule do all this
>> >> connecting
>> >> > via to first
>> >> > > > two zones with
>> >> > > > > same netcode. This works well
>> as far as
>> >> > zones are up the
>> >> > > > date. And that
>> >> > > > > is not always true. For
>> example in
>> >> DRC, if
>> >> > you forgot to
>> >> > > > refill zones
>> >> > > > > before running DRC, vias can
>> >> corrupted to
>> >> > wrong net.
>> >> > > Thats
>> >> > > > why running
>> >> > > > > first refilling zones in DRC,
>> keeps
>> >> vias right
>> >> > > connected.
>> >> > > > > I found two another, and
>> there might be
>> >> > more, situation
>> >> > > > when user can
>> >> > > > > accidentally damage
>> connection. Cleanup
>> >> > and saving a
>> >> > > > board. Saving is
>> >> > > > > not that broblem, but opening
>> is. But I
>> >> > have solution of
>> >> > > > them. Just
>> >> > > > > running zone filling
>> algorithm before
>> >> > running ratsnest
>> >> > > > algorithm.
>> >> > > > > But usually, when working
>> with via
>> >> > stitching, user keeps
>> >> > > > zones up to
>> >> > > > > date running refill to see
>> what he
>> >> or she
>> >> > have done. I
>> >> > > > know there is
>> >> > > > > always better solutions, but
>> I can
>> >> manage
>> >> > this at the
>> >> > > > moment before
>> >> > > > > there are official one. I
>> know, if
>> >> > algorithm is
>> >> > > different
>> >> > > > than mine it
>> >> > > > > does not ruin my designs.
>> >> > > > >
>> >> > > > > Cheers
>> >> > > > >
>> >> > > > > Heikki
>> >> > > > >
>> >> > > > >
>> >> > > > > 24.10.2016 23.58 "Wayne
>> Stambaugh"
>> >> > > <stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
>> >> > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>>
>> >> > > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
>> >> > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>>>>> kirjoitti:
>> >> > > > >
>> >> > > > > I finally had a chance to
>> look
>> >> at this
>> >> > patch and I
>> >> > > > have similar
>> >> > > > > concerns. I thought I
>> was pretty
>> >> > clear about *not*
>> >> > > > being comfortable
>> >> > > > > with making assumptions
>> about
>> >> via zone
>> >> > > connections and
>> >> > > > always using the
>> >> > > > > assigned net code. I'm a
>> bit
>> >> > concerned with the
>> >> > > > connection testing and
>> >> > > > > it's decision to change a
>> via's
>> >> net code
>> >> > > depending on
>> >> > > > which zone(s) that
>> >> > > > > it intersects. I see
>> this as an
>> >> > unacceptable
>> >> > > risk for
>> >> > > > kicad to assume.
>> >> > > > > I would rather put the
>> >> responsibility
>> >> > in hands
>> >> > > of the
>> >> > > > user and just have
>> >> > > > > kicad complain when there
>> is a
>> >> drc issue.
>> >> > > > >
>> >> > > > > Please configure your
>> editor to
>> >> clean
>> >> > up trailing
>> >> > > > white space and fix
>> >> > > > > the other coding policy
>> errors.
>> >> > > > >
>> >> > > > > Cheers,
>> >> > > > >
>> >> > > > > Wayne
>> >> > > > >
>> >> > > > > On 10/23/2016 10:44 PM,
>> >> Strontium wrote:
>> >> > > > > > Hello Heikki,
>> >> > > > > >
>> >> > > > > > Can you explain the
>> logic you are
>> >> > using to
>> >> > > determine
>> >> > > > the net of
>> >> > > > > the vias
>> >> > > > > > during DRC reconnect? It
>> >> looks like
>> >> > you are only
>> >> > > > considering the top
>> >> > > > > > and bottom layer, but
>> >> stitching vias
>> >> > may be
>> >> > > > stitching internal layers?
>> >> > > > > >
>> >> > > > > > Steven
>> >> > > > > >
>> >> > > > > >
>> >> > > > > > On 23/10/16 21:48, Heikki
>> >> Pulkkinen
>> >> > wrote:
>> >> > > > > >> Hi Wayne and all,
>> >> > > > > >>
>> >> > > > > >> About that my
>> suggestion of Via
>> >> > Stitching. I do
>> >> > > > some tests and found
>> >> > > > > >> that if DRC first fill
>> zones and
>> >> > then do tests it
>> >> > > > does not break
>> >> > > > > >> anything. if you forgot
>> to
>> >> Fill or
>> >> > Refill zoenes
>> >> > > > before running DRC.
>> >> > > > > >>
>> >> > > > > >> Regards
>> >> > > > > >>
>> >> > > > > >> Heikki
>> >> > > > > >>
>> >> > > > > >>
>> >> > > > > >> On Fri, Oct 21, 2016
>> at 6:41 PM,
>> >> > Heikki Pulkkinen
>> >> > > > > <hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>
>> >> > > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>>
>> >> > > > > >>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>
>> >> > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>
>> >> > > > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>
>> >> > <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx> <mailto:hei6mail@xxxxxxxxx
>> <mailto:hei6mail@xxxxxxxxx>>
>> >> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>
>> <mailto:hei6mail@xxxxxxxxx <mailto:hei6mail@xxxxxxxxx>>>>>>>> wrote:
>> >> > > > > >>
>> >> > > > > >> Hi Wayne,
>> >> > > > > >>
>> >> > > > > >> If you try this, I
>> send the
>> >> > last full
>> >> > > patch of
>> >> > > > that Via
>> >> > > > > Stitching.
>> >> > > > > >> Do not care other
>> patches in
>> >> > mailing
>> >> > > list, they
>> >> > > > are more or less
>> >> > > > > >> incomplete.
>> >> > > > > >>
>> >> > > > > >> Regards
>> >> > > > > >>
>> >> > > > > >> Heikki
>> >> > > > > >>
>> >> > > > > >> On Tue, Oct 18,
>> 2016 at 3:22
>> >> > PM, Wayne
>> >> > > Stambaugh
>> >> > > > > >>
>> <stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
>> >> > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>>> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>>>
>> >> > > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>> >> <mailto:stambaughw@xxxxxxxxx <mailto:stambaughw@xxxxxxxxx>>
>> >> > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx> <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>>>
>> >> > > <mailto:stambaughw@xxxxxxxxx
>> <mailto:stambaughw@xxxxxxxxx>
>
>
From a03072ae2bc65ac262337373fa035bd5701236ca Mon Sep 17 00:00:00 2001
From: heikki <hei6mail@xxxxxxxxx>
Date: Fri, 3 Feb 2017 18:16:29 +0200
Subject: [PATCH] Via Stitching
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.7.4"
This is a multi-part message in MIME format.
--------------2.7.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
CMakeModules/FindwxWidgets.cmake | 3 +-
common/geometry/shape_poly_set.cpp | 26 +++++++
common/pcb.keywords | 3 +-
include/geometry/shape_poly_set.h | 3 +
include/layers_id_colors_and_visibility.h | 7 ++
pcbnew/CMakeLists.txt | 1 +
pcbnew/array_creator.cpp | 6 ++
pcbnew/class_drc_item.cpp | 6 ++
pcbnew/class_pcb_layer_widget.cpp | 9 +++
pcbnew/class_track.cpp | 7 +-
pcbnew/class_track.h | 22 +++++-
pcbnew/clean.cpp | 29 +++++++-
pcbnew/connect.cpp | 25 ++++++-
pcbnew/drc.cpp | 22 +++---
pcbnew/drc_marker_functions.cpp | 27 +++++++
pcbnew/drc_stuff.h | 4 ++
pcbnew/edit.cpp | 9 +++
pcbnew/hotkeys_board_editor.cpp | 12 +++-
pcbnew/kicad_plugin.cpp | 3 +
pcbnew/onrightclick.cpp | 19 +++++
pcbnew/pcb_draw_panel_gal.cpp | 7 +-
pcbnew/pcb_painter.cpp | 112 ++++++++++++++++++++++-------
pcbnew/pcb_painter.h | 4 ++
pcbnew/pcb_parser.cpp | 10 ++-
pcbnew/pcbnew_id.h | 2 +
pcbnew/router/pns_router.h | 3 +-
pcbnew/router/router_tool.cpp | 6 +-
pcbnew/tools/common_actions.cpp | 11 ++-
pcbnew/tools/common_actions.h | 2 +
pcbnew/tools/pcb_editor_control.cpp | 20 +++++-
pcbnew/tools/pcb_editor_control.h | 2 +
pcbnew/tools/pcbnew_control.cpp | 2 +-
pcbnew/zones_by_polygon_fill_functions.cpp | 47 +++++++-----
33 files changed, 401 insertions(+), 70 deletions(-)
--------------2.7.4
Content-Type: text/x-patch; name="0001-Via-Stitching.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-Via-Stitching.patch"
diff --git a/CMakeModules/FindwxWidgets.cmake b/CMakeModules/FindwxWidgets.cmake
index 9a6e56f..374f129 100644
--- a/CMakeModules/FindwxWidgets.cmake
+++ b/CMakeModules/FindwxWidgets.cmake
@@ -733,7 +733,8 @@ else()
#-----------------------------------------------------------------
# Support cross-compiling, only search in the target platform.
find_program(wxWidgets_CONFIG_EXECUTABLE
- NAMES wx-config wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8
+ #Fedora needs compat-wx* libs.
+ NAMES wx-config-3.0-gtk2 wx-config wx-config-3.1 wx-config-3.0 wx-config-2.9 wx-config-2.8
DOC "Location of wxWidgets library configuration provider binary (wx-config)."
ONLY_CMAKE_FIND_ROOT_PATH
)
diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp
index 287ebd6..b3d44b3 100644
--- a/common/geometry/shape_poly_set.cpp
+++ b/common/geometry/shape_poly_set.cpp
@@ -741,6 +741,32 @@ bool SHAPE_POLY_SET::Contains( const VECTOR2I& aP, int aSubpolyIndex ) const
}
+const SHAPE_POLY_SET::POLYGON* SHAPE_POLY_SET::GetPolygon( const VECTOR2I& aP, int aSubpolyIndex ) const
+{
+ if( m_polys.size() == 0 ) // empty set?
+ return nullptr;
+
+ if( aSubpolyIndex >= 0 )
+ {
+ if( pointInPolygon( aP, m_polys[aSubpolyIndex][0] ) )
+ return &m_polys[aSubpolyIndex];
+ else
+ return nullptr;
+ }
+
+ for( const POLYGON& polys : m_polys )
+ {
+ if( polys.size() == 0 )
+ continue;
+
+ if( pointInPolygon( aP, polys[0] ) )
+ return &polys;
+ }
+
+ return nullptr;
+}
+
+
bool SHAPE_POLY_SET::pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath ) const
{
int result = 0;
diff --git a/common/pcb.keywords b/common/pcb.keywords
index e8ffab2..f9a01e4 100644
--- a/common/pcb.keywords
+++ b/common/pcb.keywords
@@ -164,6 +164,7 @@ target
title
title_block
tedit
+thermal
thermal_width
thermal_gap
thermal_bridge_width
@@ -208,4 +209,4 @@ zone_45_only
zone_clearance
zone_connect
zone_type
-zones
\ No newline at end of file
+zones
diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h
index 842f2de..582302b 100644
--- a/include/geometry/shape_poly_set.h
+++ b/include/geometry/shape_poly_set.h
@@ -332,6 +332,9 @@ class SHAPE_POLY_SET : public SHAPE
///> Returns true is a given subpolygon contains the point aP. If aSubpolyIndex < 0 (default value),
///> checks all polygons in the set
bool Contains( const VECTOR2I& aP, int aSubpolyIndex = -1 ) const;
+
+ //Acts same way as Contains, but return POLYGON if true.
+ const POLYGON* GetPolygon( const VECTOR2I& aP, int aSubpolyIndex = -1 ) const;
///> Returns true if the set is empty (no polygons at all)
bool IsEmpty() const
diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h
index 3ac8c90..f9f065c 100644
--- a/include/layers_id_colors_and_visibility.h
+++ b/include/layers_id_colors_and_visibility.h
@@ -515,6 +515,9 @@ enum NETNAMES_VISIBLE
PAD_BK_NETNAMES_VISIBLE,
PADS_NETNAMES_VISIBLE,
+ VIA_THROUGH_NETNAMES_VISIBLE,
+ VIA_BBLIND_NETNAMES_VISIBLE,
+
END_NETNAMES_VISIBLE_LIST // sentinel
};
#endif
@@ -677,6 +680,10 @@ inline int GetNetnameLayer( int aLayer )
return NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE );
else if( aLayer == ITEM_GAL_LAYER( PAD_BK_VISIBLE ) )
return NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE );
+ else if( aLayer == ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) )
+ return NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE );
+ else if( aLayer == ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) )
+ return NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE );
// Fallback
return Cmts_User;
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index eedb3a6..5540fef 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -265,6 +265,7 @@ set( PCBNEW_CLASS_SRCS
tracepcb.cpp
tr_modif.cpp
undo_redo.cpp
+ viastitching.cpp
zones_convert_brd_items_to_polygons_with_Boost.cpp
zones_convert_to_polygons_aux_functions.cpp
zones_by_polygon.cpp
diff --git a/pcbnew/array_creator.cpp b/pcbnew/array_creator.cpp
index 5787e35..56572fa 100644
--- a/pcbnew/array_creator.cpp
+++ b/pcbnew/array_creator.cpp
@@ -31,6 +31,8 @@
#include <board_commit.h>
#include <dialogs/dialog_create_array.h>
+#include "viastitching.h"
+#include "drc_stuff.h"
void ARRAY_CREATOR::Invoke()
@@ -89,6 +91,10 @@ void ARRAY_CREATOR::Invoke()
if( new_item )
{
array_opts->TransformItem( ptN, new_item, rotPoint );
+
+ if( ViaStitching::DestroyConflictingThermalVia( new_item, getBoard(), &m_parent ) )
+ continue;
+
prePushAction( new_item );
commit.Add( new_item );
postPushAction( new_item );
diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp
index cf92901..787d276 100644
--- a/pcbnew/class_drc_item.cpp
+++ b/pcbnew/class_drc_item.cpp
@@ -126,6 +126,12 @@ wxString DRC_ITEM::GetErrorText() const
case DRCE_PAD_INSIDE_TEXT:
return wxString( _( "Pad inside a text" ) );
+ case DRCE_THERMAL_VIA_UNCONNECTED:
+ return wxString( _( "Thermal Via unconnected" ) );
+
+ case DRCE_THERMAL_VIA_CONNECTED_POURS:
+ return wxString( _( "Thermal Via Connected Pours < 2" ) );
+
default:
return wxString::Format( wxT( "Unknown DRC error code %d" ), m_ErrorCode );
}
diff --git a/pcbnew/class_pcb_layer_widget.cpp b/pcbnew/class_pcb_layer_widget.cpp
index 6faef76..a0de750 100644
--- a/pcbnew/class_pcb_layer_widget.cpp
+++ b/pcbnew/class_pcb_layer_widget.cpp
@@ -502,8 +502,17 @@ void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal
EDA_DRAW_PANEL_GAL* galCanvas = myframe->GetGalCanvas();
if( galCanvas )
+ {
galCanvas->GetView()->SetLayerVisible( aLayer, isVisible );
+ //Update thermal vias netnames.
+ for( TRACK* track = brd->m_Track; track; track = track->Next() )
+ {
+ if( track->Type() == PCB_VIA_T )
+ galCanvas->GetView()->Update( track, KIGFX::GEOMETRY );
+ }
+ }
+
if( isFinal )
myframe->GetCanvas()->Refresh();
}
diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp
index 27a622f..746e8ff 100644
--- a/pcbnew/class_track.cpp
+++ b/pcbnew/class_track.cpp
@@ -155,6 +155,10 @@ VIA::VIA( BOARD_ITEM* aParent ) :
SetViaType( VIA_THROUGH );
m_BottomLayer = B_Cu;
SetDrillDefault();
+
+ m_thermal = 0;
+ m_thermal_zones.clear();
+ m_thermal_polys_zones.clear();
}
@@ -184,7 +188,6 @@ wxString VIA::GetSelectMenuText() const
break;
}
-
if( board )
{
wxString netname = GetNetname();
@@ -992,6 +995,7 @@ void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
{
case VIA_THROUGH:
aLayers[1] = ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE );
+ aLayers[aCount++] = NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE );
break;
case VIA_BLIND_BURIED:
@@ -999,6 +1003,7 @@ void VIA::ViewGetLayers( int aLayers[], int& aCount ) const
aLayers[2] = m_Layer;
aLayers[3] = m_BottomLayer;
aCount += 2;
+ aLayers[aCount++] = NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE );
break;
case VIA_MICROVIA:
diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h
index e185179..b0239cc 100644
--- a/pcbnew/class_track.h
+++ b/pcbnew/class_track.h
@@ -36,7 +36,8 @@
#include <class_board_connected_item.h>
#include <PolyLine.h>
#include <trigo.h>
-
+#include <class_zone.h>
+#include <unordered_map>
class TRACK;
class VIA;
@@ -442,6 +443,21 @@ public:
VIATYPE_T GetViaType() const { return m_ViaType; }
void SetViaType( VIATYPE_T aViaType ) { m_ViaType = aViaType; }
+ int GetThermalCode( void ) const { return m_thermal; }
+ void SetThermalCode( const int aThermalCode ) { m_thermal = aThermalCode; }
+ std::vector<ZONE_CONTAINER*>* GetThermalZones( void ) {
+ return &m_thermal_zones;
+ }
+ void SetThermalZones( std::vector<ZONE_CONTAINER*>& aZones ) {
+ m_thermal_zones.swap(aZones);
+ }
+ std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>* GetThermalPolysZones( void ) {
+ return &m_thermal_polys_zones;
+ }
+ void SetThermalPolysZones( std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>& aPolyZone ) {
+ m_thermal_polys_zones.swap( aPolyZone );
+ }
+
/**
* Function SetDrill
* sets the drill value for vias.
@@ -486,6 +502,10 @@ private:
VIATYPE_T m_ViaType; // Type of via
int m_Drill; // for vias: via drill (- 1 for default value)
+
+ int m_thermal{0};
+ std::vector<ZONE_CONTAINER*> m_thermal_zones;
+ std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*> m_thermal_polys_zones;
};
diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp
index cd75aec..e8abbcf 100644
--- a/pcbnew/clean.cpp
+++ b/pcbnew/clean.cpp
@@ -40,6 +40,7 @@
#include <board_commit.h>
#include <tuple>
+#include "viastitching.h"
// Helper class used to clean tracks and vias
class TRACKS_CLEANER: CONNECTIONS
@@ -134,13 +135,17 @@ void PCB_EDIT_FRAME::Clean_Pcb()
return;
// Old model has to be refreshed, GAL normally does not keep updating it
- Compile_Ratsnest( NULL, false );
+ //Compile_Ratsnest( NULL, false );
wxBusyCursor( dummy );
BOARD_COMMIT commit( this );
TRACKS_CLEANER cleaner( GetBoard(), commit );
+ bool modified = false;
- bool modified = cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
+ modified |= ViaStitching::CleanThermalVias( this, &commit );
+ Fill_All_Zones( this, false );
+
+ modified |= cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
if( modified )
@@ -288,6 +293,13 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
{
segment->SetState( FLAG0, false );
+ //Do not remove thermal via.
+ if( dynamic_cast<const VIA*>( segment ) )
+ {
+ if( dynamic_cast<const VIA*>( segment )->GetThermalCode() && segment->GetNetCode() )
+ continue;
+ }
+
for( unsigned ii = 0; ii < segment->m_PadsConnected.size(); ++ii )
{
if( segment->GetNetCode() != segment->m_PadsConnected[ii]->GetNetCode() )
@@ -374,6 +386,11 @@ bool TRACKS_CLEANER::clean_vias()
{
modified |= remove_duplicates_of_via( via );
+ //Do not remove thermal via with netcode.
+ if( via->GetThermalCode() )
+ if( via->GetNetCode() || const_cast<VIA*>(via)->GetThermalZones()->size() )
+ continue;
+
/* To delete through Via on THT pads at same location
* Examine the list of connected pads:
* if one through pad is found, the via can be removed */
@@ -482,6 +499,14 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
{
next_track = track->Next();
+ //Do not remove thermal via.
+ if( dynamic_cast<const VIA*>( track ) )
+ {
+ if( dynamic_cast<const VIA*>( track )->GetThermalCode()
+ && const_cast<VIA*>( dynamic_cast<const VIA*>( track ) )->GetThermalZones()->size() )
+ continue;
+ }
+
bool flag_erase = false; // Start without a good reason to erase it
/* if a track endpoint is not connected to a pad, test if
diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp
index 99e6eb9..ef40d86 100644
--- a/pcbnew/connect.cpp
+++ b/pcbnew/connect.cpp
@@ -38,6 +38,7 @@
// Helper classes to handle connection points
#include <connect.h>
+#include "viastitching.h"
extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb );
extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
@@ -851,7 +852,6 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
return;
}
-
/* search connections between tracks and pads and propagate pad net codes to the track
* segments.
* Pads netcodes are assumed to be up to date.
@@ -861,9 +861,18 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
// Build the net info list
GetBoard()->BuildListOfNets();
+ // Via Stitching. Temp container.
+ std::unordered_map<const VIA*, int> collected_vias;
+ collected_vias.clear();
+
// Reset variables and flags used in computation
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
+ // Via Stitching. Collect Vias.
+ const VIA* via = dynamic_cast<const VIA*>( t );
+ if( via )
+ collected_vias.insert( std::pair<const VIA*, int> ( via, t->GetNetCode() ) );
+
t->m_TracksConnected.clear();
t->m_PadsConnected.clear();
t->start = NULL;
@@ -888,6 +897,9 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
// set the track net code to the pad netcode
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
+ if( ViaStitching::IsThermalVia( t ) )
+ continue;
+
if( t->m_PadsConnected.size() )
t->SetNetCode( t->m_PadsConnected[0]->GetNetCode() );
}
@@ -895,6 +907,9 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
// Pass 2: build connections between track ends
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
+ if( ViaStitching::IsThermalVia( t ) )
+ continue;
+
connections.SearchConnectedTracks( t );
connections.GetConnectedTracks( t );
}
@@ -909,6 +924,9 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
for( TRACK* t = m_Pcb->m_Track; t; t = t->Next() )
{
+ if( ViaStitching::IsThermalVia( t ) )
+ continue;
+
int netcode = t->GetNetCode();
if( netcode == 0 )
@@ -917,6 +935,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
for( unsigned kk = 0; kk < t->m_TracksConnected.size(); kk++ )
{
int altnetcode = t->m_TracksConnected[kk]->GetNetCode();
+
if( altnetcode )
{
new_pass_request = true;
@@ -943,6 +962,9 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
}
}
+ //Via Stitching. Set netcode to thermal vias.
+ ViaStitching::SetThermalViasNetcodes( m_Pcb, collected_vias );
+
if( IsGalCanvasActive() )
{
/// @todo LEGACY tracks might have changed their nets, so we need to refresh labels in GAL
@@ -955,7 +977,6 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
}
-
/*
* Function SortTracksByNetCode used in RebuildTrackChain()
* to sort track segments by net code.
diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp
index bdc14b7..c0d1441 100644
--- a/pcbnew/drc.cpp
+++ b/pcbnew/drc.cpp
@@ -52,6 +52,7 @@
#include <dialog_drc.h>
#include <wx/progdlg.h>
+#include "viastitching.h"
void DRC::ShowDRCDialog( wxWindow* aParent )
@@ -230,15 +231,6 @@ void DRC::RunTests( wxTextCtrl* aMessages )
testPad2Pad();
}
- // test track and via clearances to other tracks, pads, and vias
- if( aMessages )
- {
- aMessages->AppendText( _( "Track clearances...\n" ) );
- wxSafeYield();
- }
-
- testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
-
// Before testing segments and unconnected, refill all zones:
// this is a good caution, because filled areas can be outdated.
if( aMessages )
@@ -259,6 +251,15 @@ void DRC::RunTests( wxTextCtrl* aMessages )
testZones();
+ // test track and via clearances to other tracks, pads, and vias
+ if( aMessages )
+ {
+ aMessages->AppendText( _( "Track clearances...\n" ) );
+ wxSafeYield();
+ }
+
+ testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
+
// find and gather unconnected pads.
if( m_doUnconnectedTest )
{
@@ -544,6 +545,9 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
m_pcbEditorFrame->GetGalCanvas()->GetView()->Add( m_currentMarker );
m_currentMarker = 0;
}
+
+ //Test Thermal via.
+ ViaStitching::RuleCheck( segm, this );
}
if( progressDialog )
diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp
index 5642361..1547e08 100644
--- a/pcbnew/drc_marker_functions.cpp
+++ b/pcbnew/drc_marker_functions.cpp
@@ -44,6 +44,9 @@
#include <class_zone.h>
#include <class_marker_pcb.h>
#include <class_pcb_text.h>
+#include <class_board.h>
+#include <wxPcbStruct.h>
+#include <view/view.h>
MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode,
@@ -224,3 +227,27 @@ MARKER_PCB* DRC::fillMarker( int aErrorCode, const wxString& aMessage, MARKER_PC
return fillMe;
}
+void DRC::AddMarker( const BOARD_CONNECTED_ITEM* aItem, const wxPoint aMarkerPos, const int aErrorCode, MARKER_PCB* aFillMarker )
+{
+ if( aItem )
+ {
+ if( aFillMarker )
+ aFillMarker ->SetData( aErrorCode, aMarkerPos, aItem->GetSelectMenuText(), aItem->GetPosition() );
+ else
+ {
+ aFillMarker = new MARKER_PCB( aErrorCode, aMarkerPos, aItem->GetSelectMenuText(), aItem->GetPosition() );
+ aFillMarker->SetItem( aItem );
+ }
+
+ if( aFillMarker )
+ {
+ wxASSERT( aFillMarker );
+ m_pcb->Add( aFillMarker );
+ m_pcbEditorFrame->GetGalCanvas()->GetView()->Add( static_cast<BOARD_ITEM*>( aFillMarker ) );
+ aFillMarker = 0;
+ }
+ }
+}
+
+
+
diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h
index 2546829..79cdd07 100644
--- a/pcbnew/drc_stuff.h
+++ b/pcbnew/drc_stuff.h
@@ -31,6 +31,7 @@
#include <vector>
#include <memory>
+#include <wxBasePcbFrame.h>
#define OK_DRC 0
#define BAD_DRC 1
@@ -80,6 +81,8 @@
#define DRCE_VIA_INSIDE_TEXT 41 ///< Via in inside a text area
#define DRCE_TRACK_INSIDE_TEXT 42 ///< Track in inside a text area
#define DRCE_PAD_INSIDE_TEXT 43 ///< Pad in inside a text area
+#define DRCE_THERMAL_VIA_UNCONNECTED 44 ///< Thermal Via unconnected
+#define DRCE_THERMAL_VIA_CONNECTED_POURS 45 ///< Thermal Via too less zones connected
class EDA_DRAW_PANEL;
@@ -510,6 +513,7 @@ public:
return m_currentMarker;
}
+ void AddMarker( const BOARD_CONNECTED_ITEM* aItem, const wxPoint aMarkerPos, const int aErrorCode, MARKER_PCB* aFillMarker );
};
diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp
index 12ebcb3..9da3b6b 100644
--- a/pcbnew/edit.cpp
+++ b/pcbnew/edit.cpp
@@ -59,6 +59,8 @@
#include <tool/tool_manager.h>
#include <tools/common_actions.h>
+#include "viastitching.h"
+
// Handles the selection of command events.
void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
@@ -117,6 +119,8 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT:
case ID_POPUP_PCB_MOVE_ZONE_OUTLINES:
case ID_POPUP_PCB_ADD_ZONE_CORNER:
+ case ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA:
+ case ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA:
case ID_POPUP_PCB_DELETE_TRACKSEG:
case ID_POPUP_PCB_DELETE_TRACK:
case ID_POPUP_PCB_DELETE_TRACKNET:
@@ -678,6 +682,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->Refresh();
break;
+ case ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA:
+ case ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA:
+ ViaStitching::AddThermalVia( this, id, &dc);
+ break;
+
case ID_POPUP_PCB_MOVE_TEXTEPCB_REQUEST:
StartMoveTextePcb( (TEXTE_PCB*) GetCurItem(), &dc );
m_canvas->SetAutoPanRequest( true );
diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp
index 516388d..16f34de 100644
--- a/pcbnew/hotkeys_board_editor.cpp
+++ b/pcbnew/hotkeys_board_editor.cpp
@@ -372,9 +372,13 @@ bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
if( !itemCurrentlyEdited ) // no track in progress: switch layer only
{
- Other_Layer_Route( NULL, aDC );
- if( displ_opts->m_ContrastModeDisplay )
- m_canvas->Refresh();
+ //Add thermal via.
+ if( GetToolId() == ID_TRACK_BUTT )
+ {
+ evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ?
+ ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA : ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA;
+ break;
+ }
break;
}
@@ -502,6 +506,7 @@ bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
case HK_ZONE_REMOVE_FILLED:
evt_type = ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES;
break;
+
}
if( evt_type != 0 )
@@ -1071,6 +1076,7 @@ bool PCB_EDIT_FRAME::OnHotkeyDuplicateOrArrayItem( int aIdCommand )
case PCB_LINE_T:
case PCB_TEXT_T:
case PCB_TRACE_T:
+ case PCB_VIA_T:
case PCB_ZONE_AREA_T:
case PCB_TARGET_T:
case PCB_DIMENSION_T:
diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp
index 93f3b8e..399e40e 100644
--- a/pcbnew/kicad_plugin.cpp
+++ b/pcbnew/kicad_plugin.cpp
@@ -1467,6 +1467,9 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
THROW_IO_ERROR( wxString::Format( _( "unknown via type %d" ), via->GetViaType() ) );
}
+ if( via->GetThermalCode() )
+ m_out->Print( 0, " thermal" );
+
m_out->Print( 0, " (at %s) (size %s)",
FMT_IU( aTrack->GetStart() ).c_str(),
FMT_IU( aTrack->GetWidth() ).c_str() );
diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp
index f5ed5d0..ffe51d4 100644
--- a/pcbnew/onrightclick.cpp
+++ b/pcbnew/onrightclick.cpp
@@ -398,6 +398,18 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
_( "Select Working Layer" ), KiBitmap( select_w_layer_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_SELECT_LAYER_PAIR,
_( "Select Layer Pair for Vias" ), KiBitmap( select_layer_pair_xpm ) );
+
+ msg = AddHotkeyName( _( "Place Through Via" ), g_Board_Editor_Hokeys_Descr,
+ HK_ADD_THROUGH_VIA );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA, msg, KiBitmap( via_xpm ) );
+ if( GetDesignSettings().m_BlindBuriedViaAllowed )
+ {
+ msg = AddHotkeyName( _( "Place Blind/Buried Via" ),
+ g_Board_Editor_Hokeys_Descr, HK_ADD_BLIND_BURIED_VIA );
+ AddMenuItem( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA,
+ msg, KiBitmap( via_buried_xpm ) );
+ }
+
aPopMenu->AppendSeparator();
}
break;
@@ -635,6 +647,12 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
AddMenuItem( PopMenu, Append_Track_Width_List( GetBoard() ), ID_POPUP_PCB_SELECT_WIDTH,
_( "Select Track Width" ), KiBitmap( width_track_xpm ) );
+ if( !flags && (Track->Type() == PCB_VIA_T) )
+ {
+ msg = AddHotkeyName( _("Create Via Array" ), g_Board_Editor_Hokeys_Descr, HK_CREATE_ARRAY );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_CREATE_ARRAY, msg, KiBitmap( via_xpm ) );
+ }
+
// Delete control:
PopMenu->AppendSeparator();
wxMenu* trackdel_mnu = new wxMenu;
@@ -938,6 +956,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
msg = AddHotkeyName( _( "Edit Pad" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM );
AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_EDIT_PAD, msg, KiBitmap( options_pad_xpm ) );
+
sub_menu_Pad->AppendSeparator();
AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp
index 422a5a4..6a8e4e9 100644
--- a/pcbnew/pcb_draw_panel_gal.cpp
+++ b/pcbnew/pcb_draw_panel_gal.cpp
@@ -50,6 +50,7 @@ const LAYER_NUM GAL_LAYER_ORDER[] =
ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ),
ITEM_GAL_LAYER( RATSNEST_VISIBLE ), ITEM_GAL_LAYER( ANCHOR_VISIBLE ),
+ NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE ), NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ),
ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ),
ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
@@ -209,6 +210,7 @@ void PCB_DRAW_PANEL_GAL::SetHighContrastLayer( LAYER_ID aLayer )
GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
+ NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE ), NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE )
};
@@ -242,7 +244,8 @@ void PCB_DRAW_PANEL_GAL::SetTopLayer( LAYER_ID aLayer )
// Layers that should always have on-top attribute enabled
const LAYER_NUM layers[] = {
- ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ),
+ ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE ),
+ ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ), NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ),
ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ),
ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), Dwgs_User,
@@ -420,6 +423,8 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
// Some more required layers settings
m_view->SetRequired( ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) );
+ m_view->SetRequired( NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ) );
+ m_view->SetRequired( NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) );
m_view->SetRequired( ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) );
m_view->SetRequired( NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ) );
diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp
index f46bf85..8a69054 100644
--- a/pcbnew/pcb_painter.cpp
+++ b/pcbnew/pcb_painter.cpp
@@ -83,6 +83,8 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSet
m_layerColors[ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE )] = COLOR4D( 0.6, 0.6, 0.6, 0.8 );
m_layerColors[ITEM_GAL_LAYER( VIA_MICROVIA_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.8, 0.8 );
m_layerColors[ITEM_GAL_LAYER( PADS_VISIBLE )] = COLOR4D( 0.6, 0.6, 0.6, 0.8 );
+ m_layerColors[NETNAMES_GAL_LAYER( VIA_THROUGH_NETNAMES_VISIBLE )]= COLOR4D( 1.0, 1.0, 1.0, 0.9 );
+ m_layerColors[NETNAMES_GAL_LAYER( VIA_BBLIND_NETNAMES_VISIBLE )]= COLOR4D( 1.0, 1.0, 1.0, 0.9 );
m_layerColors[NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_FR_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
@@ -392,6 +394,32 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
if( !( brd->GetVisibleLayers() & aVia->GetLayerSet() ).any() )
return;
+ if( IsNetnameLayer( aLayer ) )
+ {
+ if( aVia->GetThermalCode() && m_pcbSettings.m_netNamesOnTracks && aVia->GetNetCode() )
+ {
+ const wxString& netName = aVia->GetShortNetname();
+ VECTOR2D textPosition = aVia->GetEnd();
+ double textOrientation = 0.0;
+
+ double tsize = aVia->GetDrillValue() / netName.Length();
+ VECTOR2D namesize( tsize, tsize );
+
+ m_gal->SetIsStroke( true );
+ m_gal->SetIsFill( false );
+ m_gal->SetStrokeColor( m_pcbSettings.GetColor( NULL, aLayer ) );
+ m_gal->SetLineWidth( namesize.x / 12.0 );
+ m_gal->SetFontBold( false );
+ m_gal->SetFontItalic( false );
+ m_gal->SetTextMirrored( false );
+ m_gal->SetGlyphSize( namesize );
+ m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
+ m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
+ m_gal->BitmapText( netName, textPosition, textOrientation );
+ }
+ return;
+ }
+
// Choose drawing settings depending on if we are drawing via's pad or hole
if( aLayer == ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ) )
radius = aVia->GetDrillValue() / 2.0;
@@ -420,6 +448,9 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
break;
}
+ m_gal->SetIsFill( !sketchMode );
+ m_gal->SetIsStroke( sketchMode );
+
if( aVia->GetViaType() == VIA_BLIND_BURIED )
{
// Buried vias are drawn in a special way to indicate the top and bottom layers
@@ -427,42 +458,69 @@ void PCB_PAINTER::draw( const VIA* aVia, int aLayer )
aVia->LayerPair( &layerTop, &layerBottom );
if( aLayer == ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ) )
- { // TODO outline mode
- m_gal->SetIsFill( true );
- m_gal->SetIsStroke( false );
- m_gal->SetFillColor( color );
+ {
+ if( sketchMode ) //Outline mode
+ {
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetStrokeColor( color );
+ }
+ else //Filled mode
+ {
+ m_gal->SetFillColor( color );
+ }
m_gal->DrawCircle( center, radius );
}
else
{
- double width = ( aVia->GetWidth() - aVia->GetDrillValue() ) / 2.0;
-
- m_gal->SetLineWidth( width );
- m_gal->SetIsFill( true );
- m_gal->SetIsStroke( false );
- m_gal->SetFillColor( color );
-
- if( aLayer == layerTop )
- {
- m_gal->DrawArc( center, radius, 0.0, M_PI / 2.0 );
- }
- else if( aLayer == layerBottom )
+ if( sketchMode ) //Outline mode
{
- m_gal->DrawArc( center, radius, M_PI, 3.0 * M_PI / 2.0 );
+ m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
+ m_gal->SetStrokeColor( color );
+ if( aLayer == layerTop )
+ {
+ m_gal->DrawArc( center, radius, 0.0, M_PI_2 );
+ m_gal->DrawLine( center, center + VECTOR2D( radius, 0.0 ) );
+ m_gal->DrawLine( center, center + VECTOR2D( 0.0, radius ) );
+ }
+ else if( aLayer == layerBottom )
+ {
+ m_gal->DrawArc( center, radius, M_PI, M_PI_2_x3 );
+ m_gal->DrawLine( center, center + VECTOR2D( -radius, 0.0 ) );
+ m_gal->DrawLine( center, center + VECTOR2D( 0.0, -radius ) );
+ }
+ else if( aLayer == ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) )
+ {
+ m_gal->DrawArc( center, radius, M_PI_2, M_PI );
+ m_gal->DrawArc( center, radius, M_PI_2_x3, M_PI_x2 );
+ double r1 = aVia->GetDrillValue() / 2.0;
+ m_gal->DrawLine( center + VECTOR2D( r1, 0.0 ), center + VECTOR2D( radius, 0.0 ) );
+ m_gal->DrawLine( center + VECTOR2D( 0.0, r1 ), center + VECTOR2D( 0.0, radius ) );
+ m_gal->DrawLine( center + VECTOR2D( -r1, 0.0 ), center + VECTOR2D( -radius, 0.0 ) );
+ m_gal->DrawLine( center + VECTOR2D( 0.0, -r1 ), center + VECTOR2D( 0.0, -radius ) );
+ }
}
- else if( aLayer == ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) )
+ else //Filled mode
{
- m_gal->DrawArc( center, radius, M_PI / 2.0, M_PI );
- m_gal->DrawArc( center, radius, 3.0 * M_PI / 2.0, 2.0 * M_PI );
+ m_gal->SetFillColor( color );
+
+ if( aLayer == layerTop )
+ {
+ m_gal->DrawArc( center, radius, 0.0, M_PI_2 );
+ }
+ else if( aLayer == layerBottom )
+ {
+ m_gal->DrawArc( center, radius, M_PI, M_PI_2_x3 );
+ }
+ else if( aLayer == ITEM_GAL_LAYER( VIA_BBLIND_VISIBLE ) )
+ {
+ m_gal->DrawArc( center, radius, M_PI_2, M_PI );
+ m_gal->DrawArc( center, radius, M_PI_2_x3, M_PI_x2);
+ }
}
}
}
else
{
- // Regular vias
- m_gal->SetIsFill( !sketchMode );
- m_gal->SetIsStroke( sketchMode );
-
if( sketchMode )
{
// Outline mode
@@ -685,8 +743,8 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
if( m_pcbSettings.m_sketchMode[ITEM_GAL_LAYER( PADS_VISIBLE )] )
{
// Outline mode
- m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
- m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI / 2, -M_PI / 2 );
+ m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI_2, M_PI_2_x3 );
+ m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI_2, -M_PI_2 );
m_gal->DrawLine( VECTOR2D( -m, -n ), VECTOR2D( m, -n ) );
m_gal->DrawLine( VECTOR2D( -m, n ), VECTOR2D( m, n ) );
}
@@ -1061,7 +1119,7 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget )
if( aTarget->GetShape() )
{
// shape x
- m_gal->Rotate( M_PI / 4.0 );
+ m_gal->Rotate( M_PI_4 );
size = 2.0 * aTarget->GetSize() / 3.0;
radius = aTarget->GetSize() / 2.0;
}
diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h
index c869918..cd510a0 100644
--- a/pcbnew/pcb_painter.h
+++ b/pcbnew/pcb_painter.h
@@ -228,6 +228,10 @@ protected:
void draw( const DIMENSION* aDimension, int aLayer );
void draw( const PCB_TARGET* aTarget );
void draw( const MARKER_PCB* aMarker );
+
+private:
+ static constexpr double M_PI_x2 = M_PI * 2.0;
+ static constexpr double M_PI_2_x3 = M_PI_2 * 3.0;
};
} // namespace KIGFX
diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp
index 744bc73..a8ef586 100644
--- a/pcbnew/pcb_parser.cpp
+++ b/pcbnew/pcb_parser.cpp
@@ -2562,6 +2562,7 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt;
T token;
+ bool is_thermal = false;
std::unique_ptr< VIA > via( new VIA( m_board ) );
@@ -2629,11 +2630,18 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
NeedRIGHT();
break;
+ case T_thermal:
+ is_thermal = true;
+ break;
+
default:
- Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
+ Expecting( "blind, micro, at, size, drill, layers, net, tstamp, thermal, or status" );
}
}
+ if( is_thermal )
+ via->SetThermalCode( via->GetNetCode() );
+
return via.release();
}
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index 8e98979..9d553ac 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -125,6 +125,8 @@ enum pcbnew_ids
ID_POPUP_PCB_PLACE_DRAGGED_ZONE_OUTLINE_SEGMENT,
ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES,
ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE,
+ ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA,
+ ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA,
ID_POPUP_PCB_DELETE_MARKER,
diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h
index 5454243..06f1312 100644
--- a/pcbnew/router/pns_router.h
+++ b/pcbnew/router/pns_router.h
@@ -35,6 +35,7 @@
#include "pns_item.h"
#include "pns_itemset.h"
#include "pns_node.h"
+#include "pns_placement_algo.h"
namespace KIGFX
{
@@ -205,7 +206,7 @@ public:
const wxString& FailureReason() const { return m_failureReason; }
PLACEMENT_ALGO* Placer() { return m_placer.get(); }
-
+
ROUTER_IFACE* GetInterface() const
{
return m_iface;
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
index 59c18fc..b92ed64 100644
--- a/pcbnew/router/router_tool.cpp
+++ b/pcbnew/router/router_tool.cpp
@@ -724,7 +724,11 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
}
else if( evt->IsAction( &ACT_PlaceThroughVia ) )
{
- m_toolMgr->RunAction( COMMON_ACTIONS::layerToggle, true );
+ m_toolMgr->RunAction( COMMON_ACTIONS::placeThermalThroughVia, true );
+ }
+ else if( evt->IsAction( &ACT_PlaceBlindVia ) )
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::placeThermalBlindVia, true );
}
else if( evt->IsAction( &COMMON_ACTIONS::remove ) )
{
diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
index 9a7b45c..3ef29f4 100644
--- a/pcbnew/tools/common_actions.cpp
+++ b/pcbnew/tools/common_actions.cpp
@@ -313,7 +313,8 @@ TOOL_ACTION COMMON_ACTIONS::layerPrev( "pcbnew.Control.layerPrev",
"", "" );
TOOL_ACTION COMMON_ACTIONS::layerToggle( "pcbnew.Control.layerToggle",
- AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ),
+ //AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ),
+ AS_GLOBAL, 0,
"", "" );
TOOL_ACTION COMMON_ACTIONS::layerAlphaInc( "pcbnew.Control.layerAlphaInc",
@@ -401,6 +402,14 @@ TOOL_ACTION COMMON_ACTIONS::zoneMerge( "pcbnew.EditorControl.zoneMerge",
AS_GLOBAL, 0,
_( "Merge zones" ), _( "Merge zones" ) );
+TOOL_ACTION COMMON_ACTIONS::placeThermalThroughVia( "pcbnew.Control.placeThermalThroughVia",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ),
+ "", "" );
+
+TOOL_ACTION COMMON_ACTIONS::placeThermalBlindVia( "pcbnew.Control.placeThermalBlindVia",
+ AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_ADD_BLIND_BURIED_VIA ),
+ "", "" );
+
TOOL_ACTION COMMON_ACTIONS::placeTarget( "pcbnew.EditorControl.placeTarget",
AS_GLOBAL, 0,
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
index b8167cf..2295a41 100644
--- a/pcbnew/tools/common_actions.h
+++ b/pcbnew/tools/common_actions.h
@@ -255,6 +255,8 @@ public:
static TOOL_ACTION zoneUnfill;
static TOOL_ACTION zoneUnfillAll;
static TOOL_ACTION zoneMerge;
+ static TOOL_ACTION placeThermalThroughVia;
+ static TOOL_ACTION placeThermalBlindVia;
// Module editor tools
/// Activation of the drawing tool (placing a PAD)
diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp
index 5fc9779..4fd0c69 100644
--- a/pcbnew/tools/pcb_editor_control.cpp
+++ b/pcbnew/tools/pcb_editor_control.cpp
@@ -51,6 +51,7 @@
#include <origin_viewitem.h>
#include <functional>
+#include <viastitching.h>
using namespace std::placeholders;
@@ -555,10 +556,13 @@ int PCB_EDITOR_CONTROL::ZoneFillAll( const TOOL_EVENT& aEvent )
BOARD* board = getModel<BOARD>();
RN_DATA* ratsnest = board->GetRatsnest();
+ //Via Stitching.
+ m_frame->Fill_All_Zones( m_frame, false );
+
for( int i = 0; i < board->GetAreaCount(); ++i )
{
ZONE_CONTAINER* zone = board->GetArea( i );
- m_frame->Fill_Zone( zone );
+ //m_frame->Fill_Zone( zone );
zone->SetIsFilled( true );
ratsnest->Update( zone );
getView()->Update( zone );
@@ -717,6 +721,18 @@ int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
}
+int PCB_EDITOR_CONTROL::PlaceThermalThroughVia( const TOOL_EVENT& aEvent )
+{
+ ViaStitching::AddThermalVia( m_frame, getModel<BOARD>(), VIA_THROUGH );
+ return 0;
+}
+
+int PCB_EDITOR_CONTROL::PlaceThermalBlindVia( const TOOL_EVENT& aEvent )
+{
+ ViaStitching::AddThermalVia( m_frame, getModel<BOARD>(), VIA_BLIND_BURIED );
+ return 0;
+}
+
int PCB_EDITOR_CONTROL::CrossProbePcbToSch( const TOOL_EVENT& aEvent )
{
if( m_probingSchToPcb )
@@ -883,6 +899,8 @@ void PCB_EDITOR_CONTROL::SetTransitions()
Go( &PCB_EDITOR_CONTROL::ZoneUnfill, COMMON_ACTIONS::zoneUnfill.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneUnfillAll, COMMON_ACTIONS::zoneUnfillAll.MakeEvent() );
Go( &PCB_EDITOR_CONTROL::ZoneMerge, COMMON_ACTIONS::zoneMerge.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::PlaceThermalThroughVia, COMMON_ACTIONS::placeThermalThroughVia.MakeEvent() );
+ Go( &PCB_EDITOR_CONTROL::PlaceThermalBlindVia, COMMON_ACTIONS::placeThermalBlindVia.MakeEvent() );
// Placing tools
Go( &PCB_EDITOR_CONTROL::PlaceTarget, COMMON_ACTIONS::placeTarget.MakeEvent() );
diff --git a/pcbnew/tools/pcb_editor_control.h b/pcbnew/tools/pcb_editor_control.h
index 1647297..6e3cbf4 100644
--- a/pcbnew/tools/pcb_editor_control.h
+++ b/pcbnew/tools/pcb_editor_control.h
@@ -62,6 +62,8 @@ public:
int ZoneUnfill( const TOOL_EVENT& aEvent );
int ZoneUnfillAll( const TOOL_EVENT& aEvent );
int ZoneMerge( const TOOL_EVENT& aEvent );
+ int PlaceThermalThroughVia( const TOOL_EVENT& aEvent );
+ int PlaceThermalBlindVia( const TOOL_EVENT& aEvent );
/**
* Function PlaceTarget()
diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp
index c6cd77f..7da22e9 100644
--- a/pcbnew/tools/pcbnew_control.cpp
+++ b/pcbnew/tools/pcbnew_control.cpp
@@ -259,7 +259,7 @@ int PCBNEW_CONTROL::ViaDisplayMode( const TOOL_EVENT& aEvent )
for( TRACK* track = getModel<BOARD>()->m_Track; track; track = track->Next() )
{
- if( track->Type() == PCB_TRACE_T )
+ if( track->Type() == PCB_VIA_T )
getView()->Update( track, KIGFX::GEOMETRY );
}
diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp
index ebe2964..ee23bbb 100644
--- a/pcbnew/zones_by_polygon_fill_functions.cpp
+++ b/pcbnew/zones_by_polygon_fill_functions.cpp
@@ -42,11 +42,12 @@
#include <pcbnew.h>
#include <zones.h>
+#include "viastitching.h"
#include <view/view.h>
-#define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." )
-
+//#define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." )
+#define FORMAT_STRING _( "Filling zone %d out of %d (net %s) Pass %d/2 ..." ) //Via stitching:
/**
* Function Delete_OldZone_Fill (obsolete)
@@ -140,7 +141,7 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
if( aActiveWindow )
progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg,
- areaCount+2, aActiveWindow,
+ areaCount*2+1, aActiveWindow,
wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
// Display the actual message
@@ -152,29 +153,43 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
int ii;
- for( ii = 0; ii < areaCount; ii++ )
+ //Via Stitching: Set all thermal vias netcodes for recovering.
+ Compile_Ratsnest( nullptr, false );
+
+ int progressCount = 1;
+ for(int n = 0; n < 2; n++) //Via Stitching: Fill pours twice.
{
- ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii );
- if( zoneContainer->GetIsKeepout() )
- continue;
+ for( ii = 0; ii < areaCount; ii++ )
+ {
+ ZONE_CONTAINER* zoneContainer = GetBoard()->GetArea( ii );
+ if( zoneContainer->GetIsKeepout() )
+ continue;
- msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ) );
+ msg.Printf( FORMAT_STRING, ii + 1, areaCount, GetChars( zoneContainer->GetNetname() ), n+1 );
- if( progressDialog )
- {
- if( !progressDialog->Update( ii+1, msg ) )
- break; // Aborted by user
+ if( progressDialog )
+ {
+ if( !progressDialog->Update( progressCount++, msg ) )
+ break; // Aborted by user
+ }
+
+ errorLevel = Fill_Zone( zoneContainer );
+
+ if( errorLevel && !aVerbose )
+ break;
}
- errorLevel = Fill_Zone( zoneContainer );
+ if( progressDialog )
+ progressDialog->Update( progressCount, _( "Calculate copper pour connections..." ) );
- if( errorLevel && !aVerbose )
- break;
+ //Via Stitching: Recalclate vias zones connections after fill.
+ n? ViaStitching::SetThermalViasNetcodes( GetBoard() ) : ViaStitching::ConnectThermalViasZonesPolygons( GetBoard() );
}
if( progressDialog )
{
- progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
+ //progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
+ progressDialog->Update( progressCount, _( "Updating ratsnest..." ) );
#ifdef __WXMAC__
// Work around a dialog z-order issue on OS X
aActiveWindow->Raise();
--------------2.7.4--
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Heikki Pulkkinen.
* Copyright (C) 2016 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
*/
#include "viastitching.h"
#include "connect.h"
#include "pcbnew_id.h"
#include "drc_stuff.h"
#include "ratsnest_data.h"
#include "router/router_tool.h"
#include "board_commit.h"
#include <tool/tool_manager.h>
#include <view/view.h>
#include "tools/common_actions.h"
using namespace ViaStitching;
//Legacy canvas add.
void ViaStitching::AddThermalVia( const PCB_EDIT_FRAME* aEditFrame, const int aViaType_ID, wxDC* aDC)
{
aEditFrame->GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH;
if( aViaType_ID == ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA )
{
if( aEditFrame->GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed )
aEditFrame->GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED;
else
return;
}
//Set right layerpair.
const_cast<PCB_EDIT_FRAME*>(aEditFrame)->Other_Layer_Route( nullptr, aDC );
const_cast<PCB_EDIT_FRAME*>(aEditFrame)->Other_Layer_Route( nullptr, aDC );
LAYER_ID layer = aEditFrame->GetActiveLayer();
wxPoint pos = aEditFrame->GetCrossHairPosition();
ZONE_CONTAINER* zone = aEditFrame->GetBoard()->HitTestForAnyFilledArea( pos, layer, layer, -1 );
if( zone )
{
TRACK* track = const_cast<PCB_EDIT_FRAME*>( aEditFrame )->Begin_Route( nullptr, aDC );
if( track )
{
if( track->GetNetCode() )
{
const_cast<PCB_EDIT_FRAME*>( aEditFrame )->Other_Layer_Route( track, aDC );
if( layer == aEditFrame->GetActiveLayer() )
{
g_CurrentTrackList.DeleteAll();
const_cast<PCB_EDIT_FRAME*>( aEditFrame )->SetCurItem( nullptr );
}
else
{
for( TRACK* d_t = g_CurrentTrackList.begin(); d_t != g_CurrentTrackList.end(); d_t = d_t->Next() )
if( dynamic_cast<VIA*>(d_t) )
dynamic_cast<VIA*>(d_t)->SetThermalCode( track->GetNetCode() );
const_cast<PCB_EDIT_FRAME*>( aEditFrame )->End_Route( track, aDC );
}
}
else
const_cast<PCB_EDIT_FRAME*>( aEditFrame )->End_Route( track, aDC );
}
const_cast<PCB_EDIT_FRAME*>( aEditFrame )->SetActiveLayer( layer );
}
}
//Gal canvas add.
void ViaStitching::AddThermalVia( const PCB_EDIT_FRAME* aEditFrame, const BOARD* aBoard, const VIATYPE_T aViaType )
{
if( aEditFrame->GetToolId() == ID_TRACK_BUTT )
{
wxPoint pos = aEditFrame->GetCrossHairPosition();
LAYER_ID currentLayer = aEditFrame->GetActiveLayer();
LAYER_ID pairTop = aEditFrame->GetScreen()->m_Route_Layer_TOP;
LAYER_ID pairBottom = aEditFrame->GetScreen()->m_Route_Layer_BOTTOM;
if( ( currentLayer != pairTop ) && ( currentLayer != pairBottom ) )
{
const_cast<PCB_EDIT_FRAME*>(aEditFrame)->SetActiveLayer( ToLAYER_ID( pairBottom ) );
}
LAYER_ID layer = aEditFrame->GetActiveLayer();
//wxPoint pos = wxPoint( start_snap_point.x, start_snap_point.y );
ZONE_CONTAINER* zone = aEditFrame->GetBoard()->HitTestForAnyFilledArea( pos, layer, layer, -1 );
if( zone )
{
int netcode = zone->GetNetCode();
BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
VIA* via = new VIA( const_cast<BOARD*>(aBoard) );
via->SetFlags( IS_NEW );
via->SetWidth( bds.GetCurrentViaSize());
via->SetDrill( bds.GetCurrentViaDrill() );
via->SetViaType( aViaType );
if( aViaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) )
&& ( ( pairTop == B_Cu && pairBottom == F_Cu )
|| ( pairTop == F_Cu && pairBottom == B_Cu ) ) )
via->SetViaType( VIA_THROUGH );
via->SetLayerPair( pairTop, pairBottom );
if( aViaType == VIA_BLIND_BURIED )
{
if( currentLayer == pairTop || currentLayer == pairBottom )
via->SetLayerPair( pairTop, pairBottom );
else
via->SetLayerPair( pairTop, currentLayer );
}
via->SetNetCode( netcode );
via->SetPosition( pos );
const_cast<VIA*>(dynamic_cast<const VIA*>(via))->SetThermalCode( netcode );
if( !DestroyConflictingThermalVia( via, aBoard, const_cast<PCB_EDIT_FRAME*>(aEditFrame) ) )
{
BOARD_COMMIT commit( const_cast<PCB_EDIT_FRAME*>(aEditFrame) );
commit.Add( via );
commit.Push( _( "Add Thermal Via" ) );
}
}
}
}
bool ViaStitching::IsTrackConnection( const VIA* aVia, const int aNetcode )
{
TRACK* start_track = const_cast<VIA*>(aVia);
if( start_track )
{
for( int n = 0; n < 2; ++n )
{
TRACK* track_seg = start_track;
if( n )
track_seg = start_track->Back();
while( track_seg )
{
if( track_seg->Type() == PCB_TRACE_T )
{
if( track_seg->GetNetCode() == aNetcode )
{
if( aVia->IsOnLayer( track_seg->GetLayer() ) )
{
if( track_seg->HitTest( aVia->GetEnd() ) )
{
return true;
}
}
}
else
track_seg = nullptr;
}
if( track_seg )
(n)? track_seg = track_seg->Back() : track_seg = track_seg->Next();
}
}
}
return false;
}
void ViaStitching::SetThermalViasNetcodes( const BOARD* aBoard, const std::unordered_map<const VIA*, int>& aVias )
{
for( auto& via_n : aVias )
{
const VIA* via = via_n.first;
int netcode_was = via_n.second;
int thermalcode = dynamic_cast<const VIA*>( via) ->GetThermalCode();
int netcode = via->GetNetCode();
if( thermalcode )
{
// Remove thermalcode reconnected thermalvia.
if( ( netcode && ( netcode_was == netcode ) && via->m_TracksConnected.size() ) ||
IsTrackConnection( via, thermalcode ) )
const_cast<VIA*>( via )->SetThermalCode( 0 );
// Set netcode to thermalvia.
else
const_cast<VIA*>( via )->SetNetCode( thermalcode );
}
else
// Set thermalcode unconnected via inside zone.
if( ( netcode_was && !netcode ) ||
( netcode_was && netcode && ( netcode_was == netcode ) && !via->m_TracksConnected.size() ) )
{
std::vector<ZONE_CONTAINER*> zones;
Collect_Zones_Hit_Via( zones, via, netcode_was, aBoard );
if( zones.size() )
{
const_cast<VIA*>( via )->SetNetCode( netcode_was );
const_cast<VIA*>( via )->SetThermalCode( netcode_was );
}
}
}
}
//Set zone connections to thermal vias.
void ViaStitching::SetThermalViasNetcodes( const BOARD* aBoard )
{
std::unordered_map<const VIA*, int> collected_vias;
collected_vias.clear();
for( TRACK* t = aBoard->m_Track; t; t = t->Next() )
{
const VIA* via = dynamic_cast<const VIA*>( t );
if( via && ( dynamic_cast<const VIA*>(via)->GetThermalCode()
|| ( t->GetNetCode()
&& !via->m_TracksConnected.size()
&& !dynamic_cast<const VIA*>(via)->GetThermalCode() ) ) )
collected_vias.insert( std::pair<const VIA*, int> ( via, t->GetNetCode() ) );
}
SetThermalViasNetcodes( aBoard, collected_vias );
}
//Set real zone polygon connections to thermal vias.
void ViaStitching::ConnectThermalViasZonesPolygons( const BOARD* aBoard )
{
//Connect unconnected single vias in copper pours.
if( aBoard->GetAreaCount() )
{
//Collect all vias that has no netcode and vias with thermal code.
std::unordered_map<const VIA*, bool> thermal_vias_all; //Via map with flag that it has been examined.
thermal_vias_all.clear();
//Collect other vias own container to look up connectivity.
std::vector<const VIA*> other_zone_vias;
other_zone_vias.clear();
for( TRACK* t = aBoard->m_Track; t; t = t->Next() )
{
const VIA* via = dynamic_cast<const VIA*>( t );
if( via )
{
int thermalcode = dynamic_cast<const VIA*>(via)->GetThermalCode();
int netcode = via->GetNetCode();
// Clear vias polyzone and zone containers.
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*> poly_zone;
poly_zone.clear();
if( thermalcode )
{
netcode = NETINFO_LIST::UNCONNECTED;
const_cast<VIA*>( via )->SetNetCode( netcode );
}
std::vector<ZONE_CONTAINER*> zones;
int zonecode = thermalcode? thermalcode : netcode;
Collect_Zones_Hit_Via( zones, via, zonecode, aBoard );
if( ( zones.size() >= MIN_THERMALVIA_ZONES ) || ( zones.size() && netcode ) )
{
wxPoint via_pos = via->GetEnd();
for( auto& zone : zones )
{
const SHAPE_POLY_SET& zone_polys = zone->GetFilledPolysList();
const SHAPE_POLY_SET::POLYGON* poly = zone_polys.GetPolygon( VECTOR2I( via_pos.x, via_pos.y ) );
if( poly )
poly_zone.insert( std::pair<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*> ( poly, zone ) );
}
if( !netcode )
thermal_vias_all.insert( std::pair<const VIA*, int>( via, false ) );
else
// ... other vias own container.
if( poly_zone.size() )
other_zone_vias.push_back( via );
}
const_cast<VIA*>(via)->SetThermalPolysZones( poly_zone );
const_cast<VIA*>(via)->SetThermalZones( zones );
}
}
//Test all collected vias connectivity.
for( auto& zone_via : thermal_vias_all )
{
const VIA* via = zone_via.first;
bool via_tested = zone_via.second;
int thermalcode = dynamic_cast<const VIA*>(via)->GetThermalCode();
int netcode = via->GetNetCode();
if( !netcode && !via_tested )
{
zone_via.second = true;
std::unordered_multimap<const VIA*, const SHAPE_POLY_SET::POLYGON*> vias_polys;
vias_polys.clear();
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>* via_polyzone
= const_cast<VIA*>(via)->GetThermalPolysZones();
if( via_polyzone->size() >= MIN_THERMALVIA_ZONES )
{
for( auto& polyzone : *via_polyzone )
{
const SHAPE_POLY_SET::POLYGON* poly = polyzone.first;
vias_polys.insert( std::pair<const VIA*, const SHAPE_POLY_SET::POLYGON*> ( via, poly ) );
//Collect all zones poly and vias that hits with via in same zone poly.
Collect_Vias_Zones_Chain( vias_polys, thermalcode, poly, thermal_vias_all, aBoard );
}
//Test pad connectivity.
bool hit = false;
CONNECTIONS connections( const_cast<BOARD*>( aBoard ) );
connections.BuildPadsList( thermalcode );
std::vector<D_PAD*> test_pads = connections.GetPadsList();
for( auto& poly: vias_polys )
{
const VIA* via = poly.first;
const SHAPE_POLY_SET::POLYGON* via_poly = poly.second;
// Other vias have pad connectivity.
for( auto& other_via : other_zone_vias)
{
if( other_via->GetNetCode() == thermalcode )
{
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>* othervia_polyszones = const_cast<VIA*>(other_via)->GetThermalPolysZones();
for( auto& othervia_polyzone : *othervia_polyszones )
{
if( othervia_polyzone.first == via_poly )
{
hit = true;
break;
}
}
}
}
if( !hit )
{
via_polyzone = const_cast<VIA*>(via)->GetThermalPolysZones();
ZONE_CONTAINER* zone = nullptr;
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>::const_iterator vpz = via_polyzone->find( via_poly );
if( vpz != via_polyzone->end() ) //always true, must be.
zone = vpz->second;
if( zone )
{
LAYER_ID zone_layer = zone->GetLayer();
// Tracks have pad connectivity.
TRACK* start_track = const_cast<VIA*>(via);
if( start_track )
{
for( int n = 0; n < 2; ++n )
{
TRACK* track_seg = start_track;
if( n )
track_seg = start_track->Back();
while( track_seg )
{
if( track_seg->Type() == PCB_TRACE_T )
{
if( track_seg->GetNetCode() == thermalcode )
{
if( track_seg->IsOnLayer( zone_layer ) && via->IsOnLayer( zone_layer ) )
{
for( int m = 0; m < 2; ++m )
{
wxPoint seg_pos = m? track_seg->GetEnd() : track_seg->GetStart();
if( zone->HitTestInsideZone( seg_pos ) )
{
const SHAPE_POLY_SET& zone_polys = zone->GetFilledPolysList();
const SHAPE_POLY_SET::POLYGON* seg_poly = zone_polys.GetPolygon( VECTOR2I( seg_pos.x, seg_pos.y ) );
if( seg_poly == via_poly )
{
hit = true;
track_seg = nullptr;
break;
}
}
}
}
}
else
track_seg = nullptr;
}
if( track_seg )
(n)? track_seg = track_seg->Back() : track_seg = track_seg->Next();
}
}
}
// Pad connection if no tracks or via connectivity.
if( !hit )
{
for( D_PAD* pad : test_pads )
{
wxPoint pad_pos = pad->GetPosition();
if( via->IsOnLayer( zone_layer ) && pad->IsOnLayer( zone_layer ) && zone->HitTestInsideZone( pad_pos ) )
{
const SHAPE_POLY_SET& zone_polys = zone->GetFilledPolysList();
const SHAPE_POLY_SET::POLYGON* pad_poly = zone_polys.GetPolygon( VECTOR2I( pad_pos.x, pad_pos.y ) );
if( pad_poly == via_poly )
{
hit = true;
break;
}
}
if( hit )
break;
}
}
}
}
if( hit )
break;
}
// Set netcodes if connection with pad or track.
if( hit )
for( auto& via_poly: vias_polys )
const_cast<VIA*>(via_poly.first)->SetNetCode( thermalcode );
}
}
}
}
}
//Recursively collect all vias to aViasPolys container which hits aVia in aZonePoly.
void ViaStitching::Collect_Vias_Zones_Chain( std::unordered_multimap<const VIA*, const SHAPE_POLY_SET::POLYGON*>& aViasPolys,
const int aThermalCode,
const SHAPE_POLY_SET::POLYGON* aZonePoly,
std::unordered_map<const VIA*, bool>& aThermalViasAll,
const BOARD* aPcb )
{
for( auto& thermal_via : aThermalViasAll )
{
const VIA* via_in_poly = thermal_via.first;
if( !thermal_via.second )
{
int via_in_poly_thermalcode = dynamic_cast<const VIA*>( via_in_poly )->GetThermalCode();
if( via_in_poly_thermalcode == aThermalCode )
{
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>* via_polyzone
= const_cast<VIA*>( via_in_poly )->GetThermalPolysZones();
std::unordered_map<const SHAPE_POLY_SET::POLYGON*, ZONE_CONTAINER*>::const_iterator vpz
= via_polyzone->find ( aZonePoly );
if( vpz != via_polyzone->end() )
{
thermal_via.second = true;
if( via_polyzone->size() >= MIN_THERMALVIA_ZONES )
{
for( auto& polyzone : *via_polyzone )
{
const SHAPE_POLY_SET::POLYGON* poly = polyzone.first;
aViasPolys.insert( std::pair<const VIA*, const SHAPE_POLY_SET::POLYGON*>( via_in_poly, poly ) );
Collect_Vias_Zones_Chain( aViasPolys, aThermalCode, poly, aThermalViasAll, aPcb );
}
}
}
}
}
}
}
//Collect all zones to aZone container, which hits aVia pos inside layer pair in same netcode.
void ViaStitching::Collect_Zones_Hit_Via( std::vector<ZONE_CONTAINER*>& aZones,
const VIA* aVia,
const int aNetCode,
const BOARD* aPcb,
const LAYER_NUM aLayerOnly )
{
LAYER_ID via_top_layer, via_bottom_layer;
aVia->LayerPair( &via_top_layer, &via_bottom_layer );
wxPoint via_pos = aVia->GetEnd();
ViaStitching::Collect_Zones_Hit_Pos( aZones, via_pos, via_top_layer, via_bottom_layer, aNetCode, aPcb, aLayerOnly );
}
void ViaStitching::Collect_Zones_Hit_Pos( std::vector<ZONE_CONTAINER*>& aZones,
wxPoint aPos,
LAYER_ID aTopLayer,
LAYER_ID aBottomLayer,
const int aNetCode,
const BOARD* aPcb,
const LAYER_NUM aLayerOnly )
{
int num_areas = aPcb->GetAreaCount();
aZones.clear();
for( int area_index = 0; area_index < num_areas; area_index++ )
{
ZONE_CONTAINER* area = aPcb->GetArea( area_index );
if(area)
{
LAYER_NUM area_layer = area->GetLayer();
if( ( aLayerOnly < F_Cu ) || ( aLayerOnly == area_layer ) )
if( (area_layer >= aTopLayer) && (area_layer <= aBottomLayer) )
{
if( area->HitTestInsideZone( aPos ) && ( area->GetNetCode() == aNetCode ) )
{
aZones.push_back( area );
}
}
}
}
}
void ViaStitching::RuleCheck( const TRACK* aTrack, DRC* aDRC )
{
if( dynamic_cast<const VIA*>( aTrack ) )
{
if( dynamic_cast<const VIA*>( aTrack )->GetThermalCode() )
{
std::vector<const SHAPE_POLY_SET::POLYGON*> via_zonepoly;
via_zonepoly.clear();
std::vector<ZONE_CONTAINER*>* zones = const_cast<VIA*>(dynamic_cast<const VIA*>( aTrack ))->GetThermalZones();;
wxPoint via_pos = aTrack->GetEnd();
for( auto& zone : *zones )
{
const SHAPE_POLY_SET& zone_polys = zone->GetFilledPolysList();
const SHAPE_POLY_SET::POLYGON* poly = zone_polys.GetPolygon( VECTOR2I( via_pos.x, via_pos.y ) );
if( poly )
via_zonepoly.push_back( poly );
}
//Warning Do not have at least two pours connected.
//Locking via disables warning. Is that good?
if( ( via_zonepoly.size() < 2 ) && !aTrack->IsLocked() )
{
aDRC->AddMarker( aTrack, aTrack->GetEnd(), DRCE_THERMAL_VIA_CONNECTED_POURS, nullptr );
}
//Unconnected thermal via.
if( !via_zonepoly.size() )
{
aDRC->AddMarker( aTrack, aTrack->GetEnd(), DRCE_THERMAL_VIA_UNCONNECTED, nullptr );
}
}
}
}
bool ViaStitching::CleanThermalVias( PCB_EDIT_FRAME* aEditFrame, BOARD_COMMIT* aCommit )
{
BOARD* board = aEditFrame->GetBoard();
std::set<TRACK*> vias_remove;
vias_remove.clear();
bool modified = false;
for( TRACK* t = board->m_Track; t; t = t->Next() )
{
const VIA* thermal_via = dynamic_cast<const VIA*>( t );
if( thermal_via )
{
int thermalcode = dynamic_cast<const VIA*>(thermal_via)->GetThermalCode();
if( thermalcode )
{
wxPoint via_pos = thermal_via->GetEnd();
LSET via_layerset = thermal_via->GetLayerSet();
int netcode = 0;
if( thermalcode )
{
BOARD_CONNECTED_ITEM* lock_point_item = const_cast<BOARD*>(board)->GetLockPoint( via_pos, via_layerset );
if( lock_point_item )
{
if( ( lock_point_item->Type() == PCB_PAD_T ) && ( lock_point_item->GetNetCode() != thermalcode ) )
netcode = lock_point_item->GetNetCode();
}
if( !netcode )
{
TRACK* start_track = board->m_Track;
TRACK* track = ViaStitching::ViaBreakTrack( start_track, thermal_via );
bool test_again = true;
do
{
if( track )
{
//Do not have to remove when thermal via in track with same netcode.
test_again = track->GetNetCode() == thermalcode;
//But, if it is via.
if( track->Type() == PCB_VIA_T )
{
//Remove thermal, if it conflicts with normal via with diff netcode.
int test_via_thermalcode = dynamic_cast<VIA*>(track)->GetThermalCode();
if( !test_via_thermalcode && ( track->GetNetCode() != thermalcode ) )
test_again = false;
//Remove if both are same thermalcode thermals.
if( test_via_thermalcode == thermalcode )
{
//But not, if other is removed already.
std::set<TRACK*>::iterator it = vias_remove.find( track );
if( it == vias_remove.end() )
test_again = false;
}
else //Both are thermal and diff netcode. Do not Remove.
if( test_via_thermalcode && ( test_via_thermalcode != thermalcode ) )
test_again = true;
}
if( test_again )
{
start_track = track->Next();
if( start_track )
track = ViaStitching::ViaBreakTrack( start_track, thermal_via );
else
{
track = nullptr;
test_again = false;
}
}
}
else
test_again = false;
}
while( test_again );
if( track )
netcode = track->GetNetCode();
}
if( netcode )
{
vias_remove.insert( const_cast<VIA*>( thermal_via ) );
}
}
}
}
}
for( auto via_remove : vias_remove )
{
board->Remove( via_remove );
aCommit->Removed( via_remove );
modified = true;
}
return modified;
}
TRACK* ViaStitching::ViaBreakTrack( const TRACK* aStartingTrack,
const VIA* aVia )
{
LAYER_ID via_top_layer, via_bottom_layer;
aVia->LayerPair( &via_top_layer, &via_bottom_layer );
wxPoint via_pos = aVia->GetEnd();
for( const TRACK* track = aStartingTrack; track; track = track->Next() )
{
if( track != aVia )
{
if( ( track->Type() == PCB_VIA_T ) )
{
if( track->IsOnLayer( via_top_layer ) || track->IsOnLayer( via_bottom_layer ) )
{
if( ( aVia->GetThermalCode() == dynamic_cast<const VIA*>(track)->GetThermalCode() ) )
{
if( track->HitTest( via_pos ) )
return const_cast<TRACK*>( track );
}
else
if( HitTestPoints( via_pos, track->GetEnd(),
aVia->GetWidth() / 2 + track->GetWidth() / 2 ) )
return const_cast<TRACK*>( track );
}
}
else
{
if( aVia->IsOnLayer( track->GetLayer() ) )
{
if( track->HitTest( via_pos ) )
return const_cast<TRACK*>( track );
else
//Track endpoints may connect with zone.
//Test endpoints with clearance. Do not want break connection to zone.
if( HitTestPoints( via_pos, track->GetStart(),
aVia->GetWidth() / 2 + track->GetWidth() / 2 + track->GetClearance() ) )
return const_cast<TRACK*>( track );
else
if( HitTestPoints( via_pos, track->GetEnd(),
aVia->GetWidth() / 2 + track->GetWidth() / 2 + track->GetClearance() ) )
return const_cast<TRACK*>( track );
}
}
}
}
return nullptr;
}
//Do not add thermal vias. if no zone in current layer. And use DRC if it is ON.
bool ViaStitching::DestroyConflictingThermalVia( BOARD_ITEM* aItem, const BOARD* aPcb, PCB_BASE_FRAME* aFrame )
{
if( aItem->Type() == PCB_VIA_T )
if( dynamic_cast<const VIA*>(aItem)->GetThermalCode() )
{
std::vector<ZONE_CONTAINER*> zones;
ViaStitching::Collect_Zones_Hit_Via( zones,
static_cast<const VIA*>(aItem),
dynamic_cast<const VIA*>(aItem)->GetNetCode(),
aPcb,
aFrame->GetActiveLayer() );
aItem->SetFlags( IS_NEW );
if( !zones.size() ||
( dynamic_cast<PCB_EDIT_FRAME*>(aFrame)->GetDrcController()->Drc( static_cast<TRACK*>(aItem),
aPcb->m_Track ) &&
g_Drc_On ) )
{
delete aItem; aItem = nullptr;
return true;
}
aItem->ClearFlags( IS_NEW );
}
return false;
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Heikki Pulkkinen.
* Copyright (C) 2016 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 viastitching.h
* @brief Definitions for Via Stitching.
*/
#ifndef VIASTITCHING_H
#define VIASTITCHING_H
#include <class_zone.h>
#include <class_track.h>
#include <class_board.h>
#include <wxPcbStruct.h>
#include <tool/tool_event.h>
namespace ViaStitching
{
const int MIN_THERMALVIA_ZONES = 1;
inline int IsThermalVia(const TRACK* aItem ) {
if( aItem->Type() == PCB_VIA_T )
return dynamic_cast<VIA*>(static_cast<TRACK*>(const_cast<TRACK*>(aItem)))->GetThermalCode();
return 0;
}
void SetThermalViasNetcodes( const BOARD* aBoard, const std::unordered_map<const VIA*, int>& aVias );
void SetThermalViasNetcodes( const BOARD* aBoard );
void AddThermalVia( const PCB_EDIT_FRAME* aEditFrame, const int aViaType_ID, wxDC* aDC );//Legacy
void AddThermalVia( const PCB_EDIT_FRAME* aEditFrame, const BOARD* aBoard, const VIATYPE_T aViaType ); //GAL
void ConnectThermalViasZonesPolygons( const BOARD* aBoard );
void Collect_Vias_Zones_Chain( std::unordered_multimap<const VIA*, const SHAPE_POLY_SET::POLYGON*>& aViasPolys,
const int aNetCode,
const SHAPE_POLY_SET::POLYGON* aZonePoly,
std::unordered_map<const VIA*, bool>& aViasAll,
const BOARD* aPcb );
void Collect_Zones_Hit_Via( std::vector<ZONE_CONTAINER*>& aZones,
const VIA* aVia,
const int aNetCode,
const BOARD* aPcb,
const LAYER_NUM aLayerOnly = UNDEFINED_LAYER );
void Collect_Zones_Hit_Pos( std::vector<ZONE_CONTAINER*>& aZones,
wxPoint aPos,
LAYER_ID aTopLayer,
LAYER_ID aBottomLayer,
const int aNetCode,
const BOARD* aPcb,
const LAYER_NUM aLayerOnly = UNDEFINED_LAYER );
bool IsTrackConnection( const VIA* aVia, const int aNetcode );
void RuleCheck( const TRACK* aTrack, DRC* aDRC );
bool CleanThermalVias( PCB_EDIT_FRAME* aEditFrame, BOARD_COMMIT* aCommit );
TRACK* ViaBreakTrack( const TRACK* aStartingTrack, const VIA* aVia );
bool DestroyConflictingThermalVia( BOARD_ITEM* aItem, const BOARD* aPcb, PCB_BASE_FRAME* aFrame );
} //namespace Via_Stitching
#endif //VIASTITCHING_H
Follow ups
References
-
Via Stitching
From: Heikki Pulkkinen, 2016-09-24
-
Re: Via Stitching
From: Heikki Pulkkinen, 2016-10-29
-
Re: Via Stitching
From: Heikki Pulkkinen, 2016-11-07
-
Re: Via Stitching
From: Heikki Pulkkinen, 2016-11-08
-
Re: Via Stitching
From: Heikki Pulkkinen, 2016-12-21
-
Re: Via Stitching
From: Heikki Pulkkinen, 2017-01-09
-
Re: Via Stitching
From: Wayne Stambaugh, 2017-01-16
-
Re: Via Stitching
From: Heikki Pulkkinen, 2017-01-17
-
Re: Via Stitching
From: Wayne Stambaugh, 2017-01-18
-
Re: Via Stitching
From: Maciej Sumiński, 2017-01-19
-
Re: Via Stitching
From: Heikki Pulkkinen, 2017-01-25
-
Re: Via Stitching
From: Kristoffer Ödmark, 2017-02-03