Commit e9b3322f authored by CHARRAS's avatar CHARRAS

On line DRC when creating a zone outline

parent da3f4430
...@@ -4,6 +4,12 @@ Started 2007-June-11 ...@@ -4,6 +4,12 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2008-Jan-20 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
On line DRC when creating a zone outline.
Needs more work to display errors DRC.
2008-Jan-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2008-Jan-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================
......
...@@ -491,10 +491,11 @@ public: ...@@ -491,10 +491,11 @@ public:
/** /**
* Function End_Zone * Function End_Zone
* terminates the zone edge creation process * terminates (if no DRC error ) the zone edge creation process
* @param DC = current Device Context * @param DC = current Device Context
* @return true if Ok, false if DRC error
*/ */
void End_Zone( wxDC* DC ); bool End_Zone( wxDC* DC );
/** Function Fill_Zone() /** Function Fill_Zone()
* Calculate the zone filling for the outline zone_container * Calculate the zone filling for the outline zone_container
......
...@@ -56,7 +56,7 @@ public: ...@@ -56,7 +56,7 @@ public:
* Is virtual from EDA_BaseStruct. * Is virtual from EDA_BaseStruct.
* @param frame A WinEDA_BasePcbFrame in which to print status information. * @param frame A WinEDA_BasePcbFrame in which to print status information.
*/ */
void Display_Infos( WinEDA_DrawFrame* frame ); virtual void Display_Infos( WinEDA_DrawFrame* frame );
/** /**
......
...@@ -70,7 +70,10 @@ wxString DRC_ITEM::GetErrorText() const ...@@ -70,7 +70,10 @@ wxString DRC_ITEM::GetErrorText() const
case COPPERAREA_INSIDE_COPPERAREA: case COPPERAREA_INSIDE_COPPERAREA:
return wxString( _("Copper area inside copper area")); return wxString( _("Copper area inside copper area"));
case COPPERAREA_CLOSE_TO_COPPERAREA: case COPPERAREA_CLOSE_TO_COPPERAREA:
return wxString( _("Copper areas intersect or too close")); return wxString( _("Copper areas intersect or are too close"));
case DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE:
return wxString( _("Copper area has a non existent net name"));
default: default:
return wxString( wxT("PROGRAM BUG, PLEASE LEAVE THE ROOM.") ); return wxString( wxT("PROGRAM BUG, PLEASE LEAVE THE ROOM.") );
...@@ -83,7 +86,7 @@ wxString DRC_ITEM::ShowCoord( const wxPoint& aPos ) ...@@ -83,7 +86,7 @@ wxString DRC_ITEM::ShowCoord( const wxPoint& aPos )
wxString temp; wxString temp;
wxString ret; wxString ret;
ret << wxT("@(") << valeur_param( aPos.x, temp ); ret << wxT("@ (") << valeur_param( aPos.x, temp );
ret << wxT(",") << valeur_param( aPos.y, temp ); ret << wxT(",") << valeur_param( aPos.y, temp );
ret << wxT(")"); ret << wxT(")");
......
...@@ -37,7 +37,6 @@ enum Mod_Attribut /* Attributs d'un module */ ...@@ -37,7 +37,6 @@ enum Mod_Attribut /* Attributs d'un module */
class MODULE : public BOARD_ITEM class MODULE : public BOARD_ITEM
{ {
public: public:
wxPoint m_Pos; // Real coord on board wxPoint m_Pos; // Real coord on board
D_PAD* m_Pads; /* Pad list (linked list) */ D_PAD* m_Pads; /* Pad list (linked list) */
...@@ -46,27 +45,29 @@ public: ...@@ -46,27 +45,29 @@ public:
TEXTE_MODULE* m_Reference; // texte reference du composant (U34, R18..) TEXTE_MODULE* m_Reference; // texte reference du composant (U34, R18..)
TEXTE_MODULE* m_Value; // texte valeur du composant (74LS00, 22K..) TEXTE_MODULE* m_Value; // texte valeur du composant (74LS00, 22K..)
wxString m_LibRef; /* nom du module en librairie */ wxString m_LibRef; /* nom du module en librairie */
wxString m_AlternateReference; /* Used when m_Reference cannot be used to
int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */ * identify the footprint ( after a full reannotation of the schematic */
int m_Orient; /* orientation en 1/10 degres */
int flag; /* flag utilise en trace rastnest et routage auto */ int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */ int m_Orient; /* orientation en 1/10 degres */
EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/ int flag; /* flag utilise en trace rastnest et routage auto */
EDA_Rect m_RealBoundaryBox; /* position/taille du module (coord relles) */ int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
int m_PadNum; // Nombre total de pads EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
int m_AltPadNum; // en placement auto Nombre de pads actifs pour EDA_Rect m_RealBoundaryBox; /* position/taille du module (coord relles) */
int m_PadNum; // Nombre total de pads
int m_AltPadNum; // en placement auto Nombre de pads actifs pour
// les calculs // les calculs
int m_CntRot90; // Placement auto: cout ( 0..10 ) de la rotation 90 degre
int m_CntRot180; // Placement auto: cout ( 0..10 ) de la rotation 180 degre
wxSize m_Ext; // marges de "garde": utilise en placement auto.
float m_Surface; // surface du rectangle d'encadrement
unsigned long m_Link; // variable temporaire ( pour editions, ...) int m_CntRot90; // Placement auto: cout ( 0..10 ) de la rotation 90 degre
long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies) int m_CntRot180; // Placement auto: cout ( 0..10 ) de la rotation 180 degre
wxSize m_Ext; // marges de "garde": utilise en placement auto.
float m_Surface; // surface du rectangle d'encadrement
unsigned long m_Link; // variable temporaire ( pour editions, ...)
long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies)
wxString m_Doc; // Texte de description du module wxString m_Doc; // Texte de description du module
wxString m_KeyWord; // Liste des mots cles relatifs au module wxString m_KeyWord; // Liste des mots cles relatifs au module
public: public:
MODULE( BOARD* parent ); MODULE( BOARD* parent );
...@@ -77,11 +78,11 @@ public: ...@@ -77,11 +78,11 @@ public:
MODULE* Next() { return (MODULE*) Pnext; } MODULE* Next() { return (MODULE*) Pnext; }
void Set_Rectangle_Encadrement();/* mise a jour du rect d'encadrement void Set_Rectangle_Encadrement(); /* mise a jour du rect d'encadrement
* en coord locales (orient 0 et origine = pos module) */ * en coord locales (orient 0 et origine = pos module) */
void SetRectangleExinscrit();/* mise a jour du rect d'encadrement void SetRectangleExinscrit(); /* mise a jour du rect d'encadrement
* et de la surface en coord reelles */ * et de la surface en coord reelles */
/** /**
* Function GetPosition * Function GetPosition
...@@ -94,7 +95,7 @@ public: ...@@ -94,7 +95,7 @@ public:
return m_Pos; return m_Pos;
} }
// deplacements // deplacements
void SetPosition( const wxPoint& newpos ); void SetPosition( const wxPoint& newpos );
void SetOrientation( int newangle ); void SetOrientation( int newangle );
...@@ -105,7 +106,7 @@ public: ...@@ -105,7 +106,7 @@ public:
/** /**
* Function IsLocked * Function IsLocked
* (virtual from BOARD_ITEM ) * (virtual from BOARD_ITEM )
* @returns bool - true if the MODULE is locked, else false * @returns bool - true if the MODULE is locked, else false
*/ */
bool IsLocked() const bool IsLocked() const
...@@ -129,15 +130,15 @@ public: ...@@ -129,15 +130,15 @@ public:
/* Reading and writing data on files */ /* Reading and writing data on files */
/** /**
* Function Save * Function Save
* writes the data structures for this object out to a FILE in "*.brd" format. * writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to. * @param aFile The FILE to write to.
* @return bool - true if success writing else false. * @return bool - true if success writing else false.
*/ */
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
int Write_3D_Descr( FILE* File ) const; int Write_3D_Descr( FILE* File ) const;
int ReadDescr( FILE* File, int* LineNum = NULL ); int ReadDescr( FILE* File, int* LineNum = NULL );
int Read_3D_Descr( FILE* File, int* LineNum = NULL ); int Read_3D_Descr( FILE* File, int* LineNum = NULL );
...@@ -156,10 +157,10 @@ public: ...@@ -156,10 +157,10 @@ public:
* has knowledge about the frame and how and where to put status information * has knowledge about the frame and how and where to put status information
* about this object into the frame's message panel. * about this object into the frame's message panel.
* @param frame A WinEDA_DrawFrame in which to print status information. * @param frame A WinEDA_DrawFrame in which to print status information.
*/ */
void Display_Infos( WinEDA_DrawFrame* frame ); void Display_Infos( WinEDA_DrawFrame* frame );
/** /**
* Function HitTest * Function HitTest
* tests if the given wxPoint is within the bounds of this object. * tests if the given wxPoint is within the bounds of this object.
...@@ -168,7 +169,7 @@ public: ...@@ -168,7 +169,7 @@ public:
*/ */
bool HitTest( const wxPoint& refPos ); bool HitTest( const wxPoint& refPos );
/** /**
* Function HitTest (overlayed) * Function HitTest (overlayed)
* tests if the given EDA_Rect intersect the bounds of this object. * tests if the given EDA_Rect intersect the bounds of this object.
...@@ -177,7 +178,7 @@ public: ...@@ -177,7 +178,7 @@ public:
*/ */
bool HitTest( EDA_Rect& refArea ); bool HitTest( EDA_Rect& refArea );
/** /**
* Function GetReference * Function GetReference
* @return wxString - the reference designator text. * @return wxString - the reference designator text.
*/ */
...@@ -185,8 +186,8 @@ public: ...@@ -185,8 +186,8 @@ public:
{ {
return m_Reference->m_Text; return m_Reference->m_Text;
} }
/** /**
* Function Visit * Function Visit
* should be re-implemented for each derived class in order to handle * should be re-implemented for each derived class in order to handle
...@@ -195,15 +196,15 @@ public: ...@@ -195,15 +196,15 @@ public:
* to do so on lists of such data. * to do so on lists of such data.
* @param inspector An INSPECTOR instance to use in the inspection. * @param inspector An INSPECTOR instance to use in the inspection.
* @param testData Arbitrary data used by the inspector. * @param testData Arbitrary data used by the inspector.
* @param scanTypes Which KICAD_T types are of interest and the order * @param scanTypes Which KICAD_T types are of interest and the order
* is significant too, terminated by EOT. * is significant too, terminated by EOT.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE; * else SCAN_CONTINUE;
*/ */
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] ); const KICAD_T scanTypes[] );
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.
...@@ -214,17 +215,17 @@ public: ...@@ -214,17 +215,17 @@ public:
return wxT( "MODULE" ); return wxT( "MODULE" );
} }
#if defined(DEBUG) #if defined (DEBUG)
/**
/**
* Function Show * Function Show
* is used to output the object tree, currently for debugging only. * is used to output the object tree, currently for debugging only.
* @param nestLevel An aid to prettier tree indenting, and is the level * @param nestLevel An aid to prettier tree indenting, and is the level
* of nesting of this object within the overall tree. * of nesting of this object within the overall tree.
* @param os The ostream& to output to. * @param os The ostream& to output to.
*/ */
virtual void Show( int nestLevel, std::ostream& os ); virtual void Show( int nestLevel, std::ostream& os );
#endif #endif
}; };
...@@ -62,20 +62,9 @@ wxString TRACK::ShowWidth() ...@@ -62,20 +62,9 @@ wxString TRACK::ShowWidth()
/***************************/ /***************************/
{ {
wxString msg; wxString msg;
#if 0
double value = To_User_Unit( g_UnitMetric, m_Width, PCB_INTERNAL_UNIT );
if( g_UnitMetric == INCHES ) // Affichage en mils
msg.Printf( wxT( "%.1f" ), value * 1000 );
else
msg.Printf( wxT( "%.3f" ), value );
#else
valeur_param( m_Width, msg ); valeur_param( m_Width, msg );
#endif
return msg; return msg;
} }
...@@ -673,6 +662,26 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ) ...@@ -673,6 +662,26 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx , GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx ,
m_Start.x - ay, m_Start.y + ax, 0, color ); m_Start.x - ay, m_Start.y + ax, 0, color );
} }
// for Buried Vias, draw a partial line :
// orient depending on layer pair
// (so we can see superimposed buried vias ):
if ( Shape() == VIA_BLIND_BURIED )
{
int ax = 0, ay = rayon, bx = 0, by = drill_rayon;
int layer_top, layer_bottom ;
((SEGVIA*)this)->ReturnLayerPair(&layer_top, &layer_bottom);
/* lines for the top layer */
RotatePoint( &ax, &ay, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount);
RotatePoint( &bx, &by, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount);
GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay,
m_Start.x - bx , m_Start.y - by, 0, color );
/* lines for the bottom layer */
ax = 0; ay = rayon; bx = 0; by = drill_rayon;
RotatePoint( &ax, &ay, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount);
RotatePoint( &bx, &by, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount);
GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay,
m_Start.x - bx , m_Start.y - by, 0, color );
}
} }
return; return;
} }
......
...@@ -15,12 +15,17 @@ ...@@ -15,12 +15,17 @@
/**********************/ /**********************/
/* Class EDGE_ZONE */ /* Class EDGE_ZONE */
/**********************/ /**********************/
/* now used only to create a zone outline
* TODO: remove this class and use only the ZONE_CONTAINER::m_Poly
* to create outlines
*/
/* Constructor */ /* Constructor */
EDGE_ZONE::EDGE_ZONE( BOARD_ITEM* parent ) : EDGE_ZONE::EDGE_ZONE( BOARD* parent ) :
DRAWSEGMENT( parent, TYPEEDGEZONE ) DRAWSEGMENT( parent, TYPEEDGEZONE )
{ {
m_Width = 2; // a minimum for visibility, while dragging m_Width = 2; // a minimum for visibility, while dragging
SetNet(0);
} }
...@@ -32,10 +37,42 @@ EDGE_ZONE:: ~EDGE_ZONE() ...@@ -32,10 +37,42 @@ EDGE_ZONE:: ~EDGE_ZONE()
/****************************************/ /****************************************/
bool EDGE_ZONE::Save( FILE* aFile ) const bool EDGE_ZONE::Save( FILE* aFile ) const
/****************************************/ /****************************************/
/* edge_zone is a temporary item only used when creating a zone area.
* it will not saved in file
*/
{ {
return true; return true;
} }
// see pcbstruct.h
void EDGE_ZONE::Display_Infos( WinEDA_DrawFrame* frame )
{
int itype;
wxString msg;
frame->MsgPanel->EraseMsgBox();
itype = m_Type & 0x0F;
msg = wxT( "Edge Zone" );
Affiche_1_Parametre( frame, 1, _( "Type" ), msg, DARKCYAN );
Affiche_1_Parametre( frame, 16, _( "Layer" ),
ReturnPcbLayerName( GetLayer() ), BROWN );
msg.Empty(); msg << GetNet();
Affiche_1_Parametre( frame, 25, _( "Netcode" ), msg, RED );
msg = wxT("???");
if ( m_Parent )
{
EQUIPOT* net = ((BOARD*) m_Parent)->FindNet( GetNet() );
if( net )
msg = net->m_Netname;
}
Affiche_1_Parametre( frame, 34, _( "Netname" ), msg, RED );
}
/************************/ /************************/
/* class ZONE_CONTAINER */ /* class ZONE_CONTAINER */
...@@ -330,26 +367,22 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos ) ...@@ -330,26 +367,22 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
/** /**
* Function HitTestForCorner * Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* "near" means MIN_DIST_IN_PIXELS pixels * "near" means CORNER_MIN_DIST_IN_PIXELS pixels
* @return -1 if none, corner index in .corner <vector> * @return -1 if none, corner index in .corner <vector>
* @param refPos : A wxPoint to test * @param refPos : A wxPoint to test
*/ */
int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
{ {
#define MIN_DIST_IN_PIXELS 5 #define CORNER_MIN_DIST 500 // distance (in internal units) to detect a corner in a zone outline
int dist; int dist;
unsigned item_pos, lim; unsigned item_pos, lim;
lim = m_Poly->corner.size(); lim = m_Poly->corner.size();
m_CornerSelection = -1; m_CornerSelection = -1;
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
int min_dist = frame ? frame->GetZoom() * MIN_DIST_IN_PIXELS : 3;
for ( item_pos = 0; item_pos < lim; item_pos++ ) for ( item_pos = 0; item_pos < lim; item_pos++ )
{ {
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y ); dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y );
if( dist <= min_dist ) if( dist <= CORNER_MIN_DIST )
{ {
m_CornerSelection = item_pos; m_CornerSelection = item_pos;
return item_pos; return item_pos;
...@@ -362,21 +395,17 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) ...@@ -362,21 +395,17 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
/** /**
* Function HitTestForEdge * Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners. * tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* "near" means MIN_DIST_IN_PIXELS pixels * "near" means EDGE_MIN_DIST_IN_PIXELS pixels
* @return -1 if none, or index of the starting corner in .corner <vector> * @return -1 if none, or index of the starting corner in .corner <vector>
* @param refPos : A wxPoint to test * @param refPos : A wxPoint to test
*/ */
int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
{ {
#define MIN_DIST_IN_PIXELS 5 #define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
int dist; int dist;
unsigned item_pos, lim; unsigned item_pos, lim;
lim = m_Poly->corner.size(); lim = m_Poly->corner.size();
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
int min_dist = frame ? frame->GetZoom() * MIN_DIST_IN_PIXELS : 3;
/* Test for an entire segment */ /* Test for an entire segment */
unsigned first_corner_pos = 0, end_segm; unsigned first_corner_pos = 0, end_segm;
m_CornerSelection = -1; m_CornerSelection = -1;
...@@ -402,7 +431,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) ...@@ -402,7 +431,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
m_Poly->corner[item_pos].y, m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x, m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y ); m_Poly->corner[end_segm].y );
if( dist <= min_dist ) if( dist <= EDGE_MIN_DIST )
{ {
m_CornerSelection = item_pos; m_CornerSelection = item_pos;
return item_pos; return item_pos;
......
...@@ -62,7 +62,7 @@ public: ...@@ -62,7 +62,7 @@ public:
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int draw_mode ); const wxPoint& offset, int draw_mode );
int GetNet( void ) { return m_NetCode; } int GetNet( void ) const { return m_NetCode; }
void SetNet( int anet_code ); void SetNet( int anet_code );
/** /**
* Function HitTest * Function HitTest
...@@ -137,19 +137,37 @@ public: ...@@ -137,19 +137,37 @@ public:
/*******************/ /*******************/
/* class EDGE_ZONE */ /* class EDGE_ZONE */
/*******************/ /*******************/
/* Classe used temporary to create a zone outline.
*
* TODO: remove this class and use only the ZONE_CONTAINER::m_Poly
* to create outlines
*/
class EDGE_ZONE : public DRAWSEGMENT class EDGE_ZONE : public DRAWSEGMENT
{ {
private:
int m_NetCode;
public: public:
EDGE_ZONE( BOARD_ITEM* StructFather ); EDGE_ZONE( BOARD * StructFather );
EDGE_ZONE( const EDGE_ZONE& edgezone );
~EDGE_ZONE(); ~EDGE_ZONE();
EDGE_ZONE* Next() { return (EDGE_ZONE*) Pnext; } EDGE_ZONE* Next() { return (EDGE_ZONE*) Pnext; }
EDGE_ZONE* Back() { return (EDGE_ZONE*) Pback; } EDGE_ZONE* Back() { return (EDGE_ZONE*) Pback; }
int GetNet( void ) const { return m_NetCode; }
void SetNet( int anet_code ) { m_NetCode = anet_code; }
/**
* Function Display_Infos
* has knowledge about the frame and how and where to put status information
* about this object into the frame's message panel.
* Is virtual from EDA_BaseStruct.
* @param frame A WinEDA_BasePcbFrame in which to print status information.
*/
void Display_Infos( WinEDA_DrawFrame* frame );
/** /**
* Function Save * Function Save
* writes the data structures for this object out to a FILE in "*.brd" format. * writes the data structures for this object out to a FILE in "*.brd" format.
......
...@@ -139,9 +139,9 @@ DRC::~DRC() ...@@ -139,9 +139,9 @@ DRC::~DRC()
delete m_unconnected[i]; delete m_unconnected[i];
} }
/***********************************************************************/ /*********************************************/
int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/***********************************************************************/ /*********************************************/
{ {
updatePointers(); updatePointers();
...@@ -157,6 +157,33 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) ...@@ -157,6 +157,33 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
} }
/*********************************************/
int DRC::Drc( const EDGE_ZONE* aEdge )
/*********************************************/
/**
* Function Drc
* tests the current EDGE_ZONE segment and returns the result and displays the error
* in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
{
updatePointers();
if( ! doEdgeZoneDrc( aEdge ) )
{
wxASSERT( m_currentMarker );
m_currentMarker->Display_Infos( m_mainWindow );
return BAD_DRC;
}
return OK_DRC;
}
void DRC::RunTests() void DRC::RunTests()
{ {
// someone should have cleared the two lists before calling this. // someone should have cleared the two lists before calling this.
...@@ -169,8 +196,7 @@ void DRC::RunTests() ...@@ -169,8 +196,7 @@ void DRC::RunTests()
testTracks(); testTracks();
// test zone clearances to other zones, pads, tracks, and vias // test zone clearances to other zones, pads, tracks, and vias
if( m_doZonesTest ) testZones(m_doZonesTest);
testZones();
// find and gather unconnected pads. // find and gather unconnected pads.
if( m_doUnconnectedTest ) if( m_doUnconnectedTest )
...@@ -283,9 +309,23 @@ void DRC::testUnconnected() ...@@ -283,9 +309,23 @@ void DRC::testUnconnected()
} }
void DRC::testZones() void DRC::testZones(bool adoTestFillSegments)
{ {
// Test copper areas for valide netcodes
// if a netcode is < 0 the netname was not found when reading a netlist
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii );
if( Area_To_Test->GetNet() <= 0 )
{
m_currentMarker = fillMarker( Area_To_Test,
DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker );
m_pcb->Add( m_currentMarker );
m_currentMarker = 0;
}
}
// Test copper areas outlines, and create markers when needed // Test copper areas outlines, and create markers when needed
m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true ); m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true );
...@@ -296,7 +336,7 @@ void DRC::testZones() ...@@ -296,7 +336,7 @@ void DRC::testZones()
for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() ) for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() )
++m_pcb->m_NbSegmZone; ++m_pcb->m_NbSegmZone;
*/ */
if ( ! adoTestFillSegments ) return;
for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() ) for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() )
{ {
// Test zoneSeg with other zone segments and with all pads // Test zoneSeg with other zone segments and with all pads
...@@ -407,6 +447,34 @@ MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillM ...@@ -407,6 +447,34 @@ MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillM
return fillMe; return fillMe;
} }
MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe )
{
wxString textA = aArea->MenuText( m_pcb );
wxPoint posA = aArea->GetPosition();
if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA );
else
fillMe = new MARKER( aErrorCode, posA, textA, posA );
return fillMe;
}
MARKER* DRC::fillMarker( const EDGE_ZONE * aEdge, const wxPoint & aPos, int aErrorCode, MARKER* fillMe )
{
wxString textA = aEdge->MenuText( m_pcb );
wxPoint posA = aPos;
if( fillMe )
fillMe->SetData( aErrorCode, posA, textA, posA );
else
fillMe = new MARKER( aErrorCode, posA, textA, posA );
return fillMe;
}
/***********************************************************************/ /***********************************************************************/
bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent) #define DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR 21 ///< micro via's layer pair incorrect (layers must be adjacent)
#define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect #define COPPERAREA_INSIDE_COPPERAREA 22 ///< copper area outlines intersect
#define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close #define COPPERAREA_CLOSE_TO_COPPERAREA 23 ///< copper area outlines are too close
#define DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE 24 ///< copper area outline has an incorrect netcode due to a netname not found
/** /**
* Class DRC_ITEM * Class DRC_ITEM
...@@ -358,6 +359,21 @@ private: ...@@ -358,6 +359,21 @@ private:
MARKER* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe ); MARKER* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe );
MARKER* fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe );
/**
* Function fillMarker
* optionally creates a marker and fills it in with information,
* but does not add it to the BOARD. Use this to report any kind of
* DRC problem, or unconnected pad problem.
*
* @param aEdge edge zone to test
* @param aPos position of error
* @param aErrorCode Type of error
* @param fillMe A MARKER* which is to be filled in, or NULL if one is to
* first be allocated, then filled.
*/
MARKER* fillMarker( const EDGE_ZONE * aEdge, const wxPoint & aPos, int aErrorCode, MARKER* fillMe );
//-----<categorical group tests>----------------------------------------- //-----<categorical group tests>-----------------------------------------
...@@ -367,7 +383,7 @@ private: ...@@ -367,7 +383,7 @@ private:
void testUnconnected(); void testUnconnected();
void testZones(); void testZones(bool adoTestFillSegments);
//-----<single "item" tests>----------------------------------------- //-----<single "item" tests>-----------------------------------------
...@@ -395,6 +411,17 @@ private: ...@@ -395,6 +411,17 @@ private:
bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart ); bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart );
/**
* Function doEdgeZoneDrc
* tests the current EDGE_ZONE segment:
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @return bool - false if DRC error or true if OK
*/
bool doEdgeZoneDrc( const EDGE_ZONE* aEdge );
//-----<single tests>---------------------------------------------- //-----<single tests>----------------------------------------------
/** /**
...@@ -467,6 +494,16 @@ public: ...@@ -467,6 +494,16 @@ public:
*/ */
int Drc( TRACK* aRefSeg, TRACK* aList ); int Drc( TRACK* aRefSeg, TRACK* aList );
/**
* Function Drc
* tests the current EDGE_ZONE segment and returns the result and displays the error
* in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int Drc( const EDGE_ZONE* aEdge );
/** /**
* Function DrcBlind * Function DrcBlind
......
...@@ -810,8 +810,8 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -810,8 +810,8 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
if( GetCurItem() && (GetCurItem()->m_Flags & IS_NEW) ) if( GetCurItem() && (GetCurItem()->m_Flags & IS_NEW) )
{ {
End_Zone( &dc ); if ( End_Zone( &dc ) )
SetCurItem( NULL ); SetCurItem( NULL );
} }
break; break;
......
...@@ -406,9 +406,11 @@ void WinEDA_PcbFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos ) ...@@ -406,9 +406,11 @@ void WinEDA_PcbFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
break; break;
case ID_PCB_ZONES_BUTT: case ID_PCB_ZONES_BUTT:
End_Zone( DC ); if ( End_Zone( DC ) )
DrawPanel->m_AutoPAN_Request = FALSE; {
SetCurItem( NULL ); DrawPanel->m_AutoPAN_Request = FALSE;
SetCurItem( NULL );
}
break; break;
case ID_LINE_COMMENT_BUTT: case ID_LINE_COMMENT_BUTT:
......
...@@ -197,7 +197,7 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC ) ...@@ -197,7 +197,7 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC )
/** /**
* Function Abort_Zone_Create_Outline * Function Abort_Zone_Create_Outline
* cancels the Begin_Zone command if at least one EDGE_ZONE has been created. * cancels the Begin_Zone command if at least one EDGE_ZONE was created.
*/ */
{ {
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent; WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
...@@ -235,7 +235,10 @@ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw ) ...@@ -235,7 +235,10 @@ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
next = segment->Next(); next = segment->Next();
if( Redraw && DC ) if( Redraw && DC )
{
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_OR );
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR ); Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR );
}
delete segment; delete segment;
} }
...@@ -388,7 +391,7 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_contai ...@@ -388,7 +391,7 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_contai
zone_container->m_Poly->DeleteCorner(zone_container->m_CornerSelection); zone_container->m_Poly->DeleteCorner(zone_container->m_CornerSelection);
// modify zones outlines accordiing to the new zone_container shape // modify zones outlines according to the new zone_container shape
m_Pcb->AreaPolygonModified( zone_container, true, verbose ); m_Pcb->AreaPolygonModified( zone_container, true, verbose );
if ( DC ) if ( DC )
{ {
...@@ -506,7 +509,7 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) ...@@ -506,7 +509,7 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
break; break;
} }
if( ii == m_Pcb->GetAreaCount() ) // Not found: coul be deleted since last selection if( ii == m_Pcb->GetAreaCount() ) // Not found: could be deleted since last selection
{ {
s_AddCutoutToCurrentZone = false; s_AddCutoutToCurrentZone = false;
s_CurrentZone = NULL; s_CurrentZone = NULL;
...@@ -560,6 +563,14 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) ...@@ -560,6 +563,14 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED; newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED;
newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur; newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur;
newedge->SetLayer( GetScreen()->m_Active_Layer ); newedge->SetLayer( GetScreen()->m_Active_Layer );
newedge->SetNet( s_NetcodeSelection );
if( Drc_On && m_drc->Drc( newedge ) == BAD_DRC )
{
delete newedge;
SetCurItem(NULL);
DisplayError(this, _("DRC error: this start point is inside or too close an other area"));
return NULL;
}
// link into list: // link into list:
newedge->Pnext = oldedge; newedge->Pnext = oldedge;
...@@ -578,12 +589,18 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) ...@@ -578,12 +589,18 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
/* edge in progress : the ending point coordinate was set by Show_New_Zone_Edge_While_Move_Mouse */ /* edge in progress : the ending point coordinate was set by Show_New_Zone_Edge_While_Move_Mouse */
if( oldedge->m_Start != oldedge->m_End ) if( oldedge->m_Start != oldedge->m_End )
{ {
if ( Drc_On && m_drc->Drc( oldedge ) == BAD_DRC )
{
return oldedge;
}
oldedge->m_Flags &= ~(IS_NEW | IS_MOVED); oldedge->m_Flags &= ~(IS_NEW | IS_MOVED);
newedge = new EDGE_ZONE( oldedge ); newedge = new EDGE_ZONE( m_Pcb );
newedge->m_Flags = IS_NEW | IS_MOVED; newedge->m_Flags = IS_NEW | IS_MOVED;
newedge->m_Start = newedge->m_End = oldedge->m_End; newedge->m_Start = newedge->m_End = oldedge->m_End;
newedge->SetLayer( GetScreen()->m_Active_Layer ); newedge->SetLayer( oldedge->GetLayer() );
newedge->SetNet( s_NetcodeSelection );
// link into list: // link into list:
newedge->Pnext = oldedge; newedge->Pnext = oldedge;
...@@ -597,44 +614,65 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) ...@@ -597,44 +614,65 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
/*********************************************/ /*********************************************/
void WinEDA_PcbFrame::End_Zone( wxDC* DC ) bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
/*********************************************/ /*********************************************/
/** Function End_Zone /** Function End_Zone
* Terminates a zone outline creation * Terminates a zone outline creation
* Close the current zone outline considered as a polygon * terminates (if no DRC error ) the zone edge creation process
* put it in the main list m_Pcb->m_ZoneDescriptorList (a vector<ZONE_CONTAINER*>) * @param DC = current Device Context
* @return true if Ok, false if DRC error
* if ok, put it in the main list m_Pcb->m_ZoneDescriptorList (a vector<ZONE_CONTAINER*>)
*/ */
{ {
EDGE_ZONE* edge; if( m_Pcb->m_CurrentLimitZone == NULL ) return true;
int layer = GetScreen()->m_Active_Layer;
EDGE_ZONE* edge = m_Pcb->m_CurrentLimitZone;
if( m_Pcb->m_CurrentLimitZone ) EDGE_ZONE* last_edge = m_Pcb->m_CurrentLimitZone;
{ int layer = edge->GetLayer();
Begin_Zone( DC );
// Validate the current edge:
/* The last segment is a stub: its lenght is 0. if ( edge->m_Start != edge->m_End )
* Use it to close the polygon by setting its ending point coordinate = start point of first segment {
*/ Begin_Zone( DC );
edge = m_Pcb->m_CurrentLimitZone; if ( edge == m_Pcb->m_CurrentLimitZone ) // no new segment -> DRC error
edge->m_Flags &= ~(IS_NEW | IS_MOVED); {
return false;
}
}
while( edge && edge->Next() ) /* The last segment is a stub: its lenght is 0.
{ * Use it to close the polygon by setting its ending point coordinate = start point of first segment
edge = edge->Next(); */
if( edge->m_Flags & STARTPOINT ) /* search first segment outline ( last item of the linked list ) */
break; edge = m_Pcb->m_CurrentLimitZone;
while( edge->Next() )
{
edge = edge->Next();
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
}
edge->m_Flags &= ~(IS_NEW | IS_MOVED); wxPoint curr_endpoint = m_Pcb->m_CurrentLimitZone->m_End;
} m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
edge = m_Pcb->m_CurrentLimitZone;
if ( Drc_On && m_drc->Drc( edge ) == BAD_DRC )
{
edge->m_End = curr_endpoint;
if ( last_edge != edge ) // Remove edge create previously
{
delete edge;
m_Pcb->m_CurrentLimitZone = edge = last_edge;
edge->Pback = NULL;
edge->m_Flags = (IS_NEW | IS_MOVED);
}
SetCurItem( edge );
DisplayError(this, _("DRC error: closing this area creates a drc error with an other area"));
DrawPanel->MouseToCursorSchema();
return false;
}
if( edge ) edge->m_Flags &= ~(IS_NEW | IS_MOVED);
{ Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
}
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
}
DrawPanel->ManageCurseur = NULL; DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL;
...@@ -642,9 +680,9 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC ) ...@@ -642,9 +680,9 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
// Undraw old drawings, because they can have important changes // Undraw old drawings, because they can have important changes
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ ) for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{ {
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea(ii); ZONE_CONTAINER* area = m_Pcb->GetArea(ii);
if( layer == edge_zone->GetLayer() ) if( layer == area->GetLayer() )
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); area->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
} }
/* Put edges in list */ /* Put edges in list */
...@@ -717,6 +755,7 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC ) ...@@ -717,6 +755,7 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
} }
GetScreen()->SetModify(); GetScreen()->SetModify();
return true;
} }
...@@ -744,12 +783,6 @@ static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* ...@@ -744,12 +783,6 @@ static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC*
} }
} }
/* Reinit layer (which can be changed) */
for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() )
{
edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer );
}
/* Redraw the curent edge in its new position */ /* Redraw the curent edge in its new position */
currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone; currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone;
if( Zone_45_Only ) if( Zone_45_Only )
......
This diff is collapsed.
...@@ -1323,56 +1323,6 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y ) ...@@ -1323,56 +1323,6 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y )
return FALSE; return FALSE;
} }
// Test for intersection of sides
//
int CPolyLine::TestIntersection( CPolyLine * poly )
{
if( !GetClosed() )
wxASSERT(0);
if( !poly->GetClosed() )
wxASSERT(0);
for( int ic=0; ic<GetNumContours(); ic++ )
{
int istart = GetContourStart(ic);
int iend = GetContourEnd(ic);
for( int is=istart; is<=iend; is++ )
{
int xf, yf;
if( is < GetContourEnd(ic) )
{
xf = GetX(is+1);
yf = GetY(is+1);
}
else
{
xf = GetX(istart);
yf = GetY(istart);
}
for( int ic2=0; ic2<poly->GetNumContours(); ic2++ )
{
int istart2 = poly->GetContourStart(ic2);
int iend2 = poly->GetContourEnd(ic2);
for( int is2=istart2; is2<=iend2; is2++ )
{
int xf2, yf2;
if( is2 < poly->GetContourEnd(ic2) )
{
xf2 = poly->GetX(is2+1);
yf2 = poly->GetY(is2+1);
}
else
{
xf2 = poly->GetX(istart2);
yf2 = poly->GetY(istart2);
}
// test for intersection between side and side2
}
}
}
}
return 0;
}
// copy data from another poly, but don't draw it // copy data from another poly, but don't draw it
// //
......
...@@ -93,7 +93,6 @@ public: ...@@ -93,7 +93,6 @@ public:
bool TestPointInside( int x, int y ); bool TestPointInside( int x, int y );
bool TestPointInsideContour( int icont, int x, int y ); bool TestPointInsideContour( int icont, int x, int y );
bool IsCutoutContour( int icont ); bool IsCutoutContour( int icont );
int TestIntersection( CPolyLine * poly );
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ); void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment