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
Please add newer entries at the top, list the date and your name with
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>
================================================================================
......
......@@ -491,10 +491,11 @@ public:
/**
* Function End_Zone
* terminates the zone edge creation process
* terminates (if no DRC error ) the zone edge creation process
* @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()
* Calculate the zone filling for the outline zone_container
......
......@@ -56,7 +56,7 @@ public:
* Is virtual from EDA_BaseStruct.
* @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:
return wxString( _("Copper area inside copper area"));
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:
return wxString( wxT("PROGRAM BUG, PLEASE LEAVE THE ROOM.") );
......@@ -83,7 +86,7 @@ wxString DRC_ITEM::ShowCoord( const wxPoint& aPos )
wxString temp;
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(")");
......
......@@ -37,7 +37,6 @@ enum Mod_Attribut /* Attributs d'un module */
class MODULE : public BOARD_ITEM
{
public:
wxPoint m_Pos; // Real coord on board
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_Value; // texte valeur du composant (74LS00, 22K..)
wxString m_LibRef; /* nom du module en librairie */
int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */
int m_Orient; /* orientation en 1/10 degres */
int flag; /* flag utilise en trace rastnest et routage auto */
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
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
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_Orient; /* orientation en 1/10 degres */
int flag; /* flag utilise en trace rastnest et routage auto */
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
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
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, ...)
long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies)
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, ...)
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
wxString m_Doc; // Texte de description du module
wxString m_KeyWord; // Liste des mots cles relatifs au module
public:
MODULE( BOARD* parent );
......@@ -77,11 +78,11 @@ public:
MODULE* Next() { return (MODULE*) Pnext; }
void Set_Rectangle_Encadrement();/* mise a jour du rect d'encadrement
* en coord locales (orient 0 et origine = pos module) */
void Set_Rectangle_Encadrement(); /* mise a jour du rect d'encadrement
* en coord locales (orient 0 et origine = pos module) */
void SetRectangleExinscrit();/* mise a jour du rect d'encadrement
* et de la surface en coord reelles */
void SetRectangleExinscrit(); /* mise a jour du rect d'encadrement
* et de la surface en coord reelles */
/**
* Function GetPosition
......@@ -94,7 +95,7 @@ public:
return m_Pos;
}
// deplacements
void SetPosition( const wxPoint& newpos );
void SetOrientation( int newangle );
......@@ -105,7 +106,7 @@ public:
/**
* Function IsLocked
* (virtual from BOARD_ITEM )
* (virtual from BOARD_ITEM )
* @returns bool - true if the MODULE is locked, else false
*/
bool IsLocked() const
......@@ -129,15 +130,15 @@ public:
/* Reading and writing data on files */
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @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 ReadDescr( 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
* about this object into the frame's message panel.
* @param frame A WinEDA_DrawFrame in which to print status information.
*/
*/
void Display_Infos( WinEDA_DrawFrame* frame );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
......@@ -168,7 +169,7 @@ public:
*/
bool HitTest( const wxPoint& refPos );
/**
* Function HitTest (overlayed)
* tests if the given EDA_Rect intersect the bounds of this object.
......@@ -177,7 +178,7 @@ public:
*/
bool HitTest( EDA_Rect& refArea );
/**
/**
* Function GetReference
* @return wxString - the reference designator text.
*/
......@@ -185,8 +186,8 @@ public:
{
return m_Reference->m_Text;
}
/**
* Function Visit
* 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.
* @param inspector An INSPECTOR instance to use in the inspection.
* @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.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE;
*/
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] );
/**
* Function GetClass
* returns the class name.
......@@ -214,17 +215,17 @@ public:
return wxT( "MODULE" );
}
#if defined(DEBUG)
/**
#if defined (DEBUG)
/**
* Function Show
* 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.
* @param os The ostream& to output to.
*/
virtual void Show( int nestLevel, std::ostream& os );
#endif
};
......@@ -62,20 +62,9 @@ wxString TRACK::ShowWidth()
/***************************/
{
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 );
#endif
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 ,
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;
}
......
......@@ -15,12 +15,17 @@
/**********************/
/* 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 */
EDGE_ZONE::EDGE_ZONE( BOARD_ITEM* parent ) :
EDGE_ZONE::EDGE_ZONE( BOARD* parent ) :
DRAWSEGMENT( parent, TYPEEDGEZONE )
{
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
/****************************************/
/* edge_zone is a temporary item only used when creating a zone area.
* it will not saved in file
*/
{
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 */
......@@ -330,26 +367,22 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
/**
* Function HitTestForCorner
* 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>
* @param refPos : A wxPoint to test
*/
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;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
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++ )
{
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;
return item_pos;
......@@ -362,21 +395,17 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
/**
* Function HitTestForEdge
* 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>
* @param refPos : A wxPoint to test
*/
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;
unsigned item_pos, lim;
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 */
unsigned first_corner_pos = 0, end_segm;
m_CornerSelection = -1;
......@@ -402,7 +431,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y );
if( dist <= min_dist )
if( dist <= EDGE_MIN_DIST )
{
m_CornerSelection = item_pos;
return item_pos;
......
......@@ -62,7 +62,7 @@ public:
void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int draw_mode );
int GetNet( void ) { return m_NetCode; }
int GetNet( void ) const { return m_NetCode; }
void SetNet( int anet_code );
/**
* Function HitTest
......@@ -137,19 +137,37 @@ public:
/*******************/
/* 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
{
private:
int m_NetCode;
public:
EDGE_ZONE( BOARD_ITEM* StructFather );
EDGE_ZONE( const EDGE_ZONE& edgezone );
EDGE_ZONE( BOARD * StructFather );
~EDGE_ZONE();
EDGE_ZONE* Next() { return (EDGE_ZONE*) Pnext; }
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
* writes the data structures for this object out to a FILE in "*.brd" format.
......
......@@ -139,9 +139,9 @@ DRC::~DRC()
delete m_unconnected[i];
}
/***********************************************************************/
/*********************************************/
int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/***********************************************************************/
/*********************************************/
{
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()
{
// someone should have cleared the two lists before calling this.
......@@ -169,8 +196,7 @@ void DRC::RunTests()
testTracks();
// test zone clearances to other zones, pads, tracks, and vias
if( m_doZonesTest )
testZones();
testZones(m_doZonesTest);
// find and gather unconnected pads.
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
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() )
++m_pcb->m_NbSegmZone;
*/
if ( ! adoTestFillSegments ) return;
for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() )
{
// 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;
}
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 )
......
......@@ -57,6 +57,7 @@
#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_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
......@@ -358,6 +359,21 @@ private:
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>-----------------------------------------
......@@ -367,7 +383,7 @@ private:
void testUnconnected();
void testZones();
void testZones(bool adoTestFillSegments);
//-----<single "item" tests>-----------------------------------------
......@@ -395,6 +411,17 @@ private:
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>----------------------------------------------
/**
......@@ -467,6 +494,16 @@ public:
*/
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
......
......@@ -810,8 +810,8 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
DrawPanel->MouseToCursorSchema();
if( GetCurItem() && (GetCurItem()->m_Flags & IS_NEW) )
{
End_Zone( &dc );
SetCurItem( NULL );
if ( End_Zone( &dc ) )
SetCurItem( NULL );
}
break;
......
......@@ -406,9 +406,11 @@ void WinEDA_PcbFrame::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
break;
case ID_PCB_ZONES_BUTT:
End_Zone( DC );
DrawPanel->m_AutoPAN_Request = FALSE;
SetCurItem( NULL );
if ( End_Zone( DC ) )
{
DrawPanel->m_AutoPAN_Request = FALSE;
SetCurItem( NULL );
}
break;
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
* 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;
......@@ -235,7 +235,10 @@ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
next = segment->Next();
if( Redraw && DC )
{
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_OR );
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR );
}
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);
// 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 );
if ( DC )
{
......@@ -506,7 +509,7 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
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_CurrentZone = NULL;
......@@ -560,6 +563,14 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED;
newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur;
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:
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 */
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);
newedge = new EDGE_ZONE( oldedge );
newedge = new EDGE_ZONE( m_Pcb );
newedge->m_Flags = IS_NEW | IS_MOVED;
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:
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
* Terminates a zone outline creation
* Close the current zone outline considered as a polygon
* put it in the main list m_Pcb->m_ZoneDescriptorList (a vector<ZONE_CONTAINER*>)
* terminates (if no DRC error ) the zone edge creation process
* @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;
int layer = GetScreen()->m_Active_Layer;
if( m_Pcb->m_CurrentLimitZone )
{
Begin_Zone( DC );
/* 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 = m_Pcb->m_CurrentLimitZone;
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
if( m_Pcb->m_CurrentLimitZone == NULL ) return true;
EDGE_ZONE* edge = m_Pcb->m_CurrentLimitZone;
EDGE_ZONE* last_edge = m_Pcb->m_CurrentLimitZone;
int layer = edge->GetLayer();
// Validate the current edge:
if ( edge->m_Start != edge->m_End )
{
Begin_Zone( DC );
if ( edge == m_Pcb->m_CurrentLimitZone ) // no new segment -> DRC error
{
return false;
}
}
while( edge && edge->Next() )
{
edge = edge->Next();
if( edge->m_Flags & STARTPOINT )
break;
/* 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
*/
/* search first segment outline ( last item of the linked list ) */
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);
m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
}
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
}
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
......@@ -642,9 +680,9 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
// Undraw old drawings, because they can have important changes
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea(ii);
if( layer == edge_zone->GetLayer() )
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
ZONE_CONTAINER* area = m_Pcb->GetArea(ii);
if( layer == area->GetLayer() )
area->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
}
/* Put edges in list */
......@@ -717,6 +755,7 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
}
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 */
currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone;
if( Zone_45_Only )
......
This diff is collapsed.
......@@ -1323,56 +1323,6 @@ bool CPolyLine::TestPointInsideContour( int icont, int x, int y )
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
//
......
......@@ -93,7 +93,6 @@ public:
bool TestPointInside( int x, int y );
bool TestPointInsideContour( int icont, int x, int y );
bool IsCutoutContour( int icont );
int TestIntersection( CPolyLine * poly );
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