kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #14258
[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