From 97be005035d259314f5af70f00e3b778d5608a42 Mon Sep 17 00:00:00 2001 From: CHARRAS Date: Sat, 5 Jan 2008 13:37:51 +0000 Subject: [PATCH] Added: Delete cutout outline in zone popup menu --- change_log.txt | 11 +- include/id.h | 2 +- include/wxPcbStruct.h | 377 ++++++++++++------------ internat/fr/kicad.mo | Bin 140822 -> 140740 bytes internat/fr/kicad.po | 207 ++++++------- pcbnew/class_board_item.cpp | 5 + pcbnew/class_zone.cpp | 11 + pcbnew/edit.cpp | 14 +- pcbnew/onrightclick.cpp | 31 +- pcbnew/zone_filling_algorithm.cpp | 2 +- pcbnew/zones_by_polygon.cpp | 57 +++- pcbnew/zones_test_and_combine_areas.cpp | 106 ++++--- polygon/PolyLine.cpp | 75 ++--- polygon/PolyLine.h | 32 +- polygon/PolyLine2Kicad.h | 25 -- polygon/cdisplaylist_stuff.cpp | 20 +- polygon/php_polygon.cpp | 19 +- 17 files changed, 500 insertions(+), 494 deletions(-) diff --git a/change_log.txt b/change_log.txt index efe4ec7afe..696b4365fb 100644 --- a/change_log.txt +++ b/change_log.txt @@ -4,12 +4,21 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +2008-jan-05 UPDATE Jean-Pierre Charras +================================================================================ ++pcbnew: + Added: Delete cutout outline in zone popup menu + the GUI about zones is now working. + Some work is needed ( a zone in a zone of the same net is not merged ) + Currently No DRC for outlines + + 2008-jan-04 UPDATE Jean-Pierre Charras ================================================================================ +pcbnew: More about zones: Outlines can be edited. Outlines are merged if needeed. - Current No DRC for outlines + Currently No DRC for outlines 2008-jan-01 UPDATE Jean-Pierre Charras diff --git a/include/id.h b/include/id.h index d02429c463..7c3a201fdd 100644 --- a/include/id.h +++ b/include/id.h @@ -560,7 +560,7 @@ enum main_id { ID_POPUP_PCB_PLACE_ZONE_CORNER, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE, - ID_POPUP_ZONE_UNUSED1, + ID_POPUP_PCB_DELETE_ZONE_CUTOUT, ID_POPUP_ZONE_UNUSED2, ID_POPUP_ZONE_UNUSED3, ID_POPUP_ZONE_UNUSED4, diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 0d9bfcbbfd..08defca4fc 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -1,6 +1,6 @@ /***********************************************************/ -/* wxstruct.h: */ -/* descriptions des principales classes derivees utilisees */ +/* wxPcbStruct.h: */ +/* Classes used in pcbnew, cvpcb and gerbview */ /***********************************************************/ #ifndef WXPCB_STRUCT_H @@ -14,14 +14,6 @@ #define PCB_INTERNAL_UNIT 10000 #endif -// Option for dialog boxes -// #define DIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxFRAME_FLOAT_ON_PARENT|wxSTAY_ON_TOP -#define DIALOG_STYLE wxDEFAULT_DIALOG_STYLE | wxFRAME_FLOAT_ON_PARENT | MAYBE_RESIZE_BORDER - -#define KICAD_DEFAULT_DRAWFRAME_STYLE wxDEFAULT_FRAME_STYLE|wxWANTS_CHARS -#define EDA_DRAW_PANEL wxScrolledWindow - -class wxMyDialogModalData; /* Forward declarations of classes. */ class WinEDA_DrawPanel; @@ -29,25 +21,12 @@ class WinEDA_DrawFrame; #include "base_struct.h" -class WinEDA_App; -class WinEDA_MsgPanel; -class COMMAND; -class WinEDA_MainFrame; -class BASE_SCREEN; -class SCH_SCREEN; class PCB_SCREEN; -class WinEDA_SchematicFrame; // Schematic main frame -class WinEDA_LibeditFrame; // Component creation and edition main frame -class WinEDA_ViewlibFrame; // Component viewer main frame class WinEDA_GerberFrame; // GERBER viewer main frame class WinEDA_Toolbar; class WinEDA_CvpcbFrame; class WinEDA_PcbFrame; class WinEDA_ModuleEditFrame; -class WinEDAChoiceBox; -#define WinEDA_MenuBar wxMenuBar -#define WinEDA_Menu wxMenu -#define WinEDA_MenuItem wxMenuItem // Used but not defined here: class BOARD; @@ -92,7 +71,7 @@ public: WinEDA_BasePcbFrame( wxWindow* father, WinEDA_App* parent, int idtype, const wxString& title, const wxPoint& pos, const wxSize& size, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); ~WinEDA_BasePcbFrame(); @@ -175,131 +154,140 @@ public: */ GENERAL_COLLECTORS_GUIDE GetCollectorsGuide(); - + /** * Function CursorGoto * positions the cursor at a given coordinate and reframes the drawing if the * requested point is out of view. * @param aPos The point to go to. */ - void CursorGoto( const wxPoint& aPos ); - - + void CursorGoto( const wxPoint& aPos ); + + /* Place un repere sur l'ecran au point de coordonnees PCB pos */ void place_marqueur( wxDC* DC, const wxPoint& pos, char* pt_bitmap, int DrawMode, int color, int type ); // Gestion des modules - void InstallModuleOptionsFrame( MODULE* Module, - wxDC* DC, const wxPoint& pos ); - MODULE* Copie_Module( MODULE* module ); - MODULE* Exchange_Module( wxWindow* winaff, MODULE* old_module, MODULE* new_module ); - int Save_1_Module( const wxString& LibName, MODULE* Module, - bool Overwrite, bool DisplayDialog ); - void Archive_Modules( const wxString& LibName, bool NewModulesOnly ); - MODULE* Select_1_Module_From_BOARD( BOARD* Pcb ); - MODULE* GetModuleByName(); + void InstallModuleOptionsFrame( MODULE* Module, + wxDC* DC, const wxPoint& pos ); + MODULE* Copie_Module( MODULE* module ); + MODULE* Exchange_Module( wxWindow* winaff, + MODULE* old_module, + MODULE* new_module ); + int Save_1_Module( const wxString& LibName, MODULE* Module, + bool Overwrite, bool DisplayDialog ); + void Archive_Modules( const wxString& LibName, bool NewModulesOnly ); + MODULE* Select_1_Module_From_BOARD( BOARD* Pcb ); + MODULE* GetModuleByName(); // Modules (footprints) - MODULE* Create_1_Module( wxDC* DC, const wxString& module_name ); - void Edit_Module( MODULE* module, wxDC* DC ); - void Rotate_Module( wxDC* DC, MODULE* module, int angle, bool incremental ); - void Change_Side_Module( MODULE* Module, wxDC* DC ); - void Place_Module( MODULE* module, wxDC* DC ); - void InstallExchangeModuleFrame( MODULE* ExchangeModuleModule, - wxDC* DC, const wxPoint& pos ); + MODULE* Create_1_Module( wxDC* DC, const wxString& module_name ); + void Edit_Module( MODULE* module, wxDC* DC ); + void Rotate_Module( wxDC* DC, + MODULE* module, + int angle, + bool incremental ); + void Change_Side_Module( MODULE* Module, wxDC* DC ); + void Place_Module( MODULE* module, wxDC* DC ); + void InstallExchangeModuleFrame( MODULE* ExchangeModuleModule, + wxDC* DC, const wxPoint& pos ); // module texts - void RotateTextModule( TEXTE_MODULE* Text, wxDC* DC ); - void DeleteTextModule( TEXTE_MODULE* Text, wxDC* DC ); - void PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC ); - void StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC ); - TEXTE_MODULE* CreateTextModule( MODULE* Module, wxDC* DC ); + void RotateTextModule( TEXTE_MODULE* Text, wxDC* DC ); + void DeleteTextModule( TEXTE_MODULE* Text, wxDC* DC ); + void PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC ); + void StartMoveTexteModule( TEXTE_MODULE* Text, wxDC* DC ); + TEXTE_MODULE* CreateTextModule( MODULE* Module, wxDC* DC ); - void InstallPadOptionsFrame( D_PAD* pad, wxDC* DC, const wxPoint& pos ); - void InstallTextModOptionsFrame( TEXTE_MODULE* TextMod, - wxDC* DC, const wxPoint& pos ); + void InstallPadOptionsFrame( D_PAD* pad, wxDC* DC, const wxPoint& pos ); + void InstallTextModOptionsFrame( TEXTE_MODULE* TextMod, + wxDC* DC, const wxPoint& pos ); // Pads sur modules - void AddPad( MODULE* Module, wxDC* DC ); - void DeletePad( D_PAD* Pad, wxDC* DC ); - void StartMovePad( D_PAD* Pad, wxDC* DC ); - void RotatePad( D_PAD* Pad, wxDC* DC ); - void PlacePad( D_PAD* Pad, wxDC* DC ); - void Export_Pad_Settings( D_PAD* pt_pad ); - void Import_Pad_Settings( D_PAD* pt_pad, wxDC* DC ); - void Global_Import_Pad_Settings( D_PAD* Pad, wxDC* DC ); + void AddPad( MODULE* Module, wxDC* DC ); + void DeletePad( D_PAD* Pad, wxDC* DC ); + void StartMovePad( D_PAD* Pad, wxDC* DC ); + void RotatePad( D_PAD* Pad, wxDC* DC ); + void PlacePad( D_PAD* Pad, wxDC* DC ); + void Export_Pad_Settings( D_PAD* pt_pad ); + void Import_Pad_Settings( D_PAD* pt_pad, wxDC* DC ); + void Global_Import_Pad_Settings( D_PAD* Pad, wxDC* DC ); // loading footprints - MODULE* Get_Librairie_Module( wxWindow* winaff, const wxString& library, - const wxString& ModuleName, bool show_msg_err ); + MODULE* Get_Librairie_Module( wxWindow* winaff, + const wxString& library, + const wxString& ModuleName, + bool show_msg_err ); - wxString Select_1_Module_From_List( + wxString Select_1_Module_From_List( WinEDA_DrawFrame* active_window, const wxString& Library, const wxString& Mask, const wxString& KeyWord ); - MODULE* Load_Module_From_Library( const wxString& library, wxDC* DC ); + MODULE* Load_Module_From_Library( const wxString& library, wxDC* DC ); // ratsnest functions - void Compile_Ratsnest( wxDC* DC, bool affiche ); /* Recalcul complet du chevelu */ - void ReCompile_Ratsnest_After_Changes( wxDC* DC ); - int Test_1_Net_Ratsnest( wxDC* DC, int net_code ); - char* build_ratsnest_module( wxDC* DC, MODULE* Module ); - void trace_ratsnest_module( wxDC* DC ); - void Build_Board_Ratsnest( wxDC* DC ); - void DrawGeneralRatsnest( wxDC* DC, int net_code = 0 ); - void trace_ratsnest_pad( wxDC* DC ); - void recalcule_pad_net_code(); /* compute and update the PAD net codes */ - void build_liste_pads(); - int* build_ratsnest_pad( EDA_BaseStruct* ref, const wxPoint& refpos, bool init ); + void Compile_Ratsnest( wxDC* DC, bool affiche ); /* Recalcul complet du chevelu */ + void ReCompile_Ratsnest_After_Changes( wxDC* DC ); + int Test_1_Net_Ratsnest( wxDC* DC, int net_code ); + char* build_ratsnest_module( wxDC* DC, MODULE* Module ); + void trace_ratsnest_module( wxDC* DC ); + void Build_Board_Ratsnest( wxDC* DC ); + void DrawGeneralRatsnest( wxDC* DC, int net_code = 0 ); + void trace_ratsnest_pad( wxDC* DC ); + void recalcule_pad_net_code(); /* compute and update the PAD net codes */ + void build_liste_pads(); + int* build_ratsnest_pad( EDA_BaseStruct* ref, + const wxPoint& refpos, + bool init ); - void Tst_Ratsnest( wxDC* DC, int ref_netcode ); - void test_connexions( wxDC* DC ); - void test_1_net_connexion( wxDC* DC, int net_code ); - void reattribution_reference_piste( int affiche ); + void Tst_Ratsnest( wxDC* DC, int ref_netcode ); + void test_connexions( wxDC* DC ); + void test_1_net_connexion( wxDC* DC, int net_code ); + void reattribution_reference_piste( int affiche ); // Plotting - void ToPlotter( wxCommandEvent& event ); - void Plot_Serigraphie( int format_plot, FILE* File, int masque_layer ); - void Genere_GERBER( const wxString& FullFileName, int Layer, - bool PlotOriginIsAuxAxis ); - void Genere_HPGL( const wxString& FullFileName, int Layer ); - void Genere_PS( const wxString& FullFileName, int Layer ); - void Plot_Layer_HPGL( FILE* File, int masque_layer, - int garde, int tracevia, int modetrace ); - void Plot_Layer_GERBER( FILE* File, int masque_layer, - int garde, int tracevia ); - int Gen_D_CODE_File( FILE* file ); - void Plot_Layer_PS( FILE* File, int masque_layer, - int garde, int tracevia, int modetrace ); + void ToPlotter( wxCommandEvent& event ); + void Plot_Serigraphie( int format_plot, FILE* File, int masque_layer ); + void Genere_GERBER( const wxString& FullFileName, int Layer, + bool PlotOriginIsAuxAxis ); + void Genere_HPGL( const wxString& FullFileName, int Layer ); + void Genere_PS( const wxString& FullFileName, int Layer ); + void Plot_Layer_HPGL( FILE* File, int masque_layer, + int garde, int tracevia, int modetrace ); + void Plot_Layer_GERBER( FILE* File, int masque_layer, + int garde, int tracevia ); + int Gen_D_CODE_File( FILE* file ); + void Plot_Layer_PS( FILE* File, int masque_layer, + int garde, int tracevia, int modetrace ); /* Block operations: */ - void Block_Delete( wxDC* DC ); - void Block_Rotate( wxDC* DC ); - void Block_Invert( wxDC* DC ); - void Block_Move( wxDC* DC ); - void Block_Duplicate( wxDC* DC ); + void Block_Delete( wxDC* DC ); + void Block_Rotate( wxDC* DC ); + void Block_Invert( wxDC* DC ); + void Block_Move( wxDC* DC ); + void Block_Duplicate( wxDC* DC ); + - /** * Function DelLimitesZone * deletes the limits of a zone. * @param DC A wxDC to draw onto. * @param Redraw If true, means redraw the pcb without the zone limits */ - void DelLimitesZone( wxDC* DC, bool Redraw ); + void DelLimitesZone( wxDC* DC, bool Redraw ); // layerhandling: // (See pcbnew/sel_layer.cpp for description of why null_layer parameter is provided) - int SelectLayer( int default_layer, int min_layer, int max_layer, - bool null_layer = false ); - void SelectLayerPair(); - virtual void SwitchLayer( wxDC* DC, int layer ); + int SelectLayer( int default_layer, int min_layer, int max_layer, + bool null_layer = false ); + void SelectLayerPair(); + virtual void SwitchLayer( wxDC* DC, int layer ); // divers - void AddHistory( int value, KICAD_T type ); // Add value in data list history - void InstallGridFrame( const wxPoint& pos ); + void AddHistory( int value, KICAD_T type ); // Add value in data list history + void InstallGridFrame( const wxPoint& pos ); DECLARE_EVENT_TABLE() }; @@ -321,10 +309,10 @@ private: wxMenu* m_FilesMenu; DRC* m_drc; ///< the DRC controller, see drc.cpp - - + + // we'll use lower case function names for private member functions. - void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu ); + void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu ); void createPopUpMenuForFootprints( MODULE* aModule, wxMenu* aPopMenu ); void createPopUpMenuForFpTexts( TEXTE_MODULE* aText, wxMenu* aPopMenu ); void createPopUpMenuForFpPads( D_PAD* aPad, wxMenu* aPopMenu ); @@ -335,7 +323,7 @@ private: public: WinEDA_PcbFrame( wxWindow* father, WinEDA_App* parent, const wxString& title, const wxPoint& pos, const wxSize& size, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); ~WinEDA_PcbFrame(); @@ -445,7 +433,7 @@ public: // Track and via edition: void DisplayTrackSettings(); - + /** * Function Other_Layer_Route * operates in one of two ways. If argument track is NULL, then swap the active @@ -457,7 +445,7 @@ public: * @param DC A device context to draw on. * @return bool - true if the operation was successful, else false such as * the case where DRC would not allow a via. - */ + */ bool Other_Layer_Route( TRACK* track, wxDC* DC ); void Affiche_PadsNoConnect( wxDC* DC ); void Affiche_Status_Net( wxDC* DC ); @@ -483,97 +471,114 @@ public: bool Genere_Pad_Connexion( wxDC* DC, int layer ); // zone handling -/** Function Delete_Zone - * Remove the zone which include the segment aZone, or the zone which have the given time stamp. - * A zone is a group of segments which have the same TimeStamp - * @param DC = current Device Context (can be NULL) - * @param aZone = zone segment within the zone to delete. Can be NULL - * @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL - */ - void Delete_Zone( wxDC* DC, SEGZONE* Track, long aTimestamp = 0 ); + + /** Function Delete_Zone_Fill + * Remove the zone filling which include the segment aZone, or the zone which have the given time stamp. + * A zone is a group of segments which have the same TimeStamp + * @param DC = current Device Context (can be NULL) + * @param aZone = zone segment within the zone to delete. Can be NULL + * @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL + */ + void Delete_Zone_Fill( wxDC* DC, SEGZONE* Track, long aTimestamp = 0 ); EDGE_ZONE* Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone ); + /** * Function Begin_Zone * initiates a zone edge creation process, - * or terminates the current zone edge and creates a new zone edge stub + * or terminates the current zone edge and creates a new zone edge stub */ EDGE_ZONE* Begin_Zone( wxDC* DC ); - + /** * Function End_Zone * terminates the zone edge creation process - * @param DC = current Device Context + * @param DC = current Device Context */ void End_Zone( wxDC* DC ); - - /** Function Fill_Zone() - * Calculate the zone filling for the outline zone_container - * The zone outline is a frontier, and can be complex (with holes) - * The filling starts from starting points like pads, tracks. - * If exists the old filling is removed - * @param DC = current Device Context - * @param zone_container = zone to fill - * @param verbose = true to show error messages - * @return error level (0 = no error) - */ - int Fill_Zone( wxDC* DC, ZONE_CONTAINER * zone_container, bool verbose = TRUE ); - /** Function Fill_All_Zones() - * Fill all zones on the board - * The old fillings are removed - * @param frame = reference to the main frame - * @param DC = current Device Context - * @param verbose = true to show error messages - * @return error level (0 = no error) - */ - int Fill_All_Zones( wxDC* DC, bool verbose = TRUE ); + /** Function Fill_Zone() + * Calculate the zone filling for the outline zone_container + * The zone outline is a frontier, and can be complex (with holes) + * The filling starts from starting points like pads, tracks. + * If exists the old filling is removed + * @param DC = current Device Context + * @param zone_container = zone to fill + * @param verbose = true to show error messages + * @return error level (0 = no error) + */ + int Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool verbose = TRUE ); + + /** Function Fill_All_Zones() + * Fill all zones on the board + * The old fillings are removed + * @param frame = reference to the main frame + * @param DC = current Device Context + * @param verbose = true to show error messages + * @return error level (0 = no error) + */ + int Fill_All_Zones( wxDC* DC, bool verbose = TRUE ); - /** - * Function Add_Zone_Cutout - * Add a cutout zone to a given zone outline - * @param DC = current Device Context - * @param zone_container = parent zone outline - */ - void Add_Zone_Cutout( wxDC* DC , ZONE_CONTAINER * zone_container ); + /** + * Function Add_Zone_Cutout + * Add a cutout zone to a given zone outline + * @param DC = current Device Context + * @param zone_container = parent zone outline + */ + void Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container ); - /** - * Function Add_Similar_Zone - * Add a zone to a given zone outline. - * if the zones are overlappeing they will be merged - * @param DC = current Device Context - * @param zone_container = parent zone outline - */ - void Add_Similar_Zone( wxDC* DC , ZONE_CONTAINER * zone_container ); + /** + * Function Add_Similar_Zone + * Add a zone to a given zone outline. + * if the zones are overlappeing they will be merged + * @param DC = current Device Context + * @param zone_container = parent zone outline + */ + void Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* zone_container ); - /** - * Function Edit_Zone_Params - * Edit params (layer, clearance, ...) for a zone outline - */ - void Edit_Zone_Params( wxDC* DC , ZONE_CONTAINER * zone_container ); + /** + * 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 ); + /** + * 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 - * Remove the currently selected corner in a zone outline - * the .m_CornerSelection is used as corner selection - */ - void Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_container ); + /** + * 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 + /** + * Function End_Move_Zone_Corner + * Remove the currently selected corner in a zone outline + * the .m_CornerSelection is used as corner selection + */ + void Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_container ); + + /** Function Delete_Zone + * Remove the zone which include the segment aZone, or the zone which have the given time stamp. + * A zone is a group of segments which have the same TimeStamp + * @param DC = current Device Context (can be NULL) + * @param zone_container = zone to modify + * the member .m_CornerSelection is used to find the outline to remove. + * if the outline is the main outline, all the zone is removed + * otherwise, the hole is deleted + */ + void Delete_Zone_Contour( 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 ); @@ -618,7 +623,7 @@ public: void GlobalRoute( wxDC* DC ); // divers - void Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC ); + void Show_1_Ratsnest( EDA_BaseStruct* item, wxDC* DC ); void Ratsnest_On_Off( wxDC* DC ); void Clean_Pcb( wxDC* DC ); BOARD_ITEM* SaveItemEfface( BOARD_ITEM* PtItem, int nbitems ); @@ -660,7 +665,7 @@ private: public: WinEDA_GerberFrame( wxWindow* father, WinEDA_App* parent, const wxString& title, const wxPoint& pos, const wxSize& size, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); ~WinEDA_GerberFrame(); @@ -766,7 +771,7 @@ public: WinEDA_ModuleEditFrame( wxWindow* father, WinEDA_App* parent, const wxString& title, const wxPoint& pos, const wxSize& size, - long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); + long style = KICAD_DEFAULT_DRAWFRAME_STYLE ); ~WinEDA_ModuleEditFrame(); @@ -795,7 +800,7 @@ public: BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 ); - /* Undo and redo functions */ + /* Undo and redo functions */ public: void SaveCopyInUndoList( EDA_BaseStruct* ItemToCopy, int flag_type_command = 0 ); diff --git a/internat/fr/kicad.mo b/internat/fr/kicad.mo index 23fa1270cb31188061a35ffefb5286e44bfed242..b9cb42970bb81112f7a6e389c4cb10474085f6ad 100644 GIT binary patch delta 49984 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\n" "MIME-Version: 1.0\n" @@ -639,7 +639,7 @@ msgstr "Cuivre" #: pcbnew/classpcb.cpp:210 #: pcbnew/class_track.cpp:806 #: pcbnew/class_module.cpp:1217 -#: pcbnew/class_zone.cpp:407 +#: pcbnew/class_zone.cpp:441 #: gerbview/affiche.cpp:109 msgid "Layer" msgstr "Couche" @@ -1357,7 +1357,7 @@ msgstr "Module" #: pcbnew/classpcb.cpp:194 #: pcbnew/class_marker.cpp:112 #: pcbnew/class_track.cpp:750 -#: pcbnew/class_zone.cpp:388 +#: pcbnew/class_zone.cpp:422 #: gerbview/affiche.cpp:93 msgid "Type" msgstr "Type" @@ -1629,11 +1629,11 @@ msgstr "Hauteur Texte Module" msgid "Text Module Size H" msgstr "Largeur Texte Module" -#: pcbnew/zone_filling_algorithm.cpp:156 +#: pcbnew/zone_filling_algorithm.cpp:155 msgid "No pads or starting point found to fill this zone outline" msgstr "Pas de pads ou de points de départ pour remplir ce contour de zone" -#: pcbnew/zone_filling_algorithm.cpp:194 +#: pcbnew/zone_filling_algorithm.cpp:193 msgid "Ok" msgstr "Ok" @@ -1911,8 +1911,8 @@ msgstr "Garder" #: pcbnew/dialog_netlist.cpp:143 #: pcbnew/onrightclick.cpp:589 -#: pcbnew/onrightclick.cpp:749 -#: pcbnew/onrightclick.cpp:846 +#: pcbnew/onrightclick.cpp:754 +#: pcbnew/onrightclick.cpp:851 #: eeschema/edit_component_in_lib.cpp:239 #: eeschema/edit_component_in_lib.cpp:320 msgid "Delete" @@ -2086,7 +2086,7 @@ msgid "Add Drawing" msgstr "Ajout d'éléments graphiques" #: pcbnew/modedit.cpp:424 -#: pcbnew/edit.cpp:536 +#: pcbnew/edit.cpp:518 #: eeschema/schedit.cpp:455 #: eeschema/libframe.cpp:579 msgid "Delete item" @@ -2144,8 +2144,8 @@ msgid "Delete Block (shift+ctrl + drag mouse)" msgstr "Effacement Bloc (shift+ctrl + drag mouse)" #: pcbnew/modedit_onclick.cpp:252 -#: pcbnew/onrightclick.cpp:743 -#: pcbnew/onrightclick.cpp:840 +#: pcbnew/onrightclick.cpp:748 +#: pcbnew/onrightclick.cpp:845 msgid "Rotate" msgstr "Rotation" @@ -2170,17 +2170,17 @@ msgid "Move Pad" msgstr "Déplace Pad" #: pcbnew/modedit_onclick.cpp:274 -#: pcbnew/onrightclick.cpp:782 +#: pcbnew/onrightclick.cpp:787 msgid "Edit Pad" msgstr "Edit Pad" #: pcbnew/modedit_onclick.cpp:276 -#: pcbnew/onrightclick.cpp:786 +#: pcbnew/onrightclick.cpp:791 msgid "New Pad Settings" msgstr "Nouvelles Caract. Pads" #: pcbnew/modedit_onclick.cpp:278 -#: pcbnew/onrightclick.cpp:788 +#: pcbnew/onrightclick.cpp:793 msgid "Export Pad Settings" msgstr "Exporte Caract. Pads" @@ -2189,7 +2189,7 @@ msgid "delete Pad" msgstr "Supprimer Pad" #: pcbnew/modedit_onclick.cpp:285 -#: pcbnew/onrightclick.cpp:793 +#: pcbnew/onrightclick.cpp:798 msgid "Global Pad Settings" msgstr "Edition Globale des pads" @@ -2222,9 +2222,9 @@ msgid "Place edge" msgstr "Place contour" #: pcbnew/modedit_onclick.cpp:317 -#: pcbnew/onrightclick.cpp:711 -#: pcbnew/onrightclick.cpp:745 -#: pcbnew/onrightclick.cpp:842 +#: pcbnew/onrightclick.cpp:716 +#: pcbnew/onrightclick.cpp:750 +#: pcbnew/onrightclick.cpp:847 #: eeschema/onrightclick.cpp:313 msgid "Edit" msgstr "Editer" @@ -2565,7 +2565,7 @@ msgid "Footprint name:" msgstr "Nom Module: " #: pcbnew/modules.cpp:281 -#: pcbnew/onrightclick.cpp:717 +#: pcbnew/onrightclick.cpp:722 msgid "Delete Module" msgstr "Supprimer Module" @@ -3212,7 +3212,6 @@ msgid "Add Similar Zone" msgstr "Addition d'une Zone Semblable" #: pcbnew/onrightclick.cpp:664 -#, fuzzy msgid "Add Cutout Area" msgstr "Addition d'une Zone Interdite" @@ -3224,44 +3223,48 @@ msgstr "Remplir Zone" msgid "Edit Zone Params" msgstr "Editer Paramètres de la Zone" -#: pcbnew/onrightclick.cpp:673 +#: pcbnew/onrightclick.cpp:675 +msgid "Delete Cutout" +msgstr "Supprimer Zone Interdite" + +#: pcbnew/onrightclick.cpp:678 msgid "Delete Zone Outline" msgstr "Supprimer Contour de Zone" -#: pcbnew/onrightclick.cpp:695 -#: pcbnew/onrightclick.cpp:740 -#: pcbnew/onrightclick.cpp:778 -#: pcbnew/onrightclick.cpp:837 +#: pcbnew/onrightclick.cpp:700 +#: pcbnew/onrightclick.cpp:745 +#: pcbnew/onrightclick.cpp:783 +#: pcbnew/onrightclick.cpp:842 msgid "Move" msgstr "Move" -#: pcbnew/onrightclick.cpp:698 -#: pcbnew/onrightclick.cpp:780 +#: pcbnew/onrightclick.cpp:703 +#: pcbnew/onrightclick.cpp:785 msgid "Drag" msgstr "Drag" -#: pcbnew/onrightclick.cpp:702 +#: pcbnew/onrightclick.cpp:707 msgid "Rotate +" msgstr "Rotation +" -#: pcbnew/onrightclick.cpp:706 +#: pcbnew/onrightclick.cpp:711 #: eeschema/onrightclick.cpp:301 msgid "Rotate -" msgstr "Rotation -" -#: pcbnew/onrightclick.cpp:707 +#: pcbnew/onrightclick.cpp:712 msgid "Flip" msgstr "Change côté" -#: pcbnew/onrightclick.cpp:797 +#: pcbnew/onrightclick.cpp:802 msgid "delete" msgstr "Effacer" -#: pcbnew/onrightclick.cpp:804 +#: pcbnew/onrightclick.cpp:809 msgid "Autoroute Pad" msgstr "Autoroute Pad" -#: pcbnew/onrightclick.cpp:805 +#: pcbnew/onrightclick.cpp:810 msgid "Autoroute Net" msgstr "Autoroute Net" @@ -3612,11 +3615,11 @@ msgstr "Pcb Graphic" #: pcbnew/class_board_item.cpp:59 #: pcbnew/class_board_item.cpp:68 #: pcbnew/class_board_item.cpp:145 -#: pcbnew/class_board_item.cpp:164 -#: pcbnew/class_board_item.cpp:180 -#: pcbnew/class_board_item.cpp:207 -#: pcbnew/class_board_item.cpp:224 -#: pcbnew/class_board_item.cpp:230 +#: pcbnew/class_board_item.cpp:169 +#: pcbnew/class_board_item.cpp:185 +#: pcbnew/class_board_item.cpp:212 +#: pcbnew/class_board_item.cpp:229 +#: pcbnew/class_board_item.cpp:235 msgid " on " msgstr " sur " @@ -3659,46 +3662,51 @@ msgid "Length:" msgstr "Long.:" #: pcbnew/class_board_item.cpp:152 -#: pcbnew/class_zone.cpp:385 +#: pcbnew/class_zone.cpp:416 msgid "Zone Outline" msgstr "Contour de Zone" -#: pcbnew/class_board_item.cpp:168 +#: pcbnew/class_board_item.cpp:156 +#: pcbnew/class_zone.cpp:419 +msgid "(Cutout)" +msgstr "(Cutout)" + +#: pcbnew/class_board_item.cpp:173 #: pcbnew/class_track.cpp:743 msgid "Zone" msgstr "Zone" -#: pcbnew/class_board_item.cpp:186 +#: pcbnew/class_board_item.cpp:191 #: pcbnew/pcbframe.cpp:479 msgid "Via" msgstr "Via" -#: pcbnew/class_board_item.cpp:190 +#: pcbnew/class_board_item.cpp:195 msgid "Blind" msgstr "Enterrée" -#: pcbnew/class_board_item.cpp:192 +#: pcbnew/class_board_item.cpp:197 msgid "Buried" msgstr "Borgne" -#: pcbnew/class_board_item.cpp:214 +#: pcbnew/class_board_item.cpp:219 #: pcbnew/class_marker.cpp:112 msgid "Marker" msgstr "Marqueur" -#: pcbnew/class_board_item.cpp:219 +#: pcbnew/class_board_item.cpp:224 msgid "Dimension" msgstr "Dimension" -#: pcbnew/class_board_item.cpp:224 +#: pcbnew/class_board_item.cpp:229 msgid "Target" msgstr "Mire" -#: pcbnew/class_board_item.cpp:225 +#: pcbnew/class_board_item.cpp:230 msgid "size" msgstr "dimension" -#: pcbnew/class_board_item.cpp:230 +#: pcbnew/class_board_item.cpp:235 msgid "Edge Zone" msgstr "Contour Zone" @@ -3874,13 +3882,13 @@ msgstr "Pads" #: pcbnew/class_track.cpp:765 #: pcbnew/zones.cpp:873 -#: pcbnew/zones_by_polygon.cpp:705 -#: pcbnew/class_zone.cpp:398 +#: pcbnew/zones_by_polygon.cpp:831 +#: pcbnew/class_zone.cpp:432 msgid "NetName" msgstr "NetName" #: pcbnew/class_track.cpp:770 -#: pcbnew/class_zone.cpp:403 +#: pcbnew/class_zone.cpp:437 msgid "NetCode" msgstr "NetCode" @@ -4433,73 +4441,30 @@ msgid "Delete Current Zone Edges" msgstr "Effacer contour zone courant" #: pcbnew/zones.cpp:871 -#: pcbnew/zones_by_polygon.cpp:703 +#: pcbnew/zones_by_polygon.cpp:829 msgid "No Net" msgstr "No Net" -#: pcbnew/dsn.cpp:456 -msgid "Line length exceeded" -msgstr "Longueur de ligne dépassée" - -#: pcbnew/dsn.cpp:518 -msgid "'quoted text delimiter'" -msgstr "'delimiteur de texte balisé'" - -#: pcbnew/dsn.cpp:524 -msgid "'symbol'" -msgstr "'symbole'" - -#: pcbnew/dsn.cpp:527 -msgid "'number'" -msgstr "'nombre'" - -#: pcbnew/dsn.cpp:536 -msgid "\"quoted string\"" -msgstr "\"chaîne entre quotes\"" - -#: pcbnew/dsn.cpp:539 -msgid "'end of file'" -msgstr "fin de fichier'" - -#: pcbnew/dsn.cpp:556 -msgid "in file" -msgstr "dans le fichier" - -#: pcbnew/dsn.cpp:557 -msgid "on line" -msgstr "en ligne" - -#: pcbnew/dsn.cpp:558 -msgid "at offset" -msgstr "a l'offset" - -#: pcbnew/dsn.cpp:597 -msgid "String delimiter must be a single character of ', \", or $" -msgstr "Le caractère de délimitation de ligne doit être un seul caractère ', \", or $" - -#: pcbnew/dsn.cpp:676 -msgid "Un-terminated delimited string" -msgstr "Ligne délimitée non terminée" - -#: pcbnew/specctra.cpp:271 -#: pcbnew/specctra.cpp:280 +#: pcbnew/specctra.cpp:1015 +#: pcbnew/specctra.cpp:1022 msgid "Expecting" msgstr "Attendu" -#: pcbnew/specctra.cpp:300 +#: pcbnew/specctra.cpp:1031 +#: pcbnew/specctra.cpp:1038 +msgid "Unexpected" +msgstr "Inattendu" + +#: pcbnew/specctra.cpp:1059 +#: pcbnew/specctra.cpp:1817 #, c-format msgid "Unable to open file \"%s\"" msgstr "Ne peut pas ouvrirle fichier \"%s\"" -#: pcbnew/specctra.cpp:401 -#: pcbnew/specctra.cpp:467 -#: pcbnew/specctra.cpp:474 -msgid "on or off" -msgstr "on ou off" - -#: pcbnew/specctra.cpp:452 -msgid "testpoint, guides, or image_conductor" -msgstr "testpoint, guides, ou image_conductor" +#: pcbnew/specctra.cpp:1792 +#, c-format +msgid "System file error writing to file \"%s\"" +msgstr "Erreur système sur écriture fichier \"%s\"" #: pcbnew/move_or_drag_track.cpp:714 msgid "Unable to drag this segment: too many segments connected" @@ -4545,6 +4510,30 @@ msgstr "Erreur. Vous devez choisir une couche" msgid "Error : you must choose a net name" msgstr "Erreur. Vous devez choisir une équipotentielle" +#: pcbnew/dsn.cpp:467 +msgid "Line length exceeded" +msgstr "Longueur de ligne dépassée" + +#: pcbnew/dsn.cpp:577 +msgid "in file" +msgstr "dans le fichier" + +#: pcbnew/dsn.cpp:578 +msgid "on line" +msgstr "en ligne" + +#: pcbnew/dsn.cpp:579 +msgid "at offset" +msgstr "a l'offset" + +#: pcbnew/dsn.cpp:618 +msgid "String delimiter must be a single character of ', \", or $" +msgstr "Le caractère de délimitation de ligne doit être un seul caractère ', \", or $" + +#: pcbnew/dsn.cpp:697 +msgid "Un-terminated delimited string" +msgstr "Ligne délimitée non terminée" + #: pcbnew/initpcb.cpp:125 msgid "Current Board will be lost ?" msgstr "Le C.I. courant sera perdu ?" @@ -4860,11 +4849,11 @@ msgstr "Fichier rapport termin msgid "DRC Report file" msgstr "Fichier rapport de contrôle DRC:" -#: pcbnew/class_zone.cpp:411 +#: pcbnew/class_zone.cpp:445 msgid "Corners" msgstr "Sommets" -#: pcbnew/class_zone.cpp:415 +#: pcbnew/class_zone.cpp:449 msgid "Hatch lines" msgstr "Lignes de Hachure" diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index d9f070788e..3b912a7d62 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -150,6 +150,11 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const case TYPEZONE_CONTAINER: text = _( "Zone Outline" ); + { + ZONE_CONTAINER* area = (ZONE_CONTAINER*) this; + int ncont = area->m_Poly->GetContour(area->m_CornerSelection); + if ( ncont ) text << wxT(" ") << _("(Cutout)"); + } text << wxT( " " ); { wxString TimeStampText; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 38483e3ed2..053c76b760 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -331,6 +331,7 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) int dist; unsigned item_pos, lim; lim = m_Poly->corner.size(); + m_CornerSelection = -1; // Min distance to hit = MIN_DIST_IN_PIXELS pixels : WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame; @@ -340,7 +341,10 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) { dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y ); if( dist <= min_dist ) + { + m_CornerSelection = item_pos; return item_pos; + } } return -1; @@ -366,6 +370,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) /* Test for an entire segment */ unsigned first_corner_pos = 0, end_segm; + m_CornerSelection = -1; for ( item_pos = 0; item_pos < lim; item_pos++ ) { @@ -389,7 +394,10 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) m_Poly->corner[end_segm].x, m_Poly->corner[end_segm].y ); if( dist <= min_dist ) + { + m_CornerSelection = item_pos; return item_pos; + } } return -1; @@ -407,6 +415,9 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) msg = _( "Zone Outline" ); + int ncont = m_Poly->GetContour(m_CornerSelection); + if ( ncont ) msg << wxT(" ") << _("(Cutout)"); + text_pos = 1; Affiche_1_Parametre( frame, text_pos, _( "Type" ), msg, DARKCYAN ); diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index 677afea236..d4a54596c3 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -441,7 +441,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) DrawPanel->MouseToCursorSchema(); if( GetCurItem() == NULL ) break; - Delete_Zone( &dc, (SEGZONE*) GetCurItem() ); + Delete_Zone_Fill( &dc, (SEGZONE*) GetCurItem() ); SetCurItem( NULL ); break; @@ -460,15 +460,11 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_DELETE_ZONE_CONTAINER: - { + case ID_POPUP_PCB_DELETE_ZONE_CUTOUT: DrawPanel->MouseToCursorSchema(); - ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem(); - zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR); - Delete_Zone( &dc, NULL, zone_cont->m_TimeStamp ); - m_Pcb->Delete( zone_cont ); + Delete_Zone_Contour( &dc, (ZONE_CONTAINER*)GetCurItem() ); SetCurItem( NULL ); - break; - } + break; case ID_POPUP_PCB_DELETE_ZONE_CORNER: Remove_Zone_Corner( &dc, (ZONE_CONTAINER*)GetCurItem() ); @@ -1010,7 +1006,7 @@ void WinEDA_PcbFrame::RemoveStruct( BOARD_ITEM* Item, wxDC* DC ) break; case TYPEZONE: - Delete_Zone( DC, (SEGZONE*) Item ); + Delete_Zone_Fill( DC, (SEGZONE*) Item ); break; case TYPEMARKER: diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index e860974626..d96aa56a31 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -639,37 +639,42 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu } else { - edge_zone->m_CornerSelection = -1; + wxMenu * zones_menu = new wxMenu(); + ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu, + -1, _( "Zones" ), add_zone_xpm ); 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, + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER, _( "Move Corner" ), move_xpm ); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_CORNER, + ADD_MENUITEM( zones_menu, 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, + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER, _( "Create Corner" ), Add_Corner_xpm ); } - aPopMenu->AppendSeparator(); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE, + zones_menu->AppendSeparator(); + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE, _( "Add Similar Zone" ), add_zone_xpm ); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE, + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE, _( "Add Cutout Area" ), add_zone_cutout ); - aPopMenu->AppendSeparator(); + zones_menu->AppendSeparator(); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ZONE, + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_FILL_ZONE, _( "Fill Zone" ), fill_zone_xpm ); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_EDIT_ZONE_PARAMS, + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS, _( "Edit Zone Params" ), edit_xpm ); - ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER, + + if ( index >= 0 && edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) ) + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT, + _( "Delete Cutout" ), delete_xpm ); + + ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CONTAINER, _( "Delete Zone Outline" ), delete_xpm ); } } diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 5fdf426a9e..0a4a36ceb2 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -48,7 +48,7 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose ) s_TimeStamp = m_TimeStamp; // Delete the old filling, if any : - frame->Delete_Zone( DC, NULL, m_TimeStamp ); + frame->Delete_Zone_Fill( DC, NULL, m_TimeStamp ); // calculate the fixed step of the routing matrix as 5 mils or more E_scale = g_GridRoutingSize / 50; diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index a17bf2d5ec..9caacbf0fe 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -104,11 +104,11 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container /*****************************************************************************/ -void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone, long aTimestamp ) +void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestamp ) /******************************************************************************/ -/** Function Delete_Zone - * Remove the zone which include the segment aZone, or the zone which have the given time stamp. +/** Function Delete_Zone_Fill + * Remove the zone fillig which include the segment aZone, or the zone which have the given time stamp. * A zone is a group of segments which have the same TimeStamp * @param DC = current Device Context (can be NULL) * @param aZone = zone segment within the zone to delete. Can be NULL @@ -257,14 +257,13 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con */ { /* Show the Net */ - if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) ) + if( g_HightLigt_Status ) { Hight_Light( DC ); // Remove old hightlight selection } - g_HightLigth_NetCode = s_NetcodeSelection; - if( !g_HightLigt_Status ) - Hight_Light( DC ); + g_HightLigth_NetCode = s_NetcodeSelection = zone_container->GetNet(); + Hight_Light( DC ); zone_container->m_Flags = IN_EDIT; DrawPanel->ManageCurseur = Show_Zone_Corner_While_Move_Mouse; @@ -327,7 +326,7 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_contai { if ( zone_container->m_Poly->GetNumCorners() <= 3 ) { - Delete_Zone( DC, NULL, zone_container->m_TimeStamp ); + Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); m_Pcb->Delete( zone_container ); return; } @@ -466,7 +465,7 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) s_Zone_Hatching = s_CurrentZone->m_Poly->GetHatchStyle(); } /* Show the Net */ - if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) ) + if( g_HightLigt_Status && (g_HightLigth_NetCode != s_NetcodeSelection) ) { Hight_Light( DC ); // Remove old hightlight selection } @@ -474,8 +473,7 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) if( s_CurrentZone ) s_NetcodeSelection = s_CurrentZone->GetNet(); g_HightLigth_NetCode = s_NetcodeSelection; - if( !g_HightLigt_Status ) - Hight_Light( DC ); + Hight_Light( DC ); if( !s_AddCutoutToCurrentZone ) s_CurrentZone = NULL; // the zone is used only once @@ -742,6 +740,39 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container GetScreen()->SetModify(); } +/************************************************************************************/ +void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_container ) +/************************************************************************************/ + +/** Function Delete_Zone_Contour + * Remove the zone which include the segment aZone, or the zone which have the given time stamp. + * A zone is a group of segments which have the same TimeStamp + * @param DC = current Device Context (can be NULL) + * @param zone_container = zone to modify + * the member .m_CornerSelection is used to find the outline to remove. + * if the outline is the main outline, all the zone_container is removed (deleted) + * otherwise, the hole is deleted + */ +{ + int ncont = zone_container->m_Poly->GetContour(zone_container->m_CornerSelection); + + if ( DC ) + zone_container->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR); + + Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); // Remove fill segments + + if ( ncont == 0 ) // This is the main outline: remove all + m_Pcb->Delete( zone_container ); + + else + { + zone_container->m_Poly->RemoveContour( ncont ); + if ( DC ) + zone_container->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR); + } + GetScreen()->SetModify(); +} + /***************************************************************************************/ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool verbose ) @@ -770,13 +801,13 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v /* Show the Net */ s_NetcodeSelection = zone_container->GetNet(); - if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) && DC ) + if( g_HightLigt_Status && (g_HightLigth_NetCode != s_NetcodeSelection) && DC ) { Hight_Light( DC ); // Remove old hightlight selection } g_HightLigth_NetCode = s_NetcodeSelection; - if( !g_HightLigt_Status && DC ) + if( DC ) Hight_Light( DC ); if( g_HightLigth_NetCode > 0 ) diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index 4039cc6ece..0bd5d0e955 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -20,12 +20,6 @@ bool bDontShowIntersectionArcsWarning; bool bDontShowIntersectionWarning; -#define poly m_Poly - -// carea: describes a copper area -#define carea ZONE_CONTAINER - - /** * Function AddArea * add empty copper area to net @@ -69,7 +63,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int else m_ZoneDescriptorList.push_back( new_area ); - new_area->poly->Start( layer, 1, 10 * NM_PER_MIL, x, y, + new_area->m_Poly->Start( layer, 1, 10 * NM_PER_MIL, x, y, hatch ); return new_area; } @@ -85,9 +79,9 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int */ int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style ) { - if( area_to_complete->poly->GetNumCorners() > 2 ) + if( area_to_complete->m_Poly->GetNumCorners() > 2 ) { - area_to_complete->poly->Close( style ); + area_to_complete->m_Poly->Close( style ); return 1; } else @@ -111,7 +105,7 @@ int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style ) */ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) { - CPolyLine* p = CurrArea->poly; + CPolyLine* p = CurrArea->m_Poly; // first, check for sides intersecting other sides, especially arcs bool bInt = false; @@ -234,7 +228,7 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs ) { - CPolyLine* p = CurrArea->poly; + CPolyLine* p = CurrArea->m_Poly; int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag if( test == -1 && !bRetainArcs ) @@ -284,7 +278,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, { std::vector * pa = new std::vector; p->Undraw(); - int n_poly = CurrArea->poly->NormalizeWithGpc( pa, bRetainArcs ); + int n_poly = CurrArea->m_Poly->NormalizeWithGpc( pa, bRetainArcs ); if( n_poly > 1 ) // i.e if clippinf has created some polygons, we must add these new copper areas { for( int ip = 1; ip < n_poly; ip++ ) @@ -295,9 +289,9 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, // remove the poly that was automatically created for the new area // and replace it with a poly from NormalizeWithGpc - delete CurrArea->poly; - CurrArea->poly = new_p; - CurrArea->poly->Draw(); + delete CurrArea->m_Poly; + CurrArea->m_Poly = new_p; + CurrArea->m_Poly->Draw(); CurrArea->utility = 1; } } @@ -368,15 +362,15 @@ int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtilit continue; // legal polygon - CRect b1 = curr_area->poly->GetCornerBounds(); + CRect b1 = curr_area->m_Poly->GetCornerBounds(); bool mod_ia1 = false; for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; - if( curr_area->poly->GetLayer() == area2->poly->GetLayer() + if( curr_area->GetLayer() == area2->GetLayer() && curr_area->utility2 != -1 && area2->utility2 != -1 ) { - CRect b2 = area2->poly->GetCornerBounds(); + CRect b2 = area2->m_Poly->GetCornerBounds(); if( !( b1.left > b2.right || b1.right < b2.left || b1.bottom > b2.top || b1.top < b2.bottom ) ) { @@ -443,7 +437,7 @@ int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtilit */ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) { - CPolyLine* poly1 = area_to_test->poly; + CPolyLine* poly1 = area_to_test->m_Poly; for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) { @@ -456,7 +450,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) if( area_to_test->GetLayer() != area2->GetLayer() ) continue; - CPolyLine* poly2 = area2->poly; + CPolyLine* poly2 = area2->m_Poly; // test bounding rects CRect b1 = poly1->GetCornerBounds(); @@ -488,7 +482,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) yf1 = poly1->GetY( is1 ); } style1 = poly1->GetSideStyle( ic1 ); - for( int icont2 = 0; icont2GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < poly2->GetNumContours(); icont2++ ) { int is2 = poly2->GetContourStart( icont2 ); int ie2 = poly2->GetContourEnd( icont2 ); @@ -539,8 +533,8 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ if( area_ref->GetLayer() != area_to_test->GetLayer() ) return 0; - CPolyLine* poly1 = area_ref->poly; - CPolyLine* poly2 = area_to_test->poly; + CPolyLine* poly1 = area_ref->m_Poly; + CPolyLine* poly2 = area_to_test->m_Poly; // test bounding rects CRect b1 = poly1->GetCornerBounds(); @@ -647,8 +641,8 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi #endif // polygons intersect, combine them - CPolyLine* poly1 = area_ref->poly; - CPolyLine* poly2 = area_to_combine->poly; + CPolyLine* poly1 = area_ref->m_Poly; + CPolyLine* poly2 = area_to_combine->m_Poly; std::vector arc_array1; std::vector arc_array2; poly1->MakeGpcPoly( -1, &arc_array1 ); @@ -747,7 +741,7 @@ void dra_areas( CDlgLog* log, int copper_layers, // now iterate through all areas for( int ia = 0; ianareas; ia++ ) { - carea* a = &net->area[ia]; + ZONE_CONTAINER* a = &net->area[ia]; // iterate through all nets again POSITION pos2 = pos; @@ -759,17 +753,17 @@ void dra_areas( CDlgLog* log, int copper_layers, cnet* net2 = (cnet*) ptr2; for( int ia2 = 0; ia2nareas; ia2++ ) { - carea* a2 = &net2->area[ia2]; + ZONE_CONTAINER* a2 = &net2->area[ia2]; // test for same layer - if( a->poly->GetLayer() == a2->poly->GetLayer() ) + if( a->m_Poly->GetLayer() == a2->m_Poly->GetLayer() ) { // test for points inside one another - for( int ic = 0; icpoly->GetNumCorners(); ic++ ) + for( int ic = 0; icm_Poly->GetNumCorners(); ic++ ) { - int x = a->poly->GetX( ic ); - int y = a->poly->GetY( ic ); - if( a2->poly->TestPointInside( x, y ) ) + int x = a->m_Poly->GetX( ic ); + int y = a->m_Poly->GetY( ic ); + if( a2->m_Poly->TestPointInside( x, y ) ) { // COPPERAREA_COPPERAREA error id id_a = net->id; @@ -804,11 +798,11 @@ void dra_areas( CDlgLog* log, int copper_layers, } } - for( int ic2 = 0; ic2poly->GetNumCorners(); ic2++ ) + for( int ic2 = 0; ic2m_Poly->GetNumCorners(); ic2++ ) { - int x = a2->poly->GetX( ic2 ); - int y = a2->poly->GetY( ic2 ); - if( a->poly->TestPointInside( x, y ) ) + int x = a2->m_Poly->GetX( ic2 ); + int y = a2->m_Poly->GetY( ic2 ); + if( a->m_Poly->TestPointInside( x, y ) ) { // COPPERAREA_COPPERAREA error id id_a = net2->id; @@ -841,10 +835,10 @@ void dra_areas( CDlgLog* log, int copper_layers, } // now test spacing between areas - for( int icont = 0; icontpoly->GetNumContours(); icont++ ) + for( int icont = 0; icontm_Poly->GetNumContours(); icont++ ) { - int ic_start = a->poly->GetContourStart( icont ); - int ic_end = a->poly->GetContourEnd( icont ); + int ic_start = a->m_Poly->GetContourStart( icont ); + int ic_end = a->m_Poly->GetContourEnd( icont ); for( int ic = ic_start; ic<=ic_end; ic++ ) { id id_a = net->id; @@ -852,24 +846,24 @@ void dra_areas( CDlgLog* log, int copper_layers, id_a.i = ia; id_a.sst = ID_SIDE; id_a.ii = ic; - int ax1 = a->poly->GetX( ic ); - int ay1 = a->poly->GetY( ic ); + int ax1 = a->m_Poly->GetX( ic ); + int ay1 = a->m_Poly->GetY( ic ); int ax2, ay2; if( ic == ic_end ) { - ax2 = a->poly->GetX( ic_start ); - ay2 = a->poly->GetY( ic_start ); + ax2 = a->m_Poly->GetX( ic_start ); + ay2 = a->m_Poly->GetY( ic_start ); } else { - ax2 = a->poly->GetX( ic + 1 ); - ay2 = a->poly->GetY( ic + 1 ); + ax2 = a->m_Poly->GetX( ic + 1 ); + ay2 = a->m_Poly->GetY( ic + 1 ); } - int astyle = a->poly->GetSideStyle( ic ); - for( int icont2 = 0; icont2poly->GetNumContours(); icont2++ ) + int astyle = a->m_Poly->GetSideStyle( ic ); + for( int icont2 = 0; icont2m_Poly->GetNumContours(); icont2++ ) { - int ic_start2 = a2->poly->GetContourStart( icont2 ); - int ic_end2 = a2->poly->GetContourEnd( icont2 ); + int ic_start2 = a2->m_Poly->GetContourStart( icont2 ); + int ic_end2 = a2->m_Poly->GetContourEnd( icont2 ); for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) { id id_b = net2->id; @@ -877,20 +871,20 @@ void dra_areas( CDlgLog* log, int copper_layers, id_b.i = ia2; id_b.sst = ID_SIDE; id_b.ii = ic2; - int bx1 = a2->poly->GetX( ic2 ); - int by1 = a2->poly->GetY( ic2 ); + int bx1 = a2->m_Poly->GetX( ic2 ); + int by1 = a2->m_Poly->GetY( ic2 ); int bx2, by2; if( ic2 == ic_end2 ) { - bx2 = a2->poly->GetX( ic_start2 ); - by2 = a2->poly->GetY( ic_start2 ); + bx2 = a2->m_Poly->GetX( ic_start2 ); + by2 = a2->m_Poly->GetY( ic_start2 ); } else { - bx2 = a2->poly->GetX( ic2 + 1 ); - by2 = a2->poly->GetY( ic2 + 1 ); + bx2 = a2->m_Poly->GetX( ic2 + 1 ); + by2 = a2->m_Poly->GetY( ic2 + 1 ); } - int bstyle = a2->poly->GetSideStyle( ic2 ); + int bstyle = a2->m_Poly->GetSideStyle( ic2 ); int x, y; int d = ::GetClearanceBetweenSegments( bx1, by1, diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 1d3a4a8a74..b78ef2b420 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -59,7 +59,7 @@ CPolyLine::~CPolyLine() // If bRetainArcs == TRUE, try to retain arcs in polys // Returns number of external contours, or -1 if error // -int CPolyLine::NormalizeWithGpc( std::vector * pa, BOOL bRetainArcs ) +int CPolyLine::NormalizeWithGpc( std::vector * pa, bool bRetainArcs ) { std::vector arc_array; @@ -495,7 +495,7 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vectorsize(); iarc++ ) @@ -637,7 +637,7 @@ void CPolyLine::Start( int layer, int w, int sel_box, int x, int y, // add a corner to unclosed polyline // -void CPolyLine::AppendCorner( int x, int y, int style, BOOL bDraw ) +void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw ) { Undraw(); CPolyPt poly_pt( x, y ); @@ -663,7 +663,7 @@ void CPolyLine::AppendCorner( int x, int y, int style, BOOL bDraw ) // close last polyline contour // -void CPolyLine::Close( int style, BOOL bDraw ) +void CPolyLine::Close( int style, bool bDraw ) { if( GetClosed() ) ASSERT(0); @@ -686,13 +686,13 @@ void CPolyLine::MoveCorner( int ic, int x, int y ) // delete corner and adjust arrays // -void CPolyLine::DeleteCorner( int ic, BOOL bDraw ) +void CPolyLine::DeleteCorner( int ic, bool bDraw ) { Undraw(); int icont = GetContour( ic ); int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); - BOOL bClosed = icont < GetNumContours()-1 || GetClosed(); + bool bClosed = icont < GetNumContours()-1 || GetClosed(); if( !bClosed ) { @@ -719,7 +719,14 @@ void CPolyLine::DeleteCorner( int ic, BOOL bDraw ) Draw(); } +/******************************************/ void CPolyLine::RemoveContour( int icont ) +/******************************************/ +/** + * Function RemoveContour + * @param icont = contour number to remove + * remove a contour only if there is more than 1 contour + */ { Undraw(); int istart = GetContourStart( icont ); @@ -733,8 +740,8 @@ void CPolyLine::RemoveContour( int icont ) else if( icont == GetNumContours()-1 ) { // remove last contour - corner.erase( corner.begin() + icont, corner.end() ); - side_style.erase( side_style.begin() + icont, side_style.end() ); + corner.erase( corner.begin() + istart, corner.end() ); + side_style.erase( side_style.begin() + istart, side_style.end() ); } else { @@ -749,7 +756,9 @@ void CPolyLine::RemoveContour( int icont ) } +/******************************************/ void CPolyLine::RemoveAllContours( void ) +/******************************************/ /** * function RemoveAllContours * removes all corners from the lists. @@ -1162,11 +1171,6 @@ int CPolyLine::GetW() return m_Width; } -int CPolyLine::GetSelBoxSize() -{ - return m_sel_box; -} - int CPolyLine::GetNumContours() { int ncont = 0; @@ -1462,7 +1466,7 @@ void CPolyLine::Hatch() // test to see if a point is inside polyline // -BOOL CPolyLine::TestPointInside( int x, int y ) +bool CPolyLine::TestPointInside( int x, int y ) { enum { MAXPTS = 100 }; if( !GetClosed() ) @@ -1538,7 +1542,7 @@ BOOL CPolyLine::TestPointInside( int x, int y ) // test to see if a point is inside polyline contour // -BOOL CPolyLine::TestPointInsideContour( int icont, int x, int y ) +bool CPolyLine::TestPointInsideContour( int icont, int x, int y ) { if( icont >= GetNumContours() ) return FALSE; @@ -1662,25 +1666,6 @@ int CPolyLine::TestIntersection( CPolyLine * poly ) return 0; } -// set selection box size -// -void CPolyLine::SetSelBoxSize( int sel_box ) -{ -// Undraw(); - m_sel_box = sel_box; -// Draw(); -} - -// set pointer to display list, and draw into display list -// -void CPolyLine::SetDisplayList( CDisplayList * dl ) -{ - if( m_dlist ) - Undraw(); - m_dlist = dl; - if( m_dlist ) - Draw(); -} // copy data from another poly, but don't draw it // @@ -1701,6 +1686,20 @@ void CPolyLine::Copy( CPolyLine * src ) FreeGpcPoly(); } + +/*******************************************/ +bool CPolyLine::IsCutoutContour( int icont ) +/*******************************************/ +/* + * return true if the corner icont is inside the outline (i.e it is a hole) + */ +{ + int ncont = GetContour( icont ); + if ( ncont == 0 ) // the first contour is the main outline, not an hole + return false; + return true; +} + void CPolyLine::MoveOrigin( int x_off, int y_off ) { Undraw(); @@ -1719,7 +1718,11 @@ void CPolyLine::MoveOrigin( int x_off, int y_off ) // void CPolyLine::SetX( int ic, int x ) { corner[ic].x = x; } void CPolyLine::SetY( int ic, int y ) { corner[ic].y = y; } -void CPolyLine::SetEndContour( int ic, BOOL end_contour ) { corner[ic].end_contour = end_contour; } + +void CPolyLine::SetEndContour( int ic, bool end_contour ) +{ + corner[ic].end_contour = end_contour; +} // Create CPolyLine for a pad // @@ -1750,7 +1753,7 @@ CPolyLine * CPolyLine::MakePolylineForPad( int type, int x, int y, int w, int l, // void CPolyLine::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, int spoke_w ) + int hole_w, int hole_clearance, bool bThermal, int spoke_w ) { int dx = l/2; int dy = w/2; diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index ed29344910..24898819f7 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -46,17 +46,17 @@ public: int style; int xi, yi, xf, yf; int n_steps; // number of straight-line segments in gpc_poly - BOOL bFound; + bool bFound; }; class CPolyPt { public: - CPolyPt( int qx=0, int qy=0, BOOL qf=FALSE ) + 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; + bool end_contour; int utility; }; @@ -75,11 +75,11 @@ public: // 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 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 DeleteCorner( int ic, bool bDraw=TRUE ); void MoveCorner( int ic, int x, int y ); - void Close( int style = STRAIGHT, BOOL bDraw=TRUE ); + void Close( int style = STRAIGHT, bool bDraw=TRUE ); void RemoveContour( int icont ); void RemoveAllContours( void ); @@ -93,7 +93,7 @@ public: void Undraw(); void Draw( CDisplayList * dl = NULL ); void Hatch(); - void MakeVisible( BOOL visible = TRUE ); + void MakeVisible( bool visible = TRUE ); void MoveOrigin( int x_off, int y_off ); // misc. functions @@ -101,8 +101,9 @@ public: CRect GetCornerBounds(); CRect GetCornerBounds( int icont ); void Copy( CPolyLine * src ); - BOOL TestPointInside( int x, int y ); - BOOL TestPointInsideContour( int icont, int x, int y ); + bool TestPointInside( int x, int y ); + bool TestPointInsideContour( int icont, int x, int y ); + bool IsCutoutContour( int icont ); int TestIntersection( CPolyLine * poly ); void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ); @@ -124,30 +125,25 @@ public: 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 GetHatchStyle(){ 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 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 * arc_array=NULL ); int FreeGpcPoly(); gpc_polygon * GetGpcPoly(){ return m_gpc_poly; }; - int NormalizeWithGpc( std::vector * pa=NULL, BOOL bRetainArcs=FALSE ); + int NormalizeWithGpc( std::vector * pa=NULL, bool bRetainArcs=FALSE ); int RestoreArcs( std::vector * arc_array, std::vector * 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 ); + int hole_w, int hole_clearance, bool bThermal=FALSE, int spoke_w=0 ); void ClipGpcPolygon( gpc_op op, CPolyLine * poly ); // PHP functions @@ -174,7 +170,7 @@ public: private: gpc_polygon * m_gpc_poly; // polygon in gpc format polygon * m_php_poly; - BOOL bDrawn; + bool bDrawn; }; #endif // #ifndef POLYLINE_H diff --git a/polygon/PolyLine2Kicad.h b/polygon/PolyLine2Kicad.h index 8c19f2157b..9e7119378a 100644 --- a/polygon/PolyLine2Kicad.h +++ b/polygon/PolyLine2Kicad.h @@ -31,31 +31,6 @@ enum 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 diff --git a/polygon/cdisplaylist_stuff.cpp b/polygon/cdisplaylist_stuff.cpp index e87435be9f..55595cada9 100644 --- a/polygon/cdisplaylist_stuff.cpp +++ b/polygon/cdisplaylist_stuff.cpp @@ -2,25 +2,10 @@ #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; @@ -31,10 +16,6 @@ int CDisplayList::CancelHighLight() return 0; } -void CDisplayList::Set_id( dl_element * el, id * id ) -{ -} - id CDisplayList::Remove( dl_element * element ) { return 0; @@ -83,3 +64,4 @@ int CDisplayList::StartDraggingArc( CDC * pDC, int style, int x, int y, int xi, { return 0; } + diff --git a/polygon/php_polygon.cpp b/polygon/php_polygon.cpp index af4b36eeea..528c98ce3d 100644 --- a/polygon/php_polygon.cpp +++ b/polygon/php_polygon.cpp @@ -656,10 +656,15 @@ BOOL polygon::isInside( vertex * v ) int winding_number3 = 0; int winding_number4 = 0; //** vertex * point_at_infinity = new vertex(-10000000,v->Y()); // Create point at infinity - vertex * point_at_infinity = new vertex(-1000000000,-50000000); // Create point at infinity +/* vertex * point_at_infinity = new vertex(-1000000000,-50000000); // Create point at infinity vertex * point_at_infinity2 = new vertex(1000000000,+50000000); // Create point at infinity vertex * point_at_infinity3 = new vertex(500000000,1000000000); // Create point at infinity vertex * point_at_infinity4 = new vertex(-500000000,1000000000); // Create point at infinity +*/ + vertex point_at_infinity(-1000000000,-50000000); // Create point at infinity + vertex point_at_infinity2(1000000000,+50000000); // Create point at infinity + vertex point_at_infinity3(500000000,1000000000); // Create point at infinity + vertex point_at_infinity4(-500000000,1000000000); // Create point at infinity vertex * q = m_first; // End vertex of a line segment in polygon do { @@ -667,20 +672,20 @@ BOOL polygon::isInside( vertex * v ) { int n; double x[2], y[2], aP[2], aQ[2]; - if( ints( point_at_infinity, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) + if( ints( &point_at_infinity, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) winding_number += n; // Add number of intersections found - if( ints( point_at_infinity2, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) + if( ints( &point_at_infinity2, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) winding_number2 += n; // Add number of intersections found - if( ints( point_at_infinity3, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) + if( ints( &point_at_infinity3, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) winding_number3 += n; // Add number of intersections found - if( ints( point_at_infinity4, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) + if( ints( &point_at_infinity4, v, q, nxt(q->Next()), &n, x, y, aP, aQ ) ) winding_number4 += n; // Add number of intersections found } q = q->Next(); } while( q->id() != m_first->id() ); - delete point_at_infinity; - delete point_at_infinity2; +// delete point_at_infinity; +// delete point_at_infinity2; if( winding_number%2 != winding_number2%2 || winding_number3%2 != winding_number4%2 || winding_number%2 != winding_number3%2 )