← Back to team overview

kicad-developers team mailing list archive

[patch] introduce text checking in pcbnew's DRC

 

Hello,

here's a patch to tackle https://bugs.launchpad.net/kicad/+bug/1201090

It brings text checking on par with keepoutAreas (in fact I used it as template). At the moment boundary box is used as area to check (per line checking is being considered).

It lacks pin checking (as well as keepoutAreas), but I will send a patch for both as soon as I figured out a nice way to do it.


I hope the patch is not too bad - it's my first one :)

schuhumi
=== modified file 'pcbnew/class_drc_item.cpp'
--- pcbnew/class_drc_item.cpp	2014-01-28 09:43:55 +0000
+++ pcbnew/class_drc_item.cpp	2014-08-12 18:46:02 +0000
@@ -110,6 +110,15 @@
 
     case DRCE_PAD_INSIDE_KEEPOUT:
         return wxString( _("Pad inside a keepout area"));
+        
+    case DRCE_VIA_INSIDE_TEXT:
+        return wxString( _("Via inside a text area"));
+
+    case DRCE_TRACK_INSIDE_TEXT:
+        return wxString( _("Track inside a text area"));
+
+    case DRCE_PAD_INSIDE_TEXT:
+        return wxString( _("Pad inside a text area"));
 
     default:
         {

=== modified file 'pcbnew/drc.cpp'
--- pcbnew/drc.cpp	2014-06-29 20:33:29 +0000
+++ pcbnew/drc.cpp	2014-08-12 23:03:34 +0000
@@ -38,6 +38,7 @@
 #include <class_track.h>
 #include <class_pad.h>
 #include <class_zone.h>
+#include <class_pcb_text.h>
 #include <class_draw_panel_gal.h>
 #include <view/view.h>
 
@@ -260,7 +261,16 @@
 
         testKeepoutAreas();
     }
-
+    
+    // find and gather vias, tracks, pads inside text boxes.
+    if( aMessages )
+    {
+        aMessages->AppendText( _( "Test texts...\n" ) );
+        wxSafeYield();
+    }
+    
+    testTexts();
+    
     // update the m_ui listboxes
     updatePointers();
 
@@ -628,6 +638,76 @@
 }
 
 
+void DRC::testTexts()
+{
+    // Test text areas for vias, tracks and pads inside text areas
+    for( BOARD_ITEM* item = m_pcb->m_Drawings; item; item = item->Next() )
+    {
+        
+        if( item->Type() !=  PCB_TEXT_T )
+            continue;
+    
+        CPOLYGONS_LIST textOutPolygon;
+        CPolyLine      textOutLine;
+        
+        // So far the bounding box makes up the text-area
+        ( (TEXTE_PCB*) item )->TransformBoundingBoxWithClearanceToPolygon(textOutPolygon, 0);
+        // An option to make the test more accurate (test each individual line) might be: 
+        //    EDA_RECT  GetTextBox (int aLine=-1, int aThickness=-1, bool aInvertY=false) const 
+        
+        if( !textOutPolygon.GetCornersCount() )
+            continue;
+        
+        // Convert polygon to polyline by copying the individual points
+        textOutLine.Start( item->GetLayer(), textOutPolygon.GetX(0), textOutPolygon.GetY(0), 0);
+        for( unsigned int ii = 1; ii<textOutPolygon.GetCornersCount(); ii++)
+        {
+            textOutLine.AppendCorner (textOutPolygon.GetX(ii), textOutPolygon.GetY(ii));
+        }
+        textOutLine.CloseLastContour ();
+
+        for( TRACK* segm = m_pcb->m_Track; segm != NULL; segm = segm->Next() )
+        {
+            if( segm->Type() == PCB_TRACE_T )
+            {
+                if( segm->GetLayer() != textOutLine.GetLayer() )
+                    continue;
+                
+                // Error condition: Distance between text bounding box and segment ist
+                // smaller than the clearance of the segment
+                if( textOutLine.Distance( segm->GetStart(), segm->GetEnd(), segm->GetWidth(), 
+                            segm->GetClearance(NULL) ) < segm->GetClearance(NULL) )
+                {
+                    m_currentMarker = fillMarker( segm, NULL,
+                                                  DRCE_TRACK_INSIDE_TEXT, m_currentMarker );
+                    m_pcb->Add( m_currentMarker );
+                    m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+                    m_currentMarker = 0;
+                }
+            }
+            else if( segm->Type() == PCB_VIA_T )
+            {
+                if( ! ((VIA*)segm)->IsOnLayer( item->GetLayer() ) )
+                    continue;
+
+                // Error condition: Distance between text bounding box and via ist
+                // smaller than the clearance of the via
+                if( textOutLine.Distance( segm->GetPosition() ) < 
+                                ( segm->GetWidth()/2 + segm->GetClearance(NULL) ) )
+                {
+                    m_currentMarker = fillMarker( segm, NULL,
+                                                  DRCE_VIA_INSIDE_TEXT, m_currentMarker );
+                    m_pcb->Add( m_currentMarker );
+                    m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker );
+                    m_currentMarker = 0;
+                }
+            }
+        }
+        // Test pads: TODO
+    }
+}
+
+
 bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
 {
     // Test keepout areas for vias, tracks and pads inside keepout areas

=== modified file 'pcbnew/drc_stuff.h'
--- pcbnew/drc_stuff.h	2014-05-20 09:29:37 +0000
+++ pcbnew/drc_stuff.h	2014-08-12 18:47:26 +0000
@@ -75,6 +75,9 @@
 #define DRCE_VIA_INSIDE_KEEPOUT                36   ///< Via in inside a keepout area
 #define DRCE_TRACK_INSIDE_KEEPOUT              37   ///< Track in inside a keepout area
 #define DRCE_PAD_INSIDE_KEEPOUT                38   ///< Pad in inside a keepout area
+#define DRCE_VIA_INSIDE_TEXT                   39   ///< Via in inside a text area
+#define DRCE_TRACK_INSIDE_TEXT                 40   ///< Track in inside a text area
+#define DRCE_PAD_INSIDE_TEXT                   41   ///< Pad in inside a text area
 
 
 class EDA_DRAW_PANEL;
@@ -280,6 +283,8 @@
     void testZones();
 
     void testKeepoutAreas();
+    
+    void testTexts();
 
     //-----<single "item" tests>-----------------------------------------
 

=== modified file 'polygon/PolyLine.cpp'
--- polygon/PolyLine.cpp	2014-06-24 16:17:18 +0000
+++ polygon/PolyLine.cpp	2014-08-12 19:57:03 +0000
@@ -1043,6 +1043,11 @@
  */
 int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
 {
+    return Distance( aStart, aEnd, aWidth, 1 ); // min clearance, should be > 0
+}
+ 
+int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth, int aMaxDist )
+{
     // We calculate the min dist between the segment and each outline segment
     // However, if the segment to test is inside the outline, and does not cross
     // any edge, it can be seen outside the polygon.
@@ -1079,7 +1084,7 @@
             int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0,
                                                  aStart.x, aStart.y, aEnd.x, aEnd.y,
                                                  aWidth,
-                                                 1,    // min clearance, should be > 0
+                                                 aMaxDist,    
                                                  NULL, NULL );
 
             if( distance > d )

=== modified file 'polygon/PolyLine.h'
--- polygon/PolyLine.h	2014-05-26 06:54:04 +0000
+++ polygon/PolyLine.h	2014-08-12 20:57:16 +0000
@@ -408,6 +408,19 @@
      *               0 if segment intersects or is inside
      */
     int     Distance( wxPoint aStart, wxPoint aEnd, int aWidth );
+    
+    /**
+     * Function Distance
+     * Calculates the distance between a segment and the zone:
+     * @param aStart the starting point of the segment.
+     * @param aEnd  the ending point of the segment.
+     * @param aWidth  the width of the segment.
+     * @param aMaxDist the maximal distance given as result. If result=aMaxDist+1, then
+     *               measured distance is greater than aMaxDist
+     * @return int = distance between the segment and outline.
+     *               0 if segment intersects or is inside
+     */
+    int     Distance( wxPoint aStart, wxPoint aEnd, int aWidth, int aMaxDist );
 
     /**
      * Function HitTestForEdge


Follow ups