← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] Remove backtracking wires in eeschema

 

Sure, I can. I usually prefer to use dynamic_cast because it will fail 
if the subclass isn't correct (even if you don't test, since a NULL 
access will result in a segfault) - just more or less as a sanity check. 
There's really no circumstance under which the pointer should not be an 
instance of SCH_LINE, and the behavior when it fails with dynamic_cast 
is a bit more obvious.

I can throw an assert in there, though, that'd definitely be more 
correct. Modified patch attached.

On Tue, Jun 23, 2015 at 09:24:36AM +0200, jp charras wrote:
> Le 22/06/2015 22:50, Chris Pavlina a écrit :
> > If you place a wire segment and then backtrack over it, you end up with 
> > a broken wire in the end:
> > 
> > http://misc.c4757p.com/backtrack.mp4
> > 
> > This is because the two segments are merged together, rather than the 
> > second *subtracting* from the first, even though the latter case is the 
> > way it's shown as you're drawing. This patch fixes that by adding a 
> > function to erase backtracks.
> > 
> > --
> > Chris
> > 
> 
> Thanks for this patch, it is very usefull.
> 
> I noticed you are using a dynamic cast in line:
> 
> SCH_LINE *line = dynamic_cast<SCH_LINE*>( p );
> 
> but the variable line is used without any test for NULL.
> 
> Can you have a look at this (use a static cast or a test for NULL) ?
> 
> Thanks.
> 
> 
> -- 
> Jean-Pierre CHARRAS
commit 5b7beeba531124fe9b7786df9f4e977f8ada7ff5
Author: Chris Pavlina <cpavlin1@xxxxxxxxxxxxxx>
Date:   Tue Jun 23 09:18:36 2015 -0400

    Remove backtracking segments when drawing wires

diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp
index 62141bd..c173f4e 100644
--- a/eeschema/bus-wire-junction.cpp
+++ b/eeschema/bus-wire-junction.cpp
@@ -43,6 +43,7 @@
 #include <sch_text.h>
 #include <sch_component.h>
 #include <sch_sheet.h>
+#include <trigo.h>
 
 
 static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC );
@@ -53,6 +54,47 @@ static DLIST< SCH_ITEM > s_wires;       // when creating a new set of wires,
 
 
 /**
+ * In a contiguous list of wires, remove wires that backtrack over the previous
+ * wire. Example:
+ *
+ * Wire is added:
+ * ---------------------------------------->
+ *
+ * A second wire backtracks over it:
+ * -------------------<====================>
+ *
+ * RemoveBacktracks is called:
+ * ------------------->
+ */
+static void RemoveBacktracks( DLIST<SCH_ITEM>& aWires )
+{
+    SCH_LINE* last_line = NULL;
+
+    EDA_ITEM* first = aWires.GetFirst();
+    for( EDA_ITEM* p = first; p; p = p->Next() )
+    {
+        SCH_LINE *line = dynamic_cast<SCH_LINE*>( p );
+        wxASSERT_MSG( line, "RemoveBacktracks() requires SCH_LINE items" );
+        continue;
+
+        if( p != first )
+        {
+            wxASSERT_MSG( last_line->GetEndPoint() == line->GetStartPoint(),
+                    "RemoveBacktracks() requires contiguous lines" );
+            if( IsPointOnSegment( last_line->GetStartPoint(), line->GetStartPoint(),
+                        line->GetEndPoint() ) )
+            {
+                last_line->SetEndPoint( line->GetEndPoint() );
+                delete s_wires.Remove( line );
+                p = line;
+            }
+        }
+        last_line = line;
+    }
+}
+
+
+/**
  * Mouse capture callback for drawing line segments.
  */
 static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
@@ -261,6 +303,9 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
 
     SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE );
 
+    // Remove segments backtracking over others
+    RemoveBacktracks( s_wires );
+
     // Add the new wires
     screen->Append( s_wires );
 

Follow ups

References