First version of pcbnew using polygonal filled areas in zones in rats nets calculations.

This commit is contained in:
charras 2008-11-18 18:13:55 +00:00
parent f43a7acc6a
commit 178bc946e3
27 changed files with 1744 additions and 1256 deletions

View File

@ -4,6 +4,11 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2008-Nov-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++pcbnew
First version of pcbnew using polygonal filled areas in zones in rats nets calculations.
Needs more tests.
2008-Nov-14 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2008-Nov-14 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
@ -19,7 +24,7 @@ kbool:
2008-Nov-14 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Nov-14 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
+gerview +gerbiew
+ Added support for displaying most aperture macros embedded in a RS274X compatible file. + Added support for displaying most aperture macros embedded in a RS274X compatible file.
Cleanup of rs274d.cpp and added the beginning of the isDark support, which we Cleanup of rs274d.cpp and added the beginning of the isDark support, which we
need to discuss. GERBER::m_ImageNegative can toggle during the course of reading need to discuss. GERBER::m_ImageNegative can toggle during the course of reading

View File

@ -33,6 +33,7 @@ set(CVPCB_EXTRA_SRCS
../pcbnew/basepcbframe.cpp ../pcbnew/basepcbframe.cpp
../pcbnew/class_board.cpp ../pcbnew/class_board.cpp
../pcbnew/class_board_item.cpp ../pcbnew/class_board_item.cpp
../pcbnew/class_board_connected_item.cpp
../pcbnew/class_cotation.cpp ../pcbnew/class_cotation.cpp
../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.cpp
../pcbnew/class_edge_mod.cpp ../pcbnew/class_edge_mod.cpp

View File

@ -12,12 +12,11 @@ EXTRALIBS = ../common/common.a ../bitmaps/libbitmaps.a\
LIBVIEWER3D = ../3d-viewer/3d-viewer.a LIBVIEWER3D = ../3d-viewer/3d-viewer.a
# DEPEND = cvpcb.h ../include/pcbstruct.h
OBJECTS = $(TARGET).o \ OBJECTS = $(TARGET).o \
class_cvpcb.o\ class_cvpcb.o\
class_zone.o\ class_zone.o\
class_zone_setting.o\ class_zone_setting.o\
class_board_connected_item.o\
memoire.o \ memoire.o \
cvframe.o\ cvframe.o\
listboxes.o\ listboxes.o\
@ -55,30 +54,33 @@ OBJECTS = $(TARGET).o \
basepcbframe.o\ basepcbframe.o\
collectors.o collectors.o
cvpcb.o: cvpcb.cpp cvpcb.h $(DEPEND) cvpcb.o: cvpcb.cpp cvpcb.h
displayframe.o: displayframe.cpp $(DEPEND) displayframe.o: displayframe.cpp
listboxes.o: listboxes.cpp $(DEPEND) listboxes.o: listboxes.cpp
drawpanel.o: ../share/drawpanel.cpp $(DEPEND) drawpanel.o: ../share/drawpanel.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
drawframe.o: ../share/drawframe.cpp $(DEPEND) drawframe.o: ../share/drawframe.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
init.o: init.cpp $(DEPEND) init.o: init.cpp
memoire.o: memoire.cpp $(DEPEND) memoire.o: memoire.cpp
rdpcad.o: rdpcad.cpp $(DEPEND) rdpcad.o: rdpcad.cpp
classpcb.o: ../pcbnew/classpcb.cpp $(DEPEND) classpcb.o: ../pcbnew/classpcb.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_mire.o: ../pcbnew/class_mire.cpp ../pcbnew/class_mire.h $(COMMON) class_mire.o: ../pcbnew/class_mire.cpp ../pcbnew/class_mire.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_board_connected_item.o: ../pcbnew/class_board_connected_item.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h $(COMMON) class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
@ -91,68 +93,68 @@ class_cotation.o: ../pcbnew/class_cotation.cpp ../pcbnew/class_cotation.h $(COMM
class_pcb_text.o: ../pcbnew/class_pcb_text.cpp ../pcbnew/class_pcb_text.h $(COMMON) class_pcb_text.o: ../pcbnew/class_pcb_text.cpp ../pcbnew/class_pcb_text.h $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_board.o: ../pcbnew/class_board.cpp $(DEPEND) class_board.o: ../pcbnew/class_board.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_drawsegment.o: ../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.h $(DEPEND) class_drawsegment.o: ../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_track.o: ../pcbnew/class_track.cpp $(DEPEND) class_track.o: ../pcbnew/class_track.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_pad.o: ../pcbnew/class_pad.cpp $(DEPEND) class_pad.o: ../pcbnew/class_pad.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_module.o: ../pcbnew/class_module.cpp $(DEPEND) class_module.o: ../pcbnew/class_module.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_text_mod.o: ../pcbnew/class_text_mod.cpp $(DEPEND) class_text_mod.o: ../pcbnew/class_text_mod.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_edge_mod.o: ../pcbnew/class_edge_mod.cpp $(DEPEND) class_edge_mod.o: ../pcbnew/class_edge_mod.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_equipot.o: ../pcbnew/class_equipot.cpp $(DEPEND) class_equipot.o: ../pcbnew/class_equipot.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
basepcbframe.o: ../pcbnew/basepcbframe.cpp $(DEPEND) basepcbframe.o: ../pcbnew/basepcbframe.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
collectors.o: ../pcbnew/collectors.cpp $(COMMON) collectors.o: ../pcbnew/collectors.cpp $(COMMON)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
readschematicnetlist.o: readschematicnetlist.cpp $(DEPEND) readschematicnetlist.o: readschematicnetlist.cpp
viewlogi.o: viewlogi.cpp $(DEPEND) viewlogi.o: viewlogi.cpp
viewlnet.o: viewlnet.cpp $(DEPEND) viewlnet.o: viewlnet.cpp
loadcmp.o: loadcmp.cpp $(DEPEND) loadcmp.o: loadcmp.cpp
savecmp.o: savecmp.cpp $(DEPEND) savecmp.o: savecmp.cpp
writenetlistpcbnew.o: writenetlistpcbnew.cpp $(DEPEND) writenetlistpcbnew.o: writenetlistpcbnew.cpp
genequiv.o: genequiv.cpp $(DEPEND) genequiv.o: genequiv.cpp
ioascii.o: ../pcbnew/ioascii.cpp $(DEPEND) ioascii.o: ../pcbnew/ioascii.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
listlib.o: listlib.cpp $(DEPEND) listlib.o: listlib.cpp
cfg.o: cfg.cpp cfg.h $(DEPEND) cfg.o: cfg.cpp cfg.h
menucfg.o: menucfg.cpp dialog_cvpcb_config.cpp dialog_cvpcb_config.h $(DEPEND) menucfg.o: menucfg.cpp dialog_cvpcb_config.cpp dialog_cvpcb_config.h
autosel.o: autosel.cpp $(DEPEND) autosel.o: autosel.cpp
setvisu.o: setvisu.cpp $(DEPEND) setvisu.o: setvisu.cpp
zoom.o: ../share/zoom.cpp $(DEPEND) zoom.o: ../share/zoom.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
tracemod.o: ../pcbnew/tracemod.cpp ../include/gr_basic.h $(DEPEND) tracemod.o: ../pcbnew/tracemod.cpp ../include/gr_basic.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
dialog_display_options.o: dialog_display_options.cpp dialog_display_options.h $(DEPEND) dialog_display_options.o: dialog_display_options.cpp dialog_display_options.h

View File

@ -43,6 +43,7 @@ set(GERBVIEW_SRCS
set(GERBVIEW_EXTRA_SRCS set(GERBVIEW_EXTRA_SRCS
../pcbnew/basepcbframe.cpp ../pcbnew/basepcbframe.cpp
../pcbnew/class_board.cpp ../pcbnew/class_board.cpp
../pcbnew/class_board_connected_item.cpp
../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.cpp
../pcbnew/class_drc_item.cpp ../pcbnew/class_drc_item.cpp
../pcbnew/class_marker.cpp ../pcbnew/class_marker.cpp

View File

@ -7,8 +7,6 @@ EXTRACPPFLAGS= -DGERBVIEW -DPCBNEW -fno-strict-aliasing\
-I../polygon -I../polygon
#COMMON = pcbnew.h struct.h
OBJECTS= \ OBJECTS= \
$(TARGET).o\ $(TARGET).o\
classpcb.o\ classpcb.o\
@ -27,6 +25,7 @@ OBJECTS= \
class_drawsegment.o\ class_drawsegment.o\
class_track.o \ class_track.o \
class_drc_item.o \ class_drc_item.o \
class_board_connected_item.o\
drawframe.o\ drawframe.o\
drawpanel.o\ drawpanel.o\
set_color.o \ set_color.o \
@ -65,132 +64,135 @@ drawpanel.o: ../share/drawpanel.cpp
drawframe.o: ../share/drawframe.cpp drawframe.o: ../share/drawframe.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
controle.o: controle.cpp $(COMMON) controle.o: controle.cpp
hotkeys.o: hotkeys.cpp hotkeys.h $(COMMON) hotkeys.o: hotkeys.cpp hotkeys.h
set_color.o: set_color.cpp set_color.h $(COMMON) set_color.o: set_color.cpp set_color.h
files.o: files.cpp $(COMMON) files.o: files.cpp
class_marker.o: ../pcbnew/class_marker.cpp ../pcbnew/class_marker.h $(COMMON) class_board_connected_item.o: ../pcbnew/class_board_connected_item.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h $(COMMON) class_marker.o: ../pcbnew/class_marker.cpp ../pcbnew/class_marker.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone_setting.o: ../pcbnew/class_zone_setting.cpp ../pcbnew/class_zone_setting.h $(COMMON) class_zone.o: ../pcbnew/class_zone.cpp ../pcbnew/class_zone.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_zone_setting.o: ../pcbnew/class_zone_setting.cpp ../pcbnew/class_zone_setting.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_drawsegment.o: ../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.h $(DEPEND) class_drawsegment.o: ../pcbnew/class_drawsegment.cpp ../pcbnew/class_drawsegment.h $(DEPEND)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_drc_item.o: ../pcbnew/class_drc_item.cpp $(COMMON) class_drc_item.o: ../pcbnew/class_drc_item.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
sel_layer.o: ../pcbnew/sel_layer.cpp $(COMMON) sel_layer.o: ../pcbnew/sel_layer.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
wxprint.o: ../share/wxprint.cpp ../share/dialog_print.cpp ../share/dialog_print.h $(COMMON) wxprint.o: ../share/wxprint.cpp ../share/dialog_print.cpp ../share/dialog_print.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
lay2plot.o: lay2plot.cpp $(COMMON) lay2plot.o: lay2plot.cpp
classpcb.o: ../pcbnew/classpcb.cpp $(COMMON) classpcb.o: ../pcbnew/classpcb.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_pcb_text.o: ../pcbnew/class_pcb_text.cpp ../pcbnew/class_pcb_text.h $(COMMON) class_pcb_text.o: ../pcbnew/class_pcb_text.cpp ../pcbnew/class_pcb_text.h
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_board.o: ../pcbnew/class_board.cpp $(DEPEND) class_board.o: ../pcbnew/class_board.cpp $(DEPEND)
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
basepcbframe.o: ../pcbnew/basepcbframe.cpp $(COMMON) basepcbframe.o: ../pcbnew/basepcbframe.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
collectors.o: ../pcbnew/collectors.cpp $(COMMON) collectors.o: ../pcbnew/collectors.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
class_track.o: ../pcbnew/class_track.cpp $(COMMON) class_track.o: ../pcbnew/class_track.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../pcbnew/$*.cpp
$(TARGET).o: $(TARGET).cpp $(COMMON) $(TARGET).o: $(TARGET).cpp
gerbview_config.o: gerbview_config.cpp gerbview_config.h $(COMMON) gerbview_config.o: gerbview_config.cpp gerbview_config.h
tracepcb.o: tracepcb.cpp $(COMMON) tracepcb.o: tracepcb.cpp
block.o: block.cpp $(COMMON) block.o: block.cpp
trpiste.o: trpiste.cpp $(COMMON) trpiste.o: trpiste.cpp
surbrill.o: surbrill.cpp $(COMMON) surbrill.o: surbrill.cpp
pcbtexte.o: pcbtexte.cpp $(COMMON) pcbtexte.o: pcbtexte.cpp
zoom.o: ../share/zoom.cpp $(COMMON) zoom.o: ../share/zoom.cpp
$(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp $(CXX) -c $(EDACPPFLAGS) -o $@ ../share/$*.cpp
affiche.o: affiche.cpp $(COMMON) affiche.o: affiche.cpp
reglage.o: reglage.cpp $(COMMON) reglage.o: reglage.cpp
editrack.o: editrack.cpp $(COMMON) editrack.o: editrack.cpp
deltrack.o: deltrack.cpp $(COMMON) deltrack.o: deltrack.cpp
track.o: track.cpp $(COMMON) track.o: track.cpp
editrout.o: editrout.cpp autorout.h $(COMMON) editrout.o: editrout.cpp autorout.h
editmod.o: editmod.cpp autorout.h $(COMMON) editmod.o: editmod.cpp autorout.h
editpads.o: editpads.cpp $(COMMON) editpads.o: editpads.cpp
editedge.o: editedge.cpp $(COMMON) editedge.o: editedge.cpp
cotation.o: cotation.cpp $(COMMON) cotation.o: cotation.cpp
editexte.o: editexte.cpp $(COMMON) editexte.o: editexte.cpp
clean.o: clean.cpp autorout.h $(COMMON) clean.o: clean.cpp autorout.h
pcbplot.o: pcbplot.cpp $(COMMON) pcbplot.o: pcbplot.cpp
plothpgl.o: plothpgl.cpp $(COMMON) plothpgl.o: plothpgl.cpp
plotgerb.o: plotgerb.cpp pcbplot.h $(COMMON) plotgerb.o: plotgerb.cpp pcbplot.h
printps.o: printps.cpp pcbplot.h $(COMMON) printps.o: printps.cpp pcbplot.h
readgerb.o: readgerb.cpp pcbplot.h $(COMMON) readgerb.o: readgerb.cpp pcbplot.h
plot_rtn.o: plot_rtn.cpp pcbplot.h $(COMMON) plot_rtn.o: plot_rtn.cpp pcbplot.h
gendrill.o: gendrill.cpp pcbplot.h $(COMMON) gendrill.o: gendrill.cpp pcbplot.h
librairi.o: librairi.cpp autorout.h librairi.h $(COMMON) librairi.o: librairi.cpp autorout.h librairi.h
docedit.o: docedit.cpp $(COMMON) docedit.o: docedit.cpp
edgemod.o: edgemod.cpp $(COMMON) edgemod.o: edgemod.cpp
autorout.o: autorout.cpp cell.h autorout.fct autorout.h $(COMMON) autorout.o: autorout.cpp cell.h autorout.fct autorout.h
setlayer.o: setlayer.cpp $(COMMON) setlayer.o: setlayer.cpp
dist.o: dist.cpp cell.h autorout.fct $(COMMON) dist.o: dist.cpp cell.h autorout.fct
zones.o: zones.cpp cell.h autorout.fct $(COMMON) zones.o: zones.cpp cell.h autorout.fct
undelete.o: undelete.cpp $(COMMON) undelete.o: undelete.cpp
ioascii.o: ioascii.cpp $(COMMON) ioascii.o: ioascii.cpp
chrono.o: chrono.cpp pcbnew.h chrono.o: chrono.cpp pcbnew.h
coordbox.o: coordbox.cpp $(COMMON) coordbox.o: coordbox.cpp
mirepcb.o: mirepcb.cpp $(COMMON) mirepcb.o: mirepcb.cpp
dragsegm.o: dragsegm.cpp drag.h $(COMMON) dragsegm.o: dragsegm.cpp drag.h

View File

@ -1,22 +1,39 @@
/*********************************************************************/ /**********************************************************************************************/
/* board_item_struct.h : Basic classes for BOARD_ITEM descriptions */ /* board_item_struct.h : Basic classes for BOARD_ITEM and BOARD_CONNECTED_ITEM descriptions */
/*********************************************************************/ /**********************************************************************************************/
#ifndef BOARD_ITEM_STRUCT_H #ifndef BOARD_ITEM_STRUCT_H
#define BOARD_ITEM_STRUCT_H #define BOARD_ITEM_STRUCT_H
/* Forme des segments (pistes, contours ..) ( parametre .shape ) */ /**
* Class BOARD_ITEM
* is a base class for any item which can be embedded within the BOARD
* container class, and therefore instances of derived classes should only be
* found in PCBNEW or other programs that use class BOARD and its contents.
* The corresponding class in EESCHEMA is SCH_ITEM.
*/
/**
* Class BOARD_CONNECTED_ITEM
* This is a base class derived from BOARD_ITEM for items that can be connected
* mainly: tracks and pads
* Handle connection info
*
*/
/* Shapes for segments (graphic segments and tracks) ( .shape member ) */
enum Track_Shapes { enum Track_Shapes {
S_SEGMENT = 0, /* segment rectiligne */ S_SEGMENT = 0, /* usual segment : line with rounded ends */
S_RECT, /* segment forme rect (i.e. bouts non arrondis) */ S_RECT, /* segment with non rounded ends */
S_ARC, /* segment en arc de cercle (bouts arrondis)*/ S_ARC, /* Arcs (with rounded ends)*/
S_CIRCLE, /* segment en cercle (anneau)*/ S_CIRCLE, /* ring*/
S_ARC_RECT, /* segment en arc de cercle (bouts droits) (GERBER)*/ S_ARC_RECT, /* Arcs (with non rounded ends) (GERBER)*/
S_SPOT_OVALE, /* spot ovale (for GERBER)*/ S_SPOT_OVALE, /* Oblong spot (for GERBER)*/
S_SPOT_CIRCLE, /* spot rond (for GERBER)*/ S_SPOT_CIRCLE, /* rounded spot (for GERBER)*/
S_SPOT_RECT, /* spot rect (for GERBER)*/ S_SPOT_RECT, /* Rectangular spott (for GERBER)*/
S_POLYGON /* polygon shape */ S_POLYGON /* polygonal shape */
}; };
@ -165,5 +182,40 @@ public:
virtual bool Save( FILE* aFile ) const = 0; virtual bool Save( FILE* aFile ) const = 0;
}; };
class BOARD_CONNECTED_ITEM: public BOARD_ITEM
{
protected:
int m_NetCode; // Net number
int m_Subnet; /* In rastnest routines : for the current net,
* block number (number common to the current connected items found) */
int m_ZoneSubnet; // variable used in rastnest computations : for the current net,
// handle block number in zone connection
public:
BOARD_CONNECTED_ITEM( BOARD_ITEM* StructFather, KICAD_T idtype );
BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& src );
/**
* Function GetNet
* @return int - the net code.
*/
int GetNet() const;
void SetNet( int aNetCode );
/**
* Function GetSubNet
* @return int - the sub net code.
*/
int GetSubNet() const;
void SetSubNet( int aSubNetCode );
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int GetZoneSubNet() const;
void SetZoneSubNet( int aSubNetCode );
};
#endif /* BOARD_ITEM_STRUCT_H */ #endif /* BOARD_ITEM_STRUCT_H */

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@ set(PCBNEW_SRCS
board.cpp board.cpp
class_board.cpp class_board.cpp
class_board_item.cpp class_board_item.cpp
class_board_connected_item.cpp
class_cotation.cpp class_cotation.cpp
class_drawsegment.cpp class_drawsegment.cpp
class_drc_item.cpp class_drc_item.cpp
@ -145,6 +146,7 @@ set(PCBNEW_SRCS
zones_convert_brd_items_to_polygons.cpp zones_convert_brd_items_to_polygons.cpp
zone_filling_algorithm.cpp zone_filling_algorithm.cpp
zones_polygons_insulated_copper_islands.cpp zones_polygons_insulated_copper_islands.cpp
zones_polygons_test_connections.cpp
zones_test_and_combine_areas.cpp zones_test_and_combine_areas.cpp
) )

View File

@ -977,8 +977,8 @@ void Build_PlacedPads_List( BOARD* Pcb )
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext ) for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext )
{ {
*pt_liste_pad = PtPad; *pt_liste_pad = PtPad;
PtPad->m_physical_connexion = 0; PtPad->SetSubNet( 0 );
PtPad->m_logical_connexion = 0; PtPad->SetSubRatsnest( 0 );
PtPad->m_Parent = Module; PtPad->m_Parent = Module;
if( PtPad->GetNet() ) if( PtPad->GetNet() )
Pcb->m_NbNodes++; Pcb->m_NbNodes++;

View File

@ -544,6 +544,16 @@ public:
* @return errors count * @return errors count
*/ */
int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,bool aCreate_Markers ); int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,bool aCreate_Markers );
/****** function relative to ratsnest calculations: */
/**
* Function Test_Connection_To_Copper_Areas
* init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found
* @param aNetcode = netcode to analyse. if -1, analyse all nets
*/
void Test_Connections_To_Copper_Areas( int aNetcode = -1 );
}; };
#endif // #ifndef CLASS_BOARD_H #endif // #ifndef CLASS_BOARD_H

View File

@ -0,0 +1,76 @@
/*************************************************************************/
/* class_board_connected_item.cpp : BOARD_CONNECTED_ITEM class functions */
/*************************************************************************/
#include "fctsys.h"
#include "wxstruct.h"
#include "common.h"
#include "pcbnew.h"
#ifdef CVPCB
#include "cvpcb.h"
#endif
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* StructFather, KICAD_T idtype ) :
BOARD_ITEM( StructFather, idtype )
{
m_NetCode = 0;
m_Subnet = 0;
m_ZoneSubnet = 0;
}
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& src ) :
BOARD_ITEM( src )
{
m_Layer = src.m_Layer;
}
/**
* Function GetNet
* @return int - the net code.
*/
int BOARD_CONNECTED_ITEM::GetNet() const
{
return m_NetCode;
}
void BOARD_CONNECTED_ITEM::SetNet( int aNetCode )
{
m_NetCode = aNetCode;
}
/**
* Function GetSubNet
* @return int - the sub net code.
*/
int BOARD_CONNECTED_ITEM::GetSubNet() const
{
return m_Subnet;
}
void BOARD_CONNECTED_ITEM::SetSubNet( int aSubNetCode )
{
m_Subnet = aSubNetCode;
}
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int BOARD_CONNECTED_ITEM::GetZoneSubNet() const
{
return m_ZoneSubnet;
}
void BOARD_CONNECTED_ITEM::SetZoneSubNet( int aSubNetCode )
{
m_ZoneSubnet = aSubNetCode;
}

View File

@ -26,12 +26,10 @@
/* classe D_PAD : constructeur */ /* classe D_PAD : constructeur */
/*******************************/ /*******************************/
D_PAD::D_PAD( MODULE* parent ) : D_PAD::D_PAD( MODULE* parent ) : BOARD_CONNECTED_ITEM( parent, TYPEPAD )
BOARD_ITEM( parent, TYPEPAD )
{ {
m_NumPadName = 0; m_NumPadName = 0;
m_Masque_Layer = CUIVRE_LAYER; m_Masque_Layer = CUIVRE_LAYER;
SetNet( 0 ); /* Numero de net pour comparaisons rapides */
m_DrillShape = PAD_CIRCLE; // Drill shape = circle m_DrillShape = PAD_CIRCLE; // Drill shape = circle
m_Size.x = m_Size.y = 500; m_Size.x = m_Size.y = 500;
@ -45,8 +43,7 @@ D_PAD::D_PAD( MODULE* parent ) :
m_Attribut = PAD_STANDARD; // NORMAL, PAD_SMD, PAD_CONN, Bit 7 = STACK m_Attribut = PAD_STANDARD; // NORMAL, PAD_SMD, PAD_CONN, Bit 7 = STACK
m_Orient = 0; // en 1/10 degres m_Orient = 0; // en 1/10 degres
m_logical_connexion = 0; SetSubRatsnest(0);
m_physical_connexion = 0; // variables utilisee lors du calcul du chevelu
ComputeRayon(); ComputeRayon();
} }
@ -199,8 +196,8 @@ void D_PAD::Copy( D_PAD* source )
m_Attribut = source->m_Attribut; // NORMAL, PAD_SMD, PAD_CONN, Bit 7 = STACK m_Attribut = source->m_Attribut; // NORMAL, PAD_SMD, PAD_CONN, Bit 7 = STACK
m_Orient = source->m_Orient; // en 1/10 degres m_Orient = source->m_Orient; // en 1/10 degres
m_logical_connexion = 0; // variable utilisee lors du calcul du chevelu SetSubRatsnest( 0 );
m_physical_connexion = 0; // variable utilisee lors du calcul de la connexit<69> SetSubNet( 0 );
m_Netname = source->m_Netname; m_Netname = source->m_Netname;
} }
@ -890,7 +887,7 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame )
}; };
static const wxString Msg_Pad_Attribut[5] = static const wxString Msg_Pad_Attribut[5] =
{ wxT( "norm" ), wxT( "smd " ), wxT( "conn" ), wxT( "hole" ), wxT( "????" ) }; { wxT( "norm" ), wxT( "smd " ), wxT( "conn" ), wxT( "????" ) };
frame->MsgPanel->EraseMsgBox(); frame->MsgPanel->EraseMsgBox();
@ -910,9 +907,9 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame )
/* For test and debug only: display m_physical_connexion and m_logical_connexion */ /* For test and debug only: display m_physical_connexion and m_logical_connexion */
pos += 10; pos += 10;
#if 0 #if 1 // Used only to debug connectivity calculations
Line.Printf( wxT( "%d.%d " ), m_logical_connexion, m_physical_connexion ); Line.Printf( wxT( "%d-%d-%d " ), GetSubRatsnest(), GetSubNet(), m_ZoneSubnet );
Affiche_1_Parametre( frame, pos, "L.P", Line, WHITE ); Affiche_1_Parametre( frame, pos, wxT("L-P-Z"), Line, DARKGREEN );
#endif #endif
wxString LayerInfo; wxString LayerInfo;
@ -993,13 +990,9 @@ void D_PAD::Display_Infos( WinEDA_DrawFrame* frame )
Affiche_1_Parametre( frame, pos, _( "Layer" ), LayerInfo, DARKGREEN ); Affiche_1_Parametre( frame, pos, _( "Layer" ), LayerInfo, DARKGREEN );
pos += 6; pos += 6;
Affiche_1_Parametre( frame, pos, Msg_Pad_Shape[m_PadShape], wxEmptyString, DARKGREEN ); int attribut = m_Attribut & 15;
if ( attribut > 3 ) attribut = 3;
Affiche_1_Parametre( frame, Affiche_1_Parametre( frame, pos, Msg_Pad_Shape[m_PadShape],Msg_Pad_Attribut[attribut], DARKGREEN );
-1,
wxEmptyString,
Msg_Pad_Attribut[m_Attribut & 15],
DARKGREEN );
valeur_param( m_Size.x, Line ); valeur_param( m_Size.x, Line );
pos += 6; pos += 6;

View File

@ -8,7 +8,7 @@ class Pcb3D_GLCanvas;
/* Definition type Structure d'un pad */ /* Definition type Structure d'un pad */
class D_PAD : public BOARD_ITEM class D_PAD : public BOARD_CONNECTED_ITEM
{ {
private: private:
int m_NetCode; // Net number for fast comparisons int m_NetCode; // Net number for fast comparisons
@ -60,15 +60,10 @@ public:
int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN
int m_Orient; // in 1/10 degrees int m_Orient; // in 1/10 degrees
int m_logical_connexion; // variable used in rastnest computations private:
int m_SubRatsnest; // variable used in rats nest computations
// handle subnet (block) number in ratsnet connection // handle subnet (block) number in ratsnet connection
int m_physical_connexion; // variable used in rastnest computations
// handle physical subnet (block)number in track connection
protected:
int m_ZoneSubnet; // variable used in rastnest computations
// handle block number in zone connection
public: public:
D_PAD( MODULE* parent ); D_PAD( MODULE* parent );
D_PAD( D_PAD* pad ); D_PAD( D_PAD* pad );
@ -128,15 +123,9 @@ public:
* Function GetNet * Function GetNet
* @return int - the netcode * @return int - the netcode
*/ */
int GetNet() const { return m_NetCode; } int GetSubRatsnest() const { return m_SubRatsnest; }
void SetNet( int aNetCode ) { m_NetCode = aNetCode; } void SetSubRatsnest( int aSubRatsnest ) { m_SubRatsnest = aSubRatsnest; }
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int GetZoneSubNet() const { return m_ZoneSubnet; }
void SetZoneSubNet( int aSubNetCode ) { m_ZoneSubnet = aSubNetCode; }
/** /**
* Function Display_Infos * Function Display_Infos

View File

@ -58,15 +58,12 @@ static bool ShowClearance( const TRACK* aTrack )
/**********************************************************/ /**********************************************************/
TRACK::TRACK( BOARD_ITEM* StructFather, KICAD_T idtype ) : TRACK::TRACK( BOARD_ITEM* StructFather, KICAD_T idtype ) :
BOARD_ITEM( StructFather, idtype ) BOARD_CONNECTED_ITEM( StructFather, idtype )
/**********************************************************/ /**********************************************************/
{ {
m_Width = 0; m_Width = 0;
m_Shape = S_SEGMENT; m_Shape = S_SEGMENT;
start = end = NULL; start = end = NULL;
SetNet( 0 );
SetSubNet( 0 );
SetZoneSubNet( 0 );
SetDrillDefault(); SetDrillDefault();
m_Param = 0; m_Param = 0;
} }
@ -98,7 +95,7 @@ SEGVIA::SEGVIA( BOARD_ITEM* StructFather ) :
// Copy constructor // Copy constructor
TRACK::TRACK( const TRACK& Source ) : TRACK::TRACK( const TRACK& Source ) :
BOARD_ITEM( Source ) BOARD_CONNECTED_ITEM( Source )
{ {
m_Shape = Source.m_Shape; m_Shape = Source.m_Shape;
SetNet( Source.GetNet() ); SetNet( Source.GetNet() );

View File

@ -16,7 +16,7 @@
/***/ /***/
class TRACK : public BOARD_ITEM class TRACK : public BOARD_CONNECTED_ITEM
{ {
public: public:
int m_Width; // 0 = line, > 0 = tracks, bus ... int m_Width; // 0 = line, > 0 = tracks, bus ...
@ -35,12 +35,6 @@ public:
int m_Param; // Auxiliary variable ( used in some computations ) int m_Param; // Auxiliary variable ( used in some computations )
protected: protected:
int m_NetCode; // Net number
int m_Subnet; /* In rastnest routines : for the current net,
* block number (number common to the current connected items found) */
int m_ZoneSubnet; // variable used in rastnest computations : for the current net,
// handle block number in zone connection
TRACK( const TRACK& track ); // protected so Copy() is used instead. TRACK( const TRACK& track ); // protected so Copy() is used instead.
public: public:
@ -72,7 +66,7 @@ public:
EDA_Rect GetBoundingBox(); EDA_Rect GetBoundingBox();
/* supprime du chainage la structure Struct */ /* Remove "this" from the linked list */
void UnLink(); void UnLink();
@ -117,28 +111,6 @@ public:
*/ */
TRACK* GetEndNetCode( int NetCode ); TRACK* GetEndNetCode( int NetCode );
/**
* Function GetNet
* @return int - the net code.
*/
int GetNet() const { return m_NetCode; }
void SetNet( int aNetCode ) { m_NetCode = aNetCode; }
/**
* Function GetSubNet
* @return int - the sub net code.
*/
int GetSubNet() const { return m_Subnet; }
void SetSubNet( int aSubNetCode ) { m_Subnet = aSubNetCode; }
/**
* Function GetZoneSubNet
* @return int - the sub net code in zone connections.
*/
int GetZoneSubNet() const { return m_ZoneSubnet; }
void SetZoneSubNet( int aSubNetCode ) { m_ZoneSubnet = aSubNetCode; }
/** /**
* Function GetLength * Function GetLength
* returns the length of the track using the hypotenuse calculation. * returns the length of the track using the hypotenuse calculation.

View File

@ -97,15 +97,6 @@ public:
int aDrawMode, int aDrawMode,
const wxPoint& offset = ZeroOffset ); const wxPoint& offset = ZeroOffset );
EDA_Rect GetBoundingBox();
/**
* Function Test_For_Copper_Island_And_Remove__Insulated_Islands
* Remove insulated copper islands found in m_FilledPolysList.
* @param aPcb = the board to analyse
*/
void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb );
/** /**
* Function DrawWhileCreateOutline * Function DrawWhileCreateOutline
* Draws the zone outline when ir is created. * Draws the zone outline when ir is created.
@ -118,6 +109,27 @@ public:
void DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode = GR_OR ); void DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode = GR_OR );
/* Function GetBoundingBox
* @return an EDA_Rect that is the bounding box of the zone outline
*/
EDA_Rect GetBoundingBox();
/**
* Function Test_For_Copper_Island_And_Remove__Insulated_Islands
* Remove insulated copper islands found in m_FilledPolysList.
* @param aPcb = the board to analyse
*/
void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb );
/** function CalculateSubAreaBoundaryBox
* Calculates the bounding box of a a filled area ( list of CPolyPt )
* use m_FilledPolysList as list of CPolyPt (that are the corners of one or more polygons or filled areas )
* @return an EDA_Rect as bounding box
* @param aIndexStart = index of the first corner of a polygon (filled area) in m_FilledPolysList
* @param aIndexEnd = index of the last corner of a polygon in m_FilledPolysList
*/
EDA_Rect CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd );
/** /**
* Function IsOnCopperLayer * Function IsOnCopperLayer
* @return true if this zone is on a copper layer, false if on a technical layer * @return true if this zone is on a copper layer, false if on a technical layer

View File

@ -12,26 +12,28 @@
#include "protos.h" #include "protos.h"
/* Loca functions */ extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb );
static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ); extern void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn );
/* Local functions */
static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn );
static void Build_Pads_Info_Connections_By_Tracks( TRACK* pt_start_conn, TRACK* pt_end_conn );
static void RebuildTrackChain( BOARD* pcb ); static void RebuildTrackChain( BOARD* pcb );
static int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare ); static int Sort_By_NetCode( TRACK** pt_ref, TRACK** pt_compare );
/*..*/ /*..*/
/*****************************************************************/ /**************************************************************************************************/
static int change_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn, static int Merge_Two_SubNets( TRACK* pt_start_conn, TRACK* pt_end_conn, int old_val, int new_val )
int old_val, int new_val ) /**************************************************************************************************/
/*****************************************************************/
/** Function change_equipot() /** Function Merge_Two_SubNets()
* Used by propage_equipot() * Used by Propagate_SubNet()
* Change a subnet value to a new value, for tracks ans pads which are connected to corresponding track * Change a subnet value to a new value, for tracks ans pads which are connected to corresponding track
* for pads, this is the .m_physical_connexion member which is tested and modified * for pads and tracks, this is the .m_Subnet member that is tested and modified
* for tracks, this is the .m_Subnet member which is tested and modified
* these members are block numbers (or cluster numbers) for a given net * these members are block numbers (or cluster numbers) for a given net
* The result is merging 2 blocks (or subnets)
* @return modification count * @return modification count
* @param old_val = subnet value to modify * @param old_val = subnet value to modify
* @param new_val = new subnet value for each item whith have old_val as subnet value * @param new_val = new subnet value for each item whith have old_val as subnet value
@ -66,15 +68,15 @@ static int change_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn,
if( pt_conn->start && ( pt_conn->start->Type() == TYPEPAD) ) if( pt_conn->start && ( pt_conn->start->Type() == TYPEPAD) )
{ {
pt_pad = (D_PAD*) (pt_conn->start); pt_pad = (D_PAD*) (pt_conn->start);
if( pt_pad->m_physical_connexion == old_val ) if( pt_pad->GetSubNet() == old_val )
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet(pt_conn->GetSubNet());
} }
if( pt_conn->end && (pt_conn->end->Type() == TYPEPAD) ) if( pt_conn->end && (pt_conn->end->Type() == TYPEPAD) )
{ {
pt_pad = (D_PAD*) (pt_conn->end); pt_pad = (D_PAD*) (pt_conn->end);
if( pt_pad->m_physical_connexion == old_val ) if( pt_pad->GetSubNet() == old_val )
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet(pt_conn->GetSubNet());
} }
if( pt_conn == pt_end_conn ) if( pt_conn == pt_end_conn )
break; break;
@ -85,23 +87,23 @@ static int change_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn,
/******************************************************************/ /******************************************************************/
static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn ) static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
/******************************************************************/ /******************************************************************/
/** Function propage_equipot /** Function Propagate_SubNet
* Test a list of track segment, to create or propagate a sub netcode to pads and segments connected together * Test a list of track segment, to create or propagate a sub netcode to pads and segments connected together
* the track list must be sorted by nets, and all segments from pt_start_conn to pt_end_conn have the save net * the track list must be sorted by nets, and all segments from pt_start_conn to pt_end_conn have the same net
* When 2 items are connected (a track to a pad, or a track to an other track) they are grouped in a cluster. * When 2 items are connected (a track to a pad, or a track to an other track) they are grouped in a cluster.
* for pads, this is the .m_physical_connexion member which is a cluster identifier * for pads, this is the .m_physical_connexion member which is a cluster identifier
* for tracks, this is the .m_Subnet member which is a cluster identifier * for tracks, this is the .m_Subnet member which is a cluster identifier
* For a given net, if all tracks are created, there is only one cluster. * For a given net, if all tracks are created, there is only one cluster.
* but if not all tracks are created, there are are more than one cluster, and some ratsnets will be shown. * but if not all tracks are created, there are more than one cluster, and some ratsnets will be shown.
* @param pt_start_conn = first track to test * @param pt_start_conn = first track to test
* @param pt_end_conn = last segment to test * @param pt_end_conn = last segment to test
*/ */
{ {
TRACK* pt_conn; TRACK* pt_conn;
int sous_net_code; int sub_netcode;
D_PAD* pt_pad; D_PAD* pt_pad;
TRACK* pt_autre_piste; TRACK* pt_autre_piste;
BOARD_ITEM* PtStruct; BOARD_ITEM* PtStruct;
@ -113,18 +115,18 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
pt_conn->SetSubNet( 0 ); pt_conn->SetSubNet( 0 );
PtStruct = pt_conn->start; PtStruct = pt_conn->start;
if( PtStruct && (PtStruct->Type() == TYPEPAD) ) if( PtStruct && (PtStruct->Type() == TYPEPAD) )
( (D_PAD*) PtStruct )->m_physical_connexion = 0; ( (D_PAD*) PtStruct )->SetSubNet( 0);
PtStruct = pt_conn->end; PtStruct = pt_conn->end;
if( PtStruct && (PtStruct->Type() == TYPEPAD) ) if( PtStruct && (PtStruct->Type() == TYPEPAD) )
( (D_PAD*) PtStruct )->m_physical_connexion = 0; ( (D_PAD*) PtStruct )->SetSubNet( 0);
if( pt_conn == pt_end_conn ) if( pt_conn == pt_end_conn )
break; break;
} }
sous_net_code = 1; sub_netcode = 1;
pt_start_conn->SetSubNet( sous_net_code ); pt_start_conn->SetSubNet( sub_netcode );
/* Start of calculation */ /* Start of calculation */
pt_conn = pt_start_conn; pt_conn = pt_start_conn;
@ -139,25 +141,25 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
pt_pad = (D_PAD*) PtStruct; pt_pad = (D_PAD*) PtStruct;
if( pt_conn->GetSubNet() ) /* the track segment is already a cluster member */ if( pt_conn->GetSubNet() ) /* the track segment is already a cluster member */
{ {
if( pt_pad->m_physical_connexion > 0 ) /* The pad is already a cluster member, so we can merge the 2 clusters */ if( pt_pad->GetSubNet() > 0 ) /* The pad is already a cluster member, so we can merge the 2 clusters */
{ {
change_equipot( pt_start_conn, pt_end_conn, Merge_Two_SubNets( pt_start_conn, pt_end_conn,
pt_pad->m_physical_connexion, pt_conn->GetSubNet() ); pt_pad->GetSubNet(), pt_conn->GetSubNet() );
} }
else /* The pad is not yet attached to a cluster , so we can add this pad to the cluster */ else /* The pad is not yet attached to a cluster , so we can add this pad to the cluster */
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet( pt_conn->GetSubNet() );
} }
else /* the track segment is not attached to a cluster */ else /* the track segment is not attached to a cluster */
{ {
if( pt_pad->m_physical_connexion > 0 ) /* it is connected to a pad in a cluster, merge this track */ if( pt_pad->GetSubNet() > 0 ) /* it is connected to a pad in a cluster, merge this track */
{ {
pt_conn->SetSubNet( pt_pad->m_physical_connexion ); pt_conn->SetSubNet( pt_pad->GetSubNet() );
} }
else /* it is connected to a pad not in a cluster, so we must create a new cluster (only with the 2 items: the track and the pad) */ else /* it is connected to a pad not in a cluster, so we must create a new cluster (only with the 2 items: the track and the pad) */
{ {
sous_net_code++; sub_netcode++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sub_netcode );
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet( pt_conn->GetSubNet() );
} }
} }
} }
@ -169,25 +171,25 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
pt_pad = (D_PAD*) PtStruct; pt_pad = (D_PAD*) PtStruct;
if( pt_conn->GetSubNet() ) if( pt_conn->GetSubNet() )
{ {
if( pt_pad->m_physical_connexion > 0 ) if( pt_pad->GetSubNet() > 0 )
{ {
change_equipot( pt_start_conn, pt_end_conn, Merge_Two_SubNets( pt_start_conn, pt_end_conn,
pt_pad->m_physical_connexion, pt_conn->GetSubNet() ); pt_pad->GetSubNet(), pt_conn->GetSubNet() );
} }
else else
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet( pt_conn->GetSubNet() );
} }
else else
{ {
if( pt_pad->m_physical_connexion > 0 ) if( pt_pad->GetSubNet() > 0 )
{ {
pt_conn->SetSubNet( pt_pad->m_physical_connexion ); pt_conn->SetSubNet( pt_pad->GetSubNet() );
} }
else else
{ {
sous_net_code++; sub_netcode++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sub_netcode );
pt_pad->m_physical_connexion = pt_conn->GetSubNet(); pt_pad->SetSubNet( pt_conn->GetSubNet() );
} }
} }
} }
@ -204,7 +206,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
{ {
if( pt_autre_piste->GetSubNet() ) /* The other track is already a cluster member, so we can merge the 2 clusters */ if( pt_autre_piste->GetSubNet() ) /* The other track is already a cluster member, so we can merge the 2 clusters */
{ {
change_equipot( pt_start_conn, pt_end_conn, Merge_Two_SubNets( pt_start_conn, pt_end_conn,
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() ); pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
} }
else /* The other track is not yet attached to a cluster , so we can add this other track to the cluster */ else /* The other track is not yet attached to a cluster , so we can add this other track to the cluster */
@ -220,8 +222,8 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else /* it is connected to an other segment not in a cluster, so we must create a new cluster (only with the 2 track segments) */ else /* it is connected to an other segment not in a cluster, so we must create a new cluster (only with the 2 track segments) */
{ {
sous_net_code++; sub_netcode++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sub_netcode );
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() ); pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
} }
} }
@ -236,7 +238,7 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
{ {
if( pt_autre_piste->GetSubNet() ) if( pt_autre_piste->GetSubNet() )
{ {
change_equipot( pt_start_conn, pt_end_conn, Merge_Two_SubNets( pt_start_conn, pt_end_conn,
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() ); pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
} }
else else
@ -250,8 +252,8 @@ static void propage_equipot( TRACK* pt_start_conn, TRACK* pt_end_conn )
} }
else else
{ {
sous_net_code++; sub_netcode++;
pt_conn->SetSubNet( sous_net_code ); pt_conn->SetSubNet( sub_netcode );
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() ); pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
} }
} }
@ -283,9 +285,12 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC )
pt_pad = m_Pcb->m_Pads; pt_pad = m_Pcb->m_Pads;
for( ii = 0; ii < m_Pcb->m_NbPads; ii++, pt_pad++ ) for( ii = 0; ii < m_Pcb->m_NbPads; ii++, pt_pad++ )
{ {
(*pt_pad)->m_physical_connexion = 0; (*pt_pad)->SetZoneSubNet( 0 );
(*pt_pad)->SetSubNet( 0 );
} }
m_Pcb->Test_Connections_To_Copper_Areas( );
/* Test existing connections net by net */ /* Test existing connections net by net */
pt_start_conn = m_Pcb->m_Track; // this is the first segment of the first net pt_start_conn = m_Pcb->m_Track; // this is the first segment of the first net
while( pt_start_conn != NULL ) while( pt_start_conn != NULL )
@ -293,11 +298,13 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC )
current_net_code = pt_start_conn->GetNet(); // this is the current net because pt_start_conn is the first segment of the net current_net_code = pt_start_conn->GetNet(); // this is the current net because pt_start_conn is the first segment of the net
pt_end_conn = pt_start_conn->GetEndNetCode( current_net_code ); // this is the last segment of the current net pt_end_conn = pt_start_conn->GetEndNetCode( current_net_code ); // this is the last segment of the current net
calcule_connexite_1_net( pt_start_conn, pt_end_conn ); Build_Pads_Info_Connections_By_Tracks( pt_start_conn, pt_end_conn );
pt_start_conn = (TRACK*) pt_end_conn->Pnext; // this is now the first segment of the next net pt_start_conn = (TRACK*) pt_end_conn->Pnext; // this is now the first segment of the next net
} }
Merge_SubNets_Connected_By_CopperAreas( m_Pcb );
return; return;
} }
@ -333,9 +340,11 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
if( pad_net_code > net_code ) if( pad_net_code > net_code )
break; break;
(*pt_pad)->m_physical_connexion = 0; (*pt_pad)->SetSubNet( 0 );
} }
m_Pcb->Test_Connections_To_Copper_Areas( net_code );
/* Search for the first and the last segment relative to the given net code */ /* Search for the first and the last segment relative to the given net code */
if( m_Pcb->m_Track ) if( m_Pcb->m_Track )
{ {
@ -347,9 +356,10 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
if( pt_start_conn && pt_end_conn ) // c.a.d. s'il y a des segments if( pt_start_conn && pt_end_conn ) // c.a.d. s'il y a des segments
{ {
calcule_connexite_1_net( pt_start_conn, pt_end_conn ); Build_Pads_Info_Connections_By_Tracks( pt_start_conn, pt_end_conn );
} }
} }
Merge_SubNets_Connected_By_CopperAreas( m_Pcb, net_code );
/* Test the rastnest for this net */ /* Test the rastnest for this net */
nb_net_noconnect = Test_1_Net_Ratsnest( DC, net_code ); nb_net_noconnect = Test_1_Net_Ratsnest( DC, net_code );
@ -364,9 +374,9 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
} }
/***************************************************************************/ /*******************************************************************************************/
static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn ) static void Build_Pads_Info_Connections_By_Tracks( TRACK* pt_start_conn, TRACK* pt_end_conn )
/***************************************************************************/ /*******************************************************************************************/
/** Used after a track change (delete a track ou add a track) /** Used after a track change (delete a track ou add a track)
* Compute connections (initialize the .start and .end members) for a single net. * Compute connections (initialize the .start and .end members) for a single net.
@ -435,8 +445,8 @@ static void calcule_connexite_1_net( TRACK* pt_start_conn, TRACK* pt_end_conn )
break; break;
} }
/* Generation des sous equipots du net */ /* Creates sub nets (cluster) for the current net: */
propage_equipot( pt_start_conn, pt_end_conn ); Propagate_SubNet( pt_start_conn, pt_end_conn );
} }
@ -600,6 +610,7 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext ) for( ; pt_piste != NULL; pt_piste = (TRACK*) pt_piste->Pnext )
{ {
pt_piste->SetState( BUSY | EDIT | BEGIN_ONPAD | END_ONPAD, OFF ); pt_piste->SetState( BUSY | EDIT | BEGIN_ONPAD | END_ONPAD, OFF );
pt_piste->SetZoneSubNet( 0 );
pt_piste->SetNet( 0 ); // net code = 0 means not connected pt_piste->SetNet( 0 ); // net code = 0 means not connected
} }

View File

@ -548,7 +548,9 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE: case ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_CURRENT_ZONE:
if ( ( GetCurItem())->Type() == TYPEZONE_CONTAINER) if ( ( GetCurItem())->Type() == TYPEZONE_CONTAINER)
{ {
((ZONE_CONTAINER* )GetCurItem())->m_FilledPolysList.clear(); ZONE_CONTAINER* zone_container = (ZONE_CONTAINER* )GetCurItem();
zone_container->m_FilledPolysList.clear();
test_1_net_connexion( NULL, zone_container->GetNet( ));
GetScreen()->SetModify(); GetScreen()->SetModify();
DrawPanel->Refresh(); DrawPanel->Refresh();
} }
@ -566,13 +568,16 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
ZONE_CONTAINER* zone_container = m_Pcb->GetArea( ii ); ZONE_CONTAINER* zone_container = m_Pcb->GetArea( ii );
zone_container->m_FilledPolysList.clear();; zone_container->m_FilledPolysList.clear();;
} }
test_connexions( NULL );
GetScreen()->SetModify(); GetScreen()->SetModify();
DrawPanel->Refresh(); DrawPanel->Refresh();
break; break;
case ID_POPUP_PCB_FILL_ZONE: case ID_POPUP_PCB_FILL_ZONE:
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
Fill_Zone( &dc, (ZONE_CONTAINER*) GetCurItem() ); Fill_Zone( NULL, (ZONE_CONTAINER*) GetCurItem() );
test_1_net_connexion( NULL, ((ZONE_CONTAINER* )GetCurItem())->GetNet( ));
DrawPanel->Refresh();
break; break;
case ID_PCB_DELETE_ITEM_BUTT: case ID_PCB_DELETE_ITEM_BUTT:

View File

@ -23,7 +23,7 @@ static void CreateShapesSection( FILE* file, BOARD* pcb );
static void CreatePadsShapesSection( FILE* file, BOARD* pcb ); static void CreatePadsShapesSection( FILE* file, BOARD* pcb );
static void ModuleWriteShape( FILE* File, MODULE* module ); static void ModuleWriteShape( FILE* File, MODULE* module );
// layer name pour extensions fichiers de tracewxString // layer name pour extensions fichiers de tracewxString
static const wxString GenCAD_Layer_Name[32] = { static const wxString GenCAD_Layer_Name[32] = {
wxT( "BOTTOM" ), wxT( "INNER1" ), wxT( "INNER2" ), wxT("INNER3" ), wxT( "BOTTOM" ), wxT( "INNER1" ), wxT( "INNER2" ), wxT("INNER3" ),
wxT( "INNER4" ), wxT( "INNER5" ), wxT( "INNER6" ), wxT("INNER7" ), wxT( "INNER4" ), wxT( "INNER5" ), wxT( "INNER6" ), wxT("INNER7" ),
@ -149,7 +149,7 @@ static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
const D_PAD* padref = *(D_PAD**)refptr; const D_PAD* padref = *(D_PAD**)refptr;
const D_PAD* padcmp = *(D_PAD**)objptr; const D_PAD* padcmp = *(D_PAD**)objptr;
return D_PAD::Compare( padref, padcmp ); return D_PAD::Compare( padref, padcmp );
} }
@ -158,14 +158,14 @@ void CreatePadsShapesSection( FILE* file, BOARD* pcb )
/*****************************************************/ /*****************************************************/
/* Cree la liste des formes des pads ( 1 forme par pad ) /* Cree la liste des formes des pads ( 1 forme par pad )
* initialise le membre .m_logical_connexion de la struct pad, la valeur 1 ..n * initialise le membre .GetSubRatsnest de la struct pad, la valeur 1 ..n
* pour les formes de pad PAD1 a PADn * pour les formes de pad PAD1 a PADn
*/ */
{ {
D_PAD* pad; D_PAD* pad;
D_PAD** padlist; D_PAD** padlist;
D_PAD** pad_list_base = NULL; D_PAD** pad_list_base = NULL;
const char* pad_type; const char* pad_type;
int memsize, ii, dx, dy; int memsize, ii, dx, dy;
D_PAD* old_pad = NULL; D_PAD* old_pad = NULL;
@ -186,7 +186,7 @@ void CreatePadsShapesSection( FILE* file, BOARD* pcb )
for( padlist = pad_list_base, ii = 0; ii < pcb->m_NbPads; padlist++, ii++ ) for( padlist = pad_list_base, ii = 0; ii < pcb->m_NbPads; padlist++, ii++ )
{ {
pad = *padlist; pad = *padlist;
pad->m_logical_connexion = pad_name_number; pad->SetSubRatsnest( pad_name_number );
if( old_pad && 0==D_PAD::Compare( old_pad, pad ) ) if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
continue; // Forme deja generee continue; // Forme deja generee
@ -194,11 +194,11 @@ void CreatePadsShapesSection( FILE* file, BOARD* pcb )
old_pad = pad; old_pad = pad;
pad_name_number++; pad_name_number++;
pad->m_logical_connexion = pad_name_number; pad->SetSubRatsnest( pad_name_number );
fprintf( file, "PAD PAD%d", pad->m_logical_connexion ); fprintf( file, "PAD PAD%d", pad->GetSubRatsnest() );
dx = pad->m_Size.x / 2; dx = pad->m_Size.x / 2;
dy = pad->m_Size.y / 2; dy = pad->m_Size.y / 2;
switch( pad->m_PadShape ) switch( pad->m_PadShape )
@ -273,7 +273,7 @@ void CreatePadsShapesSection( FILE* file, BOARD* pcb )
} }
fputs( "$ENDPADS\n\n", file ); fputs( "$ENDPADS\n\n", file );
MyFree( pad_list_base ); MyFree( pad_list_base );
} }
@ -287,13 +287,13 @@ void CreateShapesSection( FILE* file, BOARD* pcb )
* une forme est creee par composant * une forme est creee par composant
* La forme est donnee normalisee, c'est a dire orientation 0, position 0 non miroir * La forme est donnee normalisee, c'est a dire orientation 0, position 0 non miroir
* Il y aura donc des formes indentiques redondantes * Il y aura donc des formes indentiques redondantes
* *
* Syntaxe: * Syntaxe:
* $SHAPES * $SHAPES
* SHAPE <shape_name> * SHAPE <shape_name>
* shape_descr (line, arc ..) * shape_descr (line, arc ..)
* PIN <pin_name> <pad_name> <x_y_ref> <layer> <rot> <mirror> * PIN <pin_name> <pad_name> <x_y_ref> <layer> <rot> <mirror>
* *
* SHAPE <shape_name> * SHAPE <shape_name>
* .. * ..
* $ENDSHAPES * $ENDSHAPES
@ -336,7 +336,7 @@ void CreateShapesSection( FILE* file, BOARD* pcb )
orient = pad->m_Orient - module->m_Orient; orient = pad->m_Orient - module->m_Orient;
NORMALIZE_ANGLE_POS( orient ); NORMALIZE_ANGLE_POS( orient );
fprintf( file, "PIN %s PAD%d %d %d %s %d %s", fprintf( file, "PIN %s PAD%d %d %d %s %d %s",
CONV_TO_UTF8( pinname ), pad->m_logical_connexion, CONV_TO_UTF8( pinname ), pad->GetSubRatsnest(),
pad->m_Pos0.x, -pad->m_Pos0.y, pad->m_Pos0.x, -pad->m_Pos0.y,
layer, orient / 10, mirror ); layer, orient / 10, mirror );
if( orient % 10 ) if( orient % 10 )
@ -459,8 +459,8 @@ void CreateSignalsSection( FILE* file, BOARD* pcb )
continue; continue;
msg = wxT( "\nSIGNAL " ) + equipot->m_Netname; msg = wxT( "\nSIGNAL " ) + equipot->m_Netname;
fputs( CONV_TO_UTF8( msg ), file ); fputs( CONV_TO_UTF8( msg ), file );
fputs( "\n", file ); fputs( "\n", file );
for( module = pcb->m_Modules; module != NULL; module = (MODULE*) module->Pnext ) for( module = pcb->m_Modules; module != NULL; module = (MODULE*) module->Pnext )
@ -470,12 +470,12 @@ void CreateSignalsSection( FILE* file, BOARD* pcb )
wxString padname; wxString padname;
if( pad->GetNet() != equipot->GetNet() ) if( pad->GetNet() != equipot->GetNet() )
continue; continue;
pad->ReturnStringPadName( padname ); pad->ReturnStringPadName( padname );
msg.Printf( wxT( "NODE %s %.4s" ), msg.Printf( wxT( "NODE %s %.4s" ),
module->m_Reference->m_Text.GetData(), padname.GetData() ); module->m_Reference->m_Text.GetData(), padname.GetData() );
fputs( CONV_TO_UTF8( msg ), file ); fputs( CONV_TO_UTF8( msg ), file );
fputs( "\n", file ); fputs( "\n", file );
} }
} }
@ -706,7 +706,7 @@ int* CreateTracksInfoData( FILE* file, BOARD* pcb )
* $TRACK * $TRACK
* TRACK <name> <width> * TRACK <name> <width>
* $ENDTRACK * $ENDTRACK
* *
* on attribut ici comme nom l'epaisseur des traits precede de "TRACK": ex * on attribut ici comme nom l'epaisseur des traits precede de "TRACK": ex
* pour une largeur de 120 : nom = "TRACK120". * pour une largeur de 120 : nom = "TRACK120".
*/ */

View File

@ -18,7 +18,8 @@ ZONE_FILES = zones_by_polygon.o zones_test_and_combine_areas.o\
dialog_non_copper_zones_properties_base.o\ dialog_non_copper_zones_properties_base.o\
zones_non_copper_type_functions.o\ zones_non_copper_type_functions.o\
zones_convert_brd_items_to_polygons.o\ zones_convert_brd_items_to_polygons.o\
zones_polygons_insulated_copper_islands.o zones_polygons_insulated_copper_islands.o\
zones_polygons_test_connections.o
SPECCTRA_TOOLS = specctra.o specctra_export.o dsn.o specctra_import.o SPECCTRA_TOOLS = specctra.o specctra_export.o dsn.o specctra_import.o
@ -54,6 +55,7 @@ OBJECTS= $(TARGET).o classpcb.o\
class_text_mod.o\ class_text_mod.o\
class_pcb_text.o\ class_pcb_text.o\
class_board_item.o\ class_board_item.o\
class_board_connected_item.o\
class_drc_item.o\ class_drc_item.o\
class_board.o\ class_board.o\
class_zone.o\ class_zone.o\

View File

@ -28,8 +28,8 @@ static bool DisplayRastnestInProgress; // Enable the display of the ratsnes
* Building the general ratsnest: * Building the general ratsnest:
* I used the "lee algoritm". * I used the "lee algoritm".
* This is a 2 steps algoritm. * This is a 2 steps algoritm.
* the m_logical_connexion member of pads handle a "block number" or a "cluster number" or a "subnet number" * the m_SubRatsnest member of pads handle a "block number" or a "cluster number" or a "subnet number"
* initially, m_logical_connexion = 0 (pad not connected). * initially, m_SubRatsnest = 0 (pad not connected).
* Build_Board_Ratsnest( wxDC* DC ) Create this rastnest * Build_Board_Ratsnest( wxDC* DC ) Create this rastnest
* for each net: * for each net:
* First: * First:
@ -40,7 +40,7 @@ static bool DisplayRastnestInProgress; // Enable the display of the ratsnes
* the pads are grouped in a logical block ( a cluster). * the pads are grouped in a logical block ( a cluster).
* until no pad without link found. * until no pad without link found.
* Each logical block has a number called block number or "subnet number", * Each logical block has a number called block number or "subnet number",
* stored in m_logical_connexion member for each pad of the block. * stored in m_SubRatsnest member for each pad of the block.
* The first block has its block number = 1, the second is 2 ... * The first block has its block number = 1, the second is 2 ...
* the function to do thas is gen_rats_pad_to_pad() * the function to do thas is gen_rats_pad_to_pad()
* *
@ -72,7 +72,7 @@ static bool DisplayRastnestInProgress; // Enable the display of the ratsnes
* (no physical track exists) or not (a physical track exists) * (no physical track exists) or not (a physical track exists)
* if a track is added or deleted only the corresponding net is tested. * if a track is added or deleted only the corresponding net is tested.
* *
* the m_logical_connexion member of pads is set to 0 (no blocks), and alls links are set to INACTIVE (ratsnest not show). * the m_SubRatsnest member of pads is set to 0 (no blocks), and alls links are set to INACTIVE (ratsnest not show).
* Before running this fast lee algorithm, we create blocks (and their corresponding block number) * Before running this fast lee algorithm, we create blocks (and their corresponding block number)
* by grouping pads connected by tracks. * by grouping pads connected by tracks.
* So, when tracks exists, the fast lee algorithm is started with some blocks already created. * So, when tracks exists, the fast lee algorithm is started with some blocks already created.
@ -81,7 +81,7 @@ static bool DisplayRastnestInProgress; // Enable the display of the ratsnes
* when a track is created without noticeable computing time * when a track is created without noticeable computing time
* First: * First:
* for all links (in this step, all are inactive): * for all links (in this step, all are inactive):
* search for a link which have 1 (or 2) pad having the m_logical_connexion member = 0. * search for a link which have 1 (or 2) pad having the m_SubRatsnest member = 0.
* if found the link is set to ACTIVE (i.e. the ratsnest will be showed) and the pad is meged with the block * if found the link is set to ACTIVE (i.e. the ratsnest will be showed) and the pad is meged with the block
* or a new block is created ( see tst_rats_pad_to_pad() ). * or a new block is created ( see tst_rats_pad_to_pad() ).
* Secondly: * Secondly:
@ -192,7 +192,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
* The search is made between the pads in block 1 (the reference block) and other blocks * The search is made between the pads in block 1 (the reference block) and other blocks
* the block n ( n > 1 ) it connected to block 1 by their 2 nearest pads. * the block n ( n > 1 ) it connected to block 1 by their 2 nearest pads.
* When the block is found, it is merged with the block 1 * When the block is found, it is merged with the block 1
* the D_PAD member m_logical_connexion handles the block number * the D_PAD member m_SubRatsnest handles the block number
* @param pt_liste_pad = starting address (within the pad list) for search * @param pt_liste_pad = starting address (within the pad list) for search
* @param pt_limite = ending address (within the pad list) for search * @param pt_limite = ending address (within the pad list) for search
* return in global variables: * return in global variables:
@ -223,7 +223,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
D_PAD* ref_pad = *pt_liste_pad; D_PAD* ref_pad = *pt_liste_pad;
/* search a pad which is in the block 1 */ /* search a pad which is in the block 1 */
if( ref_pad->m_logical_connexion != 1 ) if( ref_pad->GetSubRatsnest() != 1 )
continue; continue;
/* pad is found, search its nearest neighbour in other blocks */ /* pad is found, search its nearest neighbour in other blocks */
@ -234,7 +234,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
if( pt_liste_pad_aux >= pt_limite ) if( pt_liste_pad_aux >= pt_limite )
break; break;
if( curr_pad->m_logical_connexion == 1 ) // not in an other block if( curr_pad->GetSubRatsnest() == 1 ) // not in an other block
continue; continue;
/* Compare distance between pads ("Manhattan" distance) */ /* Compare distance between pads ("Manhattan" distance) */
@ -245,7 +245,7 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
{ {
// The tested block can be a good candidate for merging // The tested block can be a good candidate for merging
// we memorise the "best" current values for merging // we memorise the "best" current values for merging
current_num_block = curr_pad->m_logical_connexion; current_num_block = curr_pad->GetSubRatsnest();
dist_min = current_dist; dist_min = current_dist;
pt_liste_pad_tmp = pt_liste_pad_aux; pt_liste_pad_tmp = pt_liste_pad_aux;
@ -262,12 +262,12 @@ static int gen_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
if( current_num_block > 1 ) if( current_num_block > 1 )
{ {
/* The block n is merged with the bloc 1 : /* The block n is merged with the bloc 1 :
* to do that, we set the m_logical_connexion member to 1 for all pads in block n * to do that, we set the m_SubRatsnest member to 1 for all pads in block n
*/ */
for( pt_liste_pad = pt_start_liste; pt_liste_pad < pt_limite; pt_liste_pad++ ) for( pt_liste_pad = pt_start_liste; pt_liste_pad < pt_limite; pt_liste_pad++ )
{ {
if( (*pt_liste_pad)->m_logical_connexion == current_num_block ) if( (*pt_liste_pad)->GetSubRatsnest() == current_num_block )
(*pt_liste_pad)->m_logical_connexion = 1; (*pt_liste_pad)->SetSubRatsnest( 1 );
} }
pt_liste_pad = pt_liste_pad_block1; pt_liste_pad = pt_liste_pad_block1;
@ -336,7 +336,7 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
{ {
ref_pad = *pt_liste_pad; ref_pad = *pt_liste_pad;
if( ref_pad->m_logical_connexion ) if( ref_pad->GetSubRatsnest() )
continue; // Pad already connected continue; // Pad already connected
pt_liste_pad_tmp = NULL; pt_liste_pad_tmp = NULL;
@ -370,16 +370,16 @@ static int gen_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
/* Update the block number /* Update the block number
* if the 2 pads are not already created : a new block is created * if the 2 pads are not already created : a new block is created
*/ */
if( (pad->m_logical_connexion == 0) && (ref_pad->m_logical_connexion == 0) ) if( (pad->GetSubRatsnest() == 0) && (ref_pad->GetSubRatsnest() == 0) )
{ {
current_num_block++; current_num_block++;
pad->m_logical_connexion = current_num_block; pad->SetSubRatsnest( current_num_block);
ref_pad->m_logical_connexion = current_num_block; ref_pad->SetSubRatsnest( current_num_block);
} }
/* If a pad is already connected connected : merge the other pad in the block */ /* If a pad is already connected connected : merge the other pad in the block */
else else
{ {
ref_pad->m_logical_connexion = pad->m_logical_connexion; ref_pad->SetSubRatsnest( pad->GetSubRatsnest());
} }
(*nblinks)++; (*nblinks)++;
@ -456,7 +456,7 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
for( ii = m_Pcb->m_NbPads; ii > 0; pt_liste_pad++, ii-- ) for( ii = m_Pcb->m_NbPads; ii > 0; pt_liste_pad++, ii-- )
{ {
pad = *pt_liste_pad; pad = *pt_liste_pad;
pad->m_logical_connexion = 0; pad->SetSubRatsnest( 0 );
} }
/* Sort the pad list by nets */ /* Sort the pad list by nets */
@ -503,7 +503,7 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
} }
/* Search the end of pad list des pads for the current net */ /* Search the end of pad list des pads for the current net */
num_block = pad->m_logical_connexion; num_block = pad->GetSubRatsnest();
nbpads = 0; nbpads = 0;
for( pt_end_liste = pt_liste_pad + 1; ; pt_end_liste++ ) for( pt_end_liste = pt_liste_pad + 1; ; pt_end_liste++ )
{ {
@ -515,8 +515,8 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
break; break;
nbpads++; nbpads++;
if( num_block < pad->m_logical_connexion ) if( num_block < pad->GetSubRatsnest() )
num_block = pad->m_logical_connexion; num_block = pad->GetSubRatsnest();
} }
m_Pcb->m_NbLinks += nbpads; m_Pcb->m_NbLinks += nbpads;
@ -668,7 +668,7 @@ static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
min_chevelu = NULL; min_chevelu = NULL;
for( chevelu = start_rat_list; chevelu < end_rat_list; chevelu++ ) for( chevelu = start_rat_list; chevelu < end_rat_list; chevelu++ )
{ {
if( chevelu->pad_start->m_logical_connexion == chevelu->pad_end->m_logical_connexion ) // Same block if( chevelu->pad_start->GetSubRatsnest() == chevelu->pad_end->GetSubRatsnest() ) // Same block
continue; continue;
if( min_chevelu == NULL ) if( min_chevelu == NULL )
@ -684,8 +684,8 @@ static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
* we must set its status to ACTIVE and merge the 2 blocks * we must set its status to ACTIVE and merge the 2 blocks
*/ */
min_chevelu->status |= CH_ACTIF; min_chevelu->status |= CH_ACTIF;
current_num_block = min_chevelu->pad_start->m_logical_connexion; current_num_block = min_chevelu->pad_start->GetSubRatsnest();
min_block = min_chevelu->pad_end->m_logical_connexion; min_block = min_chevelu->pad_end->GetSubRatsnest();
if( min_block > current_num_block ) if( min_block > current_num_block )
EXCHG( min_block, current_num_block ); EXCHG( min_block, current_num_block );
@ -693,9 +693,9 @@ static int tst_rats_block_to_block( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
/* Merging the 2 blocks in one cluster */ /* Merging the 2 blocks in one cluster */
for( pt_liste_pad = pt_liste_pad_start; pt_liste_pad < pt_liste_pad_end; pt_liste_pad++ ) for( pt_liste_pad = pt_liste_pad_start; pt_liste_pad < pt_liste_pad_end; pt_liste_pad++ )
{ {
if( (*pt_liste_pad)->m_logical_connexion == current_num_block ) if( (*pt_liste_pad)->GetSubRatsnest() == current_num_block )
{ {
(*pt_liste_pad)->m_logical_connexion = min_block; (*pt_liste_pad)->SetSubRatsnest( min_block);
} }
} }
@ -723,7 +723,7 @@ static int tst_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
* *
* output: * output:
* ratsnest list (status member set) * ratsnest list (status member set)
* and pad list (m_logical_connexion set) * and pad list (m_SubRatsnest set)
* *
* @return new block number * @return new block number
*/ */
@ -738,22 +738,22 @@ static int tst_rats_pad_to_pad( WinEDA_DrawPanel* DrawPanel, wxDC* DC,
/* Update the block if the 2 pads are not connected : a new block is created /* Update the block if the 2 pads are not connected : a new block is created
*/ */
if( (pad_start->m_logical_connexion == 0) && (pad_end->m_logical_connexion == 0) ) if( (pad_start->GetSubRatsnest() == 0) && (pad_end->GetSubRatsnest() == 0) )
{ {
current_num_block++; current_num_block++;
pad_start->m_logical_connexion = current_num_block; pad_start->SetSubRatsnest( current_num_block);
pad_end->m_logical_connexion = current_num_block; pad_end->SetSubRatsnest( current_num_block);
chevelu->status |= CH_ACTIF; chevelu->status |= CH_ACTIF;
} }
/* If a pad is already connected : the other is merged in the current block */ /* If a pad is already connected : the other is merged in the current block */
else if( pad_start->m_logical_connexion == 0 ) else if( pad_start->GetSubRatsnest() == 0 )
{ {
pad_start->m_logical_connexion = pad_end->m_logical_connexion; pad_start->SetSubRatsnest( pad_end->GetSubRatsnest() );
chevelu->status |= CH_ACTIF; chevelu->status |= CH_ACTIF;
} }
else if( pad_end->m_logical_connexion == 0 ) else if( pad_end->GetSubRatsnest() == 0 )
{ {
pad_end->m_logical_connexion = pad_start->m_logical_connexion; pad_end->SetSubRatsnest( pad_start->GetSubRatsnest() );
chevelu->status |= CH_ACTIF; chevelu->status |= CH_ACTIF;
} }
} }
@ -795,8 +795,8 @@ void WinEDA_BasePcbFrame::Tst_Ratsnest( wxDC* DC, int ref_netcode )
for( ; pt_liste_pad < equipot->m_PadzoneEnd; pt_liste_pad++ ) for( ; pt_liste_pad < equipot->m_PadzoneEnd; pt_liste_pad++ )
{ {
pad = *pt_liste_pad; pad = *pt_liste_pad;
pad->m_logical_connexion = pad->m_physical_connexion; pad->SetSubRatsnest( pad->GetSubNet() );
num_block = MAX( num_block, pad->m_logical_connexion ); num_block = MAX( num_block, pad->GetSubRatsnest() );
} }
for( chevelu = equipot->m_RatsnestStart; chevelu < equipot->m_RatsnestEnd; chevelu++ ) for( chevelu = equipot->m_RatsnestStart; chevelu < equipot->m_RatsnestEnd; chevelu++ )
@ -981,7 +981,7 @@ void WinEDA_BasePcbFrame::build_liste_pads()
* m_Pcb->m_NbPads = pad count * m_Pcb->m_NbPads = pad count
* m_Pcb->m_NbNodes = node count * m_Pcb->m_NbNodes = node count
* set m_Pcb->m_Status_Pcb = LISTE_PAD_OK; * set m_Pcb->m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pad their m_logical_connexion member; * and clear for all pad their m_SubRatsnest member;
* delete ( free memory) m_Pcb->m_Ratsnest and set m_Pcb->m_Ratsnest to NULL * delete ( free memory) m_Pcb->m_Ratsnest and set m_Pcb->m_Ratsnest to NULL
*/ */
{ {
@ -1025,7 +1025,7 @@ void WinEDA_BasePcbFrame::build_liste_pads()
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext ) for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext )
{ {
*pt_liste_pad = PtPad; *pt_liste_pad = PtPad;
PtPad->m_logical_connexion = 0; PtPad->SetSubRatsnest( 0 );
PtPad->m_Parent = Module; // Just in case PtPad->m_Parent = Module; // Just in case
if( PtPad->GetNet() ) if( PtPad->GetNet() )
@ -1106,8 +1106,8 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module )
continue; continue;
*pt_liste_pad = pad_ref; *pt_liste_pad = pad_ref;
pad_ref->m_logical_connexion = 0; pad_ref->SetSubRatsnest( 0 );
pad_ref->m_physical_connexion = 0; pad_ref->SetSubNet( 0 );
pt_liste_pad++; nb_pads_ref++; pt_liste_pad++; nb_pads_ref++;
} }
@ -1140,8 +1140,8 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module )
if( pad_externe->m_Parent == Module ) if( pad_externe->m_Parent == Module )
continue; continue;
pad_externe->m_logical_connexion = 0; pad_externe->SetSubRatsnest(0);
pad_externe->m_physical_connexion = 0; pad_externe->SetSubNet( 0 );
*pt_liste_pad = pad_externe; *pt_liste_pad = pad_externe;
pt_liste_pad++; pt_liste_pad++;
@ -1154,7 +1154,7 @@ char* WinEDA_BasePcbFrame::build_ratsnest_module( wxDC* DC, MODULE* Module )
qsort( pt_liste_ref + nb_pads_ref, nb_pads_externes, sizeof(D_PAD*), qsort( pt_liste_ref + nb_pads_ref, nb_pads_externes, sizeof(D_PAD*),
tri_par_net ); tri_par_net );
/* Compute the internal ratsnet: /* Compute the internal rats nest:
* this is the same as general ratsnest, but considers only the current footprint pads * this is the same as general ratsnest, but considers only the current footprint pads
* it is therefore not time consuming, and it is made only once * it is therefore not time consuming, and it is made only once
*/ */
@ -1413,7 +1413,7 @@ int* WinEDA_BasePcbFrame::build_ratsnest_pad( EDA_BaseStruct* ref,
case TYPEPAD: case TYPEPAD:
pad_ref = (D_PAD*) ref; pad_ref = (D_PAD*) ref;
current_net_code = pad_ref->GetNet(); current_net_code = pad_ref->GetNet();
conn_number = pad_ref->m_physical_connexion; conn_number = pad_ref->GetSubNet();
break; break;
case TYPETRACK: case TYPETRACK:
@ -1448,7 +1448,7 @@ int* WinEDA_BasePcbFrame::build_ratsnest_pad( EDA_BaseStruct* ref,
if( pad == pad_ref ) if( pad == pad_ref )
continue; continue;
if( !pad->m_physical_connexion || (pad->m_physical_connexion != conn_number) ) if( !pad->GetSubNet() || (pad->GetSubNet() != conn_number) )
{ {
*pt_coord = pad->m_Pos.x; pt_coord++; *pt_coord = pad->m_Pos.x; pt_coord++;
*pt_coord = pad->m_Pos.y; pt_coord++; *pt_coord = pad->m_Pos.y; pt_coord++;

View File

@ -199,7 +199,7 @@ void Out_Pads( BOARD* Pcb, FILE* outfile )
{ {
pt_pad = *pt_liste_pad; pt_pad = *pt_liste_pad;
netcode = pt_pad->GetNet(); netcode = pt_pad->GetNet();
plink = pt_pad->m_physical_connexion; plink = pt_pad->GetSubNet();
/* plink = numero unique si pad non deja connecte a une piste */ /* plink = numero unique si pad non deja connecte a une piste */
if( plink <= 0 ) if( plink <= 0 )
plink = no_conn++; plink = no_conn++;

View File

@ -956,7 +956,7 @@ int WinEDA_PcbFrame::Fill_All_Zones( wxDC* DC, bool verbose )
if( error_level && !verbose ) if( error_level && !verbose )
break; break;
} }
m_Pcb->Test_Connections_To_Copper_Areas( );
DrawPanel->Refresh( true ); DrawPanel->Refresh( true );
return error_level; return error_level;
} }

View File

@ -19,7 +19,6 @@
using namespace std; using namespace std;
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h"
#include "common.h" #include "common.h"
#include "pcbnew.h" #include "pcbnew.h"
@ -28,17 +27,8 @@ using namespace std;
#include "zones.h" #include "zones.h"
static void CalculateSubAreaBoundaryBox( EDA_Rect& aBbox,
std::vector <CPolyPt> aPolysList,
int aIndexStart,
int aIndexEnd );
/* Local variables */
std::vector <wxPoint> s_ListPoints; // list of coordinates of pads and vias on this layer and on this net.
/***************************************************************************************/ /***************************************************************************************/
void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb ) void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD * aPcb )
/***************************************************************************************/ /***************************************************************************************/
/** /**
@ -50,11 +40,15 @@ void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD*
if( m_FilledPolysList.size() == 0 ) if( m_FilledPolysList.size() == 0 )
return; return;
// Build the list: // Build a list of points connected to the net:
s_ListPoints.clear(); std::vector <wxPoint> ListPointsCandidates; // list of coordinates of pads and vias on this layer and on this net.
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) for( MODULE* module = aPcb->m_Modules;
module;
module = module->Next() )
{ {
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) for( D_PAD* pad = module->m_Pads;
pad != NULL;
pad = pad->Next() )
{ {
if( !pad->IsOnLayer( GetLayer() ) ) if( !pad->IsOnLayer( GetLayer() ) )
continue; continue;
@ -62,82 +56,91 @@ void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD*
if( pad->GetNet() != GetNet() ) if( pad->GetNet() != GetNet() )
continue; continue;
s_ListPoints.push_back( pad->m_Pos ); ListPointsCandidates.push_back( pad->m_Pos );
} }
} }
for( TRACK* track = aPcb->m_Track; track; track = track->Next() ) for( TRACK* track = aPcb->m_Track;
track;
track = track->Next() )
{ {
if( !track->IsOnLayer( GetLayer() ) ) if( !track->IsOnLayer( GetLayer() ) )
continue; continue;
if( track->GetNet() != GetNet() ) if( track->GetNet() != GetNet() )
continue; continue;
s_ListPoints.push_back( track->m_Start ); ListPointsCandidates.push_back( track->m_Start );
if( track->Type() != TYPEVIA ) if( track->Type() != TYPEVIA )
s_ListPoints.push_back( track->m_End ); ListPointsCandidates.push_back( track->m_End );
} }
// test if a point is inside // test if a point is inside
unsigned indexstart = 0, indexend; unsigned indexstart = 0, indexend;
bool connected = false; bool connected = false;
for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ ) for( indexend = 0;
indexend < m_FilledPolysList.size();
indexend++ )
{ {
if( m_FilledPolysList[indexend].end_contour ) // end of area found if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found
{ {
EDA_Rect bbox; EDA_Rect bbox =
CalculateSubAreaBoundaryBox( bbox, m_FilledPolysList, indexstart, indexend ); CalculateSubAreaBoundaryBox( indexstart,
for( unsigned ic = 0; ic < s_ListPoints.size(); ic++ ) indexend );
{ for( unsigned ic = 0;
wxPoint pos = s_ListPoints[ic]; ic < ListPointsCandidates.size();
ic++ )
{ // test if this area is connected to a board item:
wxPoint pos = ListPointsCandidates[ic];
if( !bbox.Inside( pos ) ) if( !bbox.Inside( pos ) )
continue; continue;
if( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, pos.x, pos.y ) ) if( TestPointInsidePolygon(
m_FilledPolysList, indexstart,
indexend, pos.x,
pos.y ) )
{ {
connected = true; connected = true;
break; break;
} }
} }
if( connected ) // this polygon is connected: analyse next polygon if( connected ) // this polygon is connected: analyse next polygon
{ {
indexstart = indexend + 1; // indexstart points the first point of the next polygon indexstart = indexend + 1; // indexstart points the first point of the next polygon
connected = false; connected = false;
} }
else // Not connected: remove this polygon else // Not connected: remove this polygon
{ {
m_FilledPolysList.erase( m_FilledPolysList.erase(
m_FilledPolysList.begin() + indexstart, m_FilledPolysList.begin() + indexstart,
m_FilledPolysList.begin() + indexend + 1 ); m_FilledPolysList.begin() + indexend +
indexend = indexstart; /* indexstart points the first point of the next polygon 1 );
* because the current poly is removed */ indexend = indexstart; /* indexstart points the first point of the next polygon
* because the current poly is removed */
} }
} }
} }
} }
/******************************************************************/ /**************************************************************************************/
void CalculateSubAreaBoundaryBox( EDA_Rect& aBbox, EDA_Rect ZONE_CONTAINER::CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd )
std::vector <CPolyPt> aPolysList, /**************************************************************************************/
int aIndexStart,
int aIndexEnd )
/******************************************************************/
/** function CalculateSubAreaBoundaryBox /** function CalculateSubAreaBoundaryBox
* Calculates the bounding box of a polygon stored in a vector <CPolyPt> * Calculates the bounding box of a a filled area ( list of CPolyPt )
* @param aBbox = EDA_Rect to init as bounding box * use m_FilledPolysList as list of CPolyPt (that are the corners of one or more polygons or filled areas )
* @param aPolysList = set of CPolyPt that are the corners of one or more polygons * @return an EDA_Rect as bounding box
* @param aIndexStart = index of the first corner of a polygon in aPolysList * @param aIndexStart = index of the first corner of a polygon (filled area) in m_FilledPolysList
* @param aIndexEnd = index of the last corner of a polygon in aPolysList * @param aIndexEnd = index of the last corner of a polygon in m_FilledPolysList
*/ */
{ {
CPolyPt start_point, end_point; CPolyPt start_point, end_point;
EDA_Rect bbox;
start_point = aPolysList[aIndexStart]; start_point = m_FilledPolysList[aIndexStart];
end_point = start_point; end_point = start_point;
for( int ii = aIndexStart; ii <= aIndexEnd; ii++ ) for( int ii = aIndexStart; ii <= aIndexEnd; ii++ )
{ {
CPolyPt ptst = aPolysList[ii]; CPolyPt ptst = m_FilledPolysList[ii];
if( start_point.x > ptst.x ) if( start_point.x > ptst.x )
start_point.x = ptst.x; start_point.x = ptst.x;
if( start_point.y > ptst.y ) if( start_point.y > ptst.y )
@ -148,6 +151,8 @@ void CalculateSubAreaBoundaryBox( EDA_Rect& aBbox,
end_point.y = ptst.y; end_point.y = ptst.y;
} }
aBbox.SetOrigin( start_point.x, start_point.y ); bbox.SetOrigin( start_point.x, start_point.y );
aBbox.SetEnd( wxPoint( end_point.x, end_point.y ) ); bbox.SetEnd( wxPoint( end_point.x, end_point.y ) );
return bbox;
} }

View File

@ -0,0 +1,337 @@
/////////////////////////////////////////////////////////////////////////////
// Name: zones_polygons_test_connections.cpp
// Licence: GPL License
/////////////////////////////////////////////////////////////////////////////
#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 <algorithm> // sort
#include <vector>
#include "fctsys.h"
#include "common.h"
#include "pcbnew.h"
#include "PolyLine.h"
#include "zones.h"
static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b );
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
/***********************************************************/
void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
/***********************************************************/
/**
* Function Test_Connection_To_Copper_Areas
* init .m_ZoneSubnet parameter in tracks and pads according to the connections to areas found
* @param aNetcode = netcode to analyse. if -1, analyse all nets
*/
{
std::vector <BOARD_CONNECTED_ITEM*> Candidates; // list of pads and tracks candidates on this layer and on this net.
int subnet = 0;
int netcode;
ZONE_CONTAINER* curr_zone;
BOARD_CONNECTED_ITEM* item;
// clear .m_ZoneSubnet parameter for pads
for( MODULE* module = m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
if( (aNetcode < 0) || ( aNetcode == pad->GetNet() ) )
pad->SetZoneSubNet( 0 );
}
// clear .m_ZoneSubnet parameter for tracks and vias
for( TRACK* track = m_Track; track; track = track->Next() )
{
if( (aNetcode < 0) || ( aNetcode == track->GetNet() ) )
track->SetZoneSubNet( 0 );
}
// examine all zones, net by net:
for( int index = 0; index < GetAreaCount(); index++ )
{
curr_zone = GetArea( index );
if( !curr_zone->IsOnCopperLayer() )
continue;
netcode = curr_zone->GetNet();
if( (aNetcode >= 0) && !( aNetcode == netcode ) )
continue;
if( curr_zone->m_FilledPolysList.size() == 0 )
continue;
// Build a list of candidates connected to the net:
Candidates.clear();
// At this point, layers are not considered, because areas on different layers can be connected by a via or a pad.
for( MODULE* module = m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
{
if( pad->GetNet() != curr_zone->GetNet() )
continue;
Candidates.push_back( pad );
}
}
for( TRACK* track = m_Track; track; track = track->Next() )
{
if( track->GetNet() != netcode )
continue;
Candidates.push_back( track );
}
// test if a candidate is inside a filled area of this zone
unsigned indexstart = 0, indexend;
for( indexend = 0; indexend < curr_zone->m_FilledPolysList.size(); indexend++ )
{
if( curr_zone->m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found
{
subnet++;
EDA_Rect bbox = curr_zone->CalculateSubAreaBoundaryBox( indexstart, indexend );
for( unsigned ic = 0; ic < Candidates.size(); ic++ )
{ // test if this area is connected to a board item:
item = Candidates[ic];
if( !item->IsOnLayer( curr_zone->GetLayer() ) )
continue;
wxPoint pos1, pos2;
if( item->Type() == TYPEPAD )
{
pos1 = pos2 = ( (D_PAD*) item )->m_Pos;
}
else if( item->Type() == TYPEVIA )
{
pos1 = pos2 = ( (SEGVIA*) item )->m_Start;
}
else if( item->Type() == TYPETRACK )
{
pos1 = ( (TRACK*) item )->m_Start;
pos2 = ( (TRACK*) item )->m_End;
}
else
continue;
bool connected = false;
if( bbox.Inside( pos1 ) )
{
if( TestPointInsidePolygon( curr_zone->m_FilledPolysList, indexstart,
indexend, pos1.x, pos1.y ) )
connected = true;
}
if( !connected && (pos1 != pos2 ) )
{
if( bbox.Inside( pos2 ) )
if( TestPointInsidePolygon( curr_zone->m_FilledPolysList, indexstart,
indexend, pos2.x, pos2.y ) )
connected = true;
}
if( connected )
{ // Set ZoneSubnet to the current subnet value.
// If the previous subnet is not 0, merge all items with old subnet to the new one
int old_subnet = 0;
old_subnet = item->GetZoneSubNet();
item->SetZoneSubNet( subnet );
if( (old_subnet > 0) && (old_subnet != subnet) ) // Merge previous subnet with the current
{
//printf(" merge subnets: %d et %d (%d)\n", old_subnet, subnet,item->Type());
for( unsigned jj = 0; jj < Candidates.size(); jj++ )
{
BOARD_CONNECTED_ITEM* item_to_merge = Candidates[jj];
if( old_subnet == item_to_merge->GetZoneSubNet() )
item_to_merge->SetZoneSubNet( subnet );
}
} // End if ( old_subnet > 0 )
} // End if( connected )
}
// End test candidates for the current filled area
indexstart = indexend + 1; // prepare test next area, starting at indexend+1 (if exists)
} // End read one area in curr_zone->m_FilledPolysList
}
// End read full curr_zone->m_FilledPolysList
}
// End read all zones in board
}
/**************************************************************************************************/
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb )
/**************************************************************************************************/
/** Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb)
* Calls Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) for each netcode found in zone list
* @param aPcb = the current board
*/
{
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
{
ZONE_CONTAINER* curr_zone = aPcb->GetArea( index );
if ( ! curr_zone->IsOnCopperLayer() )
continue;
if ( curr_zone->GetNet() <= 0 )
continue;
Merge_SubNets_Connected_By_CopperAreas( aPcb, curr_zone->GetNet() );
}
}
/**************************************************************************************************/
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode )
/**************************************************************************************************/
/** Function Merge_SubNets_Connected_By_CopperAreas(BOARD* aPcb, int aNetcode)
* Used after connections by tracks calculations
* Merge subnets, in tracks ans pads when they are connected by a filled copper area
* for pads, this is the .m_physical_connexion member which is tested and modified
* for tracks, this is the .m_Subnet member which is tested and modified
* these members are block numbers (or cluster numbers) for a given net,
* calculated by Build_Pads_Info_Connections_By_Tracks()
* The result is merging 2 blocks (or subnets)
* @param aPcb = the current board
* @param aNetcode = netcode to consider
*/
{
BOARD_CONNECTED_ITEM* item;
int old_subnet, subnet, next_subnet_free_number;
int old_zone_subnet, zone_subnet;
// Ensure a zone with the given netcode exists: examine all zones:
bool found = false;
for( int index = 0; index < aPcb->GetAreaCount(); index++ )
{
ZONE_CONTAINER* curr_zone = aPcb->GetArea( index );
if( aNetcode == curr_zone->GetNet() )
{
found = true;
break;
}
}
if( !found ) // No zone with this netcode, therefore no connection by zone
return;
printf(" Merge_SubNets net = %d\n", aNetcode);
std::vector <BOARD_CONNECTED_ITEM*> Candidates; // list of pads and tracks candidates to test.
// Build a list of candidates connected to the net:
next_subnet_free_number = 0;
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
{
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
{
if( pad->GetNet() == aNetcode )
{
Candidates.push_back( pad );
next_subnet_free_number = MAX( next_subnet_free_number, pad->GetSubNet() );
}
}
}
for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
{
if( track->GetNet() == aNetcode )
{
Candidates.push_back( track );
next_subnet_free_number = MAX( next_subnet_free_number, track->GetSubNet() );
}
}
if( Candidates.size() == 0 )
return;
next_subnet_free_number++; // This is a subnet we can use with not connected items by tracks, but connected by zone.
// Sort by zone_subnet:
sort( Candidates.begin(), Candidates.end(), CmpZoneSubnetValue );
// Some items can be not connected, but they can be connected to a filled area:
// give them a subnet common to these items connected only by the area, and not already used.
// a value like next_subnet_free_number+zone_subnet is right
for( unsigned jj = 0; jj < Candidates.size(); jj++ )
{
item = Candidates[jj];
if ( item->GetSubNet() == 0 && (item->GetZoneSubNet() > 0) )
{
item->SetSubNet( next_subnet_free_number + item->GetZoneSubNet() );
}
}
// Now, for each zone subnet, we search for 2 items with different subnets.
// if found, the 2 subnet are merged in the whole candidate list.
old_subnet = 0;
old_zone_subnet = 0;
for( unsigned ii = 0; ii < Candidates.size(); ii++ )
{
item = Candidates[ii];
zone_subnet = item->GetZoneSubNet();
if( zone_subnet == 0 ) // Not connected by a filled area, skip it
continue;
subnet = item->GetSubNet();
if( zone_subnet != old_zone_subnet ) // a new zone subnet is found
{
old_subnet = subnet;
old_zone_subnet = zone_subnet;
continue;
}
zone_subnet = old_zone_subnet;
if( subnet == old_subnet ) // 2 successive items already from the same cluster: nothing to do
continue;
// Here we have 2 items connected by the same area have 2 differents subnets: merge subnets
if( (subnet > old_subnet) || ( subnet <= 0) )
EXCHG( subnet, old_subnet );
for( unsigned jj = 0; jj < Candidates.size(); jj++ )
{
BOARD_CONNECTED_ITEM * item_to_merge = Candidates[jj];
if( item_to_merge->GetSubNet() == old_subnet )
item_to_merge->SetSubNet( subnet );
}
old_subnet = subnet;
}
}
/* Compare function used for sorting candidates by increasing zone zubnet
*/
static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b )
{
int asubnet, bsubnet;
asubnet = a->GetZoneSubNet();
bsubnet = b->GetZoneSubNet();
return asubnet < bsubnet;
}

View File

@ -22,7 +22,7 @@ using namespace std;
* the first version is for explanations and tests (used to test the second version) * the first version is for explanations and tests (used to test the second version)
* both use the same algorithm. * both use the same algorithm.
*/ */
#if 0 #if 1
/* This text and the algorithm come from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html /* This text and the algorithm come from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
* *