On line DRC when creating a zone outline
This commit is contained in:
parent
da3f44305b
commit
e9b3322fc0
|
@ -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:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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:
|
||||||
* 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
|
||||||
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 )
|
||||||
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 */
|
||||||
|
|
||||||
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:
|
||||||
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
|
||||||
|
* identify the footprint ( after a full reannotation of the schematic */
|
||||||
|
|
||||||
int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */
|
int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */
|
||||||
int m_Orient; /* orientation en 1/10 degres */
|
int m_Orient; /* orientation en 1/10 degres */
|
||||||
int flag; /* flag utilise en trace rastnest et routage auto */
|
int flag; /* flag utilise en trace rastnest et routage auto */
|
||||||
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
|
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
|
||||||
EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
|
EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
|
||||||
EDA_Rect m_RealBoundaryBox; /* position/taille du module (coord relles) */
|
EDA_Rect m_RealBoundaryBox; /* position/taille du module (coord relles) */
|
||||||
int m_PadNum; // Nombre total de pads
|
int m_PadNum; // Nombre total de pads
|
||||||
int m_AltPadNum; // en placement auto Nombre de pads actifs pour
|
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
|
||||||
|
|
||||||
wxString m_Doc; // Texte de description du module
|
unsigned long m_Link; // variable temporaire ( pour editions, ...)
|
||||||
wxString m_KeyWord; // Liste des mots cles relatifs au module
|
long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies)
|
||||||
|
|
||||||
|
wxString m_Doc; // Texte de description du module
|
||||||
|
wxString m_KeyWord; // Liste des mots cles relatifs au module
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MODULE( BOARD* parent );
|
MODULE( BOARD* parent );
|
||||||
|
@ -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:
|
||||||
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:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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:
|
||||||
|
|
||||||
|
|
||||||
/* 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:
|
||||||
* 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:
|
||||||
*/
|
*/
|
||||||
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:
|
||||||
*/
|
*/
|
||||||
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:
|
||||||
{
|
{
|
||||||
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:
|
||||||
* 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:
|
||||||
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()
|
||||||
/***************************/
|
/***************************/
|
||||||
{
|
{
|
||||||
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 )
|
||||||
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 @@
|
||||||
/**********************/
|
/**********************/
|
||||||
/* 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()
|
||||||
/****************************************/
|
/****************************************/
|
||||||
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 )
|
||||||
/**
|
/**
|
||||||
* 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 )
|
||||||
/**
|
/**
|
||||||
* 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 )
|
||||||
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:
|
||||||
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:
|
||||||
/*******************/
|
/*******************/
|
||||||
/* 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()
|
||||||
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 )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************/
|
||||||
|
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()
|
||||||
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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()
|
||||||
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
|
||||||
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 @@
|
||||||
#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:
|
||||||
|
|
||||||
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:
|
||||||
|
|
||||||
void testUnconnected();
|
void testUnconnected();
|
||||||
|
|
||||||
void testZones();
|
void testZones(bool adoTestFillSegments);
|
||||||
|
|
||||||
|
|
||||||
//-----<single "item" tests>-----------------------------------------
|
//-----<single "item" tests>-----------------------------------------
|
||||||
|
@ -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:
|
||||||
*/
|
*/
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 )
|
||||||
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
|
||||||
|
|
||||||
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 )
|
||||||
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 )
|
||||||
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 )
|
||||||
/* 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 )
|
||||||
|
|
||||||
|
|
||||||
/*********************************************/
|
/*********************************************/
|
||||||
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;
|
||||||
|
EDGE_ZONE* last_edge = m_Pcb->m_CurrentLimitZone;
|
||||||
|
int layer = edge->GetLayer();
|
||||||
|
|
||||||
if( m_Pcb->m_CurrentLimitZone )
|
// Validate the current edge:
|
||||||
{
|
if ( edge->m_Start != edge->m_End )
|
||||||
Begin_Zone( DC );
|
{
|
||||||
|
Begin_Zone( DC );
|
||||||
|
if ( edge == m_Pcb->m_CurrentLimitZone ) // no new segment -> DRC error
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* The last segment is a stub: its lenght is 0.
|
/* 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
|
* Use it to close the polygon by setting its ending point coordinate = start point of first segment
|
||||||
*/
|
*/
|
||||||
edge = m_Pcb->m_CurrentLimitZone;
|
/* search first segment outline ( last item of the linked list ) */
|
||||||
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
|
edge = m_Pcb->m_CurrentLimitZone;
|
||||||
|
while( edge->Next() )
|
||||||
|
{
|
||||||
|
edge = edge->Next();
|
||||||
|
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
|
||||||
|
}
|
||||||
|
|
||||||
while( edge && edge->Next() )
|
wxPoint curr_endpoint = m_Pcb->m_CurrentLimitZone->m_End;
|
||||||
{
|
m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
|
||||||
edge = edge->Next();
|
edge = m_Pcb->m_CurrentLimitZone;
|
||||||
if( edge->m_Flags & STARTPOINT )
|
if ( Drc_On && m_drc->Drc( edge ) == BAD_DRC )
|
||||||
break;
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
|
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
|
||||||
}
|
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
|
||||||
|
|
||||||
if( edge )
|
|
||||||
{
|
|
||||||
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 )
|
||||||
// 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 )
|
||||||
}
|
}
|
||||||
|
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 )
|
||||||
|
|
|
@ -230,7 +230,7 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea )
|
||||||
int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
|
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
|
||||||
{
|
{
|
||||||
CPolyLine* curr_polygon = CurrArea->m_Poly;
|
CPolyLine* curr_polygon = CurrArea->m_Poly;
|
||||||
int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag
|
int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag
|
||||||
|
|
||||||
if( test == -1 && !bRetainArcs )
|
if( test == -1 && !bRetainArcs )
|
||||||
|
@ -248,7 +248,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
str += wxT( "Manual correction is recommended." );
|
str += wxT( "Manual correction is recommended." );
|
||||||
wxMessageBox( str );
|
wxMessageBox( str );
|
||||||
|
|
||||||
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
|
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
|
||||||
}
|
}
|
||||||
return -1; // arcs intersect with other sides, error
|
return -1; // arcs intersect with other sides, error
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false )
|
if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false )
|
||||||
{
|
{
|
||||||
wxString str;
|
wxString str;
|
||||||
str.Printf( wxT( "Area %8.8X of net \"%s\" is self-intersecting and will be clipped.\n" ),
|
str.Printf( wxT(
|
||||||
|
"Area %8.8X of net \"%s\" is self-intersecting and will be clipped.\n" ),
|
||||||
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
|
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
|
||||||
str += wxT( "This may result in splitting the area.\n" );
|
str += wxT( "This may result in splitting the area.\n" );
|
||||||
str += wxT( "If the area is complex, this may take a few seconds." );
|
str += wxT( "If the area is complex, this may take a few seconds." );
|
||||||
|
@ -283,7 +284,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
int n_poly = CurrArea->m_Poly->NormalizeWithGpc( pa, bRetainArcs );
|
int n_poly = CurrArea->m_Poly->NormalizeWithGpc( pa, bRetainArcs );
|
||||||
if( n_poly > 1 ) // i.e if clipping has created some polygons, we must add these new copper areas
|
if( n_poly > 1 ) // i.e if clipping has created some polygons, we must add these new copper areas
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* NewArea;
|
ZONE_CONTAINER* NewArea;
|
||||||
for( int ip = 1; ip < n_poly; ip++ )
|
for( int ip = 1; ip < n_poly; ip++ )
|
||||||
{
|
{
|
||||||
// create new copper area and copy poly into it
|
// create new copper area and copy poly into it
|
||||||
|
@ -448,94 +449,95 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
|
||||||
if( area_to_test->GetNet() != area2->GetNet() )
|
if( area_to_test->GetNet() != area2->GetNet() )
|
||||||
continue;
|
continue;
|
||||||
if( area_to_test == area2 )
|
if( area_to_test == area2 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// see if areas are on same layer
|
// see if areas are on same layer
|
||||||
if( area_to_test->GetLayer() != area2->GetLayer() )
|
if( area_to_test->GetLayer() != area2->GetLayer() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CPolyLine* poly2 = area2->m_Poly;
|
CPolyLine* poly2 = area2->m_Poly;
|
||||||
|
|
||||||
// test bounding rects
|
// test bounding rects
|
||||||
CRect b1 = poly1->GetCornerBounds();
|
CRect b1 = poly1->GetCornerBounds();
|
||||||
CRect b2 = poly2->GetCornerBounds();
|
CRect b2 = poly2->GetCornerBounds();
|
||||||
if( b1.bottom > b2.top
|
if( b1.bottom > b2.top
|
||||||
|| b1.top < b2.bottom
|
|| b1.top < b2.bottom
|
||||||
|| b1.left > b2.right
|
|| b1.left > b2.right
|
||||||
|| b1.right < b2.left )
|
|| b1.right < b2.left )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// test for intersecting segments
|
// test for intersecting segments
|
||||||
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
|
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
|
||||||
{
|
{
|
||||||
int is1 = poly1->GetContourStart( icont1 );
|
int is1 = poly1->GetContourStart( icont1 );
|
||||||
int ie1 = poly1->GetContourEnd( icont1 );
|
int ie1 = poly1->GetContourEnd( icont1 );
|
||||||
for( int ic1 = is1; ic1<=ie1; ic1++ )
|
for( int ic1 = is1; ic1<=ie1; ic1++ )
|
||||||
{
|
{
|
||||||
int xi1 = poly1->GetX( ic1 );
|
int xi1 = poly1->GetX( ic1 );
|
||||||
int yi1 = poly1->GetY( ic1 );
|
int yi1 = poly1->GetY( ic1 );
|
||||||
int xf1, yf1, style1;
|
int xf1, yf1, style1;
|
||||||
if( ic1 < ie1 )
|
if( ic1 < ie1 )
|
||||||
{
|
{
|
||||||
xf1 = poly1->GetX( ic1 + 1 );
|
xf1 = poly1->GetX( ic1 + 1 );
|
||||||
yf1 = poly1->GetY( ic1 + 1 );
|
yf1 = poly1->GetY( ic1 + 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf1 = poly1->GetX( is1 );
|
xf1 = poly1->GetX( is1 );
|
||||||
yf1 = poly1->GetY( is1 );
|
yf1 = poly1->GetY( is1 );
|
||||||
}
|
}
|
||||||
style1 = poly1->GetSideStyle( ic1 );
|
style1 = poly1->GetSideStyle( ic1 );
|
||||||
for( int icont2 = 0; icont2 < poly2->GetNumContours(); icont2++ )
|
for( int icont2 = 0; icont2 < poly2->GetNumContours(); icont2++ )
|
||||||
{
|
{
|
||||||
int is2 = poly2->GetContourStart( icont2 );
|
int is2 = poly2->GetContourStart( icont2 );
|
||||||
int ie2 = poly2->GetContourEnd( icont2 );
|
int ie2 = poly2->GetContourEnd( icont2 );
|
||||||
for( int ic2 = is2; ic2<=ie2; ic2++ )
|
for( int ic2 = is2; ic2<=ie2; ic2++ )
|
||||||
{
|
{
|
||||||
int xi2 = poly2->GetX( ic2 );
|
int xi2 = poly2->GetX( ic2 );
|
||||||
int yi2 = poly2->GetY( ic2 );
|
int yi2 = poly2->GetY( ic2 );
|
||||||
int xf2, yf2, style2;
|
int xf2, yf2, style2;
|
||||||
if( ic2 < ie2 )
|
if( ic2 < ie2 )
|
||||||
{
|
{
|
||||||
xf2 = poly2->GetX( ic2 + 1 );
|
xf2 = poly2->GetX( ic2 + 1 );
|
||||||
yf2 = poly2->GetY( ic2 + 1 );
|
yf2 = poly2->GetY( ic2 + 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf2 = poly2->GetX( is2 );
|
xf2 = poly2->GetX( is2 );
|
||||||
yf2 = poly2->GetY( is2 );
|
yf2 = poly2->GetY( is2 );
|
||||||
}
|
}
|
||||||
style2 = poly2->GetSideStyle( ic2 );
|
style2 = poly2->GetSideStyle( ic2 );
|
||||||
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
|
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
|
||||||
xi2, yi2, xf2, yf2, style2 );
|
xi2, yi2, xf2, yf2, style2 );
|
||||||
if( n_int )
|
if( n_int )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
||||||
// test a corner inside an outline (only one corner is enought)
|
// test a corner inside an outline (only one corner is enought)
|
||||||
/* for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ )
|
for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ )
|
||||||
{
|
{
|
||||||
int x = poly2->GetX( ic2 );
|
int x = poly2->GetX( ic2 );
|
||||||
int y = poly2->GetY( ic2 );
|
int y = poly2->GetY( ic2 );
|
||||||
if( poly1->TestPointInside( x, y ) )
|
if( poly1->TestPointInside( x, y ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ )
|
|
||||||
{
|
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ )
|
||||||
int x = poly1->GetX( ic1 );
|
{
|
||||||
int y = poly1->GetY( ic1 );
|
int x = poly1->GetX( ic1 );
|
||||||
if( poly2->TestPointInside( x, y ) )
|
int y = poly1->GetY( ic1 );
|
||||||
{
|
if( poly2->TestPointInside( x, y ) )
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
*/ }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -636,32 +638,34 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !bInt )
|
if( !bInt )
|
||||||
{
|
{
|
||||||
/* if( bArcInt ) return 0;
|
if( bArcInt )
|
||||||
|
return 0;
|
||||||
|
|
||||||
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
||||||
// test a corner inside an outline (only one corner is enought)
|
// test a corner inside an outline (only one corner is enought)
|
||||||
for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ )
|
for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ )
|
||||||
{
|
{
|
||||||
int x = poly2->GetX( ic2 );
|
int x = poly2->GetX( ic2 );
|
||||||
int y = poly2->GetY( ic2 );
|
int y = poly2->GetY( ic2 );
|
||||||
if( poly1->TestPointInside( x, y ) )
|
if( poly1->TestPointInside( x, y ) )
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ )
|
|
||||||
{
|
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ )
|
||||||
int x = poly1->GetX( ic1 );
|
{
|
||||||
int y = poly1->GetY( ic1 );
|
int x = poly1->GetX( ic1 );
|
||||||
if( poly2->TestPointInside( x, y ) )
|
int y = poly1->GetY( ic1 );
|
||||||
{
|
if( poly2->TestPointInside( x, y ) )
|
||||||
return 1;
|
{
|
||||||
}
|
return 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*/ return 0;
|
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
if( bArcInt )
|
if( bArcInt )
|
||||||
return 2;
|
return 2;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -777,8 +781,8 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 // Currently not used: work in progress
|
||||||
|
|
||||||
#if 0 // Currently not used: work in progress
|
|
||||||
/**
|
/**
|
||||||
* Function Is_Area_Inside_Area
|
* Function Is_Area_Inside_Area
|
||||||
* Test a given area to see if it is inside an other area, or an other area is inside the given area
|
* Test a given area to see if it is inside an other area, or an other area is inside the given area
|
||||||
|
@ -786,48 +790,52 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
|
||||||
* @param Area_Ref: the given area to compare with other areas
|
* @param Area_Ref: the given area to compare with other areas
|
||||||
* used to remove redundant areas
|
* used to remove redundant areas
|
||||||
*/
|
*/
|
||||||
ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref)
|
ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref )
|
||||||
{
|
{
|
||||||
|
int corners_inside_count;
|
||||||
|
|
||||||
int corners_inside_count;
|
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
||||||
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
{
|
||||||
{
|
ZONE_CONTAINER* Area_To_Test = GetArea( ia );
|
||||||
ZONE_CONTAINER* Area_To_Test = GetArea( ia );
|
|
||||||
|
|
||||||
if( Area_Ref == Area_To_Test )
|
if( Area_Ref == Area_To_Test )
|
||||||
continue;
|
continue;
|
||||||
// test for same layer
|
|
||||||
if( Area_Ref->GetLayer() != Area_To_Test->GetLayer() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// test if Area_Ref inside Area_To_Test
|
// test for same layer
|
||||||
corners_inside_count = Area_Ref->m_Poly->GetNumCorners();
|
if( Area_Ref->GetLayer() != Area_To_Test->GetLayer() )
|
||||||
for( int ic = 0; ic < Area_Ref->m_Poly->GetNumCorners(); ic++ )
|
continue;
|
||||||
{
|
|
||||||
int x = Area_Ref->m_Poly->GetX( ic );
|
|
||||||
int y = Area_Ref->m_Poly->GetY( ic );
|
|
||||||
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
|
||||||
corners_inside_count--;
|
|
||||||
}
|
|
||||||
if ( corners_inside_count == 0 )
|
|
||||||
return Area_Ref;
|
|
||||||
|
|
||||||
// test if Area_To_Test inside Area_Ref
|
// test if Area_Ref inside Area_To_Test
|
||||||
corners_inside_count = Area_To_Test->m_Poly->GetNumCorners();
|
corners_inside_count = Area_Ref->m_Poly->GetNumCorners();
|
||||||
for( int ic2 = 0; ic2 < Area_To_Test->m_Poly->GetNumCorners(); ic2++ )
|
for( int ic = 0; ic < Area_Ref->m_Poly->GetNumCorners(); ic++ )
|
||||||
{
|
{
|
||||||
int x = Area_To_Test->m_Poly->GetX( ic2 );
|
int x = Area_Ref->m_Poly->GetX( ic );
|
||||||
int y = Area_To_Test->m_Poly->GetY( ic2 );
|
int y = Area_Ref->m_Poly->GetY( ic );
|
||||||
if( Area_Ref->m_Poly->TestPointInside( x, y ) )
|
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
||||||
corners_inside_count--;
|
corners_inside_count--;
|
||||||
}
|
}
|
||||||
if ( corners_inside_count == 0 )
|
|
||||||
return Area_Ref;
|
|
||||||
|
|
||||||
}
|
if( corners_inside_count == 0 )
|
||||||
|
return Area_Ref;
|
||||||
return NULL;
|
|
||||||
|
// test if Area_To_Test inside Area_Ref
|
||||||
|
corners_inside_count = Area_To_Test->m_Poly->GetNumCorners();
|
||||||
|
for( int ic2 = 0; ic2 < Area_To_Test->m_Poly->GetNumCorners(); ic2++ )
|
||||||
|
{
|
||||||
|
int x = Area_To_Test->m_Poly->GetX( ic2 );
|
||||||
|
int y = Area_To_Test->m_Poly->GetY( ic2 );
|
||||||
|
if( Area_Ref->m_Poly->TestPointInside( x, y ) )
|
||||||
|
corners_inside_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( corners_inside_count == 0 )
|
||||||
|
return Area_Ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -835,14 +843,14 @@ ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref)
|
||||||
* Function Test_Drc_Areas_Outlines_To_Areas_Outlines
|
* Function Test_Drc_Areas_Outlines_To_Areas_Outlines
|
||||||
* Test Areas outlines for DRC:
|
* Test Areas outlines for DRC:
|
||||||
* Test areas inside other areas
|
* Test areas inside other areas
|
||||||
* Test areas too close
|
* Test areas too close
|
||||||
* @param aArea_To_Examine: area to compare with other areas. if NULL: all areas are compared tp all others
|
* @param aArea_To_Examine: area to compare with other areas. if NULL: all areas are compared tp all others
|
||||||
* @param aCreate_Markers: if true create DRC markers. False: do not creates anything
|
* @param aCreate_Markers: if true create DRC markers. False: do not creates anything
|
||||||
* @return errors count
|
* @return errors count
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
|
int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
|
||||||
bool aCreate_Markers)
|
bool aCreate_Markers )
|
||||||
{
|
{
|
||||||
wxString str;
|
wxString str;
|
||||||
long nerrors = 0;
|
long nerrors = 0;
|
||||||
|
@ -851,19 +859,21 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
||||||
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* Area_Ref = GetArea( ia );
|
ZONE_CONTAINER* Area_Ref = GetArea( ia );
|
||||||
if ( aArea_To_Examine && (aArea_To_Examine != Area_Ref) )
|
if( aArea_To_Examine && (aArea_To_Examine != Area_Ref) )
|
||||||
continue;
|
continue;
|
||||||
for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ )
|
for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ )
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* Area_To_Test = GetArea( ia2 );
|
ZONE_CONTAINER* Area_To_Test = GetArea( ia2 );
|
||||||
|
|
||||||
if( Area_Ref == Area_To_Test )
|
if( Area_Ref == Area_To_Test )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// test for same layer
|
// test for same layer
|
||||||
if( Area_Ref->GetLayer() != Area_To_Test->GetLayer() )
|
if( Area_Ref->GetLayer() != Area_To_Test->GetLayer() )
|
||||||
continue;
|
continue;
|
||||||
// Test for same net
|
|
||||||
if( Area_Ref->GetNet() == Area_To_Test->GetNet() )
|
// Test for same net
|
||||||
|
if( Area_Ref->GetNet() == Area_To_Test->GetNet() && Area_Ref->GetNet() > 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// test for some corners of Area_Ref inside Area_To_Test
|
// test for some corners of Area_Ref inside Area_To_Test
|
||||||
|
@ -874,20 +884,20 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
||||||
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
||||||
{
|
{
|
||||||
// COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
|
// COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
|
||||||
if ( aCreate_Markers )
|
if( aCreate_Markers )
|
||||||
{
|
{
|
||||||
wxString msg1 = Area_Ref->MenuText(this);
|
wxString msg1 = Area_Ref->MenuText( this );
|
||||||
wxString msg2 = Area_To_Test->MenuText(this);
|
wxString msg2 = Area_To_Test->MenuText( this );
|
||||||
MARKER* marker = new MARKER( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ),
|
MARKER* marker = new MARKER( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ),
|
||||||
msg1, wxPoint( x, y ),
|
msg1, wxPoint( x, y ),
|
||||||
msg2, wxPoint( x, y ) );
|
msg2, wxPoint( x, y ) );
|
||||||
Add( marker );
|
Add( marker );
|
||||||
}
|
}
|
||||||
nerrors++;
|
nerrors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test for some corners of Area_To_Test inside Area_Ref
|
// test for some corners of Area_To_Test inside Area_Ref
|
||||||
for( int ic2 = 0; ic2 < Area_To_Test->m_Poly->GetNumCorners(); ic2++ )
|
for( int ic2 = 0; ic2 < Area_To_Test->m_Poly->GetNumCorners(); ic2++ )
|
||||||
{
|
{
|
||||||
int x = Area_To_Test->m_Poly->GetX( ic2 );
|
int x = Area_To_Test->m_Poly->GetX( ic2 );
|
||||||
|
@ -895,15 +905,15 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
||||||
if( Area_Ref->m_Poly->TestPointInside( x, y ) )
|
if( Area_Ref->m_Poly->TestPointInside( x, y ) )
|
||||||
{
|
{
|
||||||
// COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
|
// COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
|
||||||
if ( aCreate_Markers )
|
if( aCreate_Markers )
|
||||||
{
|
{
|
||||||
wxString msg1 = Area_To_Test->MenuText(this);
|
wxString msg1 = Area_To_Test->MenuText( this );
|
||||||
wxString msg2 = Area_Ref->MenuText(this);
|
wxString msg2 = Area_Ref->MenuText( this );
|
||||||
MARKER* marker = new MARKER( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ),
|
MARKER* marker = new MARKER( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ),
|
||||||
msg1, wxPoint( x, y ),
|
msg1, wxPoint( x, y ),
|
||||||
msg2, wxPoint( x, y ) );
|
msg2, wxPoint( x, y ) );
|
||||||
Add( marker );
|
Add( marker );
|
||||||
}
|
}
|
||||||
nerrors++;
|
nerrors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -950,33 +960,28 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
||||||
}
|
}
|
||||||
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 );
|
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 );
|
||||||
int x, y;
|
int x, y;
|
||||||
int d = ::GetClearanceBetweenSegments( bx1,
|
int d = ::GetClearanceBetweenSegments(
|
||||||
by1,
|
bx1, by1, bx2, by2, bstyle,
|
||||||
bx2,
|
0,
|
||||||
by2,
|
ax1, ay1, ax2,
|
||||||
bstyle,
|
ay2, astyle,
|
||||||
0,
|
0,
|
||||||
ax1,
|
g_DesignSettings.
|
||||||
ay1,
|
m_TrackClearence,
|
||||||
ax2,
|
&x, &y );
|
||||||
ay2,
|
|
||||||
astyle,
|
|
||||||
0,
|
|
||||||
g_DesignSettings.m_TrackClearence,
|
|
||||||
&x,
|
|
||||||
&y );
|
|
||||||
if( d < g_DesignSettings.m_TrackClearence )
|
if( d < g_DesignSettings.m_TrackClearence )
|
||||||
{
|
{
|
||||||
// COPPERAREA_COPPERAREA error : intersect or too close
|
// COPPERAREA_COPPERAREA error : intersect or too close
|
||||||
if ( aCreate_Markers )
|
if( aCreate_Markers )
|
||||||
{
|
{
|
||||||
wxString msg1 = Area_Ref->MenuText(this);
|
wxString msg1 = Area_Ref->MenuText( this );
|
||||||
wxString msg2 = Area_To_Test->MenuText(this);
|
wxString msg2 = Area_To_Test->MenuText( this );
|
||||||
MARKER* marker = new MARKER( COPPERAREA_CLOSE_TO_COPPERAREA, wxPoint( x, y ),
|
MARKER* marker = new MARKER( COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||||
msg1, wxPoint( x, y ),
|
wxPoint( x, y ),
|
||||||
msg2, wxPoint( x, y ) );
|
msg1, wxPoint( x, y ),
|
||||||
Add( marker );
|
msg2, wxPoint( x, y ) );
|
||||||
}
|
Add( marker );
|
||||||
|
}
|
||||||
nerrors++;
|
nerrors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -985,7 +990,94 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nerrors;
|
return nerrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function doEdgeZoneDrc
|
||||||
|
* 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 bool - false if DRC error or true if OK
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge )
|
||||||
|
{
|
||||||
|
wxString str;
|
||||||
|
|
||||||
|
// iterate through all areas
|
||||||
|
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ia2 );
|
||||||
|
|
||||||
|
// test for same layer
|
||||||
|
if( Area_To_Test->GetLayer() != aEdge->GetLayer() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Test for same net
|
||||||
|
if( (aEdge->GetNet() == Area_To_Test->GetNet()) && (aEdge->GetNet() > 0) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// test for ending line inside Area_To_Test
|
||||||
|
int x = aEdge->m_End.x;
|
||||||
|
int y = aEdge->m_End.y;
|
||||||
|
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
|
||||||
|
{
|
||||||
|
// COPPERAREA_COPPERAREA error: corner inside copper area
|
||||||
|
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ),
|
||||||
|
COPPERAREA_INSIDE_COPPERAREA,
|
||||||
|
m_currentMarker );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now test spacing between areas
|
||||||
|
int astyle = CPolyLine::STRAIGHT;
|
||||||
|
int ax1 = aEdge->m_Start.x;
|
||||||
|
int ay1 = aEdge->m_Start.y;
|
||||||
|
int ax2 = aEdge->m_End.x;
|
||||||
|
int ay2 = aEdge->m_End.y;
|
||||||
|
for( int icont2 = 0; icont2 < Area_To_Test->m_Poly->GetNumContours(); icont2++ )
|
||||||
|
{
|
||||||
|
int ic_start2 = Area_To_Test->m_Poly->GetContourStart( icont2 );
|
||||||
|
int ic_end2 = Area_To_Test->m_Poly->GetContourEnd( icont2 );
|
||||||
|
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
|
||||||
|
{
|
||||||
|
int bx1 = Area_To_Test->m_Poly->GetX( ic2 );
|
||||||
|
int by1 = Area_To_Test->m_Poly->GetY( ic2 );
|
||||||
|
int bx2, by2;
|
||||||
|
if( ic2 == ic_end2 )
|
||||||
|
{
|
||||||
|
bx2 = Area_To_Test->m_Poly->GetX( ic_start2 );
|
||||||
|
by2 = Area_To_Test->m_Poly->GetY( ic_start2 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bx2 = Area_To_Test->m_Poly->GetX( ic2 + 1 );
|
||||||
|
by2 = Area_To_Test->m_Poly->GetY( ic2 + 1 );
|
||||||
|
}
|
||||||
|
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 );
|
||||||
|
int x, y;
|
||||||
|
int d = ::GetClearanceBetweenSegments( bx1, by1, bx2, by2, bstyle,
|
||||||
|
0,
|
||||||
|
ax1, ay1, ax2, ay2, astyle,
|
||||||
|
0,
|
||||||
|
g_DesignSettings.m_ZoneClearence,
|
||||||
|
&x, &y );
|
||||||
|
if( d < g_DesignSettings.m_ZoneClearence )
|
||||||
|
{
|
||||||
|
// COPPERAREA_COPPERAREA error : edge intersect or too close
|
||||||
|
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ),
|
||||||
|
COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||||
|
m_currentMarker );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -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:
|
||||||
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 );
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue