← Back to team overview

kicad-developers team mailing list archive

Re: teardrops & rounded corners & ???

 

This is latest patch. But not files in pcbnew/trackitems directory.

On Mon, May 29, 2017 at 10:46 AM, Heikki Pulkkinen <hei6mail@xxxxxxxxx>
wrote:

>
> ---------- Forwarded message ----------
> From: Heikki Pulkkinen <hei6mail@xxxxxxxxx>
> Date: Mon, May 29, 2017 at 10:44 AM
> Subject: Re: [Kicad-developers] teardrops & rounded corners & ???
> To: Russell Oliver <roliver8143@xxxxxxxxx>
>
>
> Hi
>
> It seems that this patch is not going to work, because you have removed
> preprocessor directive PCBNEW_WITH_TRACKITEMS. If you remove it you have to
> remove code witch are defined out with this directive.
>
> Maybe another way to make patch is clone both branches to their own
> directory. And then just copy master branch .git directory to my branch
> directory. And then commit that.
>
> Cheers
>
> Heikki
>
> On Sun, May 28, 2017 at 7:24 PM, Russell Oliver <roliver8143@xxxxxxxxx>
> wrote:
>
>> Hi Heikki and all.
>>
>> I'm excited to be able to present a patch of Heikki's work.
>>
>> It was created against kicad master branch as of writing. i.e. commit "3d
>> viewer: cosmetic.." 1fda668f242244af5803dd5a7dd18e1b8cc7ac33
>> Includes up to "update origin and roundedcorners copy current" from
>> Heikki's repo.
>>
>> It is also available at https://github.com/rustyoz/kicad/tree/teardrops
>>
>> Hopefully it makes it a bit easier for everyone to test
>>
>> Regards
>> Russell
>>
>> On Sat, May 27, 2017 at 10:30 PM Heikki Pulkkinen <hei6mail@xxxxxxxxx>
>> wrote:
>>
>>> Hi
>>>
>>> I think that it was  five or nine day ago some of those 'Fixed duplicate
>>> field names' or 'Component table is left aligned'..
>>>
>>> On Sat, May 27, 2017 at 3:12 PM, Heikki Pulkkinen <hei6mail@xxxxxxxxx>
>>> wrote:
>>>
>>>> I do not know that, but now it is latest and missing files are added
>>>> too.
>>>>
>>>> On Sat, May 27, 2017 at 9:54 AM, Russell Oliver <roliver8143@xxxxxxxxx>
>>>> wrote:
>>>>
>>>>> Hi Heikki,
>>>>>
>>>>> Do you know which commit or release that you started developing the
>>>>> features from? I'll see if i can recreate the necessary git history.
>>>>>
>>>>> Regards
>>>>> Russell
>>>>>
>>>>> On Sat, May 27, 2017 at 4:34 PM Heikki Pulkkinen <hei6mail@xxxxxxxxx>
>>>>> wrote:
>>>>>
>>>>>> And that menu structure is what it is. It is there just testing
>>>>>> purposes. It can be done more intuitive for all users.
>>>>>>
>>>>>> Teardrops and these things is going to change kicad_pcb file making
>>>>>> additions end of file. And that stitch via thermal word is threre too.
>>>>>>
>>>>>> 26.5.2017 23.13 "Kaspar Emanuel" <kaspar.emanuel@xxxxxxxxx>
>>>>>> kirjoitti:
>>>>>>
>>>>>>> I managed to compile by copying the missing files over from the main
>>>>>>> KiCAD repo. Seems to be working fine!
>>>>>>>
>>>>>>> Initial feedback:
>>>>>>>
>>>>>>>    - Thanks very much for working on this!
>>>>>>>    - The menu is very unintuitive but is it useful to give feedback
>>>>>>>    on this? Is it just an intermediate menu for you to continue development or
>>>>>>>    are you planning for the final functionality to be similar to what you have
>>>>>>>    there?
>>>>>>>
>>>>>>> I will continue to experiment with it in the meantime.
>>>>>>> ​
>>>>>>>
>>>>>>> On 25 May 2017 at 22:59, Nick Østergaard <oe.nick@xxxxxxxxx> wrote:
>>>>>>>
>>>>>>>> Basically described in https://help.github.com/articl
>>>>>>>> es/fork-a-repo/
>>>>>>>>
>>>>>>>> (there might exist better tutorials)
>>>>>>>>
>>>>>>>> 2017-05-25 21:22 GMT+02:00 Nick Østergaard <oe.nick@xxxxxxxxx>:
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > Den 25/05/2017 19.42 skrev "Kaspar Emanuel" <
>>>>>>>> kaspar.emanuel@xxxxxxxxx>:
>>>>>>>> >
>>>>>>>> > Hey Heikki,
>>>>>>>> >
>>>>>>>> > I wanted to give this a test with a small board I thought would
>>>>>>>> look nicer
>>>>>>>> > with curved traces.
>>>>>>>> >
>>>>>>>> > During the cmake step I noticed following error but was still
>>>>>>>> able to
>>>>>>>> > proceed to the make step.
>>>>>>>> >
>>>>>>>> > CMake Error at common/CMakeLists.txt:344 (add_library):
>>>>>>>> >   Cannot find source file:
>>>>>>>> >
>>>>>>>> >     build_version.cpp
>>>>>>>> >
>>>>>>>> >   Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++
>>>>>>>> .hm .hpp
>>>>>>>> >   .hxx .in .txx
>>>>>>>> >
>>>>>>>> > CMake Error at pcbnew/CMakeLists.txt:637 (add_library):
>>>>>>>> >   Cannot find source file:
>>>>>>>> >
>>>>>>>> >     build_BOM_from_board.cpp
>>>>>>>> >
>>>>>>>> >   Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++
>>>>>>>> .hm .hpp
>>>>>>>> >   .hxx .in .txx
>>>>>>>> >
>>>>>>>> > But the make step exited with a similar error:
>>>>>>>> >
>>>>>>>> > /home/kaspar/projects/kicad/heikkipu-kicad-devel/pcbnew/lega
>>>>>>>> cy_plugin.cpp:89:27:
>>>>>>>> > fatal error: build_version.h: No such file or directory
>>>>>>>> > compilation terminated.
>>>>>>>> > common/CMakeFiles/pcbcommon.dir/build.make:1020: recipe for
>>>>>>>> target
>>>>>>>> > 'common/CMakeFiles/pcbcommon.dir/__/pcbnew/legacy_plugin.cpp.o'
>>>>>>>> failed
>>>>>>>> > make[2]: *** [common/CMakeFiles/pcbcommon.d
>>>>>>>> ir/__/pcbnew/legacy_plugin.cpp.o]
>>>>>>>> > Error 1
>>>>>>>> > make[2]: *** Waiting for unfinished jobs....
>>>>>>>> > CMakeFiles/Makefile2:521: recipe for target
>>>>>>>> > 'common/CMakeFiles/pcbcommon.dir/all' failed
>>>>>>>> > make[1]: *** [common/CMakeFiles/pcbcommon.dir/all] Error 2
>>>>>>>> > Makefile:149: recipe for target 'all' failed
>>>>>>>> > make: *** [all] Error 2
>>>>>>>> >
>>>>>>>> > Hope this helps, let me know what to do and I can continue trying
>>>>>>>> to compile
>>>>>>>> > it.
>>>>>>>> >
>>>>>>>> > Cheers,
>>>>>>>> >
>>>>>>>> > Kaspar
>>>>>>>> >
>>>>>>>> > P.S. How come your Git repository doesn’t have the same history
>>>>>>>> as KiCAD git
>>>>>>>> > repository?
>>>>>>>> >
>>>>>>>> > Yeah, that is not the way to send patches. You need to commit in
>>>>>>>> a local
>>>>>>>> > branch from the upstream kicad master branch anf push that.
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > On 21 May 2017 at 09:41, Heikki Pulkkinen <hei6mail@xxxxxxxxx>
>>>>>>>> wrote:
>>>>>>>> >>
>>>>>>>> >> Hi Wayne and all
>>>>>>>> >>
>>>>>>>> >> Want to test.
>>>>>>>> >>
>>>>>>>> >> https://github.com/heikkipu/kicad-devel
>>>>>>>> >>
>>>>>>>> >> And yes, it is going to change kicad_pcb file.
>>>>>>>> >>
>>>>>>>> >>
>>>>>>>> >> Regards
>>>>>>>> >>
>>>>>>>> >> Heikki
>>>>>>>> >>
>>>>>>>> >> _______________________________________________
>>>>>>>> >> Mailing list: https://launchpad.net/~kicad-developers
>>>>>>>> >> Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>>>>>>> >> Unsubscribe : https://launchpad.net/~kicad-developers
>>>>>>>> >> More help   : https://help.launchpad.net/ListHelp
>>>>>>>> >>
>>>>>>>> >
>>>>>>>> >
>>>>>>>> > _______________________________________________
>>>>>>>> > Mailing list: https://launchpad.net/~kicad-developers
>>>>>>>> > Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>>>>>>> > Unsubscribe : https://launchpad.net/~kicad-developers
>>>>>>>> > More help   : https://help.launchpad.net/ListHelp
>>>>>>>> >
>>>>>>>> >
>>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>> Mailing list: https://launchpad.net/~kicad-developers
>>>>>> Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
>>>>>> Unsubscribe : https://launchpad.net/~kicad-developers
>>>>>> More help   : https://help.launchpad.net/ListHelp
>>>>>>
>>>>>
>>>>
>>>
>
>
From 258a17e2ad3c5d38c395693a1c479ebef07c36fe Mon Sep 17 00:00:00 2001
From: heikki <hei6mail@xxxxxxxxx>
Date: Mon, 29 May 2017 10:52:41 +0300
Subject: [PATCH] Teardrops Roundedcorners ViaStitching and something
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.7.5"

This is a multi-part message in MIME format.
--------------2.7.5
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit

---
 3d-viewer/3d_canvas/create_layer_items.cpp |  32 +-
 CMakeLists.txt                             |   6 +
 CMakeModules/FindwxWidgets.cmake           |   3 +-
 bitmaps_png/mk_icn_res.sh                  |   0
 common/CMakeLists.txt                      |  31 +
 common/geometry/shape_poly_set.cpp         |  28 +
 common/pcb.keywords                        |  20 +-
 include/class_board_item.h                 |   5 +
 include/class_drawpanel.h                  |   5 +
 include/core/typeinfo.h                    |   4 +
 include/geometry/shape_poly_set.h          |   5 +
 include/wxPcbStruct.h                      |   6 +
 new/make-dir-lib-source-test-data.sh       |   0
 new/make-html.sh                           |   0
 pcbnew/CMakeLists.txt                      |  23 +
 pcbnew/array_creator.cpp                   |  10 +
 pcbnew/block.cpp                           |  98 ++++
 pcbnew/board_commit.cpp                    |  26 +
 pcbnew/class_board.cpp                     |  58 ++
 pcbnew/class_board.h                       |  18 +
 pcbnew/class_drc_item.cpp                  |  72 +++
 pcbnew/class_module.cpp                    |  50 ++
 pcbnew/class_module.h                      |  10 +
 pcbnew/class_netinfo_item.cpp              |  20 +
 pcbnew/class_pad.cpp                       |  19 +
 pcbnew/class_pad.h                         |  13 +
 pcbnew/class_track.cpp                     |  30 +-
 pcbnew/class_track.h                       |  36 ++
 pcbnew/clean.cpp                           | 123 ++++
 pcbnew/connect.cpp                         |  92 ++-
 pcbnew/controle.cpp                        |  25 +
 pcbnew/deltrack.cpp                        |  46 ++
 pcbnew/dragsegm.cpp                        |  50 ++
 pcbnew/drc.cpp                             |  30 +
 pcbnew/drc_clearance_test_functions.cpp    |  96 ++++
 pcbnew/drc_marker_functions.cpp            |  37 ++
 pcbnew/drc_stuff.h                         |  53 ++
 pcbnew/edit.cpp                            | 878 +++++++++++++++++++++++++++++
 pcbnew/edit_track_width.cpp                |  40 ++
 pcbnew/editrack-part2.cpp                  |  20 +
 pcbnew/editrack.cpp                        | 274 +++++++++
 pcbnew/files.cpp                           |   6 +
 pcbnew/hotkeys.cpp                         |   3 +
 pcbnew/hotkeys.h                           |   1 +
 pcbnew/hotkeys_board_editor.cpp            |  38 ++
 pcbnew/initpcb.cpp                         |   7 +
 pcbnew/kicad_plugin.cpp                    |  20 +
 pcbnew/menubar_pcbframe.cpp                |  15 +
 pcbnew/modules.cpp                         |  45 ++
 pcbnew/move-drag_pads.cpp                  |  98 ++++
 pcbnew/move_or_drag_track.cpp              | 245 +++++++-
 pcbnew/onleftclick.cpp                     |  13 +
 pcbnew/onrightclick.cpp                    |  65 +++
 pcbnew/pcb_painter.cpp                     |  29 +
 pcbnew/pcb_parser.cpp                      |  31 +
 pcbnew/pcb_parser.h                        |   5 +
 pcbnew/pcbframe.cpp                        |  12 +
 pcbnew/pcbnew_id.h                         | 111 ++++
 pcbnew/plot_board_layers.cpp               |  19 +
 pcbnew/router/pns_router.h                 |   9 +-
 pcbnew/router/pns_tool_base.h              |   1 +
 pcbnew/router/router_tool.cpp              |  42 +-
 pcbnew/sel_layer.cpp                       |   5 +
 pcbnew/tool_pcb.cpp                        |   7 +
 pcbnew/toolbars_update_user_interface.cpp  |  15 +
 pcbnew/tools/pcb_editor_control.cpp        |  24 +
 pcbnew/tools/pcbnew_control.cpp            |   7 +
 pcbnew/tr_modif.cpp                        |  17 +
 pcbnew/tracepcb.cpp                        |  32 ++
 pcbnew/undo_redo.cpp                       |  72 ++-
 pcbnew/zones_by_polygon_fill_functions.cpp |  61 +-
 scripts/ddr3_length_match.py               |   0
 scripts/lib_convert.py                     |   0
 scripts/library-repos-install.bat          |   0
 scripts/library-repos-install.sh           |   0
 scripts/test_kicad_plugin.py               |   0
 scripts/test_plugin.py                     |   0
 tools/checkcoding.py                       |   0
 78 files changed, 3427 insertions(+), 20 deletions(-)
 mode change 100755 => 100644 bitmaps_png/mk_icn_res.sh
 mode change 100755 => 100644 new/make-dir-lib-source-test-data.sh
 mode change 100755 => 100644 new/make-html.sh
 mode change 100755 => 100644 scripts/ddr3_length_match.py
 mode change 100755 => 100644 scripts/lib_convert.py
 mode change 100644 => 100755 scripts/library-repos-install.bat
 mode change 100755 => 100644 scripts/library-repos-install.sh
 mode change 100755 => 100644 scripts/test_kicad_plugin.py
 mode change 100755 => 100644 scripts/test_plugin.py
 mode change 100755 => 100644 tools/checkcoding.py


--------------2.7.5
Content-Type: text/x-patch; name="0001-Teardrops-Roundedcorners-ViaStitching-and-something.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-Teardrops-Roundedcorners-ViaStitching-and-something.patch"

diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp
index d783a65..80f8f99 100644
--- a/3d-viewer/3d_canvas/create_layer_items.cpp
+++ b/3d-viewer/3d_canvas/create_layer_items.cpp
@@ -54,7 +54,11 @@
 #include <utility>
 #include <vector>
 
-
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include <trackitems/teardrop.h>
+#include <trackitems/roundedtrackscorner.h>
+#include <trackitems/roundedcornertrack.h>
+#endif
 
 // These variables are parameters used in addTextSegmToContainer.
 // But addTextSegmToContainer is a call-back function,
@@ -254,6 +258,12 @@ COBJECT2D *CINFO3D_VISU::createNewTrack( const TRACK* aTrack,
     SFVEC2F start3DU(  aTrack->GetStart().x * m_biuTo3Dunits,
                       -aTrack->GetStart().y * m_biuTo3Dunits ); // y coord is inverted
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( aTrack->Type() == PCB_TRACE_T && dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack)))
+        start3DU = SFVEC2F(  dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetStartVisible().x * m_biuTo3Dunits,
+                      -dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetStartVisible().y * m_biuTo3Dunits );
+#endif
+
     switch( aTrack->Type() )
     {
     case PCB_VIA_T:
@@ -264,6 +274,12 @@ COBJECT2D *CINFO3D_VISU::createNewTrack( const TRACK* aTrack,
     }
         break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+    case PCB_ROUNDEDTRACKSCORNER_T:
+        break;
+#endif
+
     default:
     {
         wxASSERT( aTrack->Type() == PCB_TRACE_T );
@@ -271,6 +287,12 @@ COBJECT2D *CINFO3D_VISU::createNewTrack( const TRACK* aTrack,
         SFVEC2F end3DU (  aTrack->GetEnd().x * m_biuTo3Dunits,
                          -aTrack->GetEnd().y * m_biuTo3Dunits );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( aTrack->Type() == PCB_TRACE_T && dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack)))
+            end3DU = SFVEC2F(  dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetEndVisible().x * m_biuTo3Dunits,
+                      -dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetEndVisible().y * m_biuTo3Dunits );
+#endif
+
         // Cannot add segments that have the same start and end point
         if( Is_segment_a_circle( start3DU, end3DU ) )
         {
@@ -1274,6 +1296,14 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
 
             // Add object item to layer container
             layerContainer->Add( createNewTrack( track, 0.0f ) );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(track->Type() == PCB_TEARDROP_T)
+                dynamic_cast<TrackNodeItem::TEARDROP*>(const_cast<TRACK*>(track))->AddTo3DContainer(layerContainer, m_biuTo3Dunits);
+            if(track->Type() == PCB_ROUNDEDTRACKSCORNER_T)
+                dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(track))->AddTo3DContainer(layerContainer, m_biuTo3Dunits);
+#endif
+                
         }
     }
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5822c44..d08494c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,6 +77,8 @@ option( KICAD_INSTALL_DEMOS
     "Install kicad demos and examples (default ON)"
     ON )
 
+option( PCBNEW_WITH_TRACKITEMS "PCBNEW with Track Items." ON )
+
 # when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
 # PYTHON_EXECUTABLE can be defined when invoking cmake
 # ( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
@@ -329,6 +331,10 @@ if( USE_WX_GRAPHICS_CONTEXT OR APPLE )
     add_definitions( -DUSE_WX_GRAPHICS_CONTEXT )
 endif()
 
+if( PCBNEW_WITH_TRACKITEMS )
+    add_definitions( -DPCBNEW_WITH_TRACKITEMS )
+endif()
+
 
 # KIFACE_SUFFIX is the file extension used for top level program modules which
 # implement the KIFACE interface.  A valid suffix starts with a period '.'.
diff --git a/CMakeModules/FindwxWidgets.cmake b/CMakeModules/FindwxWidgets.cmake
index 6a8dc90..873d1ea 100644
--- a/CMakeModules/FindwxWidgets.cmake
+++ b/CMakeModules/FindwxWidgets.cmake
@@ -734,7 +734,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/bitmaps_png/mk_icn_res.sh b/bitmaps_png/mk_icn_res.sh
old mode 100755
new mode 100644
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 0c5d1be..1ccd413 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -407,6 +407,37 @@ set( PCB_COMMON_SRCS
     ../pcbnew/pcb_painter.cpp
     )
 
+if( PCBNEW_WITH_TRACKITEMS )
+    set( PCB_COMMON_SRCS
+        ${PCB_COMMON_SRCS}
+        ../pcbnew/trackitems/tracknodeitem.cpp
+        ../pcbnew/trackitems/tracknodeitems_common.cpp
+
+        ../pcbnew/trackitems/teardrop.cpp
+        ../pcbnew/trackitems/teardrops_common.cpp
+        ../pcbnew/trackitems/teardrops_common_commit.cpp
+        ../pcbnew/trackitems/teardrops_common_edit.cpp
+        ../pcbnew/trackitems/teardrops_common_todolist.cpp
+        ../pcbnew/trackitems/teardrops_common_menus.cpp
+        ../pcbnew/trackitems/teardrops_common_misc.cpp
+        ../pcbnew/trackitems/teardrops_common_plugin_parse.cpp
+
+        ../pcbnew/trackitems/roundedcornertrack.cpp
+        ../pcbnew/trackitems/roundedtrackscorner.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_commit.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_edit.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_menus.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_misc.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_plugin_parse.cpp
+        ../pcbnew/trackitems/roundedtrackscorners_common_todolist.cpp
+
+        ../pcbnew/trackitems/trackitems_common.cpp
+
+        ../pcbnew/trackitems/viastitching_common.cpp
+    )
+endif()
+    
 # add -DPCBNEW to compilation of these PCBNEW sources
 set_source_files_properties( ${PCB_COMMON_SRCS} PROPERTIES
     COMPILE_DEFINITIONS "PCBNEW"
diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp
index cc3f4aa..054e4b2 100644
--- a/common/geometry/shape_poly_set.cpp
+++ b/common/geometry/shape_poly_set.cpp
@@ -1260,6 +1260,34 @@ bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex ) con
 }
 
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+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;
+}
+#endif
+
+
 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..10d70aa 100644
--- a/common/pcb.keywords
+++ b/common/pcb.keywords
@@ -208,4 +208,22 @@ zone_45_only
 zone_clearance
 zone_connect
 zone_type
-zones
\ No newline at end of file
+zones
+
+#PCBNEW_WITH_TRACKITEMS
+#Teardrops
+teardrop
+position
+shape
+length_ratio
+width_ratio
+segments
+parameters
+junction
+
+#Stitch VIA
+thermal
+
+#Rounded Tracks Corners
+roundedtrackscorner
+length_set
diff --git a/include/class_board_item.h b/include/class_board_item.h
index 3ccee95..46da939 100644
--- a/include/class_board_item.h
+++ b/include/class_board_item.h
@@ -192,7 +192,12 @@ public:
      */
     bool IsTrack() const
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        return ( Type() == PCB_TRACE_T ) || ( Type() == PCB_VIA_T ) || 
+                ( Type() == PCB_TEARDROP_T ) || ( Type() == PCB_ROUNDEDTRACKSCORNER_T );
+#else
         return ( Type() == PCB_TRACE_T ) || ( Type() == PCB_VIA_T );
+#endif
     }
 
     /**
diff --git a/include/class_drawpanel.h b/include/class_drawpanel.h
index 4b12e65..7375d91 100644
--- a/include/class_drawpanel.h
+++ b/include/class_drawpanel.h
@@ -54,6 +54,11 @@ typedef void ( *END_MOUSE_CAPTURE_CALLBACK )( EDA_DRAW_PANEL* aPanel, wxDC* aDC
 
 class EDA_DRAW_PANEL : public wxScrolledWindow
 {
+public:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    void IgnoreNextLeftButtonRelease( void ) { m_ignoreNextLeftButtonRelease = true; }
+#endif
+
 private:
     int     m_currentCursor;                ///< Current mouse cursor shape id.
     int     m_defaultCursor;                ///< The default mouse cursor shape id.
diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h
index 1c4c4e5..ce57c3c 100644
--- a/include/core/typeinfo.h
+++ b/include/core/typeinfo.h
@@ -114,6 +114,10 @@ enum KICAD_T
     PCB_ZONE_AREA_T,        ///< class ZONE_CONTAINER, a zone area
     PCB_ITEM_LIST_T,        ///< class BOARD_ITEM_LIST, a list of board items
     PCB_NETINFO_T,          ///< class NETINFO_ITEM, a description of a net
+#ifdef PCBNEW_WITH_TRACKITEMS
+    PCB_TEARDROP_T,             ///< class TEARDROP
+    PCB_ROUNDEDTRACKSCORNER_T,  ///< class ROUNDEDTRACKSCORNER
+#endif
 
     // Schematic draw Items.  The order of these items effects the sort order.
     // It is currently ordered to mimic the old Eeschema locate behavior where
diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h
index 37f7ca5..a767e91 100644
--- a/include/geometry/shape_poly_set.h
+++ b/include/geometry/shape_poly_set.h
@@ -849,6 +849,11 @@ class SHAPE_POLY_SET : public SHAPE
         ///> Returns true if 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;
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Acts same way as Contains, but return POLYGON if true.
+        const POLYGON* GetPolygon( const VECTOR2I& aP, int aSubpolyIndex = -1 ) const;
+#endif
 
         ///> Returns true if the set is empty (no polygons at all)
         bool IsEmpty() const
diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h
index bcd56f9..a6e8b20 100644
--- a/include/wxPcbStruct.h
+++ b/include/wxPcbStruct.h
@@ -89,6 +89,9 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
     /// The auxiliary right vertical tool bar used to access the microwave tools.
     wxAuiToolBar* m_microWaveToolBar;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    wxMenu* m_TrackItemsMenu{nullptr};
+#endif
 
 protected:
     PCB_LAYER_WIDGET* m_Layers;
@@ -325,6 +328,9 @@ public:
     void OnLayerColorChange( wxCommandEvent& aEvent );
     void OnConfigurePaths( wxCommandEvent& aEvent );
     void OnUpdatePCBFromSch( wxCommandEvent& event );
+#ifdef PCBNEW_WITH_TRACKITEMS
+    void OnUpdateSelectTeardrop( wxUpdateUIEvent& aEvent );
+#endif
 
     /**
      * called when the alt key is pressed during a mouse wheel action
diff --git a/new/make-dir-lib-source-test-data.sh b/new/make-dir-lib-source-test-data.sh
old mode 100755
new mode 100644
diff --git a/new/make-html.sh b/new/make-html.sh
old mode 100755
new mode 100644
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index ab32253..ba2254f 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -328,6 +328,29 @@ set( PCBNEW_CLASS_SRCS
     footprint_preview_panel.cpp
     )
 
+if( PCBNEW_WITH_TRACKITEMS )
+    set( PCBNEW_CLASS_SRCS
+        ${PCBNEW_CLASS_SRCS}
+        trackitems/tracknodeitems_pcbnew.cpp
+
+        trackitems/teardrops_pcbnew.cpp
+        trackitems/teardrops_pcbnew_DRC.cpp
+        trackitems/teardrops_pcbnew_menus.cpp
+        trackitems/teardrops_pcbnew_misc.cpp
+        trackitems/teardrops_pcbnew_commit.cpp
+
+        trackitems/roundedtrackscorners_pcbnew.cpp
+        trackitems/roundedtrackscorners_pcbnew_commit.cpp
+        trackitems/roundedtrackscorners_pcbnew_DRC.cpp
+        trackitems/roundedtrackscorners_pcbnew_menus.cpp
+        trackitems/roundedtrackscorners_pcbnew_misc.cpp
+
+        trackitems/trackitems_pcbnew.cpp
+
+        trackitems/viastitching_pcbnew.cpp
+    )
+endif()
+
 set( PCBNEW_SRCS
     ${PCBNEW_AUTOROUTER_SRCS}
     ${PCBNEW_MICROWAVE_SRCS}
diff --git a/pcbnew/array_creator.cpp b/pcbnew/array_creator.cpp
index 41c9a5b..567fe2f 100644
--- a/pcbnew/array_creator.cpp
+++ b/pcbnew/array_creator.cpp
@@ -31,6 +31,10 @@
 
 #include <dialogs/dialog_create_array.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "drc_stuff.h"
+#include "trackitems/viastitching.h"
+#endif
 
 void ARRAY_CREATOR::Invoke()
 {
@@ -89,6 +93,12 @@ void ARRAY_CREATOR::Invoke()
             if( new_item )
             {
                 array_opts->TransformItem( ptN, new_item, rotPoint );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+                if( getBoard()->ViaStitching()->DestroyConflictingThermalVia( new_item, &m_parent ) )
+                    continue;
+#endif
+
                 prePushAction( new_item );
                 commit.Add( new_item );
                 postPushAction( new_item );
diff --git a/pcbnew/block.cpp b/pcbnew/block.cpp
index 9393a4b..10e5e6f 100644
--- a/pcbnew/block.cpp
+++ b/pcbnew/block.cpp
@@ -50,6 +50,11 @@
 #include <pcbnew.h>
 #include <protos.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#include "trackitems/roundedtrackscorner.h"
+#endif
+
 #define BLOCK_OUTLINE_COLOR YELLOW
 
 /**
@@ -464,6 +469,10 @@ static void drawPickedItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC, wxPoint aOffset
         case PCB_TARGET_T:
         case PCB_DIMENSION_T:    // Currently markers are not affected by block commands
         case PCB_MARKER_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+        case PCB_ROUNDEDTRACKSCORNER_T:
+#endif
             item->Draw( aPanel, aDC, GR_XOR, aOffset );
             break;
 
@@ -558,6 +567,10 @@ void PCB_EDIT_FRAME::Block_Delete()
         case PCB_VIA_T:           // a via (like track segment on a copper layer)
         case PCB_DIMENSION_T:     // a dimension (graphic item)
         case PCB_TARGET_T:        // a target (graphic item)
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+        case PCB_ROUNDEDTRACKSCORNER_T:
+#endif
             item->UnLink();
             break;
 
@@ -595,6 +608,11 @@ void PCB_EDIT_FRAME::Block_Rotate()
     PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
     itemsList->m_Status = UR_CHANGED;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->Teardrops()->UpdateListClear();
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+#endif
+
     for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
     {
         BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
@@ -627,6 +645,16 @@ void PCB_EDIT_FRAME::Block_Rotate()
             ii--;
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+            m_Pcb->TrackItems()->Teardrops()->UpdateListAdd( static_cast<TrackNodeItem::TEARDROP*>(item) );
+            break;
+
+        case PCB_ROUNDEDTRACKSCORNER_T:
+            m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+            break;
+#endif
+
         default:
             wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Rotate( ) error: unexpected type" ) );
             break;
@@ -644,6 +672,11 @@ void PCB_EDIT_FRAME::Block_Rotate()
         item->Rotate( centre, rotAngle );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    m_Pcb->TrackItems()->Teardrops()->UpdateListDo();
+#endif
+    
     Compile_Ratsnest( NULL, true );
     m_canvas->Refresh( true );
 }
@@ -661,6 +694,11 @@ void PCB_EDIT_FRAME::Block_Flip()
 
     center = GetScreen()->m_BlockLocate.Centre();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->Teardrops()->UpdateListClear();
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+#endif
+    
     for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
     {
         BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
@@ -694,6 +732,15 @@ void PCB_EDIT_FRAME::Block_Flip()
             ii--;
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+            m_Pcb->TrackItems()->Teardrops()->UpdateListAdd( static_cast<TrackNodeItem::TEARDROP*>(item) );
+            break;
+
+        case PCB_ROUNDEDTRACKSCORNER_T:
+            m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+            break;
+#endif
 
         default:
             wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Flip( ) error: unexpected type" ) );
@@ -701,6 +748,11 @@ void PCB_EDIT_FRAME::Block_Flip()
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    m_Pcb->TrackItems()->Teardrops()->UpdateListDo();
+#endif
+
     SaveCopyInUndoList( *itemsList, UR_FLIPPED, center );
     Compile_Ratsnest( NULL, true );
     m_canvas->Refresh( true );
@@ -716,6 +768,11 @@ void PCB_EDIT_FRAME::Block_Move()
     PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems();
     itemsList->m_Status = UR_MOVED;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->Teardrops()->UpdateListClear();
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+#endif
+    
     for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
     {
         BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
@@ -749,12 +806,27 @@ void PCB_EDIT_FRAME::Block_Move()
             ii--;
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+            m_Pcb->TrackItems()->Teardrops()->UpdateListAdd( static_cast<TrackNodeItem::TEARDROP*>(item) );
+            break;
+
+        case PCB_ROUNDEDTRACKSCORNER_T:
+            m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+            break;
+#endif
+ 
         default:
             wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Move( ) error: unexpected type" ) );
             break;
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    m_Pcb->TrackItems()->Teardrops()->UpdateListDo();
+#endif
+
     SaveCopyInUndoList( *itemsList, UR_MOVED, MoveVector );
 
     Compile_Ratsnest( NULL, true );
@@ -776,10 +848,23 @@ void PCB_EDIT_FRAME::Block_Duplicate( bool aIncrement )
     ITEM_PICKER picker( NULL, UR_NEW );
     BOARD_ITEM* newitem;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->Teardrops()->UpdateListClear();
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+#endif
+
     for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ )
     {
         BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( item->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+        {
+            m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+            continue;
+        }
+#endif
+
         newitem = (BOARD_ITEM*)item->Clone();
 
         if( item->Type() == PCB_MODULE_T )
@@ -790,11 +875,24 @@ void PCB_EDIT_FRAME::Block_Duplicate( bool aIncrement )
         if( newitem )
         {
             newitem->Move( MoveVector );
+            
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( newitem->Type() == PCB_TEARDROP_T )
+                m_Pcb->TrackItems()->Teardrops()->UpdateListAdd( static_cast<TrackNodeItem::TEARDROP*>(newitem) );
+            if(dynamic_cast<ROUNDEDCORNERTRACK*>(newitem))
+                dynamic_cast<ROUNDEDCORNERTRACK*>(newitem)->ResetVisibleEndpoints();
+#endif
+
             picker.SetItem ( newitem );
             newList.PushItem( picker );
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_Pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo_BlockDuplicate( MoveVector, &newList );
+    m_Pcb->TrackItems()->Teardrops()->UpdateListDo_BlockDuplicate( MoveVector, &newList );
+#endif
+
     if( newList.GetCount() )
         SaveCopyInUndoList( newList, UR_NEW );
 
diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp
index 1c42175..311899a 100644
--- a/pcbnew/board_commit.cpp
+++ b/pcbnew/board_commit.cpp
@@ -32,6 +32,9 @@
 #include <tools/pcb_tool.h>
 
 #include <functional>
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
 using namespace std::placeholders;
 
 BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL* aTool )
@@ -66,6 +69,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
     if( Empty() )
         return;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    frame->GetBoard()->TrackItems()->Teardrops()->GalCommitPushPrepare();
+    frame->GetBoard()->TrackItems()->RoundedTracksCorners()->GalCommitPushPrepare();
+#endif
+
     for( COMMIT_LINE& ent : m_changes )
     {
         int changeType = ent.m_type & CHT_TYPE;
@@ -136,6 +144,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
                 }
 
                 view->Add( boardItem );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+                frame->GetBoard()->TrackItems()->Teardrops()->GalCommitPushAdd( boardItem, &undoList );
+                frame->GetBoard()->TrackItems()->RoundedTracksCorners()->GalCommitPushAdd( boardItem, &undoList );
+#endif
                 break;
             }
 
@@ -143,6 +156,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
             {
                 if( !m_editModules && aCreateUndoEntry )
                 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                    frame->GetBoard()->TrackItems()->Teardrops()->GalCommitPushRemove( boardItem, &undoList );
+                    frame->GetBoard()->TrackItems()->RoundedTracksCorners()->GalCommitPushRemove( boardItem, &undoList );
+#endif
                     undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) );
                 }
 
@@ -211,6 +228,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
                 case PCB_MARKER_T:              // a marker used to show something
                 case PCB_ZONE_T:                // SEG_ZONE items are now deprecated
                 case PCB_ZONE_AREA_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+                case PCB_TEARDROP_T:
+                case PCB_ROUNDEDTRACKSCORNER_T:
+#endif
                     view->Remove( boardItem );
 
                     if( !( changeFlags & CHT_DONE ) )
@@ -272,6 +293,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    frame->GetBoard()->TrackItems()->RoundedTracksCorners()->GalCommitPushFinish( &undoList );
+    frame->GetBoard()->TrackItems()->Teardrops()->GalCommitPushFinish( &undoList );
+#endif
+
     if( !m_editModules && aCreateUndoEntry )
         frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED );
 
diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp
index 29f6c33..0237c24 100644
--- a/pcbnew/class_board.cpp
+++ b/pcbnew/class_board.cpp
@@ -59,6 +59,11 @@
 #include <class_mire.h>
 #include <class_dimension.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#include "trackitems/trackitems.h"
+#endif
+
 
 /* This is an odd place for this, but CvPcb won't link if it is
  *  in class_board_item.cpp like I first tried it.
@@ -107,6 +112,11 @@ BOARD::BOARD() :
 
     // Initialize ratsnest
     m_ratsnest = new RN_DATA( this );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_ViaStitching = new VIASTITCHING( this );
+    m_TrackItems = new TRACKITEMS( this );
+#endif
 }
 
 
@@ -128,6 +138,13 @@ BOARD::~BOARD()
 
     delete m_CurrentZoneContour;
     m_CurrentZoneContour = NULL;
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    delete m_ViaStitching;
+    m_ViaStitching = nullptr;
+    delete m_TrackItems;
+    m_TrackItems = nullptr;
+#endif
 }
 
 
@@ -886,6 +903,10 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
 
     case PCB_TRACE_T:
     case PCB_VIA_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+    case PCB_ROUNDEDTRACKSCORNER_T:
+#endif
         if( aMode == ADD_APPEND )
         {
             m_Track.PushBack( (TRACK*) aBoardItem );
@@ -992,6 +1013,10 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem )
 
     case PCB_TRACE_T:
     case PCB_VIA_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+    case PCB_ROUNDEDTRACKSCORNER_T:
+#endif
         m_Track.Remove( (TRACK*) aBoardItem );
         break;
 
@@ -1778,6 +1803,11 @@ TRACK* BOARD::GetVisibleTrack( TRACK* aStartingTrace, const wxPoint& aPosition,
     {
         PCB_LAYER_ID layer = track->GetLayer();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( track->Type() == PCB_TEARDROP_T )
+            continue;
+#endif
+
         if( track->GetState( BUSY | IS_DELETED ) )
             continue;
 
@@ -2251,6 +2281,16 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
         return aSegment;
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( aSegment->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+        return nullptr;
+    
+    GetBoard()->TrackItems()->Teardrops()->ToMemory( aSegment );
+    GetBoard()->TrackItems()->Teardrops()->Remove( aSegment, aList, true );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->ToMemory( aSegment );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( aSegment, aList, true );
+#endif
+
     // Calculation coordinate of intermediate point relative to the start point of aSegment
      wxPoint delta = aSegment->GetEnd() - aSegment->GetStart();
 
@@ -2269,7 +2309,15 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
      */
     lockPoint += aSegment->GetStart();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    TRACK* newTrack = nullptr;
+    if(dynamic_cast<ROUNDEDCORNERTRACK*>(aSegment))
+        newTrack = static_cast<ROUNDEDCORNERTRACK*>(aSegment->Clone());
+    else
+        newTrack = (TRACK*)aSegment->Clone();
+#else
     TRACK* newTrack = (TRACK*)aSegment->Clone();
+#endif
     // The new segment begins at the new point,
     newTrack->SetStart(lockPoint);
     newTrack->start = aSegment;
@@ -2308,6 +2356,16 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
     }
 
     aPosition = lockPoint;
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->FromMemory( newTrack, aList );
+    GetBoard()->TrackItems()->Teardrops()->FromMemory( aSegment, aList );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->FromMemory( newTrack, aList );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->FromMemory( aSegment, aList );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Update( newTrack );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Update( aSegment );
+#endif
+
     return newTrack;
 }
 
diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h
index ea54cd1..ac7af38 100644
--- a/pcbnew/class_board.h
+++ b/pcbnew/class_board.h
@@ -59,6 +59,12 @@ class NETLIST;
 class REPORTER;
 class RN_DATA;
 class SHAPE_POLY_SET;
+#ifdef PCBNEW_WITH_TRACKITEMS
+class TEARDROPS;
+class VIASTITCHING;
+class ROUNDEDTRACKSCORNERS;
+class TRACKITEMS;
+#endif
 
 
 /**
@@ -226,7 +232,19 @@ private:
         return *this;       // just to mute warning
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    VIASTITCHING* m_ViaStitching{nullptr};
+    TRACKITEMS* m_TrackItems{nullptr};
+#endif
+    
+
 public:
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    VIASTITCHING* ViaStitching(void) const { return m_ViaStitching; }
+    TRACKITEMS* TrackItems(void) const { return m_TrackItems; }
+#endif
+
     static inline bool ClassOf( const EDA_ITEM* aItem )
     {
         return aItem && PCB_T == aItem->Type();
diff --git a/pcbnew/class_drc_item.cpp b/pcbnew/class_drc_item.cpp
index 754cc02..37716d1 100644
--- a/pcbnew/class_drc_item.cpp
+++ b/pcbnew/class_drc_item.cpp
@@ -34,6 +34,10 @@
 #include <class_drc_item.h>
 #include <base_units.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/teardrops.h"
+#endif
+
 
 wxString DRC_ITEM::GetErrorText() const
 {
@@ -135,6 +139,74 @@ wxString DRC_ITEM::GetErrorText() const
     case DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT:
         return wxString( _( "Footprint has incorrect courtyard (not a closed shape)" ) );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Track node items
+    case DRCE_TRACKNODEITEM_UNSPECIFIED:
+        return wxString(_("Unspecified last action"));
+        
+    //Teardrops
+    case DRCE_THERMAL_VIA_UNCONNECTED:
+        return wxString( _( "Thermal Via unconnected" ) );
+    case DRCE_THERMAL_VIA_CONNECTED_POURS:
+        return wxString( _( "Thermal Via Connected Pours < 2" ) );
+    case DRCE_TEARDROP_NEAR_TEARDROP:
+        return wxString(_("Teardrop near Teardrop"));
+    case DRCE_TEARDROP_NEAR_TRACK:
+        return wxString(_("Teardrop near Track"));
+    case DRCE_TEARDROP_NEAR_VIA:
+        return wxString(_("Teardrop near Via"));
+    case DRCE_TEARDROP_NEAR_PAD:
+        return wxString(_("Teardrop near Pad"));
+    case DRCE_TEARDROP_TOO_SMALL:
+        return wxString(_("Teardrop too small"));
+    case DRCE_JUNCTION_NEAR_TRACK:
+        return wxString(_("Junction / T-Junction near Track"));
+    case DRCE_JUNCTION_NEAR_VIA:
+        return wxString(_("Junction / T-Junction near Via"));
+    case DRCE_JUNCTION_NEAR_PAD:
+        return wxString(_("Junction / T-Junction near Pad"));
+    case DRCE_JUNCTION_NEAR_TEARDROP:
+        return wxString(_("Junction / T-Junction near Teardrop"));
+    case DRCE_JUNCTION_NEAR_JUNCTION:
+        return wxString(_("Junction / T-Junction near Junction / T-Junction"));
+    case DRCE_JUNCTION_TOO_SMALL:
+        return wxString(_("Junction / T-Junction too small"));
+    case DRCE_TJUNCTION_TRACK_SEGS_LENGTH:
+        return wxString(_("T-Junction Length of Track Segments"));
+    case DRCE_TEARDROP_INSIDE_TEXT:
+        return wxString(_("Teardrop inside a text"));
+    case DRCE_JUNCTION_INSIDE_TEXT:
+        return wxString(_("Junction / T-Junction inside a text"));
+    case DRCE_TEARDROP_TRIMMED:
+        return wxString(_("Teardrop trimmed"));
+    case DRCE_TEARDROP_BIG:
+        return wxString(_("Teardrop too big"));
+    case DRCE_TEARDROP_MISSING:
+        return wxString(_("Teardrop Missing"));
+    case DRCE_TJUNCTION_MISSING:
+        return wxString(_("T-Junction Missing"));
+    case DRCE_JUNCTION_MISSING:
+        return wxString(_("Junction Missing"));
+    case DRCE_TEARDROP_NOT_IN_PAD:
+        return wxString(_("Teardrop not in Pad"));
+    case DRCE_TEARDROP_NOT_IN_VIA:
+        return wxString(_("Teardrop not in Via"));
+    case DRCE_TEARDOPS_MULTIPLE:
+        return wxString(_("Teardrops multiple"));
+    case DRCE_TEARDROP_TRACK_ERROR:
+        return wxString(_("Teardrop Track error"));
+    case DRCE_TEARDROP_USELESS:
+        return wxString(_("Teardrop may be useless"));
+    case DRCE_TEARDROP_IMPOSSIBLE:
+        return wxString(_("Teardrop impossible"));
+    case DRCE_JUNCTION_TRACK_SEGS_WIDTH:
+        return wxString(_("Junction / T-Junction Width of Track Segments"));
+    case DRCE_TJUNCTION_ANGLE:
+        return wxString(_("T-Junction angle"));
+    case DRCE_TEARDROPS_INSIDE:
+        return wxString(_("Teardrops inside"));
+#endif
+        
     default:
         return wxString::Format( wxT( "Unknown DRC error code %d" ), m_ErrorCode );
     }
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
index b79ae81..7aa1750 100644
--- a/pcbnew/class_module.cpp
+++ b/pcbnew/class_module.cpp
@@ -78,12 +78,19 @@ MODULE::MODULE( BOARD* parent ) :
     m_Value = new TEXTE_MODULE( this, TEXTE_MODULE::TEXT_is_VALUE );
 
     m_3D_Drawings.clear();
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_pad_id_counter = 0; //Teardrops for.
+#endif
 }
 
 
 MODULE::MODULE( const MODULE& aModule ) :
     BOARD_ITEM_CONTAINER( aModule )
 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_pad_id_counter = aModule.GetPadIDCounter();
+#endif
     m_Pos = aModule.m_Pos;
     m_fpid = aModule.m_fpid;
     m_Attributs = aModule.m_Attributs;
@@ -187,12 +194,55 @@ MODULE& MODULE::operator=( const MODULE& aOther )
     m_Value->SetParent( this );
 
     // Copy auxiliary data: Pads
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Pad copy for teardrops. This do not change pad addresses. Need for teardrops.
+    //Delete this module pads that do not belong to aOther, if any.
+    std::vector<D_PAD*> del_pads;
+    del_pads.clear();
+    for( D_PAD* pad_t = m_Pads;  pad_t;  pad_t = pad_t->Next() )
+    {
+        bool hit = false;
+        for( D_PAD* pad_s = aOther.m_Pads;  pad_s;  pad_s = pad_s->Next() )
+        {
+            if( pad_t->GetIDNumber() == pad_s->GetIDNumber() )
+            {
+                hit = true;
+                break;
+            }
+        }
+        if( !hit )
+            del_pads.push_back( pad_t );
+    }
+    for( uint n = 0; n < del_pads.size(); ++n )
+        m_Pads.Remove(del_pads.at(n));
+    
+    //Copy aOther pads data to this module pads and create pads that are not in this module, if any..
+    for( D_PAD* pad_s = aOther.m_Pads;  pad_s;  pad_s = pad_s->Next() )
+    {
+        bool hit = false;
+        for( D_PAD* pad_t = m_Pads;  pad_t;  pad_t = pad_t->Next() )
+        {
+            if( pad_t->GetIDNumber() == pad_s->GetIDNumber() )
+            {
+                hit = true;
+                *pad_t = *pad_s;
+                break;
+            }
+        }
+        if( !hit )
+        {
+            Add( new D_PAD( *pad_s ) );
+        }
+    }
+    //Pads copy teardrops for END.
+#else
     m_Pads.DeleteAll();
 
     for( D_PAD* pad = aOther.m_Pads;  pad;  pad = pad->Next() )
     {
         Add( new D_PAD( *pad ) );
     }
+#endif
 
     // Copy auxiliary data: Drawings
     m_Drawings.DeleteAll();
diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h
index f332a46..cce938a 100644
--- a/pcbnew/class_module.h
+++ b/pcbnew/class_module.h
@@ -661,7 +661,17 @@ public:
     virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
 #endif
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    int GetPadIDCounter(void) const { return m_pad_id_counter; }
+    int GetAndAddPadIDCounter(void) { return ++m_pad_id_counter; } 
+#endif
+    
 private:
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    int m_pad_id_counter{0}; //Counter to set pad id number.
+#endif
+    
     DLIST<D_PAD>      m_Pads;           ///< Linked list of pads.
     DLIST<BOARD_ITEM> m_Drawings;       ///< Linked list of graphical items.
     std::list<S3D_INFO> m_3D_Drawings;  ///< Linked list of 3D models.
diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp
index 8566083..bdbedd3 100644
--- a/pcbnew/class_netinfo_item.cpp
+++ b/pcbnew/class_netinfo_item.cpp
@@ -44,6 +44,10 @@
 #include <class_module.h>
 #include <class_track.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/roundedcornertrack.h"
+#include "trackitems/roundedtrackscorner.h"
+#endif
 
 /*********************************************************/
 /* class NETINFO_ITEM: handle data relative to a given net */
@@ -126,8 +130,24 @@ void NETINFO_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
         if( track->Type() == PCB_TRACE_T )
         {
             if( track->GetNetCode() == GetNet() )
+#ifdef PCBNEW_WITH_TRACKITEMS
+            {
+                if(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(track)))
+                    lengthnet += dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(track))->GetLengthVisible();
+                else
+                    lengthnet += track->GetLength();
+            }
+#else
                 lengthnet += track->GetLength();
+#endif
         }
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( track->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+            if( track->GetNetCode() == GetNet() )
+                lengthnet += dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(track))->GetLengthVisible();
+#endif
+
     }
 
     txt.Printf( wxT( "%d" ), count );
diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp
index 8004009..3662e3d 100644
--- a/pcbnew/class_pad.cpp
+++ b/pcbnew/class_pad.cpp
@@ -60,6 +60,13 @@ int D_PAD::m_PadSketchModePenSize = 0;      // Pen size used to draw pads in ske
 D_PAD::D_PAD( MODULE* parent ) :
     BOARD_CONNECTED_ITEM( parent, PCB_PAD_T )
 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if(parent && (parent->Type() == PCB_MODULE_T))
+        m_id_number = parent->GetAndAddPadIDCounter(); //ID counter is in MODULE.
+    else
+        m_id_number = -1;   //No parent.
+#endif
+    
     m_NumPadName          = 0;
     m_Size.x = m_Size.y   = Mils2iu( 60 );  // Default pad size 60 mils.
     m_Drill.x = m_Drill.y = Mils2iu( 30 );  // Default drill size 30 mils.
@@ -94,6 +101,18 @@ D_PAD::D_PAD( MODULE* parent ) :
 }
 
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+//To set PAD id number when parse.
+void D_PAD::SetParent( EDA_ITEM* aParent )
+{
+    if( m_id_number == -1 )
+        if( aParent && ( aParent->Type() == PCB_MODULE_T ) )
+            m_id_number = dynamic_cast<MODULE*>(aParent)->GetAndAddPadIDCounter();    
+    BOARD_CONNECTED_ITEM::SetParent( aParent );
+}
+#endif
+
+
 LSET D_PAD::StandardMask()
 {
     static LSET saved = LSET::AllCuMask() | LSET( 2, B_Mask, F_Mask );
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
index 53900dd..6f15c26 100644
--- a/pcbnew/class_pad.h
+++ b/pcbnew/class_pad.h
@@ -105,6 +105,9 @@ public:
 
     D_PAD* Next() const       { return static_cast<D_PAD*>( Pnext ); }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    void SetParent( EDA_ITEM* aParent ); //Hide EDA_ITEM SetParent.
+#endif
     MODULE* GetParent() const { return (MODULE*) m_Parent; }
 
     /**
@@ -580,8 +583,18 @@ public:
     virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
 #endif
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+     int GetIDNumber(void) const { return m_id_number; }
+#endif
+
 
 private:
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //ID number. To MODULE copy for, that we do not change PAD(s) address.
+    int m_id_number; 
+#endif
+    
     /**
      * Function boundingRadius
      * returns a calculated radius of a bounding circle for this pad.
diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp
index 36d6f48..782d3fe 100644
--- a/pcbnew/class_track.cpp
+++ b/pcbnew/class_track.cpp
@@ -161,6 +161,12 @@ VIA::VIA( BOARD_ITEM* aParent ) :
     SetViaType( VIA_THROUGH );
     m_BottomLayer = B_Cu;
     SetDrillDefault();
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_thermal = 0; 
+    m_thermal_zones.clear();
+    m_thermal_polys_zones.clear();
+#endif
 }
 
 
@@ -190,7 +196,6 @@ wxString VIA::GetSelectMenuText() const
         break;
     }
 
-
     if( board )
     {
         wxString netname = GetNetname();
@@ -248,7 +253,11 @@ int VIA::GetDrillValue() const
 
 bool TRACK::IsNull()
 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( ( Type() == PCB_TRACE_T ) && ( m_Start == m_End ) ) //Only PCB_TRACE_T class.
+#else
     if( ( Type() != PCB_VIA_T ) && ( m_Start == m_End ) )
+#endif
         return true;
     else
         return false;
@@ -834,6 +843,11 @@ void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const w
         fillvia = false;
     }
 
+    if( ShowClearance( displ_opts, this ) )
+    {
+        GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color );
+    }
+
     if( fillvia )
     {
         GRFilledCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, color );
@@ -880,11 +894,6 @@ void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const w
             GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, drill_radius, 0, color );
     }
 
-    if( ShowClearance( displ_opts, this ) )
-    {
-        GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color );
-    }
-
     // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer
     // (so we can see 2 superimposed microvias ):
     if( GetViaType() == VIA_MICROVIA )
@@ -962,6 +971,11 @@ void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const w
     if( net == NULL )
         return;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( !m_thermal )
+        return;
+#endif
+
     int len = net->GetShortNetname().Len();
 
     if( len > 0 )
@@ -1462,7 +1476,11 @@ int TRACK::GetEndSegments( int aCount, TRACK** aStartTrace, TRACK** aEndTrace )
 
     for( ; ( Track != NULL ) && ( ii < aCount ); ii++, Track = Track->Next() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( Track->Type() != PCB_TRACE_T ) //All derived classes of TRACK, not only VIA.
+#else            
         if( Track->Type() == PCB_VIA_T )
+#endif
             continue;
 
         layerMask = Track->GetLayerSet();
diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h
index a9e3e88..bc8dcd9 100644
--- a/pcbnew/class_track.h
+++ b/pcbnew/class_track.h
@@ -37,6 +37,10 @@
 #include <PolyLine.h>
 #include <trigo.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include <class_zone.h>
+#include <unordered_map>
+#endif
 
 class TRACK;
 class VIA;
@@ -189,10 +193,18 @@ public:
      * clearance when the circle is approximated by segment bigger or equal
      * to the real clearance value (usually near from 1.0)
      */
+#ifdef PCBNEW_WITH_TRACKITEMS
+    virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
+                                               int             aClearanceValue,
+                                               int             aCircleToSegmentsCount,
+                                               double          aCorrectionFactor ) const;
+
+#else
     void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
                                                int             aClearanceValue,
                                                int             aCircleToSegmentsCount,
                                                double          aCorrectionFactor ) const;
+#endif
     /**
      * Function IsPointOnEnds
      * returns STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if
@@ -446,6 +458,24 @@ public:
     VIATYPE_T GetViaType() const          { return m_ViaType; }
     void SetViaType( VIATYPE_T aViaType ) { m_ViaType = aViaType; }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Stitch vias
+    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 ); 
+    }
+#endif
+
     /**
      * Function SetDrill
      * sets the drill value for vias.
@@ -490,6 +520,12 @@ private:
     VIATYPE_T m_ViaType;        // Type of via
 
     int       m_Drill;          // for vias: via drill (- 1 for default value)
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    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;
+#endif
 };
 
 
diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp
index 34c49a9..e151199 100644
--- a/pcbnew/clean.cpp
+++ b/pcbnew/clean.cpp
@@ -41,6 +41,11 @@
 
 #include <tuple>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#include "trackitems/trackitems.h"
+#endif
+
 // Helper class used to clean tracks and vias
 class TRACKS_CLEANER: CONNECTIONS
 {
@@ -134,14 +139,25 @@ void PCB_EDIT_FRAME::Clean_Pcb()
         return;
 
     // Old model has to be refreshed, GAL normally does not keep updating it
+#ifndef PCBNEW_WITH_TRACKITEMS
     Compile_Ratsnest( NULL, false );
+#endif
 
     wxBusyCursor( dummy );
     BOARD_COMMIT commit( this );
     TRACKS_CLEANER cleaner( GetBoard(), commit );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    bool modified = false;
+    modified |= GetBoard()->ViaStitching()->CleanThermalVias( this, &commit );
+    Fill_All_Zones( this, false );
+
+    modified |= cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
+                            dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
+#else
     bool modified = cleaner.CleanupBoard( dlg.m_deleteShortCircuits, dlg.m_cleanVias,
                             dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm );
+#endif
 
     if( modified )
     {
@@ -170,6 +186,10 @@ bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
 
     bool modified = false;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    modified |= ( m_brd->TrackItems()->RoundedTracksCorners()->Clean( &m_brd->m_Track, m_commit ) );
+#endif
+
     // delete redundant vias
     if( aCleanVias )
         modified |= clean_vias();
@@ -210,6 +230,11 @@ bool TRACKS_CLEANER::CleanupBoard( bool aRemoveMisConnected,
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Clean broken teardrops.
+    modified |= ( m_brd->TrackItems()->Teardrops()->Clean( &m_brd->m_Track ) );
+#endif
+
     return modified;
 }
 
@@ -288,6 +313,20 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
     {
         segment->SetState( FLAG0, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( segment->Type() == PCB_TEARDROP_T )
+            continue;
+        if( segment->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+            continue;
+        
+        //Do not remove thermal via.
+        if( dynamic_cast<const VIA*>( segment ) )
+        {
+            if( dynamic_cast<const VIA*>( segment )->GetThermalCode() && segment->GetNetCode() )
+                continue;
+        }
+#endif
+                
         for( unsigned ii = 0; ii < segment->m_PadsConnected.size(); ++ii )
         {
             if( segment->GetNetCode() != segment->m_PadsConnected[ii]->GetNetCode() )
@@ -312,6 +351,10 @@ bool TRACKS_CLEANER::removeBadTrackSegments()
 
         if( segment->GetState( FLAG0 ) )    // Segment is flagged to be removed
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            m_brd->TrackItems()->Teardrops()->Remove( segment, m_commit, true );
+            m_brd->TrackItems()->RoundedTracksCorners()->Remove( segment, m_commit, true );
+#endif
             isModified = true;
             m_brd->Remove( segment );
             m_commit.Removed( segment );
@@ -345,6 +388,9 @@ bool TRACKS_CLEANER::remove_duplicates_of_via( const VIA *aVia )
         if( ( alt_via->GetViaType() == VIA_THROUGH ) &&
                 ( alt_via->GetStart() == aVia->GetStart() ) )
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            m_brd->TrackItems()->Teardrops()->Remove( alt_via, m_commit, true );
+#endif
             m_brd->Remove( alt_via );
             m_commit.Removed( alt_via );
             modified = true;
@@ -374,6 +420,13 @@ bool TRACKS_CLEANER::clean_vias()
         {
             modified |= remove_duplicates_of_via( via );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //Do not remove thermal via with netcode.
+            if( via->GetThermalCode() )
+                if( via->GetNetCode() || const_cast<VIA*>(via)->GetThermalZones()->size() )
+                    continue;
+#endif
+                
             /* 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 */
@@ -385,6 +438,9 @@ bool TRACKS_CLEANER::clean_vias()
                 if( ( pad->GetLayerSet() & all_cu ) == all_cu )
                 {
                     // redundant: delete the via
+#ifdef PCBNEW_WITH_TRACKITEMS
+                    m_brd->TrackItems()->Teardrops()->Remove( via, m_commit, true );
+#endif
                     m_brd->Remove( via );
                     m_commit.Removed( via );
                     modified = true;
@@ -482,6 +538,21 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
         {
             next_track = track->Next();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( track->Type() == PCB_TEARDROP_T )
+                continue;
+            if( track->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+                continue;
+
+            //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;
+            }
+#endif
+            
             bool flag_erase = false; // Start without a good reason to erase it
 
             /* if a track endpoint is not connected to a pad, test if
@@ -501,6 +572,10 @@ bool TRACKS_CLEANER::deleteDanglingTracks()
 
             if( flag_erase )
             {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                m_brd->TrackItems()->Teardrops()->Remove( track, m_commit, true );
+                m_brd->TrackItems()->RoundedTracksCorners()->Remove( track, m_commit, true );
+#endif
                 m_brd->Remove( track );
                 m_commit.Removed( track );
 
@@ -529,6 +604,10 @@ bool TRACKS_CLEANER::delete_null_segments()
 
         if( segment->IsNull() )     // Length segment = 0; delete it
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            m_brd->TrackItems()->Teardrops()->Remove( segment, m_commit, true );
+            m_brd->TrackItems()->RoundedTracksCorners()->Remove( segment, m_commit, true );
+#endif
             m_brd->Remove( segment );
             m_commit.Removed( segment );
             modified = true;
@@ -552,6 +631,18 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
         if( aTrack->GetNetCode() != other->GetNetCode() )
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Do not delete teardrop(s).
+        if(aTrack->Type() == PCB_TEARDROP_T)
+            break;
+        if(other->Type() == PCB_TEARDROP_T)
+            continue;
+        if(aTrack->Type() == PCB_ROUNDEDTRACKSCORNER_T)
+            break;
+        if(other->Type() == PCB_ROUNDEDTRACKSCORNER_T)
+            continue;
+#endif
+
         // Must be of the same type, on the same layer and the endpoints
         // must be the same (maybe swapped)
         if( ( aTrack->Type() == other->Type() ) &&
@@ -562,9 +653,22 @@ bool TRACKS_CLEANER::remove_duplicates_of_track( const TRACK *aTrack )
                 ( ( aTrack->GetStart() == other->GetEnd() ) &&
                  ( aTrack->GetEnd() == other->GetStart() ) ) )
             {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                m_brd->TrackItems()->Teardrops()->ToMemory( other );
+                m_brd->TrackItems()->Teardrops()->Remove( other, m_commit, true );
+                m_brd->TrackItems()->RoundedTracksCorners()->ToMemory( other );
+                m_brd->TrackItems()->RoundedTracksCorners()->Remove( other, m_commit, true );
+#endif
                 m_brd->Remove( other );
                 m_commit.Removed( other );
                 modified = true;
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+                m_brd->TrackItems()->Teardrops()->FromMemory( aTrack, m_commit );
+                m_brd->TrackItems()->Teardrops()->Update( aTrack->GetNetCode(), aTrack );
+                m_brd->TrackItems()->RoundedTracksCorners()->FromMemory( aTrack, m_commit );
+                m_brd->TrackItems()->RoundedTracksCorners()->Update( aTrack );
+#endif
             }
         }
     }
@@ -602,6 +706,9 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
 
                     if( !yet_another )
                     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                        EDA_ITEM* seg_clone = aSegment->Clone();
+#endif
                         // Try to merge them
                         TRACK* segDelete = mergeCollinearSegmentIfPossible( aSegment,
                                 other, endpoint );
@@ -609,9 +716,25 @@ bool TRACKS_CLEANER::merge_collinear_of_track( TRACK* aSegment )
                         // Merge succesful, the other one has to go away
                         if( segDelete )
                         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                            m_brd->TrackItems()->Teardrops()->ToMemory( segDelete );
+                            m_brd->TrackItems()->Teardrops()->Remove( segDelete, m_commit, true );
+                            m_brd->TrackItems()->RoundedTracksCorners()->ToMemory( segDelete );
+                            m_brd->TrackItems()->RoundedTracksCorners()->Remove( segDelete, m_commit, true );
+#endif
                             m_brd->Remove( segDelete );
+                            //TODO
+                            //If there are more than one tracks/nodes to be removed, m_comit.Removed() craches. hp
                             m_commit.Removed( segDelete );
                             merged_this = true;
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+                            m_commit.Modified( aSegment, seg_clone );
+                            m_brd->TrackItems()->Teardrops()->FromMemory( aSegment, m_commit );
+                            m_brd->TrackItems()->Teardrops()->Update( aSegment->GetNetCode(), aSegment );
+                            m_brd->TrackItems()->RoundedTracksCorners()->FromMemory( aSegment, m_commit );
+                            m_brd->TrackItems()->RoundedTracksCorners()->Update( aSegment );
+#endif
                         }
                     }
                 }
diff --git a/pcbnew/connect.cpp b/pcbnew/connect.cpp
index 1b42fbd..b2bd197 100644
--- a/pcbnew/connect.cpp
+++ b/pcbnew/connect.cpp
@@ -39,6 +39,12 @@
 // Helper classes to handle connection points
 #include <connect.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#include "trackitems/roundedcornertrack.h"
+#include "trackitems/roundedtrackscorner.h"
+#endif
+
 extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb );
 extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
 
@@ -131,6 +137,15 @@ void CONNECTIONS::SearchTracksConnectedToPads( bool add_to_padlist, bool add_to_
             if( !( pad->GetLayerSet() & cp_item->GetTrack()->GetLayerSet() ).any() )
                 continue;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //Do not connect teardrop.
+            if( cp_item->GetTrack()->Type() == PCB_TEARDROP_T )
+                continue;
+            //Do not connect rounded corner.
+            if( cp_item->GetTrack()->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+                continue;
+#endif
+
             if( pad->HitTest( cp_item->GetPoint() ) )
             {
                 if( add_to_padlist )
@@ -274,6 +289,28 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK* aBegin, TRACK* aEnd)
     m_candidates.reserve( ii );
     for( TRACK* track = aBegin; track; track = track->Next() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        wxPoint start_point = track->GetStart();
+        if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track))
+            start_point = dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track)->GetStartVisible();
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+            start_point = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible();
+
+        CONNECTED_POINT candidate( track, start_point );
+
+        m_candidates.push_back( candidate );
+        if( track->Type() == PCB_TRACE_T )
+        {
+            wxPoint end_point = track->GetEnd();
+            if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track))
+                end_point = dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track)->GetEndVisible();
+            if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+                end_point = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetEndVisible();
+            
+            CONNECTED_POINT candidate2( track, end_point );
+            m_candidates.push_back( candidate2 );
+        }
+#else
         CONNECTED_POINT candidate( track, track->GetStart() );
 
         m_candidates.push_back( candidate );
@@ -282,6 +319,7 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK* aBegin, TRACK* aEnd)
             CONNECTED_POINT candidate2( track, track->GetEnd());
             m_candidates.push_back( candidate2 );
         }
+#endif
 
         if( track == aEnd )
             break;
@@ -319,6 +357,13 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK* aTrack )
 #endif
 
     wxPoint position = aTrack->GetStart();
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(aTrack)))
+        position = dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(aTrack))->GetStartVisible();
+    if(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack)))
+        position = dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetStartVisible();
+#endif
 
     for( int kk = 0; kk < 2; kk++ )
     {
@@ -369,6 +414,11 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK* aTrack )
             if( ctrack == aTrack )
                 continue;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //Do not connect teardrop.
+            if( ctrack->Type() == PCB_TEARDROP_T )
+                continue;
+#endif
             // We have a good candidate: calculate the actual distance
             // between ends, which should be <= dist max.
             wxPoint delta = tracks_candidates[ii]->GetPoint() - position;
@@ -387,6 +437,13 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK* aTrack )
             break;
 
         position = aTrack->GetEnd();
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(aTrack)))
+            position = dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<TRACK*>(aTrack))->GetEndVisible();
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack)))
+            position = dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetEndVisible();
+#endif
     }
 
     return count;
@@ -863,9 +920,22 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
     // Build the net info list
     GetBoard()->BuildListOfNets();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    // Via Stitching. Temp container.
+    std::unordered_map<const VIA*, int> collected_vias;
+    collected_vias.clear();
+#endif
+
     // Reset variables and flags used in computation
     for( TRACK* t = m_Pcb->m_Track;  t;  t = t->Next() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        // 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() ) );
+#endif
+
         t->m_TracksConnected.clear();
         t->m_PadsConnected.clear();
         t->start = NULL;
@@ -890,6 +960,11 @@ 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() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( ViaStitching::IsThermalVia( t ) )
+            continue;
+#endif
+
         if( t->m_PadsConnected.size() )
             t->SetNetCode( t->m_PadsConnected[0]->GetNetCode() );
     }
@@ -897,6 +972,11 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
     // Pass 2: build connections between track ends
     for( TRACK* t = m_Pcb->m_Track;  t;  t = t->Next() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( ViaStitching::IsThermalVia( t ) )
+            continue;
+#endif
+
         connections.SearchConnectedTracks( t );
         connections.GetConnectedTracks( t );
     }
@@ -911,6 +991,11 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
 
         for( TRACK* t = m_Pcb->m_Track;  t;  t = t->Next() )
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( ViaStitching::IsThermalVia( t ) )
+                continue;
+#endif
+
             int netcode = t->GetNetCode();
 
             if( netcode == 0 )
@@ -919,6 +1004,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;
@@ -945,6 +1031,11 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Via Stitching. Set netcode to thermal vias.
+    m_Pcb->ViaStitching()->SetNetcodes( collected_vias );
+#endif
+
     if( IsGalCanvasActive() )
     {
     /// @todo LEGACY tracks might have changed their nets, so we need to refresh labels in GAL
@@ -957,7 +1048,6 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
 }
 
 
-
 /*
  * Function SortTracksByNetCode used in RebuildTrackChain()
  * to sort track segments by net code.
diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp
index 760b1d7..430a6f0 100644
--- a/pcbnew/controle.cpp
+++ b/pcbnew/controle.cpp
@@ -317,6 +317,25 @@ bool PCB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KE
     igridsize.x = KiROUND( gridSize.x );
     igridsize.y = KiROUND( gridSize.y );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Force or release magnetism with SHIFT-Alt.
+    int magnetic_pad_option = g_MagneticPadOption;
+    int magnetic_track_option = g_MagneticTrackOption;
+    if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_ALT ) )
+    {
+        if( ((g_MagneticPadOption == CAPTURE_CURSOR_IN_TRACK_TOOL) && (GetToolId() == ID_TRACK_BUTT)) 
+            || (g_MagneticPadOption == CAPTURE_ALWAYS) )
+            g_MagneticPadOption = NO_EFFECT;
+        else
+            g_MagneticPadOption = CAPTURE_ALWAYS;
+        if( ((g_MagneticTrackOption == CAPTURE_CURSOR_IN_TRACK_TOOL) && (GetToolId() == ID_TRACK_BUTT)) 
+            || (g_MagneticTrackOption == CAPTURE_ALWAYS) )
+            g_MagneticTrackOption = NO_EFFECT;
+        else
+            g_MagneticTrackOption = CAPTURE_ALWAYS;
+    }
+#endif
+
     if( Magnetize( this, GetToolId(), igridsize, curs_pos, &pos ) )
     {
         SetCrossHairPosition( pos, false );
@@ -334,6 +353,12 @@ bool PCB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KE
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Magenetic options back to current state.
+    g_MagneticPadOption = magnetic_pad_option;
+    g_MagneticTrackOption = magnetic_track_option;
+#endif
+
     RefreshCrossHair( oldpos, aPosition, aDC );
 
     if( aHotKey )
diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp
index 47f6d83..31e4ec0 100644
--- a/pcbnew/deltrack.cpp
+++ b/pcbnew/deltrack.cpp
@@ -41,6 +41,10 @@
 #include <pcbnew.h>
 #include <protos.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
 {
@@ -120,6 +124,13 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
 
     int netcode = aTrack->GetNetCode();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    PICKED_ITEMS_LIST pickedItems;
+    ITEM_PICKER       picker( NULL, UR_DELETED );
+    GetBoard()->TrackItems()->Teardrops()->Remove( aTrack, &pickedItems, true );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( aTrack, &pickedItems, true );
+#endif
+    
     // Remove the segment from list, but do not delete it (it will be stored i n undo list)
     GetBoard()->Remove( aTrack );
 
@@ -128,7 +139,13 @@ TRACK* PCB_EDIT_FRAME::Delete_Segment( wxDC* DC, TRACK* aTrack )
     // redraw the area where the track was
     m_canvas->RefreshDrawingRect( aTrack->GetBoundingBox() );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    picker.SetItem( aTrack );
+    pickedItems.PushItem( picker );
+    SaveCopyInUndoList( pickedItems, UR_DELETED );
+#else
     SaveCopyInUndoList( aTrack, UR_DELETED );
+#endif
     OnModify();
     TestNetConnection( DC, netcode );
     SetMsgPanel( GetBoard() );
@@ -161,6 +178,12 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
     ITEM_PICKER       picker( NULL, UR_DELETED );
     int    netcode = aTrack->GetNetCode();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Delete teardrops at this net code.
+    GetBoard()->TrackItems()->Teardrops()->Remove( netcode, TEARDROPS::ALL_TYPES_T, &itemsList, true);
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( netcode, &itemsList, true );
+#endif
+
     /* Search the first item for the given net code */
     TRACK* trackList = GetBoard()->m_Track->GetStartNetCode( netcode );
 
@@ -173,6 +196,12 @@ void PCB_EDIT_FRAME::Delete_net( wxDC* DC, TRACK* aTrack )
         if( segm->GetNetCode() != netcode )
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Not stitch vias
+        if(segm && dynamic_cast<VIA*>(segm))
+            if( dynamic_cast<VIA*>(segm)->GetThermalCode() )
+                continue;
+#endif
         GetBoard()->GetRatsnest()->Remove( segm );
         GetBoard()->m_Track.Remove( segm );
 
@@ -196,15 +225,26 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
     if( pt_segm == NULL )
         return;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    int net_code = pt_segm->GetNetCode();
+    PICKED_ITEMS_LIST itemsList;
+    ITEM_PICKER       picker( NULL, UR_DELETED );
+    //Delete teardrops from whole net. 
+    GetBoard()->TrackItems()->Teardrops()->Remove( net_code, TEARDROPS::ALL_TYPES_T, &itemsList, true);
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( net_code, &itemsList, true );
+#endif
+
     TRACK* trackList = GetBoard()->MarkTrace( pt_segm, &segments_to_delete_count,
                                               NULL, NULL, true );
 
     if( segments_to_delete_count == 0 )
         return;
 
+#ifndef PCBNEW_WITH_TRACKITEMS
     int net_code = pt_segm->GetNetCode();
     PICKED_ITEMS_LIST itemsList;
     ITEM_PICKER       picker( NULL, UR_DELETED );
+#endif
 
     int               ii = 0;
     TRACK*            tracksegment = trackList;
@@ -228,6 +268,12 @@ void PCB_EDIT_FRAME::Remove_One_Track( wxDC* DC, TRACK* pt_segm )
         itemsList.PushItem( picker );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Add teardrops back those net tracks witch where not deleted.
+    GetBoard()->TrackItems()->Teardrops()->Recreate( net_code, &itemsList );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Recreate( net_code, &itemsList );
+#endif
+    
     SaveCopyInUndoList( itemsList, UR_DELETED );
 
     if( net_code > 0 )
diff --git a/pcbnew/dragsegm.cpp b/pcbnew/dragsegm.cpp
index 7e48f5c..21800f3 100644
--- a/pcbnew/dragsegm.cpp
+++ b/pcbnew/dragsegm.cpp
@@ -43,6 +43,10 @@
 #include <class_board.h>
 #include <connect.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 /* a list of DRAG_SEGM_PICKER items used to move or drag tracks */
 std::vector<DRAG_SEGM_PICKER> g_DragSegmentList;
@@ -293,16 +297,43 @@ void DRAG_LIST::ClearList()
 // Redraw the list of segments stored in g_DragSegmentList, while moving a footprint
 void DrawSegmentWhileMovingFootprint( EDA_DRAW_PANEL* panel, wxDC* DC )
 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+    BOARD * pcb = static_cast<PCB_EDIT_FRAME*>(panel->GetParent())->GetBoard();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+    {
+        TRACK* track = g_DragSegmentList[ii].m_Track;
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( track );
+    }
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( panel, DC, GR_XOR );
+#endif
+    
     for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
     {
         TRACK* track = g_DragSegmentList[ii].m_Track;
 
 #ifndef USE_WX_OVERLAY
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(!dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+#endif
         track->Draw( panel, DC, GR_XOR );   // erase from screen at old position
 #endif
         g_DragSegmentList[ii].SetTrackEndsCoordinates( g_Offset_Module );
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( track );
+        if(!dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+#endif
         track->Draw( panel, DC, GR_XOR );
     }
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo( panel, DC, GR_XOR, true );
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( panel, DC, GR_XOR );
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo( panel, DC, GR_XOR, true );       
+#endif
 }
 
 
@@ -345,6 +376,13 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LSET aLay
         if( track->GetNetCode() != aNetCode )   // not the same netcode: all candidates tested
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS 
+        if( track->Type() == PCB_TEARDROP_T ) //Do not collect teardrops at this time...
+            continue;
+        if( track->Type() == PCB_ROUNDEDTRACKSCORNER_T ) //Do not collect teardrops at this time...
+            continue;
+#endif
+        
         if( !( aLayerMask & track->GetLayerSet() ).any() )
             continue;                       // Cannot be connected, not on the same layer
 
@@ -352,7 +390,11 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LSET aLay
             continue;                       // already put in list
 
         STATUS_FLAGS flag = 0;
+#ifdef PCBNEW_WITH_TRACKITEMS 
+        int maxdist = std::min( aMaxDist, track->GetWidth() / 2 ); //std::min gives aMaxDist a chance.
+#else
         int maxdist = std::max( aMaxDist, track->GetWidth() / 2 );
+#endif
 
         if( (track->GetFlags() & STARTPOINT) == 0 )
         {
@@ -396,6 +438,14 @@ void Collect_TrackSegmentsToDrag( BOARD* aPcb, const wxPoint& aRefPos, LSET aLay
             if( track->Type() == PCB_VIA_T )
                 Collect_TrackSegmentsToDrag( aPcb, aRefPos, track->GetLayerSet(),
                                              aNetCode, track->GetWidth() / 2 );
+#ifdef PCBNEW_WITH_TRACKITEMS
+            else
+            {
+                //... collect teardrop(s) now.
+                aPcb->TrackItems()->Teardrops()->AddToDragList( track, g_DragSegmentList ); 
+                aPcb->TrackItems()->RoundedTracksCorners()->AddToDragList( track, g_DragSegmentList );
+            }
+#endif
         }
     }
 }
diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp
index d4d0776..6666fbb 100644
--- a/pcbnew/drc.cpp
+++ b/pcbnew/drc.cpp
@@ -53,6 +53,12 @@
 #include <wx/progdlg.h>
 #include <board_commit.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#include "trackitems/viastitching.h"
+#endif
+
+
 void DRC::ShowDRCDialog( wxWindow* aParent )
 {
     bool show_dlg_modal = true;
@@ -237,6 +243,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
         testPad2Pad();
     }
 
+#ifndef PCBNEW_WITH_TRACKITEMS
     // test track and via clearances to other tracks, pads, and vias
     if( aMessages )
     {
@@ -245,6 +252,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
     }
 
     testTracks( aMessages ? aMessages->GetParent() : m_pcbEditorFrame, true );
+#endif
 
     // Before testing segments and unconnected, refill all zones:
     // this is a good caution, because filled areas can be outdated.
@@ -266,6 +274,17 @@ void DRC::RunTests( wxTextCtrl* aMessages )
 
     testZones();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    // 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 );
+#endif
+
     // find and gather unconnected pads.
     if( m_doUnconnectedTest )
     {
@@ -549,6 +568,11 @@ void DRC::testTracks( wxWindow *aActiveWindow, bool aShowProgressBar )
             addMarkerToPcb ( m_currentMarker );
             m_currentMarker = nullptr;
         }
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Test Thermal via.
+        m_pcb->ViaStitching()->RuleCheck( segm, this );
+#endif
     }
 
     if( progressDialog )
@@ -750,6 +774,12 @@ void DRC::testTexts()
                     }
                 }
             }
+#ifdef PCBNEW_WITH_TRACKITEMS
+            else if( track->Type() == PCB_TEARDROP_T )
+                m_pcb->TrackItems()->Teardrops()->DRC_Clearance( track, text, min_dist, this );
+            else if( track->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+                m_pcb->TrackItems()->RoundedTracksCorners()->DRC_Clearance( track, text, min_dist, this );
+#endif
         }
 
         // Test pads
diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp
index f8fa8db..656e068 100644
--- a/pcbnew/drc_clearance_test_functions.cpp
+++ b/pcbnew/drc_clearance_test_functions.cpp
@@ -47,6 +47,11 @@
 #include <polygon_test_point_inside.h>
 #include <convert_basic_shapes_to_polygon.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#include "trackitems/roundedcornertrack.h"
+#endif
+
 
 /* compare 2 convex polygons and return true if distance > aDist
  * i.e if for each edge of the first polygon distance from each edge of the other polygon
@@ -156,6 +161,15 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
     layerMask    = aRefSeg->GetLayerSet();
     net_code_ref = aRefSeg->GetNetCode();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //RoundedCornerTracks
+    if(dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg))
+    {
+        origin = dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg)->GetStartVisible();
+        m_segmEnd   = delta = dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg)->GetEndVisible() - origin;
+    }
+#endif
+    
     // Phase 0 : Test vias
     if( aRefSeg->Type() == PCB_VIA_T )
     {
@@ -230,6 +244,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
     }
     else    // This is a track segment
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Test teardrop first.
+        if( aRefSeg->Type() == PCB_TEARDROP_T )
+            m_pcb->TrackItems()->Teardrops()->DRC_Rules(static_cast<TrackNodeItem::TEARDROP*>(aRefSeg), this);
+        else
+            //roundedtrackscorners may use tracks rule check
+#endif
         if( aRefSeg->GetWidth() < dsnSettings.m_TrackMinWidth )
         {
             m_currentMarker = fillMarker( aRefSeg, NULL,
@@ -299,6 +320,16 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
 
                 m_padToTestPos = dummypad.GetPosition() - origin;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+                if( !m_pcb->TrackItems()->Teardrops()->DRC_Clearance( aRefSeg, static_cast<D_PAD*>(&dummypad), 
+                                                        netclass->GetClearance(), this) )
+                    return false;
+                if( !m_pcb->TrackItems()->RoundedTracksCorners()->DRC_Clearance( aRefSeg, static_cast<D_PAD*>(&dummypad), 
+                                                        netclass->GetClearance(), this) )
+                    return false;
+                if(!dynamic_cast<TrackNodeItem::TRACKNODEITEM*>(aRefSeg))
+#endif
+
                 if( !checkClearanceSegmToPad( &dummypad, aRefSeg->GetWidth(),
                                               netclass->GetClearance() ) )
                 {
@@ -320,12 +351,24 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
             shape_pos = pad->ShapePos();
             m_padToTestPos = shape_pos - origin;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( !m_pcb->TrackItems()->Teardrops()->DRC_Clearance( aRefSeg, static_cast<D_PAD*>(pad), 
+                                                    aRefSeg->GetClearance( pad ), this) )
+                return false;
+            if( !m_pcb->TrackItems()->RoundedTracksCorners()->DRC_Clearance( aRefSeg, static_cast<D_PAD*>(pad), 
+                                                    aRefSeg->GetClearance( pad ), this) )
+                return false;
+            
+            if(!dynamic_cast<TrackNodeItem::TRACKNODEITEM*>(aRefSeg))
+#endif
+            
             if( !checkClearanceSegmToPad( pad, aRefSeg->GetWidth(), aRefSeg->GetClearance( pad ) ) )
             {
                 m_currentMarker = fillMarker( aRefSeg, pad,
                                               DRCE_TRACK_NEAR_PAD, m_currentMarker );
                 return false;
             }
+
         }
     }
 
@@ -360,12 +403,37 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
         // slightly decrease the w_dist (remove one nanometer is enough !)
         w_dist -= 1;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Test teardrops.
+        if( (aRefSeg->Type() == PCB_TEARDROP_T) || (track->Type() == PCB_TEARDROP_T) )
+        {
+            if( !m_pcb->TrackItems()->Teardrops()->DRC_Clearance(aRefSeg, track, w_dist, this) )
+                return false;
+            continue;
+        }
+        if( (aRefSeg->Type() == PCB_ROUNDEDTRACKSCORNER_T) || (track->Type() == PCB_ROUNDEDTRACKSCORNER_T) )
+        {
+            if( !m_pcb->TrackItems()->RoundedTracksCorners()->DRC_Clearance(aRefSeg, track, w_dist, this) )
+                return false;
+            continue;
+        }
+#endif
+
         // If the reference segment is a via, we test it here
         if( aRefSeg->Type() == PCB_VIA_T )
         {
             delta = track->GetEnd() - track->GetStart();
             segStartPoint = aRefSeg->GetStart() - track->GetStart();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //RoundedCornerTracks
+            if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+            {
+                delta = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetEndVisible() - dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible();
+                segStartPoint = aRefSeg->GetStart() - dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible();
+            }
+#endif
+    
             if( track->Type() == PCB_VIA_T )
             {
                 // Test distance between two vias, i.e. two circles, trivial case
@@ -402,6 +470,16 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
          */
         segStartPoint = track->GetStart() - origin;
         segEndPoint   = track->GetEnd() - origin;
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //RoundedCornerTracks
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+        {
+            segStartPoint = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible() - origin;
+            segEndPoint = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetEndVisible() - origin;
+        }
+#endif
+    
         RotatePoint( &segStartPoint, m_segmAngle );
         RotatePoint( &segEndPoint, m_segmAngle );
         if( track->Type() == PCB_VIA_T )
@@ -544,6 +622,15 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
                     // Test the starting and the ending point
                     segStartPoint = track->GetStart();
                     segEndPoint   = track->GetEnd();
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+                    //RoundedCornerTracks
+                    if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+                    {
+                        segStartPoint = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible();
+                        segEndPoint = dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetEndVisible();
+                    }
+#endif
                     delta = segEndPoint - segStartPoint;
 
                     // Compute the segment orientation (angle) en 0,1 degre
@@ -558,6 +645,15 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
                     wxPoint relStartPos = aRefSeg->GetStart() - segStartPoint;
                     wxPoint relEndPos   = aRefSeg->GetEnd() - segStartPoint;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+                    //RoundedCornerTracks
+                    if(dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg))
+                    {
+                        relStartPos = dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg)->GetStartVisible() - segStartPoint;
+                        relEndPos = dynamic_cast<ROUNDEDCORNERTRACK*>(aRefSeg)->GetEndVisible() - segStartPoint;
+                    }
+#endif
+    
                     RotatePoint( &relStartPos, angle );
                     RotatePoint( &relEndPos, angle );
 
diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp
index 0d5719c..12793e3 100644
--- a/pcbnew/drc_marker_functions.cpp
+++ b/pcbnew/drc_marker_functions.cpp
@@ -44,6 +44,13 @@
 #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>
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/teardrops.h"
+#endif
 
 
 MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode,
@@ -67,6 +74,13 @@ MARKER_PCB* DRC::fillMarker( const TRACK* aTrack, BOARD_ITEM* aItem, int aErrorC
         {
             posB = position = ((VIA*)aItem)->GetPosition();
         }
+#ifdef PCBNEW_WITH_TRACKITEMS
+        else if( aItem->Type() == PCB_TEARDROP_T )
+        {
+            //Sometimes this show wrong end of track segment. But nothing else to use.
+            posB = position = static_cast<TrackNodeItem::TEARDROP*>(aItem)->GetPosition();
+        }
+#endif
         else if( aItem->Type() == PCB_TRACE_T )
         {
             TRACK*  track  = (TRACK*) aItem;
@@ -237,3 +251,26 @@ MARKER_PCB* DRC::fillMarker( const wxPoint& aPos, int aErrorCode, const wxString
     return fillMe;
 }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+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;
+        }
+    }
+}
+#endif
diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h
index e8db31c..3d4c0f7 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
@@ -85,6 +86,45 @@
 #define DRCE_MALFORMED_COURTYARD_IN_FOOTPRINT  46   ///< footprint has a courtyard but malformed
                                                     ///< (not convetrible to polygon)
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+//Teardrop Errors
+#define DRCE_TEARDROP_NEAR_TEARDROP         500
+#define DRCE_TEARDROP_NEAR_TRACK            501
+#define DRCE_TEARDROP_NEAR_VIA              502
+#define DRCE_TEARDROP_NEAR_PAD              503
+#define DRCE_TEARDROP_TOO_SMALL             504
+#define DRCE_JUNCTION_NEAR_TRACK            505
+#define DRCE_JUNCTION_NEAR_VIA              506
+#define DRCE_JUNCTION_NEAR_PAD              507
+#define DRCE_JUNCTION_NEAR_TEARDROP         508
+#define DRCE_JUNCTION_NEAR_JUNCTION         509
+#define DRCE_JUNCTION_TOO_SMALL             510
+#define DRCE_TEARDROP_NOT_IN_PAD            511
+#define DRCE_TEARDROP_NOT_IN_VIA            512
+#define DRCE_TEARDOPS_MULTIPLE              513
+#define DRCE_TEARDROP_TRACK_ERROR           514
+#define DRCE_TJUNCTION_TRACK_SEGS_LENGTH    515
+#define DRCE_TEARDROP_INSIDE_TEXT           516
+#define DRCE_JUNCTION_INSIDE_TEXT           517
+
+//Teardrop warnings and  markings. 
+#define DRCE_TEARDROP_TRIMMED               551     
+#define DRCE_TEARDROP_BIG                   552
+#define DRCE_TEARDROP_MISSING               553
+#define DRCE_TJUNCTION_MISSING              554
+#define DRCE_JUNCTION_MISSING               555
+#define DRCE_TEARDROP_USELESS               556  
+#define DRCE_TEARDROP_IMPOSSIBLE            557
+#define DRCE_JUNCTION_TRACK_SEGS_WIDTH      558
+#define DRCE_TJUNCTION_ANGLE                559
+#define DRCE_TEARDROPS_INSIDE               560     
+
+#define DRCE_TRACKNODEITEM_UNSPECIFIED      600
+
+#define DRCE_THERMAL_VIA_UNCONNECTED        650   ///< Thermal Via unconnected
+#define DRCE_THERMAL_VIA_CONNECTED_POURS    651   ///< Thermal Via too less zones connected
+#endif
+
 
 class EDA_DRAW_PANEL;
 class PCB_EDIT_FRAME;
@@ -158,6 +198,10 @@ typedef std::vector<DRC_ITEM*> DRC_LIST;
 class DRC
 {
     friend class DIALOG_DRC_CONTROL;
+#ifdef PCBNEW_WITH_TRACKITEMS
+    friend class TEARDROPS;
+    friend class ROUNDEDTRACKSCORNERS;
+#endif
 
 private:
 
@@ -398,7 +442,13 @@ private:
      * @return bool - true if distance >= radius, else
      *                false when distance < aRadius
      */
+#ifdef PCBNEW_WITH_TRACKITEMS
+public:
+    bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
+private:
+#else
     static bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
+#endif
 
 
     /**
@@ -536,6 +586,9 @@ public:
         return m_currentMarker;
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    void AddMarker( const BOARD_CONNECTED_ITEM* aItem, const wxPoint aMarkerPos, const int aErrorCode, MARKER_PCB* aFillMarker );
+#endif
 };
 
 
diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp
index d95b187..8f92981 100644
--- a/pcbnew/edit.cpp
+++ b/pcbnew/edit.cpp
@@ -60,6 +60,12 @@
 #include <tool/tool_manager.h>
 #include <tools/pcb_actions.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#include "trackitems/trackitems.h"
+#endif
+
+
 // Handles the selection of command events.
 void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 {
@@ -154,6 +160,143 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
     case ID_POPUP_PCB_MOVE_MODULE_REQUEST:
     case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
     case ID_POPUP_PCB_MOVE_MIRE_REQUEST:
+    case ID_POPUP_PCB_DELETE_MARKER:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA:
+    case ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA:
+    case ID_POPUP_PCB_SEL_LAYERS_AND_PLACE_ZONE_BLIND_BURIED_VIA:
+    case ID_POPUP_PCB_SEL_LAYER_AND_PLACE_ZONE_THROUGH_VIA:
+    //Teardrops
+    case ID_POPUP_PCB_TEARDROP_COPYCURRENT:
+    case ID_POPUP_PCB_TEARDROP_LOCK_TOGGLE:
+    case ID_POPUP_PCB_TEARDROPS_LOCK_ALL_SAME:
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_ALL_SAME:
+    case ID_POPUP_PCB_TEARDROPS_LOCK_MODULES_ALL:
+    case ID_POPUP_PCB_TEARDROPS_LOCK_VIAS_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_LOCK_ALL:
+    case ID_POPUP_PCB_JUNCTIONS_LOCK_ALL:
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULES_ALL:
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_VIAS_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_UNLOCK_ALL:
+    case ID_POPUP_PCB_JUNCTIONS_UNLOCK_ALL:
+    case ID_POPUP_PCB_TEARDROPS_LOCK_MODULE:
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULE:
+    case ID_POPUP_PCB_TEARDROPS_LOCK:
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK:
+    case ID_POPUP_PCB_TEARDROP_EDIT_LENGTH:
+    case ID_POPUP_PCB_TEARDROP_EDIT_WIDTH:
+    case ID_POPUP_PCB_TEARDROP_SET_DEFAULT_PARAMS:
+    case ID_POPUP_PCB_TEARDROP_SELECT_TEARDROP:
+    case ID_POPUP_PCB_TEARDROP_SELECT_FILLET:
+    case ID_POPUP_PCB_TEARDROP_SELECT_SUBLAND:
+    case ID_POPUP_PCB_TEARDROP_SELECT_ZERO:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_LAST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_LAST:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_LAST:
+    case ID_POPUP_PCB_TEARDROP_PLACE:
+    case ID_POPUP_PCB_TEARDROPS_PLACE:
+    case ID_POPUP_PCB_TEARDROP_CHANGE:
+    case ID_POPUP_PCB_TEARDROPS_CHANGE:
+    case ID_POPUP_PCB_TEARDROP_DELETE:
+    case ID_POPUP_PCB_TEARDROPS_DELETE:
+    case ID_POPUP_PCB_TEARDROPS_PLACE_MODULE:
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_MODULE:
+    case ID_POPUP_PCB_TEARDROPS_DELETE_MODULE:
+    case ID_POPUP_PCB_TEARDROPS_PLACE_VIAS_ALL:
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_VIAS_ALL:
+    case ID_POPUP_PCB_TEARDROPS_DELETE_VIAS_ALL:
+    case ID_POPUP_PCB_TEARDROPS_PLACE_MODULES_ALL:
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_MODULES_ALL:
+    case ID_POPUP_PCB_TEARDROPS_DELETE_MODULES_ALL:
+    case ID_POPUP_PCB_TEARDROPS_PLACE_NET:
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_NET:
+    case ID_POPUP_PCB_TEARDROPS_DELETE_NET:
+    case ID_POPUP_PCB_TJUNCTIONS_PLACE_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_CHANGE_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_DELETE_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_MARK_NOT_T:
+    case ID_POPUP_PCB_JUNCTIONS_PLACE_ALL:
+    case ID_POPUP_PCB_JUNCTIONS_CHANGE_ALL:
+    case ID_POPUP_PCB_JUNCTIONS_DELETE_ALL:
+    case ID_POPUP_PCB_TJUNCTIONS_PLACE_NET:
+    case ID_POPUP_PCB_TJUNCTIONS_CHANGE_NET:
+    case ID_POPUP_PCB_TJUNCTIONS_DELETE_NET:
+    case ID_POPUP_PCB_JUNCTIONS_PLACE_NET:
+    case ID_POPUP_PCB_JUNCTIONS_CHANGE_NET:
+    case ID_POPUP_PCB_JUNCTIONS_DELETE_NET:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_MODULES:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_JUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_MODULES:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_JUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_MODULES:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_JUNCTIONS:
+    case ID_POPUP_PCB_VIA_PICK_SIZE:
+    case ID_POPUP_PCB_TRACK_PICK_WIDTH:
+    case ID_POPUP_PCB_TRACKS_MARK_SHARP_ANGLES:
+        //rounded corners
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_PLACE:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_DELETE:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_CHANGE:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_COPYCURRENT:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 1:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 2:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 3:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 4:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 5:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 6:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 7:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 8:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 9:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_LAST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 1:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 2:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 3:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 4:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 5:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 6:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 7:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 8:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 9:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_LAST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SET_DEFAULT_PARAMS:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_SET:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_RATIO:
+#endif
         break;
 
     case ID_POPUP_CANCEL_CURRENT_COMMAND:
@@ -388,11 +531,21 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
         if( m_canvas->IsMouseCaptured() )
             m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(TrackNodeItem::ROUNDEDTRACKSCORNER* cor = GetBoard()->TrackItems()->RoundedTracksCorners()->GetEditCorner())
+            cor->Draw( m_canvas, &dc, GR_XOR );
+#endif
+
         g_Alternate_Track_Posture = !g_Alternate_Track_Posture;
 
         if( m_canvas->IsMouseCaptured() )
             m_canvas->CallMouseCapture( &dc, wxDefaultPosition, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(TrackNodeItem::ROUNDEDTRACKSCORNER* cor = GetBoard()->TrackItems()->RoundedTracksCorners()->GetEditCorner())
+            cor->Draw( m_canvas, &dc, GR_XOR );
+#endif
+
         break;
 
     case ID_POPUP_PCB_PLACE_MICROVIA:
@@ -784,7 +937,20 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 
         // This is a simple rotation, no other editing in progress
         if( !GetCurItem()->IsMoving() )
+#ifdef PCBNEW_WITH_TRACKITEMS
+        {
+            PICKED_ITEMS_LIST pickedItems;
+            ITEM_PICKER       picker( NULL, UR_CHANGED );
+            //Delete teardrops
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<MODULE*>(GetCurItem()), &pickedItems, true );
+            picker.SetItem( GetCurItem() );
+            pickedItems.PushItem( picker );
+            SaveCopyInUndoList( pickedItems, UR_CHANGED, 
+                                static_cast<MODULE*>(GetCurItem())->GetPosition() );
+        }
+#else
             SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() );
+#endif
 
         Rotate_Module( &dc, (MODULE*) GetCurItem(), m_rotationAngle, true );
         break;
@@ -812,7 +978,20 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 
         // This is a simple rotation, no other editing in progress
         if( !GetCurItem()->IsMoving() )
+#ifdef PCBNEW_WITH_TRACKITEMS
+        {
+            PICKED_ITEMS_LIST pickedItems;
+            ITEM_PICKER       picker( NULL, UR_CHANGED );
+            //Delete teardrops
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<MODULE*>(GetCurItem()), &pickedItems, true );
+            picker.SetItem( GetCurItem() );
+            pickedItems.PushItem( picker );
+            SaveCopyInUndoList( pickedItems, UR_CHANGED, 
+                                static_cast<MODULE*>(GetCurItem())->GetPosition() );
+        }
+#else
             SaveCopyInUndoList( GetCurItem(), UR_CHANGED, ((MODULE*)GetCurItem())->GetPosition() );
+#endif
 
         Rotate_Module( &dc, (MODULE*) GetCurItem(), -m_rotationAngle, true );
         break;
@@ -840,7 +1019,20 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 
         // This is a simple flip, no other editing in progress
         if( !GetCurItem()->IsMoving() )
+#ifdef PCBNEW_WITH_TRACKITEMS
+        {
+            PICKED_ITEMS_LIST pickedItems;
+            ITEM_PICKER       picker( NULL, UR_FLIPPED );
+            //Delete teardrops
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<MODULE*>(GetCurItem()), &pickedItems, true );
+            picker.SetItem( GetCurItem() );
+            pickedItems.PushItem( picker );
+            SaveCopyInUndoList( pickedItems, UR_FLIPPED, 
+                                static_cast<MODULE*>(GetCurItem())->GetPosition() );
+        }
+#else
             SaveCopyInUndoList( GetCurItem(), UR_FLIPPED, ((MODULE*)GetCurItem())->GetPosition() );
+#endif
 
         Change_Side_Module( (MODULE*) GetCurItem(), &dc );
         break;
@@ -935,6 +1127,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 
     case ID_POPUP_PCB_EDIT_PAD:
         InstallPadOptionsFrame( (D_PAD*) GetCurItem() );
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Teardrops()->Update( static_cast<D_PAD*>(GetCurItem()) );
+#endif
         m_canvas->MoveCursorToCrossHair();
         break;
 
@@ -955,8 +1150,31 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
         break;
 
     case ID_POPUP_PCB_DELETE_PAD:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    {
+        PICKED_ITEMS_LIST pickedItems;
+        ITEM_PICKER       picker( NULL, UR_CHANGED );
+        D_PAD* pad_delete = static_cast<D_PAD*>(GetCurItem());
+        D_PAD pad_data = *pad_delete;
+        GetBoard()->TrackItems()->Teardrops()->Remove( pad_delete, &pickedItems, true );
+        picker.SetItem( GetCurItem()->GetParent() );
+        pickedItems.PushItem( picker );
+        SaveCopyInUndoList( pickedItems, UR_CHANGED );
+#else
         SaveCopyInUndoList( GetCurItem()->GetParent(), UR_CHANGED );
+#endif
         DeletePad( (D_PAD*) GetCurItem() );
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        D_PAD* still_pad = GetBoard()->GetPadFast( pad_data.GetPosition(), pad_data.GetLayerSet() );
+        if( still_pad == pad_delete )
+        {
+            GetBoard()->PadDelete( pad_delete ); //Delete pad to undo deletion.
+            wxCommandEvent e = wxID_UNDO;
+            RestoreCopyFromUndoList( e );
+        }
+    }
+#endif
         SetCurItem( NULL );
         m_canvas->MoveCursorToCrossHair();
         break;
@@ -1203,6 +1421,15 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
 
             TRACK*  newtrack = GetBoard()->CreateLockPoint( pos, track, &itemsListPicker );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+            {
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Add( newtrack, pos, &itemsListPicker );//New node
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Add( track, pos, &itemsListPicker );//or previous one
+            }
+            OnModify();
+#endif
+
             SaveCopyInUndoList( itemsListPicker, UR_UNSPECIFIED );
             track->Draw( m_canvas, &dc, GR_XOR );
             newtrack->Draw( m_canvas, &dc, GR_XOR );
@@ -1258,6 +1485,657 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
         m_canvas->Refresh();
         break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case ID_POPUP_PCB_GOTO_NEXT_MARKER:
+        if( !GetBoard()->m_markers.empty() )
+        {
+            uint index = 0;
+            if( GetCurItem() && GetCurItem()->Type() == PCB_MARKER_T )
+            {
+                for( MARKER_PCB* curma : GetBoard()->m_markers ) 
+                {
+                    index++;
+                    if( static_cast<MARKER_PCB*>(GetCurItem()) == curma )
+                        break;
+                }
+                        
+            }
+            
+            if( index >= GetBoard()->m_markers.size() )
+                index = 0;
+
+            MARKER_PCB* mark = GetBoard()->GetMARKER( index );
+            if( mark )
+            {
+                CursorGoto( mark->GetPosition() );
+                SetCurItem( mark );
+            }
+        }
+
+        break;
+
+    //Via stitching.
+    case ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA:
+    case ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA:
+    case ID_POPUP_PCB_SEL_LAYERS_AND_PLACE_ZONE_BLIND_BURIED_VIA:
+    case ID_POPUP_PCB_SEL_LAYER_AND_PLACE_ZONE_THROUGH_VIA:
+        GetBoard()->ViaStitching()->AddThermalVia( this, id ); 
+        break;
+
+    case ID_POPUP_PCB_CREATE_VIA_ARRAY:
+        if( GetCurItem()->Type() == PCB_VIA_T)
+        {
+            const VIA* via = static_cast<const VIA*>(GetCurItem());
+            if(dynamic_cast<const VIA*>(via)->GetThermalCode())
+            {
+                GetBoard()->ViaStitching()->AddViaArrayPrepare( this, via ); 
+                createArray(); 
+                GetBoard()->ViaStitching()->AddViaArrayFinnish(); 
+            }
+        }
+        break;
+            
+    //Teardrops
+    case ID_POPUP_PCB_TEARDROP_COPYCURRENT:
+        if( GetCurItem() )
+            GetBoard()->TrackItems()->Teardrops()->CopyCurrentParams( static_cast<TRACK*>(GetCurItem()), 
+                                                                      GetCrossHairPosition() );
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_LOCK_TOGGLE:
+        if( GetCurItem() )
+        {
+            GetBoard()->TrackItems()->Teardrops()->LockToggle( static_cast<TRACK*>(GetCurItem()), 
+                                                               GetCrossHairPosition() );
+            OnModify();
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_LOCK_ALL_SAME:
+        if( GetCurItem() )
+        {
+            GetBoard()->TrackItems()->Teardrops()->Lock( static_cast<TRACK*>(GetCurItem()), 
+                                                         GetCrossHairPosition(),
+                                                         &GetBoard()->m_Track);
+            OnModify();
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_ALL_SAME:
+        if( GetCurItem() )
+        {
+            GetBoard()->TrackItems()->Teardrops()->Unlock( static_cast<TRACK*>(GetCurItem()), 
+                                                           GetCrossHairPosition(),
+                                                           &GetBoard()->m_Track);
+            OnModify();
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_LOCK_NET:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() == PCB_TRACE_T )
+            {
+                GetBoard()->TrackItems()->Teardrops()->Lock( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                                             static_cast<TRACK*>(GetCurItem()) );
+                OnModify();
+            }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_NET:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() == PCB_TRACE_T )
+            {
+                GetBoard()->TrackItems()->Teardrops()->Unlock( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                                               static_cast<TRACK*>(GetCurItem()) );
+                OnModify();
+            }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_LOCK_MODULES_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Lock(&GetBoard()->m_Modules);
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULES_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Unlock(&GetBoard()->m_Modules);
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_LOCK_VIAS_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Lock( &GetBoard()->m_Track, TEARDROPS::ONLY_TEARDROPS_T );
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_VIAS_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Unlock( &GetBoard()->m_Track, TEARDROPS::ONLY_TEARDROPS_T );
+        OnModify();
+        break;
+        
+    case  ID_POPUP_PCB_TJUNCTIONS_LOCK_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Lock(&GetBoard()->m_Track, TEARDROPS::ONLY_TJUNCTIONS_T);
+        OnModify();
+        break;
+        
+    case  ID_POPUP_PCB_TJUNCTIONS_UNLOCK_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Unlock(&GetBoard()->m_Track, TEARDROPS::ONLY_TJUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_LOCK_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Lock(&GetBoard()->m_Track, TEARDROPS::ONLY_JUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_UNLOCK_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Unlock(&GetBoard()->m_Track, TEARDROPS::ONLY_JUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_LOCK_MODULE:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() != PCB_MODULE_T )
+                SetCurItem( GetCurItem()->GetParent() );
+            if( GetCurItem() )
+                if( GetCurItem()->Type() == PCB_MODULE_T )
+                {
+                    GetBoard()->TrackItems()->Teardrops()->Lock( static_cast<MODULE*>(GetCurItem()) );
+                    OnModify();
+                }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULE:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() != PCB_MODULE_T )
+                SetCurItem( GetCurItem()->GetParent() );
+            if( GetCurItem() )
+                if( GetCurItem()->Type() == PCB_MODULE_T )
+                {
+                    GetBoard()->TrackItems()->Teardrops()->Unlock( static_cast<MODULE*>(GetCurItem()) );
+                    OnModify();
+                }
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_LOCK:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Lock( static_cast<BOARD_CONNECTED_ITEM*>(GetCurItem()) );
+            OnModify();
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_UNLOCK:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Unlock( static_cast<BOARD_CONNECTED_ITEM*>(GetCurItem()) );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_EDIT_LENGTH:
+        GetBoard()->TrackItems()->Teardrops()->ToggleEdit( TEARDROPS::EDIT_SIZE_LENGTH_T );
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_EDIT_WIDTH:
+        GetBoard()->TrackItems()->Teardrops()->ToggleEdit( TEARDROPS::EDIT_SIZE_WIDTH_T );
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_SET_DEFAULT_PARAMS:
+        GetBoard()->TrackItems()->Teardrops()->LoadDefaultParams(
+            GetBoard()->TrackItems()->Teardrops()->GetCurrentShape());
+        break;
+        
+    case ID_POPUP_PCB_TEARDROP_SELECT_TEARDROP:
+        GetBoard()->TrackItems()->Teardrops()->SelectShape(TrackNodeItem::TEARDROP::TEARDROP_T);
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_SELECT_FILLET:
+        GetBoard()->TrackItems()->Teardrops()->SelectShape(TrackNodeItem::TEARDROP::FILLET_T);
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_SELECT_SUBLAND:
+        GetBoard()->TrackItems()->Teardrops()->SelectShape(TrackNodeItem::TEARDROP::SUBLAND_T);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROP_SELECT_ZERO:
+        GetBoard()->TrackItems()->Teardrops()->SelectShape(TrackNodeItem::TEARDROP::ZERO_T);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_LAST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_LAST:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 1:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 2:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 3:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 4:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 5:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 6:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 7:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 8:
+    case ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_LAST:
+        GetBoard()->TrackItems()->Teardrops()->MenuToDo_ChangeSize( id );
+        break;
+    
+    case ID_POPUP_PCB_TEARDROP_PLACE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition() );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_PLACE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<BOARD_CONNECTED_ITEM*>(GetCurItem()) );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROP_CHANGE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Change( GetBoard()->TrackItems()->Teardrops()->Get(
+                static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition()) );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_CHANGE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Change( static_cast<BOARD_CONNECTED_ITEM*>(GetCurItem()) );
+            OnModify();
+        }
+        break;
+    
+    case ID_POPUP_PCB_TEARDROP_DELETE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Remove( GetBoard()->TrackItems()->Teardrops()->Get( static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition()),  true, false );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_DELETE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<BOARD_CONNECTED_ITEM*>(GetCurItem()), true, false );
+            OnModify();
+        }
+        break;
+    
+    case ID_POPUP_PCB_TEARDROPS_PLACE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<TRACK*>(GetCurItem())->GetNetCode(), 
+                                          TEARDROPS::ONLY_TEARDROPS_T );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Change( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_TEARDROPS_T );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_DELETE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_TEARDROPS_T,  true, false );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_PLACE_MODULE:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() != PCB_MODULE_T )
+                SetCurItem( GetCurItem()->GetParent() );
+            if( GetCurItem() )
+                if( GetCurItem()->Type() == PCB_MODULE_T )
+                {
+                    GetBoard()->TrackItems()->Teardrops()->Add( static_cast<MODULE*>(GetCurItem()) );
+                    OnModify();
+                }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_MODULE:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() != PCB_MODULE_T )
+                SetCurItem( GetCurItem()->GetParent() );
+            if( GetCurItem() )
+                if( GetCurItem()->Type() == PCB_MODULE_T )
+                {
+                    GetBoard()->TrackItems()->Teardrops()->Change( static_cast<MODULE*>(GetCurItem()) );
+                    OnModify();
+                }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_DELETE_MODULE:
+        if( GetCurItem() )
+        {
+            if( GetCurItem()->Type() != PCB_MODULE_T )
+                SetCurItem( GetCurItem()->GetParent() );
+            if( GetCurItem() )
+                if( GetCurItem()->Type() == PCB_MODULE_T )
+                {
+                    GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<MODULE*>(GetCurItem()), true, false );
+                    OnModify();
+                }
+        }
+        break;
+        
+    case ID_POPUP_PCB_TJUNCTIONS_PLACE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                          TEARDROPS::ONLY_TJUNCTIONS_T);
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TJUNCTIONS_CHANGE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Change( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_TJUNCTIONS_T );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TJUNCTIONS_DELETE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_TJUNCTIONS_T, true, false );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_PLACE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                          TEARDROPS::ONLY_JUNCTIONS_T );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_CHANGE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Change( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_JUNCTIONS_T 
+                                           );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_DELETE_NET:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->Teardrops()->Remove( static_cast<TRACK*>(GetCurItem())->GetNetCode(),
+                                             TEARDROPS::ONLY_JUNCTIONS_T, true, false );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_PLACE_MODULES_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Add(&GetBoard()->m_Modules);
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_MODULES_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Change(&GetBoard()->m_Modules);
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_DELETE_MODULES_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Remove(&GetBoard()->m_Modules);
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_PLACE_VIAS_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Add( &GetBoard()->m_Track, TEARDROPS::ONLY_TEARDROPS_T );
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_CHANGE_VIAS_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Change( &GetBoard()->m_Track, TEARDROPS::ONLY_TEARDROPS_T );
+        OnModify();
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_DELETE_VIAS_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Remove( &GetBoard()->m_Track, TEARDROPS::ONLY_TEARDROPS_T );
+        OnModify();
+        break;
+        
+    case  ID_POPUP_PCB_TJUNCTIONS_PLACE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Add(&GetBoard()->m_Track, TEARDROPS::ONLY_TJUNCTIONS_T);
+        OnModify();
+        break;
+        
+    case  ID_POPUP_PCB_TJUNCTIONS_CHANGE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Change(&GetBoard()->m_Track, TEARDROPS::ONLY_TJUNCTIONS_T);
+        OnModify();
+        break;
+
+    case  ID_POPUP_PCB_TJUNCTIONS_DELETE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Remove(&GetBoard()->m_Track, TEARDROPS::ONLY_TJUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_PLACE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Add(&GetBoard()->m_Track, TEARDROPS::ONLY_JUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_CHANGE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Change(&GetBoard()->m_Track, TEARDROPS::ONLY_JUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_JUNCTIONS_DELETE_ALL:
+        GetBoard()->TrackItems()->Teardrops()->Remove(&GetBoard()->m_Track, TEARDROPS::ONLY_JUNCTIONS_T);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_MODULES:
+        GetBoard()->TrackItems()->Teardrops()->MarkWarnings(&GetBoard()->m_Modules, m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_JUNCTIONS:
+        GetBoard()->TrackItems()->Teardrops()->MarkWarnings(&GetBoard()->m_Track, TEARDROPS::TEARDROPS_TYPE_TODO(TEARDROPS::ONLY_TEARDROPS_T + id - ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TEARDROPS_VIAS), m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_MODULES:
+        GetBoard()->TrackItems()->Teardrops()->MarkDifferent(&GetBoard()->m_Track, TEARDROPS::ONLY_PAD_TEARDROPS_T, m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_DIFF_JUNCTIONS:
+        GetBoard()->TrackItems()->Teardrops()->MarkDifferent(&GetBoard()->m_Track, TEARDROPS::TEARDROPS_TYPE_TODO(TEARDROPS::ONLY_TEARDROPS_T + id - ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TEARDROPS_VIAS), m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_MODULES:
+        GetBoard()->TrackItems()->Teardrops()->MarkCurrent(&GetBoard()->m_Track, TEARDROPS::ONLY_PAD_TEARDROPS_T, m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_TEARDROPS_VIAS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_TJUNCTIONS:
+    case ID_POPUP_PCB_TEARDROPS_MARK_CURR_JUNCTIONS:
+        GetBoard()->TrackItems()->Teardrops()->MarkCurrent(&GetBoard()->m_Track, TEARDROPS::TEARDROPS_TYPE_TODO(TEARDROPS::ONLY_TEARDROPS_T + id - ID_POPUP_PCB_TEARDROPS_MARK_CURR_TEARDROPS_VIAS), m_drc);
+        break;
+        
+    case ID_POPUP_PCB_VIA_PICK_SIZE:
+        if(GetCurItem()->Type() == PCB_VIA_T)
+        {
+            GetBoard()->TrackItems()->PickViaSize(static_cast<VIA*>(GetCurItem()));
+            updateViaSizeSelectBox();
+        }
+        break;
+        
+    case ID_POPUP_PCB_TRACK_PICK_WIDTH:
+        if(GetCurItem()->Type() == PCB_TRACE_T)
+        {
+            GetBoard()->TrackItems()->PickTrackSize(static_cast<TRACK*>(GetCurItem()));
+            updateTraceWidthSelectBox();
+        }
+        break;
+    
+    case ID_POPUP_PCB_TRACKS_MARK_SHARP_ANGLES:
+        GetBoard()->TrackItems()->MarkSharpAngles(&GetBoard()->m_Track, m_drc);
+        break;
+        
+    case ID_POPUP_PCB_TRACKS_CONNECT_CENTER_IN_ITEM:
+        GetBoard()->TrackItems()->FixTrackConnectionsInCenter(&GetBoard()->m_Track);
+        OnModify();
+        break;
+
+//------------------------------------------------------------------------------------
+//Rounded corner
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_PLACE:
+        if( GetCurItem() && GetCurItem()->Type() == PCB_TRACE_T )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->RoundedTracksCorners()->Add( static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition() );
+            if( static_cast<TRACK*>(GetCurItem())->GetNetCode() > 0 )
+                TestNetConnection( nullptr, static_cast<TRACK*>(GetCurItem())->GetNetCode() );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_PLACE_ALL:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Add(&GetBoard()->m_Track);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_DELETE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( GetBoard()->TrackItems()->RoundedTracksCorners()->Get( static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition()), true, false );
+            OnModify();
+        }
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_DELETE_ALL:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Remove(&GetBoard()->m_Track);
+        OnModify();
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_CHANGE:
+        if( GetCurItem() )
+        {
+            m_canvas->MoveCursorToCrossHair();
+            GetBoard()->TrackItems()->RoundedTracksCorners()->Change( GetBoard()->TrackItems()->RoundedTracksCorners()->Get( static_cast<TRACK*>(GetCurItem()), GetCrossHairPosition()), true, false );
+            OnModify();
+        }
+        break;
+        
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_CHANGE_ALL:
+        break;
+        
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNER_COPYCURRENT:
+        if( GetCurItem() )
+            GetBoard()->TrackItems()->RoundedTracksCorners()->CopyCurrentParams( static_cast<TRACK*>(GetCurItem()), 
+                                                        GetCrossHairPosition() 
+                                                      );
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 1:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 2:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 3:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 4:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 5:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 6:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 7:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 8:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 9:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_LAST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 1:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 2:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 3:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 4:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 5:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 6:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 7:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 8:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 9:
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_LAST:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->MenuToDo_ChangeSize( id );
+        break;
+    
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SET_DEFAULT_PARAMS:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->LoadDefaultParams();
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_SET:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->ToggleEdit( ROUNDEDTRACKSCORNERS::EDIT_LENGTH_SET_T );
+        break;
+
+    case ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_RATIO:
+        GetBoard()->TrackItems()->RoundedTracksCorners()->ToggleEdit( ROUNDEDTRACKSCORNERS::EDIT_LENGTH_RATIO_T );
+        break;
+
+#endif        
+
     default:
         wxString msg;
         msg.Printf( wxT( "PCB_EDIT_FRAME::Process_Special_Functions() unknown event id %d" ), id );
diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp
index 8441c93..fee4b12 100644
--- a/pcbnew/edit_track_width.cpp
+++ b/pcbnew/edit_track_width.cpp
@@ -38,6 +38,10 @@
 #include <pcbnew.h>
 #include <drc_stuff.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK*             aTrackItem,
                                            PICKED_ITEMS_LIST* aItemsListPicker,
@@ -182,6 +186,14 @@ void PCB_EDIT_FRAME::Edit_TrackSegm_Width( wxDC* aDC, TRACK* aTrackItem )
     if( change == 0 || aTrackItem->GetFlags() )
         return;     // No change
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( aTrackItem, &itemsListPicker, true);
+    GetBoard()->TrackItems()->Teardrops()->Repopulate( aTrackItem->GetNetCode(),
+                                         TEARDROPS::JUNCTIONS_AND_TJUNCTIONS_T, 
+                                         &itemsListPicker );
+    GetBoard()->TrackItems()->Teardrops()->Refresh( aTrackItem );
+#endif
+    
     // The segment has changed: redraw it and save it in undo list
     if( aDC )
     {
@@ -211,21 +223,41 @@ void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
     if( aTrackSegment == NULL )
         return;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    PICKED_ITEMS_LIST itemsListPicker;
+    bool change = false;
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( aTrackSegment->GetNetCode(), &itemsListPicker, true);
+#endif
+    
     pt_track = GetBoard()->MarkTrace( aTrackSegment, &nb_segm, NULL, NULL, true );
 
+#ifndef PCBNEW_WITH_TRACKITEMS
     PICKED_ITEMS_LIST itemsListPicker;
     bool change = false;
+#endif
 
     for( int ii = 0; ii < nb_segm; ii++, pt_track = pt_track->Next() )
     {
         pt_track->SetState( BUSY, false );
 
         if( SetTrackSegmentWidth( pt_track, &itemsListPicker, false ) )
+        {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            GetBoard()->TrackItems()->Teardrops()->Refresh( pt_track );
+#endif
             change = true;
+        }            
     }
 
     if( !change )
+#ifdef PCBNEW_WITH_TRACKITEMS
+    {
+        PutDataInPreviousState(&itemsListPicker, false, false); //Removed corners
+        return;
+    }
+#else
         return;
+#endif
 
     // Some segment have changed: redraw them and save in undo list
     if( aDC )
@@ -235,6 +267,10 @@ void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
         for( unsigned ii = 0; ii < itemsListPicker.GetCount(); ii++ )
         {
             TRACK* segm = (TRACK*) itemsListPicker.GetPickedItemLink( ii );
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(!segm)       //Removed corner.
+                continue;
+#endif
             segm->Draw( m_canvas, aDC, GR_XOR );            // Erase old track shape
             segm = (TRACK*) itemsListPicker.GetPickedItem( ii );
             segm->Draw( m_canvas, aDC, GR_OR );             // Display new track shape
@@ -246,6 +282,10 @@ void PCB_EDIT_FRAME::Edit_Track_Width( wxDC* aDC, TRACK* aTrackSegment )
         m_canvas->CrossHairOn( aDC );                   // Display cursor shape
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->RoundedTracksCorners()->Recreate( aTrackSegment->GetNetCode(), &itemsListPicker);
+#endif
+
     SaveCopyInUndoList( itemsListPicker, UR_CHANGED );
 }
 
diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp
index c0f3b87..12e053b 100644
--- a/pcbnew/editrack-part2.cpp
+++ b/pcbnew/editrack-part2.cpp
@@ -43,6 +43,10 @@
 #include <pcbnew.h>
 #include <drc_stuff.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
 {
@@ -177,6 +181,10 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
 
     TRACK*  lastNonVia = g_CurrentTrackSegment;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, via, &g_CurrentTrackList );
+#endif
+
     /* A new via was created. It was Ok.
      */
     g_CurrentTrackList.PushBack( via );
@@ -205,12 +213,24 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
 
     g_CurrentTrackList.PushBack( track );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( g_Track_45_Only_Allowed )
+        GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, via, 
+                                      &g_CurrentTrackList, false );
+#endif
+    
     if( g_TwoSegmentTrackBuild )
     {
         // Create a second segment (we must have 2 track segments to adjust)
         g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( !g_Track_45_Only_Allowed )
+        GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, via, 
+                                      &g_CurrentTrackList, false);
+#endif
+    
     m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
     SetMsgPanel( via );
     UpdateStatusBar();
diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp
index bddba8b..fb93a12 100644
--- a/pcbnew/editrack.cpp
+++ b/pcbnew/editrack.cpp
@@ -42,6 +42,11 @@
 #include <class_track.h>
 #include <class_zone.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#include "connect.h"
+#endif
+
 
 static void Abort_Create_Track( EDA_DRAW_PANEL* panel, wxDC* DC );
 void        ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
@@ -63,6 +68,12 @@ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC )
     BOARD* pcb = frame->GetBoard();
     TRACK* track = dyn_cast<TRACK*>( frame->GetCurItem() );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->Teardrops()->RouteCreate_Stop();
+    pcb->TrackItems()->RoundedTracksCorners()->RouteCreate_Stop();
+    pcb->TrackItems()->Edittrack_Clear();
+#endif
+    
     if( track )
     {
         // Erase the current drawing
@@ -116,6 +127,13 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
         if( GetBoard()->IsHighLightNetON() )
             HighLight( aDC );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Teardrops()->RouteCreate_Start();
+        GetBoard()->TrackItems()->RoundedTracksCorners()->RouteCreate_Start();
+        if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+            g_CurrentTrackList.PushBack( new ROUNDEDCORNERTRACK( GetBoard() ) );
+        else
+#endif
         g_CurrentTrackList.PushBack( new TRACK( GetBoard() ) );
         g_CurrentTrackSegment->SetFlags( IS_NEW );
 
@@ -124,6 +142,9 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
         // Search for a starting point of the new track, a track or pad
         lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        VIA* via = nullptr;
+#endif
         D_PAD* pad = NULL;
         if( lockPoint ) // An item (pad or track) is found
         {
@@ -139,7 +160,21 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
             {
                 trackOnStartPoint    = (TRACK*) lockPoint;
                 GetBoard()->SetHighLightNet( trackOnStartPoint->GetNetCode() );
+#ifdef PCBNEW_WITH_TRACKITEMS
+                TRACK* new_track = GetBoard()->CreateLockPoint( pos, trackOnStartPoint, &s_ItemsListPicker );
+                TRACK* isVia = trackOnStartPoint->GetVia( NULL, pos, layerMask );
+                if( dynamic_cast<VIA*>(isVia) )
+                    if( isVia->GetStart() == pos )
+                        via = static_cast<VIA*>(isVia);
+
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Update(trackOnStartPoint, m_canvas, aDC, GR_XOR, true);
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Update(new_track, m_canvas, aDC, GR_XOR, true);
+                
+                if( !g_Track_45_Only_Allowed )
+                    GetBoard()->TrackItems()->Edittrack_Init(trackOnStartPoint, pos);
+#else
                 GetBoard()->CreateLockPoint( pos, trackOnStartPoint, &s_ItemsListPicker );
+#endif
             }
         }
         else
@@ -189,9 +224,29 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
             g_CurrentTrackSegment->start = pad;
         }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( g_Track_45_Only_Allowed )
+        {
+            if( via )
+                GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, via, 
+                                              &g_CurrentTrackList, false );
+            if( pad )
+            {
+                GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, pad, 
+                                              &g_CurrentTrackList, false );
+                g_FirstTrackSegment->start = pad;
+            }
+        }
+#endif
+        
         if( g_TwoSegmentTrackBuild )
         {
             // Create 2nd segment
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+                g_CurrentTrackList.PushBack( (ROUNDEDCORNERTRACK*)g_CurrentTrackSegment->Clone() );
+            else
+#endif
             g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() );
 
             DBG( g_CurrentTrackList.VerifyListIntegrity(); );
@@ -202,6 +257,21 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
             g_FirstTrackSegment->SetState( BEGIN_ONPAD | END_ONPAD, false );
         }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( !g_Track_45_Only_Allowed )
+        {
+            if( via )
+               GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, via, 
+                                             &g_CurrentTrackList, false );
+            if( pad )
+            {
+               GetBoard()->TrackItems()->Teardrops()->Add( g_CurrentTrackSegment, pad, 
+                                             &g_CurrentTrackList, false );
+                g_FirstTrackSegment->start = pad;
+            }
+        }
+#endif
+        
         DBG( g_CurrentTrackList.VerifyListIntegrity(); );
 
         SetMsgPanel( g_CurrentTrackSegment );
@@ -246,6 +316,11 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
           && g_CurrentTrackSegment->Back()->IsNull() )
             CanCreateNewSegment = false;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(!GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn() && 
+            g_TwoSegmentTrackBuild && g_CurrentTrackSegment->IsNull())
+            CanCreateNewSegment = false;
+#endif
         if( CanCreateNewSegment )
         {
             // Erase old track on screen
@@ -255,12 +330,27 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
 
             DBG( g_CurrentTrackList.VerifyListIntegrity(); );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(!GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+#endif
             if( g_Raccord_45_Auto )
                 Add45DegreeSegment( aDC );
 
             TRACK* previousTrack = g_CurrentTrackSegment;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            TRACK* newTrack = nullptr;
+            if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+            {
+                GetBoard()->TrackItems()->RoundedTracksCorners()->DestroyRouteEdit();
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Add(g_CurrentTrackSegment);
+                newTrack = (ROUNDEDCORNERTRACK*)g_CurrentTrackSegment->Clone();
+            }
+            else
+                newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
+#else
             TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone();
+#endif
             g_CurrentTrackList.PushBack( newTrack );
             newTrack->SetFlags( IS_NEW );
 
@@ -289,6 +379,20 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
 
             // Show the new position
             ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( g_Track_45_Only_Allowed && !g_TwoSegmentTrackBuild )
+                if(GetBoard()->TrackItems()->RoundedTracksCorners()->GetEditCorner())
+                    GetBoard()->TrackItems()->RoundedTracksCorners()->GetEditCorner()->Draw(m_canvas, aDC, GR_XOR, wxPoint(0,0));
+                
+            lockPoint = GetBoard()->GetLockPoint( pos, layerMask );
+            if( lockPoint )
+            {
+                End_Route( g_CurrentTrackSegment, aDC );
+                return g_CurrentTrackSegment;
+            }
+            g_Alternate_Track_Posture = !g_Alternate_Track_Posture;
+#endif
         }
     }
 
@@ -334,6 +438,16 @@ bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
 
     // Create a new segment and connect it with the previous 2 segments.
     TRACK* newTrack = (TRACK*)curTrack->Clone();
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+        {
+            if(newTrack && dynamic_cast<ROUNDEDCORNERTRACK*>(curTrack))
+            {
+                delete newTrack;
+                newTrack = (ROUNDEDCORNERTRACK*)curTrack->Clone();
+            }
+        }
+#endif
 
     newTrack->SetStart( prevTrack->GetEnd() );
     newTrack->SetEnd( curTrack->GetStart() );
@@ -416,6 +530,18 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
 {
     LSET layerMask( GetScreen()->m_Active_Layer );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+    {
+        if(GetBoard()->TrackItems()->RoundedTracksCorners()->GetEditCorner())
+            GetBoard()->TrackItems()->RoundedTracksCorners()->DestroyRouteEdit();
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Add(g_CurrentTrackSegment);
+    }
+    GetBoard()->TrackItems()->Teardrops()->RouteCreate_Stop();
+    GetBoard()->TrackItems()->RoundedTracksCorners()->RouteCreate_Stop();
+    GetBoard()->TrackItems()->Edittrack_Clear();
+#endif
+
     if( aTrack == NULL )
         return false;
 
@@ -427,8 +553,13 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
 
     DBG( g_CurrentTrackList.VerifyListIntegrity(); );
 
+#ifndef PCBNEW_WITH_TRACKITEMS
     if( Begin_Route( aTrack, aDC ) == NULL )
         return false;
+#else
+    TRACK* beginning_current_trackseg = g_CurrentTrackSegment;
+    wxPoint beginning_current_trackseg_end = g_CurrentTrackSegment->GetEnd();
+#endif
 
     ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, true );
     ShowNewTrackWhenMovingCursor( m_canvas, aDC, wxDefaultPosition, false );
@@ -458,14 +589,40 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
         if( lockPoint->Type() ==  PCB_PAD_T )     // End of track is on a pad.
         {
             EnsureEndTrackOnPad( (D_PAD*) lockPoint );
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(beginning_current_trackseg_end != g_CurrentTrackSegment->GetEnd())
+            {
+                if(beginning_current_trackseg != g_CurrentTrackSegment)
+                {
+                    beginning_current_trackseg->Back()->SetEnd(static_cast<D_PAD*>(lockPoint)->GetPosition());
+                    beginning_current_trackseg->SetStart(static_cast<D_PAD*>(lockPoint)->GetPosition());
+                    beginning_current_trackseg->SetEnd(static_cast<D_PAD*>(lockPoint)->GetPosition());
+                    g_CurrentTrackSegment->SetStart(static_cast<D_PAD*>(lockPoint)->GetPosition());
+                    g_CurrentTrackSegment->SetEnd(static_cast<D_PAD*>(lockPoint)->GetPosition());
+                }
+                else
+                {
+                    g_CurrentTrackSegment->Back()->SetEnd(g_CurrentTrackSegment->GetEnd());
+                    g_CurrentTrackSegment->SetStart(g_CurrentTrackSegment->GetEnd());
+                }
+            }
+#endif
         }
         else        // If end point of is on a different track,
                     // creates a lock point if not exists
         {
              // Creates a lock point, if not already exists:
             wxPoint hp = g_CurrentTrackSegment->GetEnd();
+#ifdef PCBNEW_WITH_TRACKITEMS
+            TRACK* n_tr = GetBoard()->CreateLockPoint( hp, (TRACK*) lockPoint, &s_ItemsListPicker );
+            
+            GetBoard()->TrackItems()->RoundedTracksCorners()->Update(static_cast<TRACK*>(lockPoint), m_canvas, aDC, GR_XOR, true);
+            GetBoard()->TrackItems()->RoundedTracksCorners()->Update(n_tr, m_canvas, aDC, GR_XOR, true);
+#else
             lockPoint = GetBoard()->CreateLockPoint( hp, (TRACK*) lockPoint, &s_ItemsListPicker );
+#endif
             g_CurrentTrackSegment->SetEnd(hp);
+            
         }
     }
 
@@ -480,6 +637,14 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
         TRACK* firstTrack = g_FirstTrackSegment;
         int    newCount   = g_CurrentTrackList.GetCount();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Teardrops()->Remove( netcode, TEARDROPS::ALL_TYPES_T, 
+                                         &s_ItemsListPicker, true );
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( netcode, &s_ItemsListPicker, true );
+        std::set<TRACK*> added_tracksegs;
+        added_tracksegs.clear();
+#endif
+
         // Put entire new current segment list in BOARD, and prepare undo command
         TRACK* track;
         TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( GetBoard() );
@@ -489,6 +654,10 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
             ITEM_PICKER picker( track, UR_NEW );
             s_ItemsListPicker.PushItem( picker );
             GetBoard()->m_Track.Insert( track, insertBeforeMe );
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(track->Type() == PCB_TRACE_T)
+                added_tracksegs.insert(track);
+#endif
         }
 
         TraceAirWiresToTargets( aDC );
@@ -507,6 +676,20 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
             EraseRedundantTrack( aDC, firstTrack, newCount, &s_ItemsListPicker );
         }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Teardrops()->Recreate( netcode, &s_ItemsListPicker );
+        if(firstTrack->Type() == PCB_VIA_T)
+            GetBoard()->TrackItems()->Teardrops()->Add( static_cast<VIA*>(firstTrack), &s_ItemsListPicker );
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Recreate( netcode, &s_ItemsListPicker );
+        for(auto tr : added_tracksegs)
+        {
+            tr->start = nullptr;
+            tr->end = nullptr;
+            if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+                GetBoard()->TrackItems()->RoundedTracksCorners()->Add(tr, &s_ItemsListPicker);
+            GetBoard()->TrackItems()->Teardrops()->Add(tr, &s_ItemsListPicker );
+        }
+#endif
         SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
         s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
 
@@ -516,6 +699,24 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
         SetMsgPanel( GetBoard() );
 
         // Redraw the entire new track.
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(GetBoard()->TrackItems()->RoundedTracksCorners()->IsOn())
+        {
+            GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+            for( auto tr : added_tracksegs )
+                if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+                    GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+            GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListDo( m_canvas, aDC, GR_OR, false );
+            GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( m_canvas, aDC, GR_XOR );
+            GetBoard()->TrackItems()->Teardrops()->UpdateListClear();
+            GetBoard()->TrackItems()->Teardrops()->UpdateListAdd( GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+            GetBoard()->TrackItems()->Teardrops()->UpdateListDo( m_canvas, aDC, GR_OR, false );
+            m_canvas->Refresh();
+        }
+        else
+#endif
+
         DrawTraces( m_canvas, aDC, firstTrack, newCount, GR_OR );
     }
 
@@ -698,8 +899,22 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
 
 #ifndef USE_WX_OVERLAY
     // Erase old track
+#ifdef PCBNEW_WITH_TRACKITEMS
+    BOARD* pcb = frame->GetBoard();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    int tcount = g_CurrentTrackList.GetCount();
+    for( TRACK* tr = g_CurrentTrackList; tcount > 0 && tr; tcount--, tr = tr->Next() )
+    {
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+    }
+#endif
     if( aErase )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, GR_XOR );
+        if(!pcb->TrackItems()->RoundedTracksCorners()->IsOn())
+#endif
         DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
 
         frame->TraceAirWiresToTargets( aDC );
@@ -710,6 +925,13 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
             DrawViaCirclesWhenEditingNewTrack( panelClipBox, aDC, g_CurrentTrackSegment->GetEnd(),
                                                boardViaRadius, viaRadiusWithClearence, color);
         }
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( !g_Track_45_Only_Allowed )
+            pcb->TrackItems()->Angles( g_CurrentTrackSegment, 
+                                                               g_CurrentTrackSegment->GetEnd(), 
+                                                               aPanel, aDC );
+#endif
     }
 #endif
     // MacOSX seems to need this.
@@ -766,6 +988,40 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
 
     // Redraw the new track
     DBG( g_CurrentTrackList.VerifyListIntegrity(); );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( !g_Track_45_Only_Allowed )
+        pcb->TrackItems()->Angles( g_CurrentTrackSegment, 
+                                                           g_CurrentTrackSegment->GetEnd(), 
+                                                           aPanel, aDC );
+    TrackNodeItem::ROUNDEDTRACKSCORNER* arc_cor = nullptr;
+    if(pcb->TrackItems()->RoundedTracksCorners()->IsOn())
+    {
+        arc_cor = pcb->TrackItems()->RoundedTracksCorners()->UpdateRouteEdit( aPanel, aDC,
+                                                        g_CurrentTrackSegment,
+                                                        g_CurrentTrackSegment->Back(), aErase,
+                                                        &g_Track_45_Only_Allowed );
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+        tcount = g_CurrentTrackList.GetCount();
+        for( TRACK* tr = g_CurrentTrackList; tcount > 0 && tr; tcount--, tr = tr->Next() )
+            if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+                pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo( aPanel, aDC, GR_XOR, aErase );
+        pcb->TrackItems()->RoundedTracksCorners()->Update( static_cast<TRACK*>(arc_cor));
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, GR_XOR );
+        pcb->TrackItems()->Teardrops()->UpdateListClear();
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+        pcb->TrackItems()->Teardrops()->UpdateListDo( aPanel, aDC, GR_XOR, aErase );       
+    }
+    else
+        pcb->TrackItems()->Teardrops()->Update(g_CurrentTrackSegment->Back());
+    pcb->TrackItems()->Teardrops()->UpdateRouteEdit( aPanel, aDC,
+                                                    g_CurrentTrackSegment,
+                                                    boardViaRadius, aErase,
+                                                    &g_Track_45_Only_Allowed );
+    if(!pcb->TrackItems()->RoundedTracksCorners()->IsOn())
+#endif
+
     DrawTraces( aPanel, aDC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_XOR );
 
     if( showTrackClearanceMode >= SHOW_CLEARANCE_NEW_TRACKS_AND_VIA_AREAS )
@@ -806,7 +1062,20 @@ void ShowNewTrackWhenMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPo
 
     // calculate track len on board:
     for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() )
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+            trackLen += dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetLengthVisible();
+        else
+            if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track))
+                trackLen += dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track)->GetLengthVisible();
+            else
+                trackLen += track->GetLength(); //TEARDROPS too. Always 0.
+        
+    if(arc_cor)
+        trackLen += arc_cor->GetLengthVisible();
+#else
         trackLen += track->GetLength();
+#endif
 
     msg = frame->LengthDoubleToString( trackLen );
     frame->AppendMsgPanel( _( "Track Len" ), msg, DARKCYAN );
@@ -1024,6 +1293,11 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList )
         if( firsttrack == oldtrack )
             firsttrack = track;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Teardrops()->Remove( oldtrack, false, true ); 
+        pcb->TrackItems()->RoundedTracksCorners()->Remove( oldtrack, false, true ); 
+#endif
+
         delete aTrackList.Remove( oldtrack );
     }
 
diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp
index b6a1583..ed828cc 100644
--- a/pcbnew/files.cpp
+++ b/pcbnew/files.cpp
@@ -55,6 +55,9 @@
 
 #include <wx/stdpaths.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
 
 //#define     USE_INSTRUMENTATION     1
 #define     USE_INSTRUMENTATION     0
@@ -529,6 +532,9 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
         }
 
         SetBoard( loadedBoard );
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->SetEditFrame( this, m_TrackItemsMenu );
+#endif
 
         // we should not ask PLUGINs to do these items:
         loadedBoard->BuildListOfNets();
diff --git a/pcbnew/hotkeys.cpp b/pcbnew/hotkeys.cpp
index 2fa1fa5..2e5390c 100644
--- a/pcbnew/hotkeys.cpp
+++ b/pcbnew/hotkeys.cpp
@@ -226,6 +226,8 @@ static EDA_HOTKEY HkTrackDisplayMode( _HKI( "Track Display Mode" ),
                                       HK_SWITCH_TRACK_DISPLAY_MODE, 'K' );
 static EDA_HOTKEY HkAddModule( _HKI( "Add Footprint" ), HK_ADD_MODULE, 'O' );
 
+static EDA_HOTKEY HkGotoNextMarker( _HKI( "Goto Next Marker" ), HK_GOTO_NEXT_MARKER, 'G' + GR_KB_CTRL );
+
 // List of common hotkey descriptors
 EDA_HOTKEY* common_Hotkey_List[] =
 {
@@ -277,6 +279,7 @@ EDA_HOTKEY* board_edit_Hotkey_List[] =
     &HkSwitchHighContrastMode,
     &HkCanvasDefault,          &HkCanvasCairo,               &HkCanvasOpenGL,
     &HkZoneFillOrRefill,       &HkZoneRemoveFilled,
+    &HkGotoNextMarker,
     NULL
 };
 
diff --git a/pcbnew/hotkeys.h b/pcbnew/hotkeys.h
index f4f3ff1..db7f35b 100644
--- a/pcbnew/hotkeys.h
+++ b/pcbnew/hotkeys.h
@@ -67,6 +67,7 @@ enum hotkey_id_commnand {
     HK_DUPLICATE_ITEM_AND_INCREMENT,
     HK_CREATE_ARRAY,
     HK_PLACE_ITEM,
+    HK_GOTO_NEXT_MARKER,
     HK_SWITCH_TRACK_WIDTH_TO_NEXT,
     HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS,
     HK_SWITCH_GRID_TO_FASTGRID1,
diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp
index 516388d..9473f4f 100644
--- a/pcbnew/hotkeys_board_editor.cpp
+++ b/pcbnew/hotkeys_board_editor.cpp
@@ -372,9 +372,19 @@ bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
 
         if( !itemCurrentlyEdited ) // no track in progress: switch layer only
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //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;
+            }
+#else
             Other_Layer_Route( NULL, aDC );
             if( displ_opts->m_ContrastModeDisplay )
                 m_canvas->Refresh();
+#endif
             break;
         }
 
@@ -395,7 +405,20 @@ bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosit
     case HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA:
         if( GetCurItem() == NULL || !GetCurItem()->IsNew() ||
             GetCurItem()->Type() != PCB_TRACE_T )
+#ifdef PCBNEW_WITH_TRACKITEMS
+        {
+            //Add thermal via with selecting layer(s)(net).
+            if( GetToolId() == ID_TRACK_BUTT )
+            {
+                evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
+                    ID_POPUP_PCB_SEL_LAYERS_AND_PLACE_ZONE_BLIND_BURIED_VIA : 
+                    ID_POPUP_PCB_SEL_LAYER_AND_PLACE_ZONE_THROUGH_VIA;
+
+                break;
+            }
             break;
+        }
+#endif
 
         evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ?
             ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA :
@@ -502,6 +525,13 @@ 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;
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case HK_GOTO_NEXT_MARKER:
+        evt_type = ID_POPUP_PCB_GOTO_NEXT_MARKER;
+        break;
+#endif
+
     }
 
     if( evt_type != 0 )
@@ -1074,11 +1104,19 @@ bool PCB_EDIT_FRAME::OnHotkeyDuplicateOrArrayItem( int aIdCommand )
     case PCB_ZONE_AREA_T:
     case PCB_TARGET_T:
     case PCB_DIMENSION_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_VIA_T:
+#endif
         switch( aIdCommand )
         {
         case HK_CREATE_ARRAY:
             if( canDuplicate )
                 evt_type = ID_POPUP_PCB_CREATE_ARRAY;
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if( canDuplicate )
+                if(item->Type() == PCB_VIA_T)
+                    evt_type = ID_POPUP_PCB_CREATE_VIA_ARRAY;
+#endif
             break;
 
         case HK_DUPLICATE_ITEM_AND_INCREMENT:
diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp
index 11fe793..39a5d96 100644
--- a/pcbnew/initpcb.cpp
+++ b/pcbnew/initpcb.cpp
@@ -35,6 +35,10 @@
 #include <pcbnew.h>
 #include <module_editor_frame.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
 {
@@ -60,6 +64,9 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery )
     // delete the old BOARD and create a new BOARD so that the default
     // layer names are put into the BOARD.
     SetBoard( new BOARD() );
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->SetEditFrame( this, m_TrackItemsMenu );
+#endif
     SetElementVisibility( LAYER_GRID, showGrid );
     SetElementVisibility( LAYER_RATSNEST, showRats );
 
diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp
index 252ee30..f96c671 100644
--- a/pcbnew/kicad_plugin.cpp
+++ b/pcbnew/kicad_plugin.cpp
@@ -50,6 +50,10 @@
 #include <boost/ptr_container/ptr_map.hpp>
 #include <memory.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 using namespace PCB_KEYS_T;
 
 #define FMTIU        BOARD_ITEM::FormatInternalUnits
@@ -506,6 +510,12 @@ void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
         format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel );
         break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+    case PCB_ROUNDEDTRACKSCORNER_T:
+        break;
+#endif
+
     default:
         wxFAIL_MSG( wxT( "Cannot format item " ) + aItem->GetClass() );
     }
@@ -780,6 +790,11 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
     // Save the polygon (which are the newer technology) zones.
     for( int i = 0; i < aBoard->GetAreaCount();  ++i )
         Format( aBoard->GetArea( i ), aNestLevel );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    aBoard->TrackItems()->RoundedTracksCorners()->Format( m_out, aNestLevel ); 
+    aBoard->TrackItems()->Teardrops()->Format( m_out, aNestLevel ); 
+#endif
 }
 
 
@@ -1481,6 +1496,11 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
             THROW_IO_ERROR( wxString::Format( _( "unknown via type %d"  ), via->GetViaType() ) );
         }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( via->GetThermalCode() )
+            m_out->Print( 0, " thermal" );
+#endif
+
         m_out->Print( 0, " (at %s) (size %s)",
                       FMT_IU( aTrack->GetStart() ).c_str(),
                       FMT_IU( aTrack->GetWidth() ).c_str() );
diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp
index b966a2a..cb3609e 100644
--- a/pcbnew/menubar_pcbframe.cpp
+++ b/pcbnew/menubar_pcbframe.cpp
@@ -40,6 +40,10 @@
 #include "pcbnew.h"
 #include "pcbnew_id.h"
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 // Build the place submenu
 static void preparePlaceMenu( wxMenu* aParentMenu );
@@ -174,6 +178,17 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     RebuildActionPluginMenus();
 #endif
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( m_TrackItemsMenu )
+    {
+        delete m_TrackItemsMenu;
+        m_TrackItemsMenu = nullptr;
+    }
+    m_TrackItemsMenu = new wxMenu;
+    AddMenuItem( toolsMenu, m_TrackItemsMenu, ID_POPUP_PCB_TRACKITEMS_COMMON_MNU, 
+                 TRACKITEMS::TXT_TRACKITEMS, KiBitmap( add_tracks_xpm ) );    
+#endif
+
 }
 
 // Build the design rules menu
diff --git a/pcbnew/modules.cpp b/pcbnew/modules.cpp
index fc09aa6..574c01c 100644
--- a/pcbnew/modules.cpp
+++ b/pcbnew/modules.cpp
@@ -43,6 +43,10 @@
 #include <drag.h>
 #include <dialog_get_footprint_by_name.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 static void MoveFootprint( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
                            const wxPoint& aPosition, bool aErase );
 static void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC );
@@ -139,6 +143,10 @@ void PCB_EDIT_FRAME::StartMoveModule( MODULE* aModule, wxDC* aDC,
 
         UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
     }
+#ifdef PCBNEW_WITH_TRACKITEMS
+    else
+        GetBoard()->TrackItems()->Teardrops()->Remove( aModule, &s_PickedList, true );
+#endif
 
     GetBoard()->m_Status_Pcb |= DO_NOT_SHOW_GENERAL_RASTNEST;
     m_canvas->SetMouseCapture( MoveFootprint, Abort_MoveOrCopyModule );
@@ -189,6 +197,9 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
                 pt_segm->Draw( Panel, DC, GR_OR );
             }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            pcbframe->GetBoard()->TrackItems()->Teardrops()->Update( module, Panel, DC, GR_XOR, true );
+#endif
             EraseDragList();
             module->ClearFlags( IS_MOVED );
         }
@@ -212,6 +223,10 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
             pcbframe->Change_Side_Module( module, NULL );
 
         module->Draw( Panel, DC, GR_OR );
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( !g_DragSegmentList.size() )
+            pcbframe->GetBoard()->TrackItems()->Teardrops()->Recreate( module, false );
+#endif
     }
 
     pcbframe->SetCurItem( NULL );
@@ -226,9 +241,13 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
     if( pcbframe->GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
         pcbframe->DrawGeneralRatsnest( DC );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    Panel->Refresh();
+#else
 #ifdef __WXMAC__
     Panel->Refresh();
 #endif
+#endif
 }
 
 
@@ -252,6 +271,14 @@ void MoveFootprint( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
     module->DrawOutlinesWhenMoving( aPanel, aDC, g_Offset_Module );
 
     DrawSegmentWhileMovingFootprint( aPanel, aDC );
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( g_DragSegmentList.size() )
+    {
+        PCB_EDIT_FRAME* edit_frame = static_cast<PCB_EDIT_FRAME*>( aPanel->GetParent() );
+        edit_frame->GetBoard()->TrackItems()->Teardrops()->Update( module, aPanel, aDC, GR_XOR, true );
+    }
+#endif
 }
 
 
@@ -264,10 +291,23 @@ bool PCB_EDIT_FRAME::Delete_Module( MODULE* aModule, wxDC* aDC )
 
     SetMsgPanel( aModule );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Delete teardrops from module 
+    PICKED_ITEMS_LIST pickedItems;
+    ITEM_PICKER       picker( NULL, UR_DELETED );
+    GetBoard()->TrackItems()->Teardrops()->Remove( aModule, &pickedItems, true );
+#endif
+
     /* Remove module from list, and put it in undo command list */
     m_Pcb->m_Modules.Remove( aModule );
     aModule->SetState( IS_DELETED, true );
+#ifdef PCBNEW_WITH_TRACKITEMS
+    picker.SetItem( aModule );
+    pickedItems.PushItem( picker );
+    SaveCopyInUndoList( pickedItems, UR_DELETED );
+#else
     SaveCopyInUndoList( aModule, UR_DELETED );
+#endif
 
     if( aDC && GetBoard()->IsElementVisible( LAYER_RATSNEST ) )
         Compile_Ratsnest( aDC, true );
@@ -405,6 +445,11 @@ void PCB_BASE_FRAME::PlaceModule( MODULE* aModule, wxDC* aDC, bool aDoNotRecreat
             track->Draw( m_canvas, aDC, GR_OR );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( g_DragSegmentList.size() )
+        GetBoard()->TrackItems()->Teardrops()->Update( aModule, m_canvas, aDC, GR_XOR, true );
+#endif
+
     // Delete drag list
     EraseDragList();
 
diff --git a/pcbnew/move-drag_pads.cpp b/pcbnew/move-drag_pads.cpp
index e52ad9f..855ec3b 100644
--- a/pcbnew/move-drag_pads.cpp
+++ b/pcbnew/move-drag_pads.cpp
@@ -19,6 +19,11 @@
 #include <pcbnew.h>
 #include <drag.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+static PICKED_ITEMS_LIST pick_list;
+#endif
+
 
 static D_PAD*  s_CurrentSelectedPad;
 static wxPoint Pad_OldPos;
@@ -40,6 +45,19 @@ static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC )
     pad->SetPosition( Pad_OldPos );
     pad->Draw( Panel, DC, GR_XOR );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    PCB_EDIT_FRAME* edit_frame = static_cast<PCB_EDIT_FRAME*>( Panel->GetParent() );
+    BOARD* pcb = edit_frame->GetBoard();
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ )
+    {
+        TRACK* tr = g_DragSegmentList[jj].m_Track;
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+    }
+#endif
+    
     // Pad move in progress: restore origin of dragged tracks, if any.
     for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
     {
@@ -49,7 +67,18 @@ static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC )
         track->ClearFlags();
         g_DragSegmentList[ii].RestoreInitialValues();
         track->Draw( Panel, DC, GR_OR );
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Teardrops()->UpdateListAdd(track);
+#endif
     }
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( !g_DragSegmentList.size() )
+        pcb->TrackItems()->Teardrops()->Recreate( pad, false );
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo();       
+    Panel->Refresh();
+#endif
 
     EraseDragList();
     s_CurrentSelectedPad = NULL;
@@ -73,17 +102,43 @@ static void Show_Pad_Move( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPo
     pad->SetPosition( aPanel->GetParent()->GetCrossHairPosition() );
     pad->Draw( aPanel, aDC, GR_XOR );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    BOARD * pcb = static_cast<PCB_EDIT_FRAME*>(aPanel->GetParent())->GetBoard();
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+    {
+        TRACK* tr = g_DragSegmentList[ii].m_Track;
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+    }
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, GR_XOR );
+#endif
+
     for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
     {
         Track = g_DragSegmentList[ii].m_Track;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( !dynamic_cast<ROUNDEDCORNERTRACK*>(Track) )
+#endif
         if( aErase )
             Track->Draw( aPanel, aDC, GR_XOR );
 
         g_DragSegmentList[ii].SetTrackEndsCoordinates( wxPoint(0, 0) );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( Track );
+        if( !dynamic_cast<ROUNDEDCORNERTRACK*>(Track) )
+#endif
         Track->Draw( aPanel, aDC, GR_XOR );
     }
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo( aPanel, aDC, GR_XOR, true );
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, GR_XOR );
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo( aPanel, aDC, GR_XOR, true );       
+#endif
 }
 
 
@@ -107,13 +162,34 @@ void PCB_BASE_FRAME::StartMovePad( D_PAD* aPad, wxDC* aDC, bool aDragConnectedTr
 
     EraseDragList();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pick_list.ClearItemsList();
+#endif
+ 
     // Build the list of track segments to drag if the command is a drag pad
     if( aDragConnectedTracks )
     {
         DRAG_LIST drglist( GetBoard() );
         drglist.BuildDragListe( aPad );
+        
+#ifdef PCBNEW_WITH_TRACKITEMS
+        ITEM_PICKER itemWrapper( NULL, UR_CHANGED );
+        for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+        {
+            TRACK* segm = g_DragSegmentList[ii].m_Track;
+            itemWrapper.SetItem( segm );
+            itemWrapper.SetLink( segm->Clone() );
+            itemWrapper.GetLink()->SetState( IN_EDIT, false );
+            pick_list.PushItem( itemWrapper );
+        }
+#endif
+
         UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
     }
+#ifdef PCBNEW_WITH_TRACKITEMS
+    else
+        GetBoard()->TrackItems()->Teardrops()->Remove( aPad, false, true );
+#endif
 }
 
 
@@ -129,6 +205,8 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
     MODULE* module = aPad->GetParent();
 
     ITEM_PICKER       picker( NULL, UR_CHANGED );
+
+#ifndef PCBNEW_WITH_TRACKITEMS
     PICKED_ITEMS_LIST pickList;
 
     // Save dragged track segments in undo list
@@ -146,6 +224,7 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
         picker.SetItem( track );
         pickList.PushItem( picker );
     }
+#endif
 
     // Save old module and old items values
     aPad->ClearFlags();
@@ -154,6 +233,15 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
     aPad->SetPosition( Pad_OldPos );
 
     if( g_DragSegmentList.size() == 0 )
+#ifdef PCBNEW_WITH_TRACKITEMS
+    {
+        GetBoard()->TrackItems()->Teardrops()->Recreate( aPad, false );
+        GetBoard()->TrackItems()->Teardrops()->Remove( aPad, &pick_list, true );
+    }
+    picker.SetItem( module );
+    pick_list.PushItem( picker );
+    SaveCopyInUndoList( pick_list, UR_CHANGED );
+#else
         SaveCopyInUndoList( module, UR_CHANGED );
     else
     {
@@ -161,6 +249,7 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
         pickList.PushItem( picker );
         SaveCopyInUndoList( pickList, UR_CHANGED );
     }
+#endif
 
     aPad->SetPosition( pad_curr_position );
     aPad->Draw( m_canvas, DC, GR_XOR );
@@ -170,6 +259,9 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
     {
         track = g_DragSegmentList[ii].m_Track;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        g_DragSegmentList[ii].SetTrackEndsCoordinates( wxPoint(0, 0) );
+#else
         // Set the new state
         if( g_DragSegmentList[ii].m_Pad_Start )
             track->SetStart( aPad->GetPosition() );
@@ -182,6 +274,7 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
 
         track->SetState( IN_EDIT, false );
         track->ClearFlags();
+#endif
 
         if( DC )
             track->Draw( m_canvas, DC, GR_OR );
@@ -199,6 +292,11 @@ void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
     if( DC )
         aPad->Draw( m_canvas, DC, GR_OR );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->Update( aPad, m_canvas, DC, GR_XOR, true );
+    m_canvas->Refresh();
+#endif
+
     module->CalculateBoundingBox();
     module->SetLastEditTime();
 
diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp
index b381e3c..039b354 100644
--- a/pcbnew/move_or_drag_track.cpp
+++ b/pcbnew/move_or_drag_track.cpp
@@ -44,6 +44,10 @@
 #include <drag.h>
 #include <pcbnew_id.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                            bool aErase );
@@ -83,6 +87,17 @@ static void Abort_MoveTrack( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
     frame->SetCurItem( NULL );
     aPanel->SetMouseCapture( NULL, NULL );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ )
+    {
+        TRACK* tr = g_DragSegmentList[jj].m_Track;
+        if( dynamic_cast<ROUNDEDCORNERTRACK*>( tr ) )
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tr );
+    }
+#endif
+
     // Undo move and redraw trace segments.
     for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ )
     {
@@ -90,8 +105,17 @@ static void Abort_MoveTrack( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
         g_DragSegmentList[jj].RestoreInitialValues();
         track->SetState( IN_EDIT, false );
         track->ClearFlags();
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( track );
+#endif
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo();       
+#endif
+
     // Clear the undo picker list:
     s_ItemsListPicker.ClearListAndDeleteItems();
     EraseDragList();
@@ -120,7 +144,21 @@ static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPo
     wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition();
 
     moveVector = Pos - s_LastPos;
+#ifdef PCBNEW_WITH_TRACKITEMS
+    BOARD * pcb = static_cast<PCB_EDIT_FRAME*>(aPanel->GetParent())->GetBoard();
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
+    {
+        TRACK* tr = g_DragSegmentList[ii].m_Track;
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tr))
+            pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd(tr);
+    }
+    if( aErase )
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, draw_mode );
+#else
     s_LastPos  = Pos;
+#endif
 
     TRACK *track = NULL;
 
@@ -129,7 +167,13 @@ static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPo
         track = g_DragSegmentList[ii].m_Track;
 
         if( aErase )
+        {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            pcb->TrackItems()->Angles( track, s_LastPos, aPanel, aDC );
+            if( !dynamic_cast<ROUNDEDCORNERTRACK*>(track) )
+#endif
             track->Draw( aPanel, aDC, draw_mode );
+        }
 
         if( track->GetFlags() & STARTPOINT )
             track->SetStart( track->GetStart() + moveVector );
@@ -139,9 +183,24 @@ static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPo
 
         if( track->Type() == PCB_VIA_T )
             track->SetEnd( track->GetStart() );
-
+#ifdef PCBNEW_WITH_TRACKITEMS
+        pcb->TrackItems()->Angles( track, Pos, aPanel, aDC );
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( track );
+        
+        if( !dynamic_cast<ROUNDEDCORNERTRACK*>(track) )
+#endif
         track->Draw( aPanel, aDC, draw_mode );
     }
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->Angles( &g_DragSegmentList, Pos, aPanel, aDC );
+    pcb->TrackItems()->Target( &g_DragSegmentList, Pos, aPanel, aDC );
+    
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo( aPanel, aDC, draw_mode, aErase );
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateList_DrawTracks( aPanel, aDC, draw_mode );
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo( aPanel, aDC, draw_mode, aErase );       
+    s_LastPos  = Pos;
+#endif
 
     displ_opts->m_DisplayPcbTrackFill = tmp;
 
@@ -214,6 +273,16 @@ static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC
      * the segment connected to its start point (if exists)
      */
     int ii = g_DragSegmentList.size() - 1;
+#ifdef PCBNEW_WITH_TRACKITEMS
+    ii = 0;
+    for(auto pitr : g_DragSegmentList)
+    {
+        if(pitr.m_Track->Type() != PCB_TRACE_T)
+            break;
+        ++ii;
+    }
+    --ii;
+#endif
     Track = g_DragSegmentList[ii].m_Track;
 
     if( Track == NULL )
@@ -240,6 +309,12 @@ static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC
 
     GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)aPanel->GetDisplayOptions();
+    int cur_displOpt_trackFill = displ_opts->m_DisplayPcbTrackFill;
+    displ_opts->m_DisplayPcbTrackFill = false;
+#endif
+
     // Undraw the current moved track segments before modification
 
 #ifndef USE_WX_OVERLAY
@@ -380,6 +455,7 @@ static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC
         }
     }
 
+#ifndef PCBNEW_WITH_TRACKITEMS
     Track->Draw( aPanel, aDC, draw_mode );
 
     if( tSegmentToStart )
@@ -387,9 +463,68 @@ static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC
 
     if( tSegmentToEnd )
         tSegmentToEnd->Draw( aPanel, aDC, draw_mode );
+#endif
 
     // Display track length
     PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent();
+    
+#ifdef PCBNEW_WITH_TRACKITEMS
+    ROUNDEDCORNERTRACK* r_track_start = nullptr;
+    ROUNDEDCORNERTRACK* r_track_end = nullptr;
+    ROUNDEDCORNERTRACK* r_track = nullptr;
+
+    if(dynamic_cast<ROUNDEDCORNERTRACK*>(Track))
+        r_track = static_cast<ROUNDEDCORNERTRACK*>(Track);
+    else
+        Track->Draw( aPanel, aDC, draw_mode );
+
+    if( tSegmentToStart )
+    {
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tSegmentToStart))
+            r_track_start = static_cast<ROUNDEDCORNERTRACK*>(tSegmentToStart);
+        else
+            tSegmentToStart->Draw( aPanel, aDC, draw_mode );
+    }
+
+    if( tSegmentToEnd )
+    {
+        if(dynamic_cast<ROUNDEDCORNERTRACK*>(tSegmentToEnd))
+            r_track_end = static_cast<ROUNDEDCORNERTRACK*>(tSegmentToEnd);
+        else
+            tSegmentToEnd->Draw( aPanel, aDC, draw_mode );
+    }
+
+    BOARD* pcb = frame->GetBoard();
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( Track );
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( Track );
+
+    if( tSegmentToStart )
+    {
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( tSegmentToStart );
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tSegmentToStart );
+    }
+
+    if( tSegmentToEnd )
+    {
+        pcb->TrackItems()->Teardrops()->UpdateListAdd( tSegmentToEnd );
+        pcb->TrackItems()->RoundedTracksCorners()->UpdateListAdd( tSegmentToEnd );
+    }
+
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo( aPanel, aDC, draw_mode, aErase );
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( pcb->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo( aPanel, aDC, draw_mode, aErase );       
+    
+    if(r_track)
+        r_track->Draw( aPanel, aDC, draw_mode );
+    if(r_track_start)
+        r_track_start->Draw( aPanel, aDC, draw_mode );
+    if(r_track_end)
+        r_track_end->Draw( aPanel, aDC, draw_mode );
+
+    displ_opts->m_DisplayPcbTrackFill = cur_displOpt_trackFill;
+#endif
     frame->SetMsgPanel( Track );
 }
 
@@ -415,6 +550,16 @@ bool InitialiseDragParameters()
      * the segment connected to its start point (if exists)
      */
     int ii = g_DragSegmentList.size() - 1;
+#ifdef PCBNEW_WITH_TRACKITEMS
+    ii = 0;
+    for(auto pitr : g_DragSegmentList)
+    {
+        if(pitr.m_Track->Type() != PCB_TRACE_T)
+            break;
+        ++ii;
+    }
+    --ii;
+#endif
     Track = g_DragSegmentList[ii].m_Track;
     if( Track == NULL )
         return false;
@@ -595,9 +740,15 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
 
         if( aCommand != ID_POPUP_PCB_MOVE_TRACK_SEGMENT )
         {
+#ifdef PCBNEW_WITH_TRACKITEMS
+            Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(),
+                                         aTrack->GetLayerSet(),
+                                         aTrack->GetNetCode(), 0 );
+#else
             Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(),
                                          aTrack->GetLayerSet(),
                                          aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+#endif
         }
 
         PosInit = aTrack->GetStart();
@@ -626,8 +777,13 @@ void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aC
 
         case ID_POPUP_PCB_MOVE_TRACK_NODE:  // Drag via or move node
             pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd();
+#ifdef PCBNEW_WITH_TRACKITEMS
+            Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(),
+                                         aTrack->GetNetCode(), 0);
+#else
             Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(),
                                          aTrack->GetNetCode(), aTrack->GetWidth() / 2 );
+#endif
             PosInit = pos;
             break;
         }
@@ -681,14 +837,33 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC*  DC
     if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) )
         TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Eliminate Junction.
+    TrackToStartPoint = GetBoard()->TrackItems()->DragKeepSlopeSegmentTypeCheck( TrackToStartPoint, 
+                                                                                track, 
+                                                                                GetBoard()->m_Track,
+                                                                                ENDPOINT_START );
+#endif
+
     //  Test if more than one segment is connected to this point
     if( TrackToStartPoint )
     {
         TrackToStartPoint->SetState( BUSY, true );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( ( TrackToStartPoint->Type() == PCB_VIA_T ) )
+            error = true;
+        //Eliminate track node items on track error check.
+        error = GetBoard()->TrackItems()->DragKeepSlopeSegmentsNumCheck( error, 
+                                                                        TrackToStartPoint, 
+                                                                        track, 
+                                                                        GetBoard()->m_Track, 
+                                                                        ENDPOINT_START );
+#else
         if( ( TrackToStartPoint->Type() == PCB_VIA_T )
            || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false ) )
             error = true;
+#endif
 
         TrackToStartPoint->SetState( BUSY, false );
     }
@@ -696,14 +871,33 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC*  DC
     if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) )
         TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Eliminate Junction.
+    TrackToEndPoint = GetBoard()->TrackItems()->DragKeepSlopeSegmentTypeCheck( TrackToEndPoint,
+                                                                              track,
+                                                                              GetBoard()->m_Track,
+                                                                              ENDPOINT_END );
+#endif
+
     //  Test if more than one segment is connected to this point
     if( TrackToEndPoint )
     {
         TrackToEndPoint->SetState( BUSY, true );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( (TrackToEndPoint->Type() == PCB_VIA_T) )
+            error = true;
+        // Eliminate track node items on track error check.
+        error = GetBoard()->TrackItems()->DragKeepSlopeSegmentsNumCheck( error,
+                                                                        TrackToEndPoint,
+                                                                        track, 
+                                                                        GetBoard()->m_Track, 
+                                                                        ENDPOINT_END );
+#else
         if( (TrackToEndPoint->Type() == PCB_VIA_T)
            || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false ) )
             error = true;
+#endif
 
         TrackToEndPoint->SetState( BUSY, false );
     }
@@ -715,11 +909,25 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC*  DC
         return;
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
     if( !TrackToStartPoint || ( TrackToStartPoint->Type() != PCB_TRACE_T ) )
+    {
+        TrackToStartPoint = nullptr;
         s_StartSegmentPresent = false;
+    }
 
     if( !TrackToEndPoint || ( TrackToEndPoint->Type() != PCB_TRACE_T ) )
+    {
+        TrackToEndPoint = nullptr;
         s_EndSegmentPresent = false;
+    }
+#else
+    if( !TrackToStartPoint || ( TrackToStartPoint->Type() != PCB_TRACE_T ) )
+        s_StartSegmentPresent = false;
+
+    if( !TrackToEndPoint || ( TrackToEndPoint->Type() != PCB_TRACE_T ) )
+        s_EndSegmentPresent = false;
+#endif
 
     // Change high light net: the new one will be highlighted
     GetBoard()->PushHighLight();
@@ -755,6 +963,21 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC*  DC
 
     AddSegmentToDragList( track->GetFlags(), track );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->AddToDragList( track, g_DragSegmentList );
+    GetBoard()->TrackItems()->RoundedTracksCorners()->AddToDragList( track, g_DragSegmentList );
+    if( TrackToStartPoint )
+    {
+        GetBoard()->TrackItems()->Teardrops()->AddToDragList( TrackToStartPoint, g_DragSegmentList ); 
+        GetBoard()->TrackItems()->RoundedTracksCorners()->AddToDragList( TrackToStartPoint, g_DragSegmentList );
+    }
+    if( TrackToEndPoint )
+    {
+        GetBoard()->TrackItems()->Teardrops()->AddToDragList( TrackToEndPoint, g_DragSegmentList ); 
+        GetBoard()->TrackItems()->RoundedTracksCorners()->AddToDragList( TrackToEndPoint, g_DragSegmentList );
+    }
+#endif
+
     UndrawAndMarkSegmentsToDrag( m_canvas, DC );
 
 
@@ -822,6 +1045,15 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
     Track->ClearFlags();
     Track->SetState( IN_EDIT, false );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    BOARD* pcb = GetBoard();
+    //Junctions. 
+    //pcb->Teardrops()->Repopulate( current_net_code, TEARDROPS::JUNCTIONS_AND_TJUNCTIONS_T, 
+    //                                     &s_ItemsListPicker );
+    pcb->TrackItems()->Teardrops()->UpdateListClear();
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+#endif
+    
     // Draw dragged tracks
     for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
     {
@@ -847,8 +1079,19 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
             Track->SetState( END_ONPAD, true );
         else
             Track->SetState( END_ONPAD, false );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListAdd( Track );
+        GetBoard()->TrackItems()->Teardrops()->UpdateListAdd( Track );
+#endif
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    pcb->TrackItems()->RoundedTracksCorners()->UpdateListDo();
+    pcb->TrackItems()->Teardrops()->UpdateListAdd( GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    pcb->TrackItems()->Teardrops()->UpdateListDo();       
+#endif
+
     EraseDragList();
 
     SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED );
diff --git a/pcbnew/onleftclick.cpp b/pcbnew/onleftclick.cpp
index 2707fe1..125428b 100644
--- a/pcbnew/onleftclick.cpp
+++ b/pcbnew/onleftclick.cpp
@@ -48,6 +48,10 @@
 #include <pcbnew_id.h>
 #include <menus_helpers.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 /* Handle the left button mouse click, when a tool is active
  */
@@ -284,6 +288,15 @@ void PCB_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
             break;
         }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Edittrack_Clear();
+        if( GetBoard()->TrackItems()->Teardrops()->IsEditOn() )
+            GetBoard()->TrackItems()->Teardrops()->ToggleEdit( TEARDROPS::EDIT_SIZE_WIDTH_T ); //Length too.
+        else
+        if( GetBoard()->TrackItems()->RoundedTracksCorners()->IsEditOn() )
+            GetBoard()->TrackItems()->RoundedTracksCorners()->ToggleEdit( ROUNDEDTRACKSCORNERS::EDIT_LENGTH_SET_T ); //Ratio too.
+        else
+#endif
         if( (curr_item == NULL) || (curr_item->GetFlags() == 0) )
         {
             curr_item = (BOARD_ITEM*) Begin_Route( NULL, aDC );
diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp
index 13f769f..dac87e9 100644
--- a/pcbnew/onrightclick.cpp
+++ b/pcbnew/onrightclick.cpp
@@ -48,6 +48,10 @@
 #include <collectors.h>
 #include <menus_helpers.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 static wxMenu* Append_Track_Width_List( BOARD* aBoard );
 
@@ -100,6 +104,12 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( GetBoard()->TrackItems()->Teardrops()->IsEditOn() || 
+        GetBoard()->TrackItems()->RoundedTracksCorners()->IsEditOn() )
+        return true;
+#endif
+    
     // Select a proper item
 
     wxPoint cursorPos = GetCrossHairPosition();
@@ -399,6 +409,32 @@ 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 ) );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+            //Via Stitching thermal vias.
+            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 ) );
+            }
+            msg = AddHotkeyName( _( "Select Layer and Place Through Via" ),
+                                g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_THROUGH_VIA );
+            AddMenuItem( aPopMenu, ID_POPUP_PCB_SEL_LAYER_AND_PLACE_ZONE_THROUGH_VIA,
+                        msg, KiBitmap( via_xpm ) );
+            if( GetDesignSettings().m_BlindBuriedViaAllowed )
+            {
+                msg = AddHotkeyName( _( "Select Layer Pair and Place Blind/Buried Via" ),
+                                    g_Board_Editor_Hokeys_Descr, HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA );
+                AddMenuItem( aPopMenu, ID_POPUP_PCB_SEL_LAYERS_AND_PLACE_ZONE_BLIND_BURIED_VIA,
+                            msg, KiBitmap( via_buried_xpm ) );
+            }
+#endif
+
             aPopMenu->AppendSeparator();
         }
         break;
@@ -636,6 +672,26 @@ 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 ) );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    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_VIA_ARRAY, msg, KiBitmap( via_xpm ) );
+    }
+    
+    if( !flags )
+        GetBoard()->TrackItems()->Popup_PickTrackOrViaWidth( PopMenu, Track );
+    if(((Track->Type() == PCB_VIA_T) && dynamic_cast<VIA*>(Track)->GetThermalCode()))
+    {
+        
+    }
+    else
+    {
+        GetBoard()->TrackItems()->Teardrops()->Popup( PopMenu, Track, cursorPosition );
+        GetBoard()->TrackItems()->RoundedTracksCorners()->Popup( PopMenu, Track, cursorPosition );
+    }
+#endif
+
     // Delete control:
     PopMenu->AppendSeparator();
     wxMenu* trackdel_mnu = new wxMenu;
@@ -826,6 +882,10 @@ void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu
         AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT,
                      msg, KiBitmap( module_editor_xpm ) );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->Teardrops()->Popup( sub_menu_footprint, aModule );
+#endif
+        
         sub_menu_footprint->AppendSeparator();
 
         msg = AddHotkeyName( _( "Delete Footprint" ),
@@ -939,6 +999,11 @@ 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 ) );
+
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->Popup( sub_menu_Pad, Pad );
+#endif
+    
     sub_menu_Pad->AppendSeparator();
 
     AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_COPY_PAD_SETTINGS,
diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp
index 60ea4aa..1340d53 100644
--- a/pcbnew/pcb_painter.cpp
+++ b/pcbnew/pcb_painter.cpp
@@ -39,6 +39,11 @@
 #include <pcb_painter.h>
 #include <gal/graphics_abstraction_layer.h>
 #include <convert_basic_shapes_to_polygon.h>
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/teardrops.h"
+#include "trackitems/roundedtrackscorner.h"
+#include "trackitems/roundedcornertrack.h"
+#endif
 
 using namespace KIGFX;
 
@@ -306,6 +311,22 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
         draw( static_cast<const MARKER_PCB*>( item ) );
         break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+        dynamic_cast<TrackNodeItem::TEARDROP*>(const_cast<EDA_ITEM*>(item))->Draw( m_gal, 
+                                                                              &m_pcbSettings, 
+                                                                              m_pcbSettings.m_outlineWidth, 
+                                                                              aLayer );
+        break;
+        
+    case PCB_ROUNDEDTRACKSCORNER_T:
+        dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(const_cast<EDA_ITEM*>(item))->Draw( m_gal, 
+                                                                              &m_pcbSettings, 
+                                                                              m_pcbSettings.m_outlineWidth, 
+                                                                              aLayer );
+        break;
+#endif
+
     default:
         // Painter does not know how to draw the object
         return false;
@@ -321,6 +342,14 @@ void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
     VECTOR2D end( aTrack->GetEnd() );
     int      width = aTrack->GetWidth();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack)))
+    {
+        start = VECTOR2D(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetStartVisible());
+        end = VECTOR2D(dynamic_cast<ROUNDEDCORNERTRACK*>(const_cast<TRACK*>(aTrack))->GetEndVisible());
+    }
+#endif
+        
     if( m_pcbSettings.m_netNamesOnTracks && IsNetnameLayer( aLayer ) )
     {
         // If there is a net name - display it on the track
diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp
index 543ff91..a0511a8 100644
--- a/pcbnew/pcb_parser.cpp
+++ b/pcbnew/pcb_parser.cpp
@@ -50,6 +50,10 @@
 #include <zones.h>
 #include <pcb_parser.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 using namespace PCB_KEYS_T;
 
 
@@ -536,6 +540,16 @@ BOARD* PCB_PARSER::parseBOARD_unchecked() throw( IO_ERROR, PARSE_ERROR )
             m_board->Add( parsePCB_TARGET(), ADD_APPEND );
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case T_roundedtrackscorner:
+            m_board->TrackItems()->RoundedTracksCorners()->Parse( this );
+            break;
+
+        case T_teardrop:
+            m_board->TrackItems()->Teardrops()->Parse( this );
+            break;
+#endif
+            
         default:
             wxString err;
             err.Printf( _( "unknown token \"%s\"" ), GetChars( FromUTF8() ) );
@@ -2562,6 +2576,9 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
 
     wxPoint pt;
     T token;
+#ifdef PCBNEW_WITH_TRACKITEMS
+    bool is_thermal = false;
+#endif
 
     std::unique_ptr< VIA > via( new VIA( m_board ) );
 
@@ -2629,11 +2646,25 @@ VIA* PCB_PARSER::parseVIA() throw( IO_ERROR, PARSE_ERROR )
             NeedRIGHT();
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case T_thermal:
+            is_thermal = true;
+            break;
+
         default:
+            Expecting( "blind, micro, at, size, drill, layers, net, tstamp, thermal, or status" );
+#else
+         default:
             Expecting( "blind, micro, at, size, drill, layers, net, tstamp, or status" );
+#endif
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( is_thermal )
+        via->SetThermalCode( via->GetNetCode() );
+#endif
+
     return via.release();
 }
 
diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h
index 068669d..a481142 100644
--- a/pcbnew/pcb_parser.h
+++ b/pcbnew/pcb_parser.h
@@ -65,6 +65,11 @@ struct LAYER;
  */
 class PCB_PARSER : public PCB_LEXER
 {
+#ifdef PCBNEW_WITH_TRACKITEMS
+    friend class TEARDROPS;
+    friend class ROUNDEDTRACKSCORNERS;
+#endif
+    
     typedef boost::unordered_map< std::string, PCB_LAYER_ID >   LAYER_ID_MAP;
     typedef boost::unordered_map< std::string, LSET >       LSET_MAP;
 
diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp
index da73f44..a1663c8 100644
--- a/pcbnew/pcbframe.cpp
+++ b/pcbnew/pcbframe.cpp
@@ -82,6 +82,10 @@
 #include <gal/graphics_abstraction_layer.h>
 #include <functional>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+ 
 using namespace std::placeholders;
 
 ///@{
@@ -317,6 +321,11 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
                          PCB_EDIT_FRAME::OnUpdateZoneDisplayStyle )
     EVT_UPDATE_UI_RANGE( ID_PCB_MUWAVE_START_CMD, ID_PCB_MUWAVE_END_CMD,
                          PCB_EDIT_FRAME::OnUpdateMuWaveToolbar )
+#ifdef PCBNEW_WITH_TRACKITEMS
+    EVT_UPDATE_UI_RANGE( ID_POPUP_PCB_TEARDROP_SELECT_TEARDROP,
+                         ID_POPUP_PCB_TEARDROP_SELECT_ZERO,
+                         PCB_EDIT_FRAME::OnUpdateSelectTeardrop )
+#endif
 
     EVT_COMMAND( wxID_ANY, LAYER_WIDGET::EVT_LAYER_COLOR_CHANGE, PCB_EDIT_FRAME::OnLayerColorChange )
 END_EVENT_TABLE()
@@ -350,6 +359,9 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
     SetGalCanvas( galCanvas );
 
     SetBoard( new BOARD() );
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->SetEditFrame( this, m_TrackItemsMenu );
+#endif
 
     // Create the PCB_LAYER_WIDGET *after* SetBoard():
 
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index e092e9c..f5713be 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -106,6 +106,117 @@ enum pcbnew_ids
     ID_POPUP_PCB_DELETE_TRACKNET,
     ID_POPUP_PCB_DELETE_TRACK_MNU,
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //TrackNodeItems
+    ID_POPUP_PCB_TRACKITEMS_COMMON_MNU,
+    ID_POPUP_PCB_VIA_PICK_SIZE,
+    ID_POPUP_PCB_TRACK_PICK_WIDTH,
+    ID_POPUP_PCB_TRACKS_MARK_SHARP_ANGLES,
+    ID_POPUP_PCB_TRACKS_CONNECT_CENTER_IN_ITEM,
+    //Teardrops
+    ID_POPUP_PCB_TEARDROPS_COMMON_MNU,
+    ID_POPUP_PCB_TEARDROP_EDIT_LENGTH,
+    ID_POPUP_PCB_TEARDROP_EDIT_WIDTH,
+    ID_POPUP_PCB_TEARDROP_COPYCURRENT,
+    ID_POPUP_PCB_TEARDROP_LOCK_TOGGLE,
+    ID_POPUP_PCB_TEARDROPS_LOCK_ALL_SAME,
+    ID_POPUP_PCB_TEARDROPS_UNLOCK_ALL_SAME,
+    ID_POPUP_PCB_TEARDROPS_LOCK_MODULE,
+    ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULE,
+    ID_POPUP_PCB_TEARDROPS_LOCK, //via or pad
+    ID_POPUP_PCB_TEARDROPS_UNLOCK, //via or pad
+    ID_POPUP_PCB_TEARDROPS_LOCK_NET, //net, junctioms & T- too.
+    ID_POPUP_PCB_TEARDROPS_UNLOCK_NET, //net, junctioms & T- too.
+    ID_POPUP_PCB_TEARDROPS_LOCK_MODULES_ALL, //0
+    ID_POPUP_PCB_TEARDROPS_LOCK_VIAS_ALL, //1
+    ID_POPUP_PCB_TJUNCTIONS_LOCK_ALL, //2
+    ID_POPUP_PCB_JUNCTIONS_LOCK_ALL, //3
+    ID_POPUP_PCB_TEARDROPS_UNLOCK_MODULES_ALL, //0
+    ID_POPUP_PCB_TEARDROPS_UNLOCK_VIAS_ALL, //1
+    ID_POPUP_PCB_TJUNCTIONS_UNLOCK_ALL, //2
+    ID_POPUP_PCB_JUNCTIONS_UNLOCK_ALL, //3
+    ID_POPUP_PCB_TEARDROP_SELECT_TEARDROP,
+    ID_POPUP_PCB_TEARDROP_SELECT_FILLET,
+    ID_POPUP_PCB_TEARDROP_SELECT_SUBLAND,
+    ID_POPUP_PCB_TEARDROP_SELECT_ZERO,
+    ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST,
+    ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_LAST = ID_POPUP_PCB_TEARDROP_SIZE_LENGTH_FIRST + 9,
+    ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST,
+    ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_LAST = ID_POPUP_PCB_TEARDROP_SIZE_WIDTH_FIRST + 9,
+    ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST,
+    ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_LAST = ID_POPUP_PCB_TEARDROP_NUM_SEGMENTS_FIRST + 9,
+    ID_POPUP_PCB_TEARDROP_SET_DEFAULT_PARAMS,
+    ID_POPUP_PCB_TEARDROP_PLACE,    //Place teardrop to via or pad, or place tjunction / junction
+    ID_POPUP_PCB_TEARDROP_CHANGE,   //Change teardrop from via, pad, or tjunction / junction
+    ID_POPUP_PCB_TEARDROP_DELETE,   //Delete teardrop from via or pad, or place tjunction / junction
+    ID_POPUP_PCB_TEARDROPS_PLACE,   //Place all connected segments of via or pad
+    ID_POPUP_PCB_TEARDROPS_CHANGE,  //Change from all connected segments of via or pad
+    ID_POPUP_PCB_TEARDROPS_DELETE,  //Delete from all connected segments of via or pad
+    ID_POPUP_PCB_TEARDROPS_PLACE_MODULE,
+    ID_POPUP_PCB_TEARDROPS_CHANGE_MODULE,
+    ID_POPUP_PCB_TEARDROPS_DELETE_MODULE,
+    ID_POPUP_PCB_TEARDROPS_PLACE_NET,
+    ID_POPUP_PCB_TEARDROPS_CHANGE_NET,
+    ID_POPUP_PCB_TEARDROPS_DELETE_NET,
+    ID_POPUP_PCB_TJUNCTIONS_PLACE_NET,
+    ID_POPUP_PCB_TJUNCTIONS_CHANGE_NET,
+    ID_POPUP_PCB_TJUNCTIONS_DELETE_NET,
+    ID_POPUP_PCB_JUNCTIONS_PLACE_NET,
+    ID_POPUP_PCB_JUNCTIONS_CHANGE_NET,
+    ID_POPUP_PCB_JUNCTIONS_DELETE_NET,
+    ID_POPUP_PCB_TEARDROPS_PLACE_MODULES_ALL, //0
+    ID_POPUP_PCB_TEARDROPS_PLACE_VIAS_ALL, //1
+    ID_POPUP_PCB_TJUNCTIONS_PLACE_ALL, //2
+    ID_POPUP_PCB_JUNCTIONS_PLACE_ALL, //3
+    ID_POPUP_PCB_TEARDROPS_CHANGE_MODULES_ALL, //0
+    ID_POPUP_PCB_TEARDROPS_CHANGE_VIAS_ALL, //1
+    ID_POPUP_PCB_TJUNCTIONS_CHANGE_ALL, //2
+    ID_POPUP_PCB_JUNCTIONS_CHANGE_ALL, //3
+    ID_POPUP_PCB_TEARDROPS_DELETE_MODULES_ALL, //0
+    ID_POPUP_PCB_TEARDROPS_DELETE_VIAS_ALL, //1 
+    ID_POPUP_PCB_TJUNCTIONS_DELETE_ALL, //2
+    ID_POPUP_PCB_JUNCTIONS_DELETE_ALL, //3
+    ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_MODULES, //0
+    ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TEARDROPS_VIAS, //1
+    ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_TJUNCTIONS, //2
+    ID_POPUP_PCB_TEARDROPS_MARK_WARNINGS_JUNCTIONS, //3
+    ID_POPUP_PCB_TEARDROPS_MARK_DIFF_MODULES, //0
+    ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TEARDROPS_VIAS, //1
+    ID_POPUP_PCB_TEARDROPS_MARK_DIFF_TJUNCTIONS, //2
+    ID_POPUP_PCB_TEARDROPS_MARK_DIFF_JUNCTIONS, //3
+    ID_POPUP_PCB_TEARDROPS_MARK_CURR_MODULES, //0
+    ID_POPUP_PCB_TEARDROPS_MARK_CURR_TEARDROPS_VIAS, //1
+    ID_POPUP_PCB_TEARDROPS_MARK_CURR_TJUNCTIONS, //2
+    ID_POPUP_PCB_TEARDROPS_MARK_CURR_JUNCTIONS, //3
+    ID_POPUP_PCB_TJUNCTIONS_MARK_NOT_T,
+
+    //Via Stitching
+    ID_POPUP_PCB_PLACE_ZONE_THROUGH_VIA,
+    ID_POPUP_PCB_PLACE_ZONE_BLIND_BURIED_VIA,
+    ID_POPUP_PCB_SEL_LAYERS_AND_PLACE_ZONE_BLIND_BURIED_VIA,
+    ID_POPUP_PCB_SEL_LAYER_AND_PLACE_ZONE_THROUGH_VIA,
+    ID_POPUP_PCB_CREATE_VIA_ARRAY,
+
+    //Rounded Corners
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_COMMON_MNU,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNER_PLACE,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_PLACE_ALL,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNER_DELETE,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_DELETE_ALL,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNER_CHANGE,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNER_CHANGE_ALL,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNER_COPYCURRENT,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_LAST = ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_SET_FIRST + 10,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_LAST = ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SIZE_LENGTH_RATIO_FIRST + 10,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_SET_DEFAULT_PARAMS,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_SET,
+    ID_POPUP_PCB_ROUNDEDTRACKSCORNERS_EDIT_LENGTH_RATIO,
+    
+    ID_POPUP_PCB_GOTO_NEXT_MARKER,
+#endif
+    
     ID_POPUP_PCB_MOVE_ZONE_CORNER,
     ID_POPUP_PCB_ADD_ZONE_CORNER,
     ID_POPUP_PCB_DELETE_ZONE_CORNER,
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
index c1cb285..5476467 100644
--- a/pcbnew/plot_board_layers.cpp
+++ b/pcbnew/plot_board_layers.cpp
@@ -52,6 +52,12 @@
 #include <pcbplot.h>
 #include <plot_auxiliary_data.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#include "trackitems/roundedcornertrack.h"
+#endif
+
+
 // Local
 /* Plot a solder mask layer.
  * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
@@ -534,6 +540,19 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
         gbr_metadata.SetNetName( track->GetNetname() );
         int width = track->GetWidth() + itemplotter.getFineWidthAdj();
         aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( track->Type() == PCB_TEARDROP_T )
+            aBoard->TrackItems()->Teardrops()->Plot( static_cast<TrackNodeItem::TEARDROP*>(track), aPlotter, 
+                                       &plotMode, &gbr_metadata );
+        else
+            if( track->Type() == PCB_ROUNDEDTRACKSCORNER_T )
+                aBoard->TrackItems()->RoundedTracksCorners()->Plot( static_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(track), aPlotter, 
+                                        &plotMode, &gbr_metadata );
+            else
+                if(dynamic_cast<ROUNDEDCORNERTRACK*>(track))
+                    aPlotter->ThickSegment( dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetStartVisible(), dynamic_cast<ROUNDEDCORNERTRACK*>(track)->GetEndVisible(), width, plotMode, &gbr_metadata );
+                else
+#endif
         aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, &gbr_metadata );
     }
 
diff --git a/pcbnew/router/pns_router.h b/pcbnew/router/pns_router.h
index 5454243..eaabeda 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
 {
@@ -114,7 +115,7 @@ public:
     void SetInterface( ROUTER_IFACE* aIface );
     void SetMode ( ROUTER_MODE aMode );
     ROUTER_MODE Mode() const { return m_mode; }
-
+    
     static ROUTER* GetInstance();
 
     void ClearWorld();
@@ -163,6 +164,10 @@ public:
 
     bool StartDragging( const VECTOR2I& aP, ITEM* aItem );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    bool IsDragging( void ) const { return m_state == DRAG_SEGMENT; }
+#endif
+
     void SetIterLimit( int aX ) { m_iterLimit = aX; }
     int GetIterLimit() const { return m_iterLimit; };
 
@@ -205,7 +210,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/pns_tool_base.h b/pcbnew/router/pns_tool_base.h
index 8974aa4..7c7f216 100644
--- a/pcbnew/router/pns_tool_base.h
+++ b/pcbnew/router/pns_tool_base.h
@@ -57,6 +57,7 @@ public:
     }
 
     ROUTER* Router() const;
+    ITEM* GetStartItem( void ) const { return m_startItem; }
 
 protected:
     const VECTOR2I snapToItem( bool aEnabled, ITEM* aItem, VECTOR2I aP);
diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp
index 1404756..dfb6fec 100644
--- a/pcbnew/router/router_tool.cpp
+++ b/pcbnew/router/router_tool.cpp
@@ -61,6 +61,10 @@ using namespace std::placeholders;
 #include "pns_segment.h"
 #include "pns_router.h"
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#endif
+
 using namespace KIGFX;
 using boost::optional;
 
@@ -142,6 +146,20 @@ static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlind
     via_buried_xpm, AF_NONE,
     (void*) VIA_ACTION_FLAGS::BLIND_VIA );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+static const TOOL_ACTION ACT_SelectLayerAndPlaceThroughVia( "pcbnew.InteractiveRouter.SelectLayerPlaceVia",
+    AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_SEL_LAYER_AND_ADD_THROUGH_VIA ),
+    _( "Select Layer And Place Through Via" ),
+    _( "Select layer and Add a through-hole via at zone" ),
+    via_xpm );
+
+static const TOOL_ACTION ACT_SelectLayerAndPlaceBlindVia( "pcbnew.InteractiveRouter.SelectLayerPlaceBlindVia",
+    AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ),
+    _( "Select Layer Pair And Place Blind/Buried Via" ),
+    _( "Select layer pair and add a blind or buried via at zone."),
+    via_buried_xpm );
+#endif
+
 static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia",
     AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_MICROVIA ),
     _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ),
@@ -312,6 +330,12 @@ public:
 
         AppendSeparator();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        Add( ACT_SelectLayerAndPlaceThroughVia );
+        Add( ACT_SelectLayerAndPlaceBlindVia );
+        AppendSeparator();
+#endif
+
         m_widthMenu.SetBoard( aBoard );
         Add( &m_widthMenu );
 
@@ -876,8 +900,24 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
         }
         else if( evt->IsAction( &ACT_PlaceThroughVia ) )
         {
-            m_toolMgr->RunAction( PCB_ACTIONS::layerToggle, true );
+#ifdef PCBNEW_WITH_TRACKITEMS
+            board->ViaStitching()->AddThermalVia( m_frame, VIA_THROUGH, false );
+        }
+        else if( evt->IsAction( &ACT_PlaceBlindVia ) )
+        {
+            board->ViaStitching()->AddThermalVia( m_frame, VIA_BLIND_BURIED, false );
+        }
+        else if( evt->IsAction( &ACT_SelectLayerAndPlaceThroughVia ) )
+        {
+            board->ViaStitching()->AddThermalVia( m_frame, VIA_THROUGH, true );
         }
+        else if( evt->IsAction( &ACT_SelectLayerAndPlaceBlindVia ) )
+        {
+            board->ViaStitching()->AddThermalVia( m_frame, VIA_BLIND_BURIED, true );
+        }
+#else
+            m_toolMgr->RunAction( PCB_ACTIONS::layerToggle, true );
+#endif
         else if( evt->IsAction( &PCB_ACTIONS::remove ) )
         {
             deleteTraces( m_startItem, true );
diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp
index 235ccc9..e17cdb2 100644
--- a/pcbnew/sel_layer.cpp
+++ b/pcbnew/sel_layer.cpp
@@ -301,6 +301,11 @@ void PCB_BASE_FRAME::SelectCopperLayerPair()
                                 _( "Warning: The Top Layer and Bottom Layer are same." ) );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //Via Stitching for.
+    SetActiveLayer( screen->m_Route_Layer_TOP );
+#endif
+
     m_canvas->MoveCursorToCrossHair();
 }
 
diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp
index f547f6e..1cc7033 100644
--- a/pcbnew/tool_pcb.cpp
+++ b/pcbnew/tool_pcb.cpp
@@ -49,6 +49,10 @@
 
 #include <wx/wupdlock.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 extern bool IsWxPythonLoaded();
 
 #define SEL_LAYER_HELP _( \
@@ -555,6 +559,9 @@ void PCB_EDIT_FRAME::ReCreateAuxiliaryToolbar()
 
         m_auxiliaryToolBar->Realize();
         m_auimgr.Update();
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->RoundedTracksCorners()->RecreateMenu();
+#endif
         return;
     }
 
diff --git a/pcbnew/toolbars_update_user_interface.cpp b/pcbnew/toolbars_update_user_interface.cpp
index 4ccc686..3982964 100644
--- a/pcbnew/toolbars_update_user_interface.cpp
+++ b/pcbnew/toolbars_update_user_interface.cpp
@@ -40,6 +40,21 @@
 #include <drc_stuff.h>
 #include <class_pcb_layer_box_selector.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+
+
+void PCB_EDIT_FRAME::OnUpdateSelectTeardrop( wxUpdateUIEvent& aEvent )
+{
+    int shapeID = 0;
+    if(GetBoard()->TrackItems()->Teardrops()->IsOn())
+        shapeID = GetBoard()->TrackItems()->Teardrops()->GetCurrentShape();
+
+    bool check = ( ( aEvent.GetId() - ID_POPUP_PCB_TEARDROP_SELECT_TEARDROP + 1 ) == shapeID );
+    aEvent.Check( check );
+}
+#endif
+
 
 void PCB_EDIT_FRAME::OnUpdateLayerPair( wxUpdateUIEvent& aEvent )
 {
diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp
index cdaf056..ae18315 100644
--- a/pcbnew/tools/pcb_editor_control.cpp
+++ b/pcbnew/tools/pcb_editor_control.cpp
@@ -57,6 +57,10 @@
 #include <tools/tool_event_utils.h>
 
 #include <functional>
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#endif
+
 using namespace std::placeholders;
 
 
@@ -670,18 +674,38 @@ int PCB_EDITOR_CONTROL::ZoneFillAll( const TOOL_EVENT& aEvent )
 
     BOARD_COMMIT commit( this );
 
+    //Via Stitching: Set all thermal vias netcodes for recovering.
+    /*
+    m_frame->Compile_Ratsnest( nullptr, false );
+    for( int i = 0; i < board->GetAreaCount(); ++i )
+    {
+        ZONE_CONTAINER* zone = board->GetArea( i );
+        commit.Modify( zone );
+        m_frame->Fill_Zone( zone );
+    }
+    ViaStitching::ConnectThermalViasZonesPolygons( m_frame->GetBoard() );
+    */
+
     for( int i = 0; i < board->GetAreaCount(); ++i )
     {
         ZONE_CONTAINER* zone = board->GetArea( i );
 
         commit.Modify( zone );
 
+#ifndef PCBNEW_WITH_TRACKITEMS
         m_frame->Fill_Zone( zone );
+#endif
         zone->SetIsFilled( true );
         ratsnest->Update( zone );
         getView()->Update( zone );
     }
 
+    //Via Stitching.
+    //ViaStitching::SetThermalViasNetcodes( m_frame->GetBoard() );
+#ifdef PCBNEW_WITH_TRACKITEMS
+    m_frame->Fill_All_Zones( m_frame, false );
+#endif
+
     commit.Push( _( "Fill All Zones" ) );
 
     ratsnest->Recalculate();
diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp
index 60caa56..124220e 100644
--- a/pcbnew/tools/pcbnew_control.cpp
+++ b/pcbnew/tools/pcbnew_control.cpp
@@ -53,6 +53,9 @@
 #include <board_commit.h>
 
 #include <functional>
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include <trackitems/tracknodeitem.h>
+#endif
 using namespace std::placeholders;
 
 
@@ -263,7 +266,11 @@ int PCBNEW_CONTROL::TrackDisplayMode( const TOOL_EVENT& aEvent )
 
     for( TRACK* track = getModel<BOARD>()->m_Track; track; track = track->Next() )
     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if( track->Type() == PCB_TRACE_T || dynamic_cast<TrackNodeItem::TRACKNODEITEM*>(track))
+#else
         if( track->Type() == PCB_TRACE_T )
+#endif
             getView()->Update( track, KIGFX::GEOMETRY );
     }
 
diff --git a/pcbnew/tr_modif.cpp b/pcbnew/tr_modif.cpp
index 5c5d5e2..a31e0dc 100644
--- a/pcbnew/tr_modif.cpp
+++ b/pcbnew/tr_modif.cpp
@@ -40,6 +40,10 @@
 #include <pcbnew.h>
 #include <protos.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 static void ListSetState( EDA_ITEM* Start, int NbItem, STATUS_FLAGS State,
                           bool onoff );
@@ -85,6 +89,11 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC*              aDC,
     if( aNewTrack->Type() == PCB_VIA_T && ( aNewTrackSegmentsCount > 1 ) )
         aNewTrack = aNewTrack->Next();
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( (aNewTrack->Type() == PCB_TEARDROP_T) && (aNewTrackSegmentsCount > 1) && (aNewTrack->Next()) )
+        aNewTrack = aNewTrack->Next();
+#endif
+
     aNewTrack = GetBoard()->MarkTrace( aNewTrack, &aNewTrackSegmentsCount, NULL, NULL, true );
     wxASSERT( aNewTrack );
 
@@ -188,7 +197,11 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC*              aDC,
         if( pt_segm == NULL )
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        if(pt_segm->Type() == PCB_TRACE_T) //Only TRACKs, not derived classes.
+#else
         if( pt_segm->Type() != PCB_VIA_T )
+#endif
         {
             if( pt_segm->GetState( IS_LINKED ) == 0 )
             {
@@ -264,6 +277,10 @@ int PCB_EDIT_FRAME::EraseRedundantTrack( wxDC*              aDC,
 
                     if( aItemsListPicker )
                     {
+#ifdef PCBNEW_WITH_TRACKITEMS
+                        GetBoard()->TrackItems()->Teardrops()->Remove( pt_del, aItemsListPicker, true );
+                        GetBoard()->TrackItems()->RoundedTracksCorners()->Remove( pt_del, aItemsListPicker, true );
+#endif
                         pt_del->UnLink();
                         pt_del->SetStatus( 0 );
                         pt_del->ClearFlags();
diff --git a/pcbnew/tracepcb.cpp b/pcbnew/tracepcb.cpp
index dc11079..272e2a1 100644
--- a/pcbnew/tracepcb.cpp
+++ b/pcbnew/tracepcb.cpp
@@ -46,6 +46,9 @@
 
 #include <wx/overlay.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
 
 // Local functions:
 /* Trace the pads of a module in sketch mode.
@@ -154,9 +157,18 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const
         if( track->IsMoving() )
             continue;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        //Draw only track segments. Draw vias later... after zones.
+        if( track->Type() != PCB_VIA_T ) 
+#endif
         track->Draw( aPanel, DC, aDrawMode );
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if(TrackNodeItem::ROUNDEDTRACKSCORNER* cor = TrackItems()->RoundedTracksCorners()->GetEditCorner())
+        cor->Draw( aPanel, DC, aDrawMode );
+#endif
+
     // SEGZONE is outdated, only her for compatibility with
     // very old designs
     for( SEGZONE* zone = m_Zone; zone; zone = zone->Next() )
@@ -201,6 +213,14 @@ void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* DC, GR_DRAWMODE aDrawMode, const
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    //... draw vias here. 
+    for( TRACK* track = m_Track; track; track = track->Next() )
+        if( !track->IsMoving() )
+            if( track->Type() == PCB_VIA_T )
+                track->Draw( aPanel, DC, aDrawMode );
+#endif
+
     LSET all_cu = LSET::AllCuMask();
 
     for( MODULE* module = m_Modules; module; module = module->Next() )
@@ -277,6 +297,17 @@ void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
     }
 
     // Redraw track and vias that have aNetCode
+#ifdef PCBNEW_WITH_TRACKITEMS
+    for( TRACK* seg = m_Track; seg; seg = seg->Next() )
+        if( seg->GetNetCode() == aNetCode )
+            if( seg->Type() != PCB_VIA_T )
+                seg->Draw( am_canvas, DC, draw_mode );
+    // Draw vias after segments.
+    for( TRACK* seg = m_Track; seg; seg = seg->Next() )
+        if( seg->GetNetCode() == aNetCode )
+            if( seg->Type() == PCB_VIA_T )
+                seg->Draw( am_canvas, DC, draw_mode );
+#else
     for( TRACK* seg = m_Track; seg; seg = seg->Next() )
     {
         if( seg->GetNetCode() == aNetCode )
@@ -284,6 +315,7 @@ void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode )
             seg->Draw( am_canvas, DC, draw_mode );
         }
     }
+#endif
 }
 
 
diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp
index bb4b4a6..b54b1bf 100644
--- a/pcbnew/undo_redo.cpp
+++ b/pcbnew/undo_redo.cpp
@@ -51,6 +51,10 @@ using namespace std::placeholders;
 #include <tool/tool_manager.h>
 
 #include <view/view.h>
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/trackitems.h"
+#endif
+
 
 /* Functions to undo and redo edit commands.
  *  commands to undo are stored in CurrentScreen->m_UndoList
@@ -170,7 +174,7 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
 
 
 void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType,
-                                              const wxPoint& aTransformPoint )
+        const wxPoint& aTransformPoint )
 {
     PICKED_ITEMS_LIST commandToUndo;
     commandToUndo.PushItem( ITEM_PICKER( aItem, aCommandType ) );
@@ -179,8 +183,9 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, UNDO_REDO_T aCo
 
 
 void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
-                                         UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint )
+        UNDO_REDO_T aTypeCommand, const wxPoint& aTransformPoint )
 {
+
     PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST();
 
     commandToUndo->m_TransformPoint = aTransformPoint;
@@ -375,7 +380,7 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
 
 
 void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRedoCommand,
-                                             bool aRebuildRatsnet )
+        bool aRebuildRatsnet )
 {
     BOARD_ITEM* item;
     bool        not_found = false;
@@ -388,6 +393,12 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
     // Undo in the reverse order of list creation: (this can allow stacked changes
     // like the same item can be changes and deleted in the same complex command
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->Teardrops()->UpdateListClear();
+    GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListClear();
+    MODULE* tears_module = nullptr;
+#endif
+
     bool build_item_list = true;    // if true the list of existing items must be rebuilt
 
     // Restore changes in reverse order
@@ -421,7 +432,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
                 // Remove this non existent item
                 aList->RemovePicker( ii );
                 ii++;       // the current item was removed, ii points now the next item
-                            // decrement it because it will be incremented later
+                // decrement it because it will be incremented later
                 not_found = true;
                 continue;
             }
@@ -433,8 +444,11 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
         switch( item->Type() )
         {
         case PCB_MODULE_T:
+#ifdef PCBNEW_WITH_TRACKITEMS
+            tears_module =  static_cast<MODULE*>( item );
+#endif
             deep_reBuild_ratsnest = true;   // Pointers on pads can be invalid
-            // Fall through
+        // Fall through
         case PCB_ZONE_AREA_T:
         case PCB_TRACE_T:
         case PCB_VIA_T:
@@ -446,6 +460,18 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
             deep_reBuild_ratsnest = true;
             break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        case PCB_TEARDROP_T:
+            if( tears_module && (dynamic_cast<TrackNodeItem::TEARDROP_PAD*>(item)) )
+                GetBoard()->TrackItems()->Teardrops()->ChangePad( static_cast<TrackNodeItem::TEARDROP_PAD*>(item), tears_module );
+            GetBoard()->TrackItems()->Teardrops()->UpdateListAdd( static_cast<TrackNodeItem::TEARDROP*>(item) );
+            break;
+
+        case PCB_ROUNDEDTRACKSCORNER_T:
+            GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+            break;
+#endif
+
         default:
             break;
         }
@@ -453,6 +479,9 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
         // It is possible that we are going to replace the selected item, so clear it
         SetCurItem( NULL );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+        GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListAdd( static_cast<TRACK*>(item) );
+#endif
         switch( aList->GetPickedItemStatus( ii ) )
         {
         case UR_CHANGED:    /* Exchange old and new data for each item */
@@ -472,6 +501,10 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
 
             item->SwapData( image );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            GetBoard()->TrackItems()->Teardrops()->Update( item );
+#endif
+
             // Update all pads/drawings/texts, as they become invalid
             // for the VIEW after SwapData() called for modules
             if( item->Type() == PCB_MODULE_T )
@@ -498,6 +531,13 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
                 module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
             }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item))
+            {    
+                dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item)->ResetVisibleEndpoints();
+                dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item)->ReleaseTrackSegs();
+            }
+#endif
             view->Remove( item );
             break;
 
@@ -511,6 +551,13 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
                 module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1, -1 ) );
             }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+            if(dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item))
+            {
+                dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item)->ConnectTrackSegs();
+                dynamic_cast<TrackNodeItem::ROUNDEDTRACKSCORNER*>(item)->ResetVisibleEndpoints();
+            }
+#endif
             view->Add( item );
             build_item_list = true;
             break;
@@ -552,6 +599,12 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
         }
     }
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateListDo_UndoRedo();
+    GetBoard()->TrackItems()->Teardrops()->UpdateListAdd( GetBoard()->TrackItems()->RoundedTracksCorners()->UpdateList_GetUpdatedTracks() );
+    GetBoard()->TrackItems()->Teardrops()->UpdateListDo_UndoRedo();
+#endif
+
     if( not_found )
         wxMessageBox( wxT( "Incomplete undo/redo operation: some items not found" ) );
 
@@ -626,6 +679,15 @@ void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
         std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) );
         break;
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    case PCB_TEARDROP_T:
+        std::swap( *((TrackNodeItem::TEARDROP*) this), *((TrackNodeItem::TEARDROP*) aImage) );
+        break;
+    case PCB_ROUNDEDTRACKSCORNER_T:
+        std::swap( *((TrackNodeItem::ROUNDEDTRACKSCORNER*) this), *((TrackNodeItem::ROUNDEDTRACKSCORNER*) aImage) );
+        break;
+#endif
+
     case PCB_ZONE_T:
     default:
         wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() );
diff --git a/pcbnew/zones_by_polygon_fill_functions.cpp b/pcbnew/zones_by_polygon_fill_functions.cpp
index ebe2964..036adc8 100644
--- a/pcbnew/zones_by_polygon_fill_functions.cpp
+++ b/pcbnew/zones_by_polygon_fill_functions.cpp
@@ -45,8 +45,12 @@
 
 #include <view/view.h>
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+#include "trackitems/viastitching.h"
+#define FORMAT_STRING _( "Filling zone %d out of %d (net %s) Pass %d/2 ..." ) //Via stitching: 
+#else
 #define FORMAT_STRING _( "Filling zone %d out of %d (net %s)..." )
-
+#endif
 
 /**
  * Function Delete_OldZone_Fill (obsolete)
@@ -138,6 +142,60 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
     // with a correct size to show this long net name
     msg.Printf( FORMAT_STRING, 000, areaCount, wxT("XXXXXXXXXXXXXXXXX" ) );
 
+#ifdef PCBNEW_WITH_TRACKITEMS
+    if( aActiveWindow )
+        progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg,
+                                     areaCount*2+1, aActiveWindow,
+                                     wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
+                                     wxPD_APP_MODAL | wxPD_ELAPSED_TIME );
+    // Display the actual message
+    if( progressDialog )
+        progressDialog->Update( 0, _( "Starting zone fill..." ) );
+
+    // Remove segment zones
+    GetBoard()->m_Zone.DeleteAll();
+
+    int 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.
+    {
+        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() ), n+1 );
+
+            if( progressDialog )
+            {
+                if( !progressDialog->Update( progressCount++, msg ) )
+                    break;  // Aborted by user
+            }
+
+            errorLevel = Fill_Zone( zoneContainer );
+
+            if( errorLevel && !aVerbose )
+                break;
+        }
+
+        if( progressDialog )
+            progressDialog->Update( progressCount, _( "Calculate copper pour connections..." ) );
+
+        //Via Stitching: Recalclate vias zones connections after fill. 
+        n? GetBoard()->ViaStitching()->SetNetcodes() : GetBoard()->ViaStitching()->ConnectThermalViasToZones();
+    }
+    Compile_Ratsnest( nullptr, false );
+
+    if( progressDialog )
+    {
+        //progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
+        progressDialog->Update( progressCount, _( "Updating ratsnest..." ) );
+#else
     if( aActiveWindow )
         progressDialog = new wxProgressDialog( _( "Fill All Zones" ), msg,
                                      areaCount+2, aActiveWindow,
@@ -175,6 +233,7 @@ int PCB_EDIT_FRAME::Fill_All_Zones( wxWindow * aActiveWindow, bool aVerbose )
     if( progressDialog )
     {
         progressDialog->Update( ii+2, _( "Updating ratsnest..." ) );
+#endif
 #ifdef __WXMAC__
         // Work around a dialog z-order issue on OS X
         aActiveWindow->Raise();
diff --git a/scripts/ddr3_length_match.py b/scripts/ddr3_length_match.py
old mode 100755
new mode 100644
diff --git a/scripts/lib_convert.py b/scripts/lib_convert.py
old mode 100755
new mode 100644
diff --git a/scripts/library-repos-install.bat b/scripts/library-repos-install.bat
old mode 100644
new mode 100755
diff --git a/scripts/library-repos-install.sh b/scripts/library-repos-install.sh
old mode 100755
new mode 100644
diff --git a/scripts/test_kicad_plugin.py b/scripts/test_kicad_plugin.py
old mode 100755
new mode 100644
diff --git a/scripts/test_plugin.py b/scripts/test_plugin.py
old mode 100755
new mode 100644
diff --git a/tools/checkcoding.py b/tools/checkcoding.py
old mode 100755
new mode 100644

--------------2.7.5--



Follow ups

References