First draft (and first code..) about new zone handling

This commit is contained in:
CHARRAS 2007-12-29 19:15:58 +00:00
parent ee3d984445
commit 5eda8a52ce
43 changed files with 5444 additions and 376 deletions

View File

@ -1,6 +1,6 @@
ADD_DEFINITIONS(-DPCBNEW)
INCLUDE_DIRECTORIES(../pcbnew)
INCLUDE_DIRECTORIES(../pcbnew ../polygon)
SET(3D-VIEWER_SRCS
3d_aux.cpp

View File

@ -1,5 +1,5 @@
EXTRALIBS =
EXTRACPPFLAGS= -I./ -I../include -I../common -I../pcbnew
EXTRACPPFLAGS= -I./ -I../include -I../common -I../polygon -I../pcbnew
CPPFLAGS += $(EXTRACPPFLAGS)

View File

@ -4,6 +4,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2007-Dec-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
First draft (and code..) about new zone handling, using polygons to define an outline.
Now currently not useable because the fill function (and many other important functions) is not implemented.
Many functions are not yet implemented: merging zones, cutout, DRC ...
Nevertheless, one can create, modify edit and save zone outlines
2007-Dec-23 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================

View File

@ -4,6 +4,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
bitmaps
../3d-viewer
../polygon
../pcbnew)
SET(CVPCB_SRCS
@ -35,6 +36,7 @@ SET(CVPCB_SRCS
SET(CVPCB_EXTRA_SRCS
../pcbnew/basepcbframe.cpp
../pcbnew/class_board.cpp
../pcbnew/class_zone.cpp
../pcbnew/class_cotation.cpp
../pcbnew/class_edge_mod.cpp
../pcbnew/class_equipot.cpp

View File

@ -1,8 +1,12 @@
# makefile pour cvpcb (mingw)
OBJSUFF = o
EXTRACPPFLAGS += -DCVPCB -fno-strict-aliasing -I./ -I../cvpcb -I../include -Ibitmaps -I../pcbnew -I../3d-viewer
EXTRALIBS = ../common/common.a
EXTRACPPFLAGS += -DCVPCB -fno-strict-aliasing\
-I./ -I../cvpcb -I../include -Ibitmaps\
-I../pcbnew -I../3d-viewer\
-I../polygon
EXTRALIBS = ../common/common.a ../polygon/lib_polygon.a
LIBVIEWER3D = ../3d-viewer/3d-viewer.a
@ -10,6 +14,7 @@ LIBVIEWER3D = ../3d-viewer/3d-viewer.a
OBJECTS = $(TARGET).o \
class_cvpcb.o\
class_zone.o\
memoire.o \
cvframe.o\
listboxes.o\
@ -69,6 +74,9 @@ classpcb.o: ../pcbnew/classpcb.cpp $(DEPEND)
class_mire.o: ../pcbnew/class_mire.cpp ../pcbnew/class_mire.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_cotation.o: ../pcbnew/class_cotation.cpp ../pcbnew/class_cotation.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp

View File

@ -4,7 +4,8 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
../3d-viewer
../cvpcb
../pcbnew)
../pcbnew
../polygon)
SET(GERBVIEW_SRCS
affiche.cpp
@ -41,6 +42,7 @@ SET(GERBVIEW_SRCS
SET(GERBVIEW_EXTRA_SRCS
../pcbnew/basepcbframe.cpp
../pcbnew/class_board.cpp
../pcbnew/class_zone.cpp
../pcbnew/class_drc_item.cpp
../pcbnew/class_marker.cpp
../pcbnew/class_pcb_text.cpp
@ -74,6 +76,6 @@ ENDIF(APPLE)
ADD_EXECUTABLE(gerbview WIN32 MACOSX_BUNDLE ${GERBVIEW_SRCS} ${GERBVIEW_EXTRA_SRCS} ${GERBVIEW_RESOURCES})
TARGET_LINK_LIBRARIES(gerbview common 3d-viewer ${wxWidgets_LIBRARIES})
TARGET_LINK_LIBRARIES(gerbview common 3d-viewer lib_polygon ${wxWidgets_LIBRARIES})
INSTALL(TARGETS gerbview RUNTIME DESTINATION ${KICAD_BIN})

View File

@ -1,12 +1,17 @@
EXTRALIBS = ../common/common.a
EXTRACPPFLAGS= -DGERBVIEW -DPCBNEW -fno-strict-aliasing -I./ -I../gerbview -I../include\
-I../share -I../pcbnew -I../3d-viewer
EXTRALIBS = ../common/common.a ../polygon/lib_polygon.a
EXTRACPPFLAGS= -DGERBVIEW -DPCBNEW -fno-strict-aliasing\
-I./ -I../gerbview -I../include\
-I../share -I../pcbnew -I../3d-viewer\
-I../polygon
#COMMON = pcbnew.h struct.h
OBJECTS= \
$(TARGET).o\
classpcb.o\
class_zone.o\
select_layers_to_pcb.o\
sel_layer.o\
lay2plot.o\
@ -69,6 +74,9 @@ files.o: files.cpp $(COMMON)
class_marker.o: ../pcbnew/class_marker.cpp ../pcbnew/class_marker.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_drc_item.o: ../pcbnew/class_drc_item.cpp $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp

View File

@ -41,7 +41,7 @@ enum KICAD_T {
TYPESCREEN,
TYPEBLOCK,
TYPEEDGEZONE,
TYPEZONE_POLYEDGE,
TYPEZONE_EDGE_CORNER,
TYPEZONE_CONTAINER,
// Draw Items in schematic

View File

@ -5,7 +5,7 @@
COMMON_GLOBL wxString g_BuildVersion
#ifdef EDA_BASE
(wxT("(2007-12-17)"))
(wxT("(2007-12-22)"))
#endif
;

View File

@ -546,8 +546,21 @@ enum main_id {
ID_POPUP_PCB_DELETE_TRACK,
ID_POPUP_PCB_DELETE_TRACKNET,
ID_POPUP_PCB_DELETE_TRACK_MNU,
ID_POPUP_PCB_EDIT_ZONE,
ID_POPUP_PCB_EDIT_ZONE_PARAMS,
ID_POPUP_PCB_DELETE_ZONE,
ID_POPUP_PCB_MOVE_ZONE_CORNER,
ID_POPUP_PCB_ADD_ZONE_CORNER,
ID_POPUP_PCB_DELETE_ZONE_CORNER,
ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
ID_POPUP_PCB_DELETE_EDGE_ZONE,
ID_POPUP_PCB_DELETE_ZONE_LIMIT,
ID_POPUP_PCB_FILL_ZONE,
ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
ID_POPUP_PCB_PLACE_ZONE_CORNER,
ID_POPUP_ZONE_UNUSED2,
ID_POPUP_ZONE_UNUSED3,
ID_POPUP_ZONE_UNUSED4,
ID_POPUP_PCB_DELETE_MARKER,
ID_POPUP_PCB_DELETE_COTATION,
@ -565,12 +578,6 @@ enum main_id {
ID_POPUP_PCB_IMPORT_PAD_SETTINGS,
ID_POPUP_PCB_EXPORT_PAD_SETTINGS,
ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
ID_POPUP_PCB_DELETE_EDGE_ZONE,
ID_POPUP_PCB_DELETE_ZONE_LIMIT,
ID_POPUP_PCB_FILL_ZONE,
ID_POPUP_PCB_SELECT_NET_ZONE,
ID_POPUP_PCB_SELECT_WIDTH,
ID_POPUP_PCB_SELECT_WIDTH1,
ID_POPUP_PCB_SELECT_WIDTH2,

View File

@ -102,6 +102,7 @@ class Ki_HotkeyInfo;
class GENERAL_COLLECTOR;
class GENERAL_COLLECTORS_GUIDE;
class DRC;
class ZONE_CONTAINER;
enum id_librarytype {
@ -728,10 +729,8 @@ public:
TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
void Delete_Track( wxDC* DC, TRACK* Track );
void Delete_net( wxDC* DC, TRACK* Track );
void Delete_Zone( wxDC* DC, SEGZONE* Track );
void Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm );
bool Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via );
void Edit_Zone_Width( wxDC* DC, SEGZONE* pt_ref );
void Edit_Net_Width( wxDC* DC, int Netcode );
void Edit_Track_Width( wxDC* DC, TRACK* Track );
int Edit_TrackSegm_Width( wxDC* DC, TRACK* segm );
@ -749,8 +748,13 @@ public:
bool Genere_Pad_Connexion( wxDC* DC, int layer );
// zone handling
void Delete_Zone( wxDC* DC, SEGZONE* Track );
EDGE_ZONE* Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone );
void CaptureNetName( wxDC* DC );
/**
* Function Begin_Zone
* initiates a zone edge creation process,
* or terminates the current zone edge and creates a new zone edge stub
*/
EDGE_ZONE* Begin_Zone( wxDC* DC );
/**
@ -761,14 +765,30 @@ public:
/**
* Function Fill_Zone
* creates a number zone segments by using a flood fill algorithm. The
* "high-lighted" net is used to determine the netcode of all the zone
* segments and what can be connected to and what must be avoided on the
* current layer as the flooding occurs.
* Fills an outline.
*/
void Fill_Zone( wxDC* DC );
void Fill_Zone( wxDC* DC, ZONE_CONTAINER * zone_container );
// Target handling
/**
* Function Edit_Zone_Params
* Edit params (layer, clearance, ...) for a zone outline
*/
void Edit_Zone_Params( wxDC* DC , ZONE_CONTAINER * zone_container );
/**
* Function Start_Move_Zone_Corner
* Prepares a move corner in a zone outline,
* called from a move corner command (IsNewCorner = false),
* or a create new cornet command (IsNewCorner = true )
*/
void Start_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container, int corner_id, bool IsNewCorner );
/**
* Function End_Move_Zone_Corner
* Terminates a move corner in a zone outline
*/
void End_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container );
// Target handling
MIREPCB* Create_Mire( wxDC* DC );
void Delete_Mire( MIREPCB* MirePcb, wxDC* DC );
void StartMove_Mire( MIREPCB* MirePcb, wxDC* DC );

View File

@ -1,4 +1,4 @@
KICAD_SUBDIRS = common 3d-viewer eeschema eeschema/plugins pcbnew kicad cvpcb gerbview
KICAD_SUBDIRS = common 3d-viewer polygon eeschema eeschema/plugins pcbnew kicad cvpcb gerbview
KICAD_SUBDIRS_BIN = eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
# How to invoke make:
MAKE = make -k -f makefile.g95

View File

@ -1,6 +1,6 @@
MAKEGTK = $(MAKE) -f makefile.gtk
KICAD_SUBDIRS = common 3d-viewer pcbnew eeschema eeschema/plugins cvpcb kicad gerbview
KICAD_SUBDIRS = common 3d-viewer polygon pcbnew eeschema eeschema/plugins cvpcb kicad gerbview
KICAD_SUBDIRS_BIN = eeschema eeschema/plugins pcbnew cvpcb kicad gerbview
KICAD_SUBDIRS_RES = internat modules template library
KICAD_SUBDIRS_HELP = help

View File

@ -1,4 +1,4 @@
KICAD_SUBDIRS = common 3d-viewer eeschema pcbnew cvpcb kicad gerbview
KICAD_SUBDIRS = common 3d-viewer polygon eeschema pcbnew cvpcb kicad gerbview
KICAD_SUBDIRS_BIN = eeschema pcbnew cvpcb kicad gerbview
# How to invoke make:
MAKE = make -f makefile.macosx

View File

@ -6,8 +6,6 @@
#include "pcbnew.h"
//#include "bitmaps.h"
/*****************/
/* Class BOARD: */
@ -76,6 +74,7 @@ BOARD::~BOARD()
m_LocalRatsnest = 0;
DeleteMARKERs();
DeleteZONEOutlines();
}
@ -128,11 +127,11 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
void BOARD::Delete( BOARD_ITEM* aBoardItem )
{
if ( aBoardItem == NULL ) return;
switch( aBoardItem->Type() )
{
// this one uses a vector
case TYPEMARKER:
case TYPEMARKER: // this one uses a vector
// find the item in the vector, then delete then erase it.
for( unsigned i=0; i<m_markers.size(); ++i )
{
@ -143,6 +142,19 @@ void BOARD::Delete( BOARD_ITEM* aBoardItem )
}
}
break;
case TYPEZONE_CONTAINER: // this one uses a vector
// find the item in the vector, then delete then erase it.
for( unsigned i=0; i<m_ZoneDescriptorList.size(); ++i )
{
if( m_ZoneDescriptorList[i] == (ZONE_CONTAINER*) aBoardItem )
{
delete m_ZoneDescriptorList[i];
m_ZoneDescriptorList.erase(m_ZoneDescriptorList.begin() + i);
break;
}
}
break;
// other types may use linked list
default:
@ -170,6 +182,15 @@ void BOARD::DeleteMARKERs()
m_markers.clear();
}
void BOARD::DeleteZONEOutlines()
{
// the vector does not know how to delete the ZONE Outlines, it holds pointers
for( unsigned i=0; i<m_ZoneDescriptorList.size(); ++i )
delete m_ZoneDescriptorList[i];
m_ZoneDescriptorList.clear();
}
/* Calculate the track segment count */
int BOARD::GetNumSegmTrack()
@ -522,6 +543,17 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
++p;
break;
case TYPEZONE_CONTAINER:
// TYPEZONE_CONTAINER are in the m_ZoneDescriptorList std::vector
for( unsigned i=0; i< m_ZoneDescriptorList.size(); ++i )
{
result = m_ZoneDescriptorList[i]->Visit( inspector, testData, p );
if( result == SEARCH_QUIT )
break;
}
++p;
break;
case PCB_EQUIPOT_STRUCT_TYPE:
result = IterateForward( m_Equipots, inspector, testData, p );
++p;
@ -782,16 +814,12 @@ bool BOARD::Save( FILE* aFile ) const
fprintf( aFile, "$EndZONE\n" );
// save the zone edges
/*
if( m_CurrentLimitZone )
{
fprintf( aFile, "$ZONE_EDGE\n" );
for( item = m_CurrentLimitZone; item; item=item->Next() )
if( !item->Save( aFile ) )
goto out;
fprintf( aFile, "$EndZONE_EDGE\n" );
}
*/
for( unsigned ii = 0; ii < m_ZoneDescriptorList.size(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_ZoneDescriptorList[ii];
edge_zone->Save( aFile );
}
if( fprintf( aFile, "$EndBOARD\n" ) != sizeof("$EndBOARD\n")-1 )
goto out;

View File

@ -20,7 +20,6 @@ class BOARD : public BOARD_ITEM
private:
std::vector<MARKER*> m_markers; ///< MARKERs for clearance problems, owned by pointer
// std::vector<MARKER*> m_markersUnconnected; ///< MARKERs for unconnected problems, owned by pointer
std::vector<ZONE_CONTAINER*> m_ZoneDescriptorList; ///< edge zone descriptors, owned by pointer
@ -86,6 +85,12 @@ public:
*/
void DeleteMARKERs();
/**
* Function DeleteZONEOutlines
* deletes ALL zone outlines from the board.
*/
void DeleteZONEOutlines();
/**
* Function DeleteMARKER

View File

@ -149,8 +149,25 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
}
break;
case TYPEZONE:
text << _( "Zone" ) << wxT( " " );
case TYPEZONE_CONTAINER:
text = _( "Zone Outline" );
text << wxT( " " );
{
wxString TimeStampText;
TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
text << TimeStampText;
}
net = aPcb->FindNet( ( (ZONE_CONTAINER*) item )->GetNet() );
if( net )
{
text << wxT( " [" ) << net->m_Netname << wxT( "]" );
}
text << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim();
break;
case TYPEZONE:
text = _( "Zone" );
text << wxT( " " );
{
wxString TimeStampText;
TimeStampText.Printf( wxT( "(%8.8X)" ), item->m_TimeStamp );
@ -268,6 +285,7 @@ const char** BOARD_ITEM::MenuIcon() const
xpm = showtrack_xpm;
break;
case TYPEZONE_CONTAINER:
case TYPEZONE:
xpm = add_zone_xpm;
break;

View File

@ -44,6 +44,7 @@ EQUIPOT::~EQUIPOT()
}
wxPoint& EQUIPOT::GetPosition()
{
static wxPoint dummy;
@ -172,3 +173,5 @@ void EQUIPOT::Show( int nestLevel, std::ostream& os )
" netcode=\"" << GetNet() << "\"/>\n";
}
#endif

View File

@ -61,7 +61,7 @@ public:
*/
int GetNet() const { return m_NetCode; }
void SetNet( int aNetCode ) { m_NetCode = aNetCode; }
/**
* Function GetClass
@ -86,3 +86,4 @@ public:
#endif
};

View File

@ -93,27 +93,9 @@ bool MIREPCB::ReadMirePcbDescr( FILE* File, int* LineNum )
return FALSE;
}
#if 0 // replaced by Save()
/************************************************/
bool MIREPCB::WriteMirePcbDescr( FILE* File )
/************************************************/
{
if( GetState( DELETED ) )
return FALSE;
fprintf( File, "$MIREPCB\n" );
fprintf( File, "Po %X %d %d %d %d %d %8.8lX\n",
m_Shape, m_Layer,
m_Pos.x, m_Pos.y,
m_Size, m_Width, m_TimeStamp );
fprintf( File, "$EndMIREPCB\n" );
return TRUE;
}
#endif
/**************************************/
bool MIREPCB::Save( FILE* aFile ) const
/**************************************/
{
if( GetState( DELETED ) )
return true;

View File

@ -14,10 +14,13 @@
/* class ZONE_CONTAINER */
/************************/
ZONE_CONTAINER::ZONE_CONTAINER (BOARD * parent):
BOARD_ITEM (parent, TYPEZONE_CONTAINER)
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
BOARD_ITEM( parent, TYPEZONE_CONTAINER )
, CPolyLine( NULL )
{
m_NetCode = -1; // Net number for fast comparisons
m_CornerSelection = -1;
}
@ -25,11 +28,6 @@ ZONE_CONTAINER::~ZONE_CONTAINER()
{
}
bool ZONE_CONTAINER::Save( FILE* aFile ) const
{
return true;
}
/**********************/
/* Class EDGE_ZONE */
@ -49,19 +47,367 @@ EDGE_ZONE:: ~EDGE_ZONE()
}
/****************************************/
bool EDGE_ZONE::Save( FILE* aFile ) const
/****************************************/
{
return true;
}
/********************************************/
bool ZONE_CONTAINER::Save( FILE* aFile ) const
/********************************************/
{
if( GetState( DELETED ) )
return true;
int ret = fprintf( aFile, "ZE %d %d %d %d %d %lX %X\n",
m_Start.x, m_Start.y,
m_End.x, m_End.y,
m_Angle,
m_TimeStamp,
ReturnStatus()
);
return (ret > 14 );
unsigned item_pos;
int ret;
unsigned corners_count = corner.size();
int outline_hatch;
fprintf( aFile, "$CZONE_OUTLINE\n");
// Save the outline main info
ret = fprintf( aFile, "ZInfo %8.8lX %d \"%s\"\n",
m_TimeStamp, m_NetCode,
CONV_TO_UTF8(m_Netname) );
if ( ret < 3 ) return false;
// Save the ouline layer info
ret = fprintf( aFile, "ZLayer %d\n", m_Layer );
if ( ret < 1 ) return false;
// Save the ouline aux info
switch ( m_HatchStyle )
{
default:
case NO_HATCH:
outline_hatch = 'N';
break;
case DIAGONAL_EDGE:
outline_hatch = 'E';
break;
case DIAGONAL_FULL:
outline_hatch = 'F';
break;
}
ret = fprintf( aFile, "ZAux %d %c\n", corners_count, outline_hatch );
if ( ret < 2 ) return false;
// Save the corner list
for ( item_pos = 0; item_pos < corners_count; item_pos++ )
{
ret = fprintf( aFile, "ZCorner %d %d %d \n",
corner[item_pos].x, corner[item_pos].y,
corner[item_pos].end_contour );
if ( ret < 3 ) return false;
}
fprintf( aFile, "$endCZONE_OUTLINE\n");
return true;
}
/**********************************************************/
int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
/**********************************************************/
/** Function ReadDescr
* @param aFile = opened file
* @param aLineNum = pointer on a line number counter (can be NULL or missing)
* @return 0 if ok or NULL
*/
{
char Line[1024], * text;
char netname_buffer[1024];
int ret;
int n_corner_item = 0;
int outline_hatch = NO_HATCH;
bool error = false, has_corner = false;
netname_buffer[0] = 0;
while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
{
if( strnicmp(Line, "ZCorner", 7 ) == 0 ) // new corner found
{
int x = 0, y = 0, flag = 0;
text = Line + 7;
ret = sscanf( text, "%d %d %d", &x, &y, &flag);
if (ret < 3 ) error = true;
else
{
if ( ! has_corner )
Start( m_Layer, 0, 0,
x, y,
outline_hatch );
else
AppendCorner( x, y );
has_corner = true;
if ( flag ) Close();
}
}
if( strnicmp(Line, "ZInfo", 5 ) == 0 ) // general info found
{
int ts = 0, netcode = 0;
text = Line + 5;
ret = sscanf( text, "%X %d %s", &ts, &netcode, netname_buffer);
if (ret < 3 ) error = true;
else
{
m_TimeStamp = ts;
m_NetCode = netcode;
ReadDelimitedText( netname_buffer, netname_buffer, 1024 );
m_Netname = CONV_FROM_UTF8(netname_buffer);
}
}
if( strnicmp(Line, "ZLayer", 6 ) == 0 ) // layer found
{
int x = 0;
text = Line + 6;
ret = sscanf( text, "%d", &x);
if (ret < 1 ) error = true;
else m_Layer = x;
}
if( strnicmp(Line, "ZAux", 4 ) == 0 ) // aux info found
{
int x = 0;
char hopt[10];
text = Line + 4;
ret = sscanf( text, "%d %c", &x, hopt );
if (ret < 2 ) error = true;
else
{
n_corner_item = x;
switch ( hopt[0] )
{
case 'n':
case 'N':
outline_hatch = NO_HATCH;
break;
case 'e':
case 'E':
outline_hatch = DIAGONAL_EDGE;
break;
case 'f':
case 'F':
outline_hatch = DIAGONAL_FULL;
break;
}
}
}
if( strnicmp(Line, "$end", 4 ) == 0 ) // end of description
{
break;
}
}
return error ? 0 : 1;
}
/****************************************************************************************************/
void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int draw_mode )
/****************************************************************************************************/
/** Function Draw
* @param panel = current Draw Panel
* @param DC = current Device Context
* @param offset = Draw offset (usually wxPoint(0,0))
* @param draw_mode = draw mode: OR, XOR ..
*/
{
int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
int color = g_DesignSettings.m_LayerColor[m_Layer];
if( ( color & (ITEM_NOT_SHOW | HIGHT_LIGHT_FLAG) ) == ITEM_NOT_SHOW )
return;
GRSetDrawMode( DC, draw_mode );
if( DisplayOpt.ContrastModeDisplay )
{
if( !IsOnLayer( curr_layer ) )
{
color &= ~MASKCOLOR;
color |= DARKDARKGRAY;
}
}
if( draw_mode & GR_SURBRILL )
{
if( draw_mode & GR_AND )
color &= ~HIGHT_LIGHT_FLAG;
else
color |= HIGHT_LIGHT_FLAG;
}
if( color & HIGHT_LIGHT_FLAG )
color = ColorRefs[color & MASKCOLOR].m_LightColor;
// draw the lines
int i_start_contour = 0;
for( unsigned ic = 0; ic < corner.size(); ic++ )
{
int xi = corner[ic].x + offset.x;
int yi = corner[ic].y + offset.y;
int xf, yf;
if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 )
{
xf = corner[ic + 1].x + offset.x;
yf = corner[ic + 1].y + offset.y;
}
else
{
xf = corner[i_start_contour].x + offset.x;
yf = corner[i_start_contour].y + offset.y;
i_start_contour = ic + 1;
}
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
}
// draw hatches
for( unsigned ic = 0; ic < m_HatchLines.size(); ic++ )
{
int xi = m_HatchLines[ic].xi + offset.x;
int yi = m_HatchLines[ic].yi + offset.y;
int xf = m_HatchLines[ic].xf + offset.x;
int yf =m_HatchLines[ic].yf + offset.y;
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
}
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
* return true if refPos is near a corner or an edge
*/
bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
{
if( HitTestForCorner( refPos ) >= 0 )
return true;
if( HitTestForEdge( refPos ) >= 0 )
return true;
return false;
}
/**
* 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
* @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
int dist;
unsigned item_pos, lim;
lim = 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;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
dist = abs( corner[item_pos].x - refPos.x ) + abs( corner[item_pos].y - refPos.y );
if( dist <= min_dist )
return item_pos;
}
return -1;
}
/**
* 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
* @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
int dist;
unsigned item_pos, lim;
lim = 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;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
end_segm = item_pos+1;
/* the last corner of the current outline is tested
* the last segment of the current outline starts at current corner, and ends
* at the first corner of the outline
*/
if( corner[item_pos].end_contour || end_segm >= lim)
{
unsigned tmp = first_corner_pos;
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
end_segm = tmp; // end_segm is the beginning of the current outline
}
/* test the dist between segment and ref point */
dist = (int) GetPointToLineSegmentDistance( refPos.x,
refPos.y,
corner[item_pos].x,
corner[item_pos].y,
corner[end_segm].x,
corner[end_segm].y );
if( dist <= min_dist )
return item_pos;
}
return -1;
}
/************************************************************/
void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame )
/************************************************************/
{
wxString msg;
int text_pos;
frame->MsgPanel->EraseMsgBox();
msg = _( "Zone Outline" );
text_pos = 1;
Affiche_1_Parametre( frame, text_pos, _( "Type" ), msg, DARKCYAN );
text_pos += 15;
EQUIPOT* equipot = ( (WinEDA_PcbFrame*) frame )->m_Pcb->FindNet( GetNet() );
if( equipot )
msg = equipot->m_Netname;
else
msg = wxT( "<noname>" );
Affiche_1_Parametre( frame, text_pos, _( "NetName" ), msg, RED );
/* Display net code : (usefull in test or debug) */
text_pos += 18;
msg.Printf( wxT( "%d" ), GetNet());
Affiche_1_Parametre( frame, text_pos, _( "NetCode" ), msg, RED );
text_pos += 8;
msg = ReturnPcbLayerName( m_Layer );
Affiche_1_Parametre( frame, text_pos, _( "Layer" ), msg, BROWN );
text_pos += 8;
msg.Printf( wxT( "%d" ), corner.size() );
Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE );
text_pos += 8;
msg.Printf( wxT( "%d" ), m_HatchLines.size() );
Affiche_1_Parametre( frame, text_pos, _( "Hatch lines" ), msg, BLUE );
}

View File

@ -5,6 +5,8 @@
#ifndef CLASS_ZONE_H
#define CLASS_ZONE_H
#include "PolyLine.h"
/************************/
/* class ZONE_CONTAINER */
/************************/
@ -13,10 +15,11 @@
* others polygons inside this main polygon are holes.
*/
class ZONE_CONTAINER : public BOARD_ITEM // Not sure BOARD_ITEM is better than EDA_BaseStruct
class ZONE_CONTAINER : public BOARD_ITEM, public CPolyLine
{
public:
wxString m_Netname; /* Net Name */
int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection
private:
int m_NetCode; // Net number for fast comparisons
@ -26,7 +29,47 @@ public:
~ZONE_CONTAINER();
bool Save( FILE* aFile ) const;
int ReadDescr( FILE* aFile, int* aLineNum = NULL );
wxPoint & GetPosition( ) { static wxPoint pos ;return pos; }
void UnLink(void) {};
void Display_Infos( WinEDA_DrawFrame* frame );
/** Function Draw
* Draws the zone outline.
* @param panel = current Draw Panel
* @param DC = current Device Context
* @param offset = Draw offset (usually wxPoint(0,0))
* @param draw_mode = draw mode: OR, XOR ..
*/
void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int draw_mode );
int GetNet( void ) { return m_NetCode; }
void SetNet( int anet_code ) { m_NetCode = anet_code; }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
/**
* Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* @return -1 if none, corner index in .corner <vector>
* @param refPos : A wxPoint to test
*/
int HitTestForCorner( const wxPoint& refPos );
/**
* Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* @return -1 if none, or index of the starting corner in .corner <vector>
* @param refPos : A wxPoint to test
*/
int HitTestForEdge( const wxPoint& refPos );
};
/*******************/

View File

@ -47,6 +47,7 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
TYPETEXTEMODULE,
TYPEMODULE,
TYPEZONE,
TYPEZONE_CONTAINER,
EOT
};
@ -212,6 +213,8 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
break;
case TYPEZONE:
break;
case TYPEZONE_CONTAINER:
break;
case TYPETEXTE:
break;
case TYPEDRAWSEGMENT:

View File

@ -68,6 +68,7 @@ WinEDA_ZoneFrame::WinEDA_ZoneFrame()
WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent,
ZONE_CONTAINER * zone_container,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
@ -75,6 +76,7 @@ WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent,
long style )
{
m_Parent = parent;
m_Zone_Container = zone_container;
if( m_Parent->m_Parent->m_EDA_Config )
{
@ -98,7 +100,6 @@ bool WinEDA_ZoneFrame::Create( wxWindow* parent,
long style )
{
////@begin WinEDA_ZoneFrame member initialisation
m_OutlinesOpt = 0;
m_GridCtrl = NULL;
m_ClearanceValueTitle = NULL;
m_ZoneClearanceCtrl = NULL;
@ -135,7 +136,7 @@ void WinEDA_ZoneFrame::CreateControls()
SetFont( *g_DialogFont );
////@begin WinEDA_ZoneFrame content construction
// Generated by DialogBlocks, 20/12/2007 15:46:22 (unregistered)
// Generated by DialogBlocks, 29/12/2007 14:29:53 (unregistered)
WinEDA_ZoneFrame* itemDialog1 = this;
@ -231,10 +232,11 @@ void WinEDA_ZoneFrame::CreateControls()
itemBoxSizer20->Add(m_LayerSelectionCtrl, 0, wxGROW|wxALL, 5);
// Set validators
m_OutlineAppearanceCtrl->SetValidator( wxGenericValidator(& m_OutlinesOpt) );
m_NetSortingOption->SetValidator( wxGenericValidator(& m_NetSorting) );
////@end WinEDA_ZoneFrame content construction
wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
// Initialise options
wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric );
m_ClearanceValueTitle->SetLabel( title );
title = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );;
@ -250,7 +252,7 @@ void WinEDA_ZoneFrame::CreateControls()
if( Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
static const int GridList[4] = { 50, 100, 250 };
static const int GridList[3] = { 50, 100, 250 };
int selection = 0;
for( unsigned ii = 0; ii < (unsigned) m_GridCtrl->GetCount(); ii++ )
@ -263,7 +265,6 @@ void WinEDA_ZoneFrame::CreateControls()
selection = ii;
}
// Initialise options
m_GridCtrl->SetSelection( selection );
if( Zone_Exclude_Pads )
@ -274,6 +275,21 @@ void WinEDA_ZoneFrame::CreateControls()
m_FillOpt->SetSelection( 2 );
}
switch( s_Zone_Hatching )
{
case CPolyLine::NO_HATCH:
m_OutlineAppearanceCtrl->SetSelection(0);
break;
case CPolyLine::DIAGONAL_EDGE:
m_OutlineAppearanceCtrl->SetSelection(1);
break;
case CPolyLine::DIAGONAL_FULL:
m_OutlineAppearanceCtrl->SetSelection(2);
break;
}
m_NetSortingOption->SetSelection(m_NetSorting == 0 ? 0 : 1 );
int layer_cnt = g_DesignSettings.m_CopperLayerCount;
@ -288,8 +304,12 @@ void WinEDA_ZoneFrame::CreateControls()
m_LayerId[ii] = layer_number;
msg = ReturnPcbLayerName( layer_number ).Trim();
m_LayerSelectionCtrl->InsertItems( 1, &msg, ii );
if( m_Parent->GetScreen()->m_Active_Layer == layer_number )
m_LayerSelectionCtrl->SetSelection( ii );
if ( m_Zone_Container )
if( m_Zone_Container->GetLayer() == layer_number )
m_LayerSelectionCtrl->SetSelection( ii );
else
if( m_Parent->GetScreen()->m_Active_Layer == layer_number )
m_LayerSelectionCtrl->SetSelection( ii );
}
wxArrayString ListNetName;
@ -298,9 +318,12 @@ void WinEDA_ZoneFrame::CreateControls()
m_ListNetNameSelection->InsertItems( ListNetName, 0 );
// Select net:
if( g_HightLigth_NetCode > 0 )
int net_select = g_HightLigth_NetCode;
if ( m_Zone_Container )
net_select = m_Zone_Container->GetNet();
if( net_select > 0 )
{
EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( g_HightLigth_NetCode );
EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( net_select );
if( equipot ) // Search net in list and select it
{
for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ )
@ -389,6 +412,21 @@ bool WinEDA_ZoneFrame::AcceptOptions(bool aPromptForErrors)
break;
}
switch( m_OutlineAppearanceCtrl->GetSelection() )
{
case 0:
s_Zone_Hatching = CPolyLine::NO_HATCH;
break;
case 1:
s_Zone_Hatching = CPolyLine::DIAGONAL_EDGE;
break;
case 2:
s_Zone_Hatching = CPolyLine::DIAGONAL_FULL;
break;
}
switch( m_GridCtrl->GetSelection() )
{
case 0:

View File

@ -75,7 +75,13 @@ class WinEDA_ZoneFrame: public wxDialog
public:
/// Constructors
WinEDA_ZoneFrame( );
WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE );
WinEDA_ZoneFrame( WinEDA_PcbFrame* parent,
ZONE_CONTAINER * zone_container = NULL,
wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME,
const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE,
const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION,
const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE,
long style = SYMBOL_WINEDA_ZONEFRAME_STYLE );
/// Creation
bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE );
@ -98,9 +104,6 @@ public:
////@begin WinEDA_ZoneFrame member function declarations
int GetOutlinesOpt() const { return m_OutlinesOpt ; }
void SetOutlinesOpt(int value) { m_OutlinesOpt = value ; }
/// Retrieves bitmap resources
wxBitmap GetBitmapResource( const wxString& name );
@ -125,13 +128,13 @@ public:
wxRadioBox* m_NetSortingOption;
wxListBox* m_ListNetNameSelection;
wxListBox* m_LayerSelectionCtrl;
int m_OutlinesOpt;
////@end WinEDA_ZoneFrame member variables
WinEDA_PcbFrame * m_Parent;
int m_NetSorting;
int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl
ZONE_CONTAINER * m_Zone_Container;
};
#endif // DIALOG_ZONES_H_

View File

@ -218,7 +218,6 @@
<string name="id-suffix">""</string>
<long name="use-xrc">0</long>
<long name="working-mode">0</long>
<string name="variable-0">"m_OutlinesOpt|int|OutlinesOpt|0|0|0|"</string>
<string name="proxy-Id name">"ID_DIALOG"</string>
<long name="proxy-Id value">10000</long>
<string name="proxy-Class">"WinEDA_ZoneFrame"</string>
@ -595,8 +594,8 @@
<bool name="proxy-Hidden">0</bool>
<bool name="proxy-Enabled">1</bool>
<string name="proxy-Platform">"&lt;Any platform&gt;"</string>
<string name="proxy-Data variable">"m_OutlinesOpt"</string>
<string name="proxy-Data validator">"wxGenericValidator(&amp; %VARIABLE%)"</string>
<string name="proxy-Data variable">""</string>
<string name="proxy-Data validator">""</string>
<string name="proxy-Data source">""</string>
<string name="proxy-Data class name">""</string>
<string name="proxy-Data class implementation filename">""</string>

View File

@ -67,13 +67,13 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE:
case ID_POPUP_PCB_DELETE_EDGE_ZONE:
case ID_POPUP_PCB_DELETE_ZONE_LIMIT:
case ID_POPUP_PCB_EDIT_ZONE:
case ID_POPUP_PCB_PLACE_ZONE_CORNER:
case ID_POPUP_PCB_EDIT_ZONE_PARAMS:
case ID_POPUP_PCB_DELETE_ZONE:
case ID_POPUP_PCB_DELETE_TRACKSEG:
case ID_POPUP_PCB_DELETE_TRACK:
case ID_POPUP_PCB_DELETE_TRACKNET:
case ID_POPUP_PCB_FILL_ZONE:
case ID_POPUP_PCB_SELECT_NET_ZONE:
case ID_POPUP_PCB_SELECT_LAYER:
case ID_POPUP_PCB_SELECT_CU_LAYER:
case ID_POPUP_PCB_SELECT_LAYER_PAIR:
@ -445,18 +445,71 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
SetCurItem( NULL );
break;
case ID_POPUP_PCB_EDIT_ZONE:
DrawPanel->MouseToCursorSchema();
if( GetCurItem() == NULL )
break;
Edit_Zone_Width( &dc, (SEGZONE*) GetCurItem() );
case ID_POPUP_PCB_EDIT_ZONE_PARAMS:
Edit_Zone_Params( &dc, (ZONE_CONTAINER*) GetCurItem() );
break;
case ID_POPUP_PCB_DELETE_ZONE_CONTAINER:
DrawPanel->MouseToCursorSchema();
((ZONE_CONTAINER*)GetCurItem())->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR);
m_Pcb->Delete( GetCurItem() );
SetCurItem( NULL );
break;
case ID_POPUP_PCB_DELETE_ZONE_CORNER:
{
DrawPanel->MouseToCursorSchema();
ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem();
zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR);
zone_cont->DeleteCorner(zone_cont->m_CornerSelection);
zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR);
SetCurItem( NULL );
break;
}
case ID_POPUP_PCB_MOVE_ZONE_CORNER:
{
DrawPanel->MouseToCursorSchema();
ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem();
Start_Move_Zone_Corner(&dc, zone_cont, zone_cont->m_CornerSelection, false);
break;
}
case ID_POPUP_PCB_ADD_ZONE_CORNER:
{
DrawPanel->MouseToCursorSchema();
ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem();
wxPoint pos = GetScreen()->m_Curseur;
/* add corner between zone_cont->m_CornerSelection
* and zone_cont->m_CornerSelection+1
* and start move the new corner
*/
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
zone_cont->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y );
zone_cont->m_CornerSelection++;
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
Start_Move_Zone_Corner(&dc, zone_cont, zone_cont->m_CornerSelection, true);
break;
}
case ID_POPUP_PCB_PLACE_ZONE_CORNER:
{
DrawPanel->MouseToCursorSchema();
ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem();
End_Move_Zone_Corner(&dc, zone_cont);
break;
}
case ID_POPUP_PCB_DELETE_ZONE_LIMIT:
DrawPanel->MouseToCursorSchema();
DelLimitesZone( &dc, TRUE );
break;
case ID_POPUP_PCB_FILL_ZONE:
DrawPanel->MouseToCursorSchema();
Fill_Zone( &dc, (ZONE_CONTAINER*)GetCurItem() );
break;
case ID_PCB_DELETE_ITEM_BUTT:
SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
break;
@ -745,16 +798,6 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
}
break;
case ID_POPUP_PCB_FILL_ZONE:
DrawPanel->MouseToCursorSchema();
Fill_Zone( &dc );
break;
case ID_POPUP_PCB_SELECT_NET_ZONE:
DrawPanel->MouseToCursorSchema();
CaptureNetName( &dc );
break;
case ID_POPUP_PCB_SELECT_WIDTH:
break;

View File

@ -1,7 +1,6 @@
/**********************************************/
/* PCBNEW : Routines d'initialisation globale */
/******* Fichier INITPCB.C ********************/
/**********************************************/
/*********************************************/
/******* file initpcb.cpp ********************/
/*********************************************/
#include "fctsys.h"
@ -148,6 +147,9 @@ bool WinEDA_BasePcbFrame::Clear_Pcb( bool query )
DelLimitesZone( NULL, FALSE );
m_Pcb->DeleteMARKERs();
m_Pcb->DeleteZONEOutlines();
for( ; g_UnDeleteStackPtr != 0; )
{
g_UnDeleteStackPtr--;
@ -221,6 +223,7 @@ void WinEDA_PcbFrame::Erase_Zones( bool query )
}
DelLimitesZone( NULL, FALSE );
m_Pcb->DeleteZONEOutlines();
GetScreen()->SetModify();
}

View File

@ -815,6 +815,13 @@ int WinEDA_PcbFrame::ReadPcbFile( wxDC* DC, FILE* File, bool Append )
continue;
}
if( strnicmp( Line, "$CZONE_OUTLINE", 7 ) == 0 )
{
ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(m_Pcb);
zone_descr->ReadDescr( File, &LineNum );
m_Pcb->m_ZoneDescriptorList.push_back(zone_descr);
}
if( strnicmp( Line, "$MODULE", 7 ) == 0 )
{
Module = new MODULE( m_Pcb );

View File

@ -1,4 +1,4 @@
EXTRALIBS = ../common/common.a
EXTRALIBS = ../common/common.a ../polygon/lib_polygon.a
EXTRACPPFLAGS += -DPCBNEW -fno-strict-aliasing -I./ -Ibitmaps -I../include -I../share\
-I../pcbnew -I../3d-viewer -I../polygon

View File

@ -38,6 +38,11 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
switch( DrawStruct->Type() )
{
case TYPEZONE_CONTAINER:
End_Move_Zone_Corner( DC, (ZONE_CONTAINER *) DrawStruct );
exit = true;
break;
case TYPETRACK:
case TYPEVIA:
if( DrawStruct->m_Flags & IS_DRAGGED )

View File

@ -275,6 +275,41 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
_( "Delete edge zone" ), delete_xpm );
break;
case TYPEZONE_CONTAINER:
{
ZONE_CONTAINER * edge_zone = (ZONE_CONTAINER *) item;
if ( edge_zone->m_Flags )
{
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_PLACE_ZONE_CORNER,
_( "Place Corner" ), apply_xpm );
}
else
{
edge_zone->m_CornerSelection = -1;
int index;
if ( (index = edge_zone->HitTestForCorner( GetScreen()->m_Curseur )) >= 0 )
{
edge_zone->m_CornerSelection = index;
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
_( "Move Corner" ), move_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
_( "Delete Corner" ), delete_xpm );
}
else if ( (index = edge_zone->HitTestForEdge( GetScreen()->m_Curseur )) >= 0 )
{
edge_zone->m_CornerSelection = index;
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ADD_ZONE_CORNER,
_( "Create Corner" ), move_xpm );
}
aPopMenu->AppendSeparator();
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_ZONE_PARAMS,
_( "Edit Zone Params" ), edit_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER,
_( "Delete Zone Outline" ), delete_xpm );
}
}
break;
case TYPETEXTE:
createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
break;
@ -286,8 +321,6 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
break;
case TYPEZONE:
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_ZONE,
_( "Edit Zone" ), edit_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE,
_( "Delete Zone" ), delete_xpm );
break;
@ -358,14 +391,6 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ZONE,
_( "Fill zone" ), fill_zone_xpm );
if( item
&& ( (item->Type() == TYPEPAD)
|| (item->Type() == TYPETRACK)
|| (item->Type() == TYPEVIA) ) )
{
add_separator = TRUE;
aPopMenu->Append( ID_POPUP_PCB_SELECT_NET_ZONE, _( "Select Net" ) );
}
if( m_Pcb->m_CurrentLimitZone )
{
add_separator = TRUE;

View File

@ -8,6 +8,8 @@
* Routines d'affichage grille, Boite de coordonnees, Curseurs, marqueurs ...
*/
#include <vector.h>
#include "fctsys.h"
#include "gr_basic.h"
@ -18,9 +20,7 @@
#include "protos.h"
/* Routines Locales : */
/* Variables Locales */
using namespace std;
/**********************************************************************/
@ -185,6 +185,12 @@ void WinEDA_PcbFrame::Trace_Pcb( wxDC* DC, int mode )
Trace_DrawSegmentPcb( DrawPanel, DC, segment, mode );
}
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
edge_zone->Draw( DrawPanel, DC, wxPoint(0,0), mode);
}
DrawGeneralRatsnest( DC );
m_CurrentScreen->ClrRefreshReq();

View File

@ -1,21 +1,27 @@
/////////////////////////////////////////////////////////////////////////////
// Name: zones_by_polygon.cpp
// Purpose:
// Author: jean-pierre Charras
// Modified by:
// Created: 25/01/2006 11:35:19
// RCS-ID:
// Copyright: GNU License
// Licence: GNU License
/////////////////////////////////////////////////////////////////////////////
// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19
#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA)
#pragma implementation "dialog_zones_by_polygon.h"
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
using namespace std;
#include "fctsys.h"
#include "gr_basic.h"
@ -28,40 +34,29 @@
#include "protos.h"
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
////@begin includes
////@end includes
////@begin XPM images
////@end XPM images
/* Imported functions */
void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code,
bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief );
/* Local functions */
static void Display_Zone_Netname( WinEDA_PcbFrame* frame );
static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
// Outile creation:
static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
// Corner moving
static void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
/* Local variables */
static bool Zone_45_Only = FALSE;
static bool Zone_Exclude_Pads = TRUE;
static bool s_Zone_Create_Thermal_Relief = TRUE;
static int s_Zone_Layer; // Layer used to put the current zone
static int s_NetcodeSelection; // Net code selection for the current zone
static int s_Zone_Layer; // Layer used to create the current zone
static int s_Zone_Hatching; // Option to show the zone area (outlines only, short hatches or full hatches
static int s_NetcodeSelection; // Net code selection for the current zone
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
// key used to store net sort option in config file :
#define ZONE_NET_SORT_OPTION_KEY wxT("Zone_NetSort_Opt")
enum zone_cmd {
@ -72,55 +67,6 @@ enum zone_cmd {
#include "dialog_zones_by_polygon.cpp"
/**************************************************************/
void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* aZone )
/**************************************************************/
/* Edite (change la largeur des segments) la zone Zone.
* La zone est constituee des segments zones de meme TimeStamp
*/
{
bool modify = FALSE;
double f_new_width;
int w_tmp;
wxString Line;
wxString Msg( _( "New zone segment width: " ) );
if( aZone == NULL )
return;
f_new_width = To_User_Unit( g_UnitMetric, aZone->m_Width, GetScreen()->GetInternalUnits() );
Line.Printf( wxT( "%.4f" ), f_new_width );
Msg += g_UnitMetric ? wxT( "(mm)" ) : wxT( "(\")" );
if( Get_Message( Msg, Line, this ) != 0 )
return;
w_tmp = g_DesignSettings.m_CurrentTrackWidth;
Line.ToDouble( &f_new_width );
g_DesignSettings.m_CurrentTrackWidth = From_User_Unit( g_UnitMetric,
f_new_width, GetScreen(
)->GetInternalUnits() );
for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() )
{
if( zone->m_TimeStamp == aZone->m_TimeStamp )
{
modify = TRUE;
Edit_TrackSegm_Width( DC, zone );
}
}
g_DesignSettings.m_CurrentTrackWidth = w_tmp;
if( modify )
{
GetScreen()->SetModify();
DrawPanel->Refresh();
}
}
/**********************************************************/
void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone )
@ -199,103 +145,12 @@ EDGE_ZONE* WinEDA_PcbFrame::Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone )
}
/*********************************************/
void WinEDA_PcbFrame::CaptureNetName( wxDC* DC )
/*********************************************/
/* routine permettant de capturer le nom net net (netcode) d'un pad
* ou d'une piste pour l'utiliser comme netcode de zone
*/
{
D_PAD* pt_pad = 0;
TRACK* adrpiste;
MODULE* Module;
int masquelayer = g_TabOneLayerMask[GetScreen()->m_Active_Layer];
int netcode;
netcode = -1;
MsgPanel->EraseMsgBox();
adrpiste = Locate_Pistes( m_Pcb->m_Track, masquelayer, CURSEUR_OFF_GRILLE );
if( adrpiste == NULL )
{
pt_pad = Locate_Any_Pad( m_Pcb, CURSEUR_OFF_GRILLE );
if( pt_pad ) /* Verif qu'il est bien sur la couche active */
{
Module = (MODULE*) pt_pad->m_Parent;
pt_pad = Locate_Pads( Module, g_TabOneLayerMask[GetScreen()->m_Active_Layer],
CURSEUR_OFF_GRILLE );
}
if( pt_pad )
{
pt_pad->Display_Infos( this );
netcode = pt_pad->GetNet();
}
}
else
{
adrpiste->Display_Infos( this );
netcode = adrpiste->GetNet();
}
// Mise en surbrillance du net
if( g_HightLigt_Status )
Hight_Light( DC );
g_HightLigth_NetCode = netcode;
if( g_HightLigth_NetCode >= 0 )
{
Hight_Light( DC );
}
/* Affichage du net selectionne pour la zone a tracer */
Display_Zone_Netname( this );
}
/*******************************************************/
static void Display_Zone_Netname( WinEDA_PcbFrame* frame )
/*******************************************************/
/*
* Affiche le net_code et le nom de net couramment selectionne
*/
{
EQUIPOT* pt_equipot;
wxString line;
pt_equipot = frame->m_Pcb->m_Equipots;
if( g_HightLigth_NetCode > 0 )
{
for( ; pt_equipot != NULL; pt_equipot = (EQUIPOT*) pt_equipot->Pnext )
{
if( pt_equipot->GetNet() == g_HightLigth_NetCode )
break;
}
if( pt_equipot )
{
line.Printf( wxT( "Zone: Net[%d] <%s>" ), g_HightLigth_NetCode,
pt_equipot->m_Netname.GetData() );
}
else
line.Printf( wxT( "Zone: NetCode[%d], Equipot not found" ),
g_HightLigth_NetCode );
}
line = _( "Zone: No net selected" );
frame->Affiche_Message( line );
}
/********************************************************/
static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC )
/********************************************************/
/*************************************************************************/
static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC )
/*************************************************************************/
/**
* Function Exit_Zones
* Function Abort_Zone_Create_Outline
* cancels the Begin_Zone state if at least one EDGE_ZONE has been created.
*/
{
@ -326,9 +181,6 @@ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
if( m_Pcb->m_CurrentLimitZone == NULL )
return;
if( !IsOK( this, _( "Delete Current Zone Edges" ) ) )
return;
// erase the old zone border, one segment at a time
for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next )
{
@ -345,13 +197,109 @@ void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
SetCurItem( NULL );
}
/*******************************************************************************************************/
void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container,
int corner_id, bool IsNewCorner )
/*******************************************************************************************************/
/**
* Function Start_Move_Zone_Corner
* Initialise parametres to move an existing corner of a zone.
* if IsNewCorner is true, the Abort_Zone_Move_Corner will remove this corner, if called
*/
{
/* Show the Net */
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) )
{
Hight_Light( DC ); // Remove old hightlight selection
}
g_HightLigth_NetCode = s_NetcodeSelection;
if ( ! g_HightLigt_Status )
Hight_Light( DC );
zone_container->m_Flags = IN_EDIT;
DrawPanel->ManageCurseur = Show_Zone_Corner_While_Move_Mouse;
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner;
s_CornerInitialPosition.x = zone_container->GetX(corner_id);
s_CornerInitialPosition.y = zone_container->GetY(corner_id);
s_CornerIsNew = IsNewCorner;
}
/***************************************************************************************/
void WinEDA_PcbFrame::End_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container )
/****************************************************************************************/
/**
* Function End_Move_Zone_Corner
* Terminates a move corner in a zone outline
*/
{
zone_container->m_Flags = 0;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
zone_container->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR);
}
/**************************************************************/
void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC )
/**************************************************************/
/**
* Function Abort_Zone_Move_Corner
* cancels the Begin_Zone state if at least one EDGE_ZONE has been created.
*/
{
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) pcbframe->GetCurItem();
zone_container->Draw(Panel, DC, wxPoint(0,0), GR_XOR);
if ( s_CornerIsNew )
{
zone_container->DeleteCorner( zone_container->m_CornerSelection );
}
else
{
wxPoint pos = s_CornerInitialPosition;
zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
}
zone_container->Draw(Panel, DC, wxPoint(0,0), GR_XOR);
Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL;
pcbframe->SetCurItem( NULL );
zone_container->m_Flags = 0;
}
/**************************************************************************************/
void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* Panel, wxDC* DC, bool erase )
/**************************************************************************************/
/* Redraws the zone outline when moving a corner according to the cursor position
*/
{
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) pcbframe->GetCurItem();
// if( erase ) /* Undraw edge in old position*/
{
zone_container->Draw(Panel, DC, wxPoint(0,0), GR_XOR);
}
wxPoint pos = pcbframe->GetScreen()->m_Curseur;
zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
zone_container->Draw(Panel, DC, wxPoint(0,0), GR_XOR);
}
/*************************************************/
EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
/*************************************************/
/**
* Function Begin_Zone
* either initializes the first segment of a new zone, or adds an
* intermediate segment.
*/
EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
{
EDGE_ZONE* oldedge;
EDGE_ZONE* newedge = NULL;
@ -401,13 +349,12 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
m_Pcb->m_CurrentLimitZone = newedge;
DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse;
DrawPanel->ForceCloseManageCurseur = Exit_Zones;
DrawPanel->ManageCurseur = Show_New_Zone_Edge_While_Move_Mouse;
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Create_Outline;
}
// edge in progress:
else /* piste en cours : les coord du point d'arrivee ont ete mises
* a jour par la routine Show_Zone_Edge_While_MoveMouse*/
{
else
{ /* edge in progress : the ending point coordinate was set by Show_New_Zone_Edge_While_Move_Mouse */
if( oldedge->m_Start != oldedge->m_End )
{
oldedge->m_Flags &= ~(IS_NEW | IS_MOVED);
@ -433,7 +380,9 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
/*********************************************/
/*
* Routine de fin de trace d'une zone (succession de segments)
* Terminates an edge zone creation
* Close the current edge zone considered as a polygon
* put it in the main list m_Pcb->m_ZoneDescriptorList (a vector<ZONE_CONTAINER*>)
*/
{
EDGE_ZONE* edge;
@ -442,8 +391,9 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
{
Begin_Zone( DC );
/* le dernier point genere est de longueur tj nulle donc inutile. */
/* il sera raccorde au point de depart */
/* 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);
@ -466,14 +416,46 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
/* Put edges in list */
ZONE_CONTAINER * polygon = new ZONE_CONTAINER( m_Pcb );
polygon->SetLayer( GetScreen()->m_Active_Layer );
polygon->SetNet( g_HightLigth_NetCode );
polygon->m_TimeStamp = GetTimeStamp();
EQUIPOT* net = m_Pcb->FindNet( g_HightLigth_NetCode );
if ( net ) polygon->m_Netname = net->m_Netname;
edge = m_Pcb->m_CurrentLimitZone;
polygon->Start( GetScreen()->m_Active_Layer, 0, NULL,
edge->m_Start.x, edge->m_Start.y,
s_Zone_Hatching );
edge = edge->Next();
while( edge )
{
polygon->AppendCorner( edge->m_Start.x, edge->m_Start.y );
edge = edge->Next();
}
polygon->Close(); // Close the current corner list
polygon->Hatch();
m_Pcb->m_ZoneDescriptorList.push_back(polygon);
/* Remove the current temporary list */
DelLimitesZone( DC, TRUE );
/* Redraw the real edge zone */
polygon->CPolyLine::Draw( ); // Build the line list
polygon->Draw( DrawPanel, DC, wxPoint(0,0), GR_OR );
GetScreen()->SetModify();
}
/******************************************************************************************/
static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/******************************************************************************************/
/* redessin du contour de la piste lors des deplacements de la souris
/* Redraws the edge zone when moving mouse
*/
{
EDGE_ZONE* edge;
@ -483,8 +465,7 @@ static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, b
if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL )
return;
/* efface ancienne position si elle a ete deja dessinee */
if( erase )
if( erase ) /* Undraw edge in old position*/
{
edge = pcbframe->m_Pcb->m_CurrentLimitZone;
@ -494,23 +475,22 @@ static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, b
}
}
/* mise a jour de la couche */
/* Reinit layer (which can be changed) */
for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() )
{
edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer );
}
/* dessin de la nouvelle piste : mise a jour du point d'arrivee */
/* Redraw the curent edge in its new position */
currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone;
if( Zone_45_Only )
{
// Calcul de l'extremite de la piste pour orientations permises:
// horiz,vertical ou 45 degre
// calculate the new position as allowed
currentEdge->m_End = pcbframe->GetScreen()->m_Curseur;
Calcule_Coord_Extremite_45( currentEdge->m_Start.x, currentEdge->m_Start.y,
&currentEdge->m_End.x, &currentEdge->m_End.y );
}
else /* ici l'angle d'inclinaison est quelconque */
else /* all orientations are allowed */
{
currentEdge->m_End = pcbframe->GetScreen()->m_Curseur;
}
@ -522,22 +502,44 @@ static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, b
}
/**********************************************/
void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
/**********************************************/
/** Function Fill_Zone()
* Init the zone filling
* If a zone edge is found, it is used.
* Otherwise the whole board is filled by the zone
* The zone edge is a frontier, and can be complex. So non filled zones can be achieved
* The zone is put on the active layer
* If a net is hightlighted, the zone will be attached to this net
* The filling start from a starting point.
* If a net is selected, all tracks attached to this net are also starting points
/***********************************************************************************/
void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC , ZONE_CONTAINER * zone_container )
/***********************************************************************************/
/**
* Function Edit_Zone_Params
* Edit params (layer, clearance, ...) for a zone outline
*/
{
DrawPanel->m_IgnoreMouseEvents = TRUE;
WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this, zone_container );
int diag = frame->ShowModal();
frame->Destroy();
DrawPanel->MouseToCursorSchema();
DrawPanel->m_IgnoreMouseEvents = FALSE;
if( diag == ZONE_ABORT )
return;
zone_container->Draw( DrawPanel, DC, wxPoint(0,0), GR_XOR );
zone_container->SetLayer( s_Zone_Layer );
zone_container->SetNet( s_NetcodeSelection );
EQUIPOT* net = m_Pcb->FindNet( s_NetcodeSelection );
if ( net ) zone_container->m_Netname = net->m_Netname;
zone_container->SetHatch(s_Zone_Hatching);
zone_container->Draw( DrawPanel, DC, wxPoint(0,0), GR_OR );
}
/***************************************************************************/
void WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER * zone_container )
/***************************************************************************/
/** Function Fill_Zone()
* Fillst the zone defined in zone_container
*/
{
EQUIPOT* pt_equipot;
wxPoint ZoneStartFill;
wxString msg;
@ -548,32 +550,10 @@ void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
return;
}
DrawPanel->m_IgnoreMouseEvents = TRUE;
WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this );
int diag = frame->ShowModal();
frame->Destroy();
DrawPanel->MouseToCursorSchema();
DrawPanel->m_IgnoreMouseEvents = FALSE;
if( diag == ZONE_ABORT )
return;
// set all the EDGE_ZONEs to the currently active layer and redraw them
// on that layer.
GetScreen()->m_Active_Layer = s_Zone_Layer;
EDGE_ZONE* PtLim = m_Pcb->m_CurrentLimitZone;
for( ; PtLim != NULL; PtLim = PtLim->Next() )
{
Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR );
PtLim->SetLayer( s_Zone_Layer );
Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR );
}
/* Show the Net */
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) )
{
Hight_Light( DC ); // Remoive old hightlight selection
Hight_Light( DC ); // Remove old hightlight selection
}
g_HightLigth_NetCode = s_NetcodeSelection;
@ -582,14 +562,17 @@ void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
if( g_HightLigth_NetCode > 0 )
{
pt_equipot = m_Pcb->FindNet( g_HightLigth_NetCode );
if( pt_equipot == NULL )
EQUIPOT* net = m_Pcb->FindNet( g_HightLigth_NetCode );
if( net == NULL )
{
if( g_HightLigth_NetCode > 0 )
{
DisplayError( this, wxT( "Unable to find Net name" ) );
return;
}
}
else
msg = pt_equipot->m_Netname;
msg = net->m_Netname;
}
else
msg = _( "No Net" );

1888
polygon/PolyLine.cpp Normal file

File diff suppressed because it is too large Load Diff

177
polygon/PolyLine.h Normal file
View File

@ -0,0 +1,177 @@
// PolyLine.h ... definition of CPolyLine class
//
// A polyline contains one or more contours, where each contour
// is defined by a list of corners and side-styles
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// each contour.
//
// When used for copper areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.
//
// If a CDisplayList pointer is provided, the polyline can draw itself
#ifndef POLYLINE_H
#define POLYLINE_H
#include <vector>
#include "defs-macros.h"
#include "GenericPolygonClipperLibrary.h"
#include "php_polygon.h"
#include "php_polygon_vertex.h"
#include "PolyLine2Kicad.h"
#include "freepcb_ids.h"
#include "freepcbDisplayList.h"
#include "math_for_graphics.h"
class CSegment {
public:
int xi, yi, xf, yf;
CSegment() {};
CSegment(int x0, int y0, int x1, int y1) {
xi = x0; yi = y0; xf = x1; yf = y1; }
};
class CArc {
public:
enum{ MAX_STEP = 50*25400 }; // max step is 20 mils
enum{ MIN_STEPS = 18 }; // min step is 5 degrees
int style;
int xi, yi, xf, yf;
int n_steps; // number of straight-line segments in gpc_poly
BOOL bFound;
};
class CPolyPt
{
public:
CPolyPt( int qx=0, int qy=0, BOOL qf=FALSE )
{ x=qx; y=qy; end_contour=qf; utility = 0; };
int x;
int y;
BOOL end_contour;
int utility;
};
class CPolyLine
{
public:
enum { STRAIGHT, ARC_CW, ARC_CCW }; // side styles
enum { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles
enum { DEF_SIZE = 50, DEF_ADD = 50 }; // number of array elements to add at a time
// constructors/destructor
CPolyLine( CDisplayList * dl );
CPolyLine();
~CPolyLine();
// functions for modifying polyline
void Start( int layer, int w, int sel_box, int x, int y,
int hatch );
void AppendCorner( int x, int y, int style = STRAIGHT, BOOL bDraw=TRUE );
void InsertCorner( int ic, int x, int y );
void DeleteCorner( int ic, BOOL bDraw=TRUE );
void MoveCorner( int ic, int x, int y );
void Close( int style = STRAIGHT, BOOL bDraw=TRUE );
void RemoveContour( int icont );
// drawing functions
void HighlightSide( int is );
void HighlightCorner( int ic );
void StartDraggingToInsertCorner( CDC * pDC, int ic, int x, int y);
void StartDraggingToMoveCorner( CDC * pDC, int ic, int x, int y);
void CancelDraggingToInsertCorner( int ic );
void CancelDraggingToMoveCorner( int ic );
void Undraw();
void Draw( CDisplayList * dl = NULL );
void Hatch();
void MakeVisible( BOOL visible = TRUE );
void MoveOrigin( int x_off, int y_off );
// misc. functions
CRect GetBounds();
CRect GetCornerBounds();
CRect GetCornerBounds( int icont );
void Copy( CPolyLine * src );
BOOL TestPointInside( int x, int y );
BOOL TestPointInsideContour( int icont, int x, int y );
int TestIntersection( CPolyLine * poly );
void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );
// access functions
int GetNumCorners();
int GetNumSides();
int GetClosed();
int GetNumContours();
int GetContour( int ic );
int GetContourStart( int icont );
int GetContourEnd( int icont );
int GetContourSize( int icont );
int GetX( int ic );
int GetY( int ic );
int GetEndContour( int ic );
int GetUtility( int ic ){ return corner[ic].utility; };
void SetUtility( int ic, int utility ){ corner[ic].utility = utility; };
int GetW();
int GetSideStyle( int is );
id GetId();
int GetSelBoxSize();
CDisplayList * GetDisplayList(){ return m_dlist; };
int GetHatch(){ return m_HatchStyle; }
void SetHatch( int hatch ){ Undraw(); m_HatchStyle = hatch; Draw(); };
void SetX( int ic, int x );
void SetY( int ic, int y );
void SetEndContour( int ic, BOOL end_contour );
// void SetLayer( int layer );
void SetW( int w );
void SetSideStyle( int is, int style );
void SetSelBoxSize( int sel_box );
void SetDisplayList( CDisplayList * dl );
// GPC functions
int MakeGpcPoly( int icontour=0, std::vector<CArc> * arc_array=NULL );
int FreeGpcPoly();
gpc_polygon * GetGpcPoly(){ return m_gpc_poly; };
int NormalizeWithGpc( std::vector<CPolyLine*> * pa=NULL, BOOL bRetainArcs=FALSE );
int RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine*> * pa=NULL );
CPolyLine * MakePolylineForPad( int type, int x, int y, int w, int l, int r, int angle );
void AddContourForPadClearance( int type, int x, int y, int w,
int l, int r, int angle, int fill_clearance,
int hole_w, int hole_clearance, BOOL bThermal=FALSE, int spoke_w=0 );
void ClipGpcPolygon( gpc_op op, CPolyLine * poly );
// PHP functions
int MakePhpPoly();
void FreePhpPoly();
void ClipPhpPolygon( int php_op, CPolyLine * poly );
private:
CDisplayList * m_dlist; // display list
int m_layer; // layer to draw on
int m_Width; // line width
int m_sel_box; // corner selection box width/2
public:
std::vector <CPolyPt> corner; // array of points for corners
std::vector <int> side_style; // array of styles for sides
private:
std::vector <dl_element*> dl_side; // graphic elements
std::vector <dl_element*> dl_side_sel;
std::vector <dl_element*> dl_corner_sel;
public:
int m_HatchStyle; // hatch style, see enum above
std::vector <CSegment> m_HatchLines; // hatch lines
private:
gpc_polygon * m_gpc_poly; // polygon in gpc format
polygon * m_php_poly;
BOOL bDrawn;
};
#endif // #ifndef POLYLINE_H

94
polygon/PolyLine2Kicad.h Normal file
View File

@ -0,0 +1,94 @@
// PolyLine.h ... definition of CPolyLine class
//
// A polyline contains one or more contours, where each contour
// is defined by a list of corners and side-styles
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// each contour.
//
// When used for copper areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.
//
// If a CDisplayList pointer is provided, the polyline can draw itself
#ifndef POLYLINE2KICAD_H
#define POLYLINE2KICAD_H
#define PCBU_PER_MIL 10
#define MAX_LAYERS 32
#define NM_PER_MIL 10 // 25400
// pad shapes
enum
{
PAD_NONE = 0,
PAD_ROUND,
PAD_SQUARE,
PAD_RECT,
PAD_RRECT,
PAD_OVAL,
PAD_OCTAGON
};
/*
enum
{
// visible layers
LAY_SELECTION = 0,
LAY_BACKGND,
LAY_VISIBLE_GRID,
LAY_HILITE,
LAY_DRC_ERROR,
LAY_BOARD_OUTLINE,
LAY_RAT_LINE,
LAY_SILK_TOP,
LAY_SILK_BOTTOM,
LAY_SM_TOP,
LAY_SM_BOTTOM,
LAY_PAD_THRU,
LAY_TOP_COPPER,
LAY_BOTTOM_COPPER,
// invisible layers
LAY_MASK_TOP = -100,
LAY_MASK_BOTTOM = -101,
LAY_PASTE_TOP = -102,
LAY_PASTE_BOTTOM = -103
};
*/
#define LAY_SELECTION 0
#define LAY_TOP_COPPER 0
#define CDC wxDC
class wxDC;
#if 0
class dl_element;
class CDisplayList {
public:
void Set_visible(void*, int) {};
int Get_x(void) { return 0;};
int Get_y(void) { return 0;};
void StopDragging(void) {};
void CancelHighLight(void) {};
void StartDraggingLineVertex(...) {};
void Add() {};
};
#endif
class CRect {
public:
int left, right, top, bottom;
};
class CPoint {
public:
int x, y;
public:
CPoint(void) { x = y = 0;};
CPoint(int i, int j) { x = i; y = j;};
};
#endif // #ifndef POLYLINE2KICAD_H

View File

@ -0,0 +1,85 @@
/* stuff for class CDisplayList */
#include "PolyLine.h"
dl_element * CDisplayList::Add( id id, void * ptr, int glayer, int gtype, int visible,
int w, int holew, int x, int y, int xf, int yf, int xo, int yo,
int radius, int orig_layer )
{
return NULL;
}
dl_element * CDisplayList::AddSelector( id id, void * ptr, int glayer, int gtype, int visible,
int w, int holew, int x, int y, int xf, int yf, int xo, int yo, int radius )
{
return NULL;
}
void CDisplayList::Set_visible( dl_element * el, int visible )
{
}
int CDisplayList::StopDragging()
{
return 0;
}
int CDisplayList::CancelHighLight()
{
return 0;
}
void CDisplayList::Set_id( dl_element * el, id * id )
{
}
id CDisplayList::Remove( dl_element * element )
{
return 0;
}
int CDisplayList::Get_w( dl_element * el )
{
return 0;
}
int CDisplayList::Get_x( dl_element * el )
{
return 0;
}
int CDisplayList::Get_y( dl_element * el )
{
return 0;
}
int CDisplayList::Get_xf( dl_element * el )
{
return 0;
}
int CDisplayList::Get_yf( dl_element * el )
{
return 0;
}
int CDisplayList::HighLight( int gtype, int x, int y, int xf, int yf, int w, int orig_layer )
{
return 0;
}
int CDisplayList::StartDraggingLineVertex( CDC * pDC, int x, int y, int xi, int yi,
int xf, int yf,
int layer1, int layer2, int w1, int w2,
int style1, int style2,
int layer_no_via, int via_w, int via_holew, int dir,
int crosshair )
{
return 0;
}
int CDisplayList::StartDraggingArc( CDC * pDC, int style, int x, int y, int xi, int yi,
int layer, int w, int crosshair )
{
return 0;
}

View File

@ -0,0 +1,269 @@
// DisplayList.h : header file for CDisplayList class
//
#ifndef FP_DISPLAY_LIST_H
#define FP_DISPLAY_LIST_H
//#define DL_MAX_LAYERS 32
#define DL_MAGIC 2674
#define PCBU_PER_WU 25400 // conversion from PCB units to world units
// graphics element types
enum
{
DL_NONE = 0,
DL_LINE, // line segment with round end-caps
DL_CIRC, // filled circle
DL_HOLLOW_CIRC, // circle outline
DL_DONUT, // annulus
DL_SQUARE, // filled square
DL_RECT, // filled rectangle
DL_RRECT, // filled rounded rectangle
DL_OVAL, // filled oval
DL_OCTAGON, // filled octagon
DL_HOLE, // hole, shown as circle
DL_HOLLOW_RECT, // rectangle outline
DL_RECT_X, // rectangle outline with X
DL_POINT, // shape to highlight a point
DL_ARC_CW, // arc with clockwise curve
DL_ARC_CCW, // arc with counter-clockwise curve
DL_X // X
};
// dragging line shapes
enum
{
DS_NONE = 0,
DS_LINE_VERTEX, // vertex between two lines
DS_LINE, // line
DS_ARC_STRAIGHT, // straight line (used when drawing polylines)
DS_ARC_CW, // clockwise arc (used when drawing polylines)
DS_ARC_CCW // counterclockwise arc (used when drawing polylines)
};
// styles of line segment when dragging line or line vertex
enum
{
DSS_STRAIGHT = 100, // straight line
DSS_ARC_CW, // clockwise arc
DSS_ARC_CCW // counterclockwise arc
};
// inflection modes for DS_LINE and DS_LINE_VERTEX
enum
{
IM_NONE = 0,
IM_90_45,
IM_45_90,
IM_90
};
class CDisplayList;
// this structure contains an element of the display list
class dl_element
{
friend class CDisplayList;
public:
CDisplayList * dlist;
int magic;
dl_element * prev;
dl_element * next;
id m_id; // identifier (see ids.h)
void * ptr; // pointer to object drawing this element
int gtype; // type of primitive
int visible; // 0 to hide
//private:
int sel_vert; // for selection rectangles, 1 if part is vertical
int w; // width (for round or square shapes)
int holew; // hole width (for round holes)
int x_org, y_org; // x origin (for rotation, reflection, etc.)
int x, y; // starting or center position of element
int xf, yf; // opposite corner (for rectangle or line)
int radius; // radius of corners for DL_RRECT
int layer; // layer to draw on
int orig_layer; // for elements on highlight layer,
// the original layer, the highlight will
// only be drawn if this layer is visible
};
class CDisplayList
{
private:
// display-list parameters for each layer
dl_element m_start[MAX_LAYERS], m_end[MAX_LAYERS];
int m_rgb[MAX_LAYERS][3]; // layer colors
BOOL m_vis[MAX_LAYERS]; // layer visibility flags
int m_layer_in_order[MAX_LAYERS]; // array of layers in draw order
int m_order_for_layer[MAX_LAYERS]; // draw order for each layer
// window parameters
int m_pcbu_per_wu; // i.e. nm per world unit
CRect m_client_r; // client rect (pixels)
CRect m_screen_r; // client rect (screen coords)
int m_pane_org_x; // left border of drawing pane (pixels)
int m_pane_org_y; // bottom border of drawing pane (pixels)
int m_bottom_pane_h; // height of bottom pane
CDC * memDC; // pointer to memory DC
double m_scale; // world units per pixel
int m_org_x; // world x-coord of left side of screen (world units)
int m_org_y; // world y-coord of bottom of screen (world units)
int m_max_x; // world x_coord of right side of screen (world units)
int m_max_y; // world y_coord of top of screen (world units)
int w_ext_x, w_ext_y; // window extents (world units)
int v_ext_x, v_ext_y; // viewport extents (pixels)
double m_wu_per_pixel_x; // ratio w_ext_x/v_ext_x (world units per pixel)
double m_wu_per_pixel_y; // ratio w_ext_y/v_ext_y (world units per pixel)
double m_pcbu_per_pixel_x;
double m_pcbu_per_pixel_y;
// general dragging parameters
int m_drag_angle; // angle of rotation of selection rectangle (starts at 0)
int m_drag_side; // 0 = no change, 1 = switch to opposite
int m_drag_vert; // 1 if item being dragged is a vertical part
// parameters for dragging polyline sides and trace segments
// that can be modified while dragging
int m_drag_flag; // 1 if dragging something
int m_drag_shape; // shape
int m_last_drag_shape; // last shape drawn
int m_drag_x; // last cursor position for dragged shape
int m_drag_y;
int m_drag_xi; // start of rubberband drag line
int m_drag_yi;
int m_drag_xf; // end of rubberband drag line
int m_drag_yf;
int m_drag_layer_1; // line layer
int m_drag_w1; // line width
int m_drag_style1; // line style
int m_inflection_mode; // inflection mode
int m_last_inflection_mode; // last mode drawn
// extra parameters when dragging vertex between 2 line segments
int m_drag_style2;
int m_drag_layer_2;
int m_drag_w2;
// parameters used to draw leading via if necessary
int m_drag_layer_no_via;
int m_drag_via_w;
int m_drag_via_holew;
int m_drag_via_drawn;
// arrays of lines and ratlines being dragged
// these can be rotated and flipped while being dragged
int m_drag_layer; // layer
int m_drag_max_lines; // max size of array for line segments
int m_drag_num_lines; // number of line segments to drag
CPoint * m_drag_line_pt; // array of relative coords for line endpoints
int m_drag_max_ratlines; // max size of ratline array
int m_drag_num_ratlines; // number of ratlines to drag
CPoint * m_drag_ratline_start_pt; // absolute coords for ratline start points
CPoint * m_drag_ratline_end_pt; // relative coords for ratline endpoints
int m_drag_ratline_width;
// cursor parameters
int m_cross_hairs; // 0 = none, 1 = cross-hairs, 2 = diagonals
CPoint m_cross_left, m_cross_right, m_cross_top, m_cross_bottom; // end-points
CPoint m_cross_topleft, m_cross_topright, m_cross_botleft, m_cross_botright;
// grid
int m_visual_grid_on;
double m_visual_grid_spacing; // in world units
public:
CDisplayList( int pcbu_per_wu );
~CDisplayList();
void SetVisibleGrid( BOOL on, double grid );
void SetMapping( CRect *client_r, CRect *screen_r, int pane_org_x, int pane_bottom_h, double scale, int org_x, int org_y );
void SetDCToWorldCoords( CDC * pDC, CDC * mDC, int pcbu_org_x, int pcbu_org_y );
void SetLayerRGB( int layer, int r, int g, int b );
void SetLayerVisible( int layer, BOOL vis );
void SetLayerDrawOrder( int layer, int order )
{ m_layer_in_order[order] = layer; m_order_for_layer[layer] = order; };
dl_element * Add( id id, void * ptr, int glayer, int gtype, int visible,
int w, int holew, int x, int y, int xf, int yf, int xo, int yo,
int radius=0, int orig_layer=LAY_SELECTION );
dl_element * AddSelector( id id, void * ptr, int glayer, int gtype, int visible,
int w, int holew, int x, int y, int xf, int yf, int xo, int yo, int radius=0 );
void RemoveAll();
void RemoveAllFromLayer( int layer );
id Remove( dl_element * element );
void Draw( CDC * pDC );
int HighLight( int gtype, int x, int y, int xf, int yf, int w, int orig_layer=LAY_SELECTION );
int CancelHighLight();
void * TestSelect( int x, int y, id * sel_id, int * layer,
id * exclude_id = NULL, void * exclude_ptr = NULL, id * include_id = NULL,
int n_include_ids=1 );
int StartDraggingArray( CDC * pDC, int x, int y, int vert, int layer, int crosshair = 1 );
int StartDraggingRatLine( CDC * pDC, int x, int y, int xf, int yf, int layer,
int w, int crosshair = 1 );
int StartDraggingRectangle( CDC * pDC, int x, int y, int xi, int yi,
int xf, int yf, int vert, int layer );
int StartDraggingLineVertex( CDC * pDC, int x, int y, int xi, int yi,
int xf, int yf,
int layer1, int layer2, int w1, int w2,
int style1, int style2,
int layer_no_via, int via_w, int via_holew, int dir,
int crosshair );
int StartDraggingLine( CDC * pDC, int x, int y, int xi, int yi, int layer1, int w,
int layer_no_via, int via_w, int via_holew,
int crosshair, int style, int inflection_mode );
int StartDraggingArc( CDC * pDC, int style, int x, int y, int xi, int yi,
int layer, int w, int crosshair );
void SetDragArcStyle( int style );
void Drag( CDC * pDC, int x, int y );
int StopDragging();
void ChangeRoutingLayer( CDC * pDC, int layer1, int layer2, int w );
void IncrementDragAngle( CDC * pDC );
int MakeDragLineArray( int num_lines );
int MakeDragRatlineArray( int num_ratlines, int width );
int AddDragLine( CPoint pi, CPoint pf );
int AddDragRatline( CPoint pi, CPoint pf );
int GetDragAngle();
void FlipDragSide( CDC * pDC );
int GetDragSide();
void SetUpCrosshairs( int type, int x, int y );
void SetInflectionMode( int mode ){ m_inflection_mode = mode; };
CPoint ScreenToPCB( CPoint point );
CPoint PCBToScreen( CPoint point );
CPoint WindowToPCB( CPoint point );
// set element parameters
void Set_gtype( dl_element * el, int gtype );
void Set_visible( dl_element * el, int visible );
void Set_sel_vert( dl_element * el, int sel_vert );
void Set_w( dl_element * el, int w );
void Set_holew( dl_element * el, int holew );
void Set_x_org( dl_element * el, int x_org );
void Set_y_org( dl_element * el, int y_org );
void Set_x( dl_element * el, int x );
void Set_y( dl_element * el, int y );
void Set_xf( dl_element * el, int xf );
void Set_yf( dl_element * el, int yf );
void Set_id( dl_element * el, id * id );
void Set_layer( dl_element * el, int layer );
void Set_radius( dl_element * el, int radius );
void Move( dl_element * el, int dx, int dy );
// get element parameters
void * Get_ptr( dl_element * el );
int Get_gtype( dl_element * el );
int Get_visible( dl_element * el );
int Get_sel_vert( dl_element * el );
int Get_w( dl_element * el );
int Get_holew( dl_element * el );
int Get_x_org( dl_element * el );
int Get_y_org( dl_element * el );
int Get_x( dl_element * el );
int Get_y( dl_element * el );
int Get_xf( dl_element * el );
int Get_yf( dl_element * el );
int Get_radius( dl_element * el );
int Get_layer( dl_element * el );
id Get_id( dl_element * el );
};
#endif // #ifndef FP_DISPLAY_LIST_H

118
polygon/freepcb_ids.h Normal file
View File

@ -0,0 +1,118 @@
// definition of ID structure used by FreePCB
//
#pragma once
// struct id : this structure is used to identify PCB design elements
// such as instances of parts or nets, and their subelements
// Each element will have its own id.
// An id is attached to each item of the Display List so that it can
// be linked back to the PCB design element which drew it.
// These are mainly used to identify items selected by clicking the mouse
//
// In general:
// id.type = type of PCB element (e.g. part, net, text)
// id.st = subelement type (e.g. part pad, net connection)
// id.i = subelement index (zero-based)
// id.sst = subelement of subelement (e.g. net connection segment)
// id.ii = subsubelement index (zero-based)
//
// For example, the id for segment 0 of connection 4 of net 12 would be
// id = { ID_NET, 12, ID_CONNECT, 4, ID_SEG, 0 };
//
//
class id {
public:
// constructor
id( int qt=0, int qst=0, int qis=0, int qsst=0, int qiis=0 )
{ type=qt; st=qst; i=qis; sst=qsst; ii=qiis; }
// operators
friend int operator ==(id id1, id id2)
{ return (id1.type==id2.type
&& id1.st==id2.st
&& id1.sst==id2.sst
&& id1.i==id2.i
&& id1.ii==id2.ii );
}
// member functions
void Clear()
{ type=0; st=0; i=0; sst=0; ii=0; }
void Set( int qt, int qst=0, int qis=0, int qsst=0, int qiis=0 )
{ type=qt; st=qst; i=qis; sst=qsst; ii=qiis; }
// member variables
unsigned int type; // type of element
unsigned int st; // type of subelement
unsigned int i; // index of subelement
unsigned int sst; // type of subsubelement
unsigned int ii; // index of subsubelement
};
// these are constants used in ids
// root types
enum {
ID_NONE = 0, // an undefined type or st (or an error)
ID_BOARD, // board outline
ID_PART, // part
ID_NET, // net
ID_TEXT, // free-standing text
ID_DRC, // DRC error
ID_SM_CUTOUT, // cutout for solder mask
ID_MULTI // if multiple selections
};
// subtypes of ID_PART
enum {
ID_PAD = 1, // pad_stack in a part
ID_SEL_PAD, // selection rectangle for pad_stack in a part
ID_OUTLINE, // part outline
ID_REF_TXT, // text showing ref num for part
ID_ORIG, // part origin
ID_SEL_RECT, // selection rectangle for part
ID_SEL_REF_TXT // selection rectangle for ref text
};
// subtypes of ID_TEXT
enum {
ID_SEL_TXT = 1, // selection rectangle
ID_STROKE // stroke for text
};
// subtypes of ID_NET
enum {
ID_ENTIRE_NET = 0,
ID_CONNECT, // connection
ID_AREA // copper area
};
// subtypes of ID_BOARD
enum {
ID_BOARD_OUTLINE = 1,
};
// subsubtypes of ID_NET.ID_CONNECT
enum {
ID_ENTIRE_CONNECT = 0,
ID_SEG,
ID_SEL_SEG,
ID_VERTEX,
ID_SEL_VERTEX,
ID_VIA
};
// subsubtypes of ID_NET.ID_AREA, ID_BOARD.ID_BOARD_OUTLINE, ID_SM_CUTOUT
enum {
ID_SIDE = 1,
ID_SEL_SIDE,
ID_SEL_CORNER,
ID_HATCH,
ID_PIN_X, // only used by ID_AREA
ID_STUB_X // only used by ID_AREA
};
// subtypes of ID_DRC
// for subsubtypes, use types in DesignRules.h
enum {
ID_DRE = 1,
ID_SEL_DRE
};

View File

@ -9,7 +9,8 @@ OBJECTS= \
php_polygon.o\
php_polygon_vertex.o\
PolyLine.o\
math_for_graphics.o
math_for_graphics.o\
cdisplaylist_stuff.o
GenericPolygonClipperLibrary.o: GenericPolygonClipperLibrary.cpp GenericPolygonClipperLibrary.h

File diff suppressed because it is too large Load Diff

104
polygon/math_for_graphics.h Normal file
View File

@ -0,0 +1,104 @@
// math stuff for graphics, from FreePCB
typedef struct PointTag
{
double X,Y;
} Point;
typedef struct EllipseTag
{
Point Center; /* ellipse center */
// double MaxRad,MinRad; /* major and minor axis */
// double Phi; /* major axis rotation */
double xrad, yrad; // radii on x and y
double theta1, theta2; // start and end angle for arc
} EllipseKH;
const CPoint zero(0,0);
class my_circle {
public:
my_circle(){};
my_circle( int xx, int yy, int rr )
{
x = xx;
y = yy;
r = rr;
};
int x, y, r;
};
class my_rect {
public:
my_rect(){};
my_rect( int xi, int yi, int xf, int yf )
{
xlo = min(xi,xf);
xhi = max(xi,xf);
ylo = min(yi,yf);
yhi = max(yi,yf);
};
int xlo, ylo, xhi, yhi;
};
class my_seg {
public:
my_seg(){};
my_seg( int xxi, int yyi, int xxf, int yyf )
{
xi = xxi;
yi = yyi;
xf = xxf;
yf = yyf;
};
int xi, yi, xf, yf;
};
// math stuff for graphics
BOOL Quadratic( double a, double b, double c, double *x1, double *x2 );
void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, BOOL bMeta=FALSE );
void RotatePoint( CPoint *p, int angle, CPoint org );
void RotateRect( CRect *r, int angle, CPoint org );
int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist );
int FindLineIntersection( double a, double b, double c, double d, double * x, double * y );
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style,
double * x1, double * y1, double * x2, double * y2, double * dist=NULL );
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
int xi2, int yi2, int xf2, int yf2, int style2,
double x[]=NULL, double y[]=NULL );
BOOL FindLineEllipseIntersections( double a, double b, double c, double d, double *x1, double *x2 );
BOOL FindVerticalLineEllipseIntersections( double a, double b, double x, double *y1, double *y2 );
BOOL TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
int x2i, int y2i, int x2f, int y2f,
int * x=NULL, int * y=NULL, double * dist=NULL );
void GetPadElements( int type, int x, int y, int wid, int len, int radius, int angle,
int * nr, my_rect r[], int * nc, my_circle c[], int * ns, my_seg s[] );
int GetClearanceBetweenPads( int type1, int x1, int y1, int w1, int l1, int r1, int angle1,
int type2, int x2, int y2, int w2, int l2, int r2, int angle2 );
int GetClearanceBetweenSegmentAndPad( int x1, int y1, int x2, int y2, int w,
int type, int x, int y, int wid, int len,
int radius, int angle );
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1,
int x2i, int y2i, int x2f, int y2f, int style2, int w2,
int max_cl, int * x, int * y );
/** Function GetPointToLineSegmentDistance
* Get distance between line segment and point
* @param x,y = point
* @param xi,yi and xf,yf = the end-points of the line segment
* @return the distance
*/
double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf );
double GetPointToLineDistance( double a, double b, int x, int y, double * xp=NULL, double * yp=NULL );
BOOL InRange( double x, double xi, double xf );
double Distance( int x1, int y1, int x2, int y2 );
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2,
double * x1=NULL, double * y1=NULL,
double * x2=NULL, double * y2=NULL );
CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode );
// quicksort (2-way or 3-way)
void quickSort(int numbers[], int index[], int array_size);
void q_sort(int numbers[], int index[], int left, int right);
void q_sort_3way( int a[], int b[], int left, int right );