diff --git a/bitmaps/Add_Zone_Cutout.xpm b/bitmaps/Add_Zone_Cutout.xpm index 171878213c..d106f039b4 100644 --- a/bitmaps/Add_Zone_Cutout.xpm +++ b/bitmaps/Add_Zone_Cutout.xpm @@ -11,12 +11,12 @@ const char * add_zone_cutout[] = { " ..............", ".... ........", "... ++++ .......", -".. + + .....", -". + + ...", -". + + ..", -". + + ..", -". + + .", -".. + + ..", +".. +++++++ .....", +". ++ ++ ...", +". ++ ++ ..", +". ++ ++ ..", +". ++ ++ .", +".. ++++++++++ ..", "... +++++++ ... ", ".... .... ", "............ ", diff --git a/change_log.txt b/change_log.txt index 2a497955d5..efe4ec7afe 100644 --- a/change_log.txt +++ b/change_log.txt @@ -4,6 +4,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +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 + + 2008-jan-01 UPDATE Jean-Pierre Charras ================================================================================ +all diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 8fe30bd10e..0d9bfcbbfd 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -529,6 +529,24 @@ public: */ 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_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 @@ -548,6 +566,13 @@ public: */ void End_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container ); + /** + * 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 ); + // Target handling MIREPCB* Create_Mire( wxDC* DC ); void Delete_Mire( MIREPCB* MirePcb, wxDC* DC ); diff --git a/internat/fr/kicad.mo b/internat/fr/kicad.mo index 9fb260b2d3..23fa1270cb 100644 Binary files a/internat/fr/kicad.mo and b/internat/fr/kicad.mo differ diff --git a/internat/fr/kicad.po b/internat/fr/kicad.po index 46fffa6354..c50d3ca0a5 100644 --- a/internat/fr/kicad.po +++ b/internat/fr/kicad.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: kicad\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2007-12-30 19:07+0100\n" +"PO-Revision-Date: 2008-01-01 17:55+0100\n" "Last-Translator: \n" "Language-Team: kicad team \n" "MIME-Version: 1.0\n" @@ -560,8 +560,8 @@ msgstr "OK" #: pcbnew/muonde.cpp:352 #: pcbnew/modedit_onclick.cpp:203 #: pcbnew/modedit_onclick.cpp:235 -#: pcbnew/onrightclick.cpp:146 -#: pcbnew/onrightclick.cpp:160 +#: pcbnew/onrightclick.cpp:145 +#: pcbnew/onrightclick.cpp:159 #: pcbnew/block.cpp:157 #: pcbnew/globaleditpad.cpp:108 #: pcbnew/cotation.cpp:109 @@ -834,7 +834,7 @@ msgstr "Sauver pr #: pcbnew/dialog_setup_libs.cpp:97 #: eeschema/dialog_eeschema_config.cpp:105 -#: cvpcb/dialog_cvpcb_config.cpp:76 +#: cvpcb/dialog_cvpcb_config.cpp:77 #: gerbview/reglage.cpp:90 msgid "from " msgstr "De " @@ -1257,7 +1257,7 @@ msgstr "Echelle" #: pcbnew/dialog_display_options.cpp:221 #: pcbnew/dialog_display_options.cpp:229 #: pcbnew/dialog_display_options.cpp:266 -#: pcbnew/class_board_item.cpp:99 +#: pcbnew/class_board_item.cpp:98 #: pcbnew/dialog_zones_by_polygon.cpp:167 #: gerbview/options.cpp:321 msgid "Line" @@ -1331,7 +1331,7 @@ msgid "Ref." msgstr "Ref." #: pcbnew/class_text_mod.cpp:345 -#: pcbnew/class_board_item.cpp:80 +#: pcbnew/class_board_item.cpp:79 #: pcbnew/class_edge_mod.cpp:286 #: eeschema/component_class.cpp:55 #: eeschema/edit_component_in_schematic.cpp:784 @@ -1341,7 +1341,7 @@ msgstr "Valeur" #: pcbnew/class_text_mod.cpp:345 #: pcbnew/class_text_mod.cpp:353 -#: pcbnew/class_board_item.cpp:85 +#: pcbnew/class_board_item.cpp:84 msgid "Text" msgstr "Texte" @@ -1629,11 +1629,11 @@ msgstr "Hauteur Texte Module" msgid "Text Module Size H" msgstr "Largeur Texte Module" -#: pcbnew/zone_filling_algorithm.cpp:158 +#: pcbnew/zone_filling_algorithm.cpp:156 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:196 +#: pcbnew/zone_filling_algorithm.cpp:194 msgid "Ok" msgstr "Ok" @@ -1706,7 +1706,7 @@ msgid "Print Module" msgstr "Imprimer Module" #: pcbnew/tool_modedit.cpp:115 -#: pcbnew/tool_pcb.cpp:270 +#: pcbnew/tool_pcb.cpp:269 #: eeschema/tool_sch.cpp:108 #: eeschema/tool_lib.cpp:170 #: gerbview/tool_gerber.cpp:271 @@ -1714,7 +1714,7 @@ msgid "zoom +" msgstr "zoom +" #: pcbnew/tool_modedit.cpp:119 -#: pcbnew/tool_pcb.cpp:274 +#: pcbnew/tool_pcb.cpp:273 #: eeschema/tool_sch.cpp:112 #: eeschema/tool_lib.cpp:174 #: gerbview/tool_gerber.cpp:278 @@ -1722,7 +1722,7 @@ msgid "zoom -" msgstr "zoom -" #: pcbnew/tool_modedit.cpp:123 -#: pcbnew/tool_pcb.cpp:278 +#: pcbnew/tool_pcb.cpp:277 #: eeschema/tool_sch.cpp:116 #: eeschema/tool_lib.cpp:178 #: gerbview/tool_gerber.cpp:285 @@ -1730,7 +1730,7 @@ msgid "redraw" msgstr "Redessin" #: pcbnew/tool_modedit.cpp:128 -#: pcbnew/tool_pcb.cpp:283 +#: pcbnew/tool_pcb.cpp:282 #: eeschema/tool_sch.cpp:121 #: eeschema/tool_lib.cpp:184 #: gerbview/tool_gerber.cpp:296 @@ -1754,18 +1754,18 @@ msgid "Add Pads" msgstr "Addition de \"pins\"" #: pcbnew/tool_modedit.cpp:168 -#: pcbnew/tool_pcb.cpp:434 +#: pcbnew/tool_pcb.cpp:433 #: eeschema/tool_sch.cpp:226 msgid "Add graphic line or polygon" msgstr "Addition de lignes ou polygones graphiques" #: pcbnew/tool_modedit.cpp:172 -#: pcbnew/tool_pcb.cpp:438 +#: pcbnew/tool_pcb.cpp:437 msgid "Add graphic circle" msgstr "Addition de graphiques (Cercle)" #: pcbnew/tool_modedit.cpp:176 -#: pcbnew/tool_pcb.cpp:442 +#: pcbnew/tool_pcb.cpp:441 msgid "Add graphic arc" msgstr "Addition de graphiques (Arc de Cercle)" @@ -1783,7 +1783,7 @@ msgid "Place anchor" msgstr "Place Ancre" #: pcbnew/tool_modedit.cpp:190 -#: pcbnew/tool_pcb.cpp:460 +#: pcbnew/tool_pcb.cpp:459 #: eeschema/tool_sch.cpp:235 #: eeschema/tool_lib.cpp:93 #: gerbview/tool_gerber.cpp:393 @@ -1791,41 +1791,41 @@ msgid "Delete items" msgstr "Suppression d'éléments" #: pcbnew/tool_modedit.cpp:212 -#: pcbnew/tool_pcb.cpp:334 +#: pcbnew/tool_pcb.cpp:333 #: eeschema/tool_sch.cpp:257 #: gerbview/tool_gerber.cpp:417 msgid "Display Grid OFF" msgstr "Suppression de l'affichage de la grille" #: pcbnew/tool_modedit.cpp:216 -#: pcbnew/tool_pcb.cpp:337 +#: pcbnew/tool_pcb.cpp:336 #: gerbview/tool_gerber.cpp:423 msgid "Display Polar Coord ON" msgstr "Activer affichage coord Polaires" #: pcbnew/tool_modedit.cpp:220 -#: pcbnew/tool_pcb.cpp:339 +#: pcbnew/tool_pcb.cpp:338 #: eeschema/tool_sch.cpp:261 #: gerbview/tool_gerber.cpp:427 msgid "Units = Inch" msgstr "Unités = pouce" #: pcbnew/tool_modedit.cpp:224 -#: pcbnew/tool_pcb.cpp:341 +#: pcbnew/tool_pcb.cpp:340 #: eeschema/tool_sch.cpp:265 #: gerbview/tool_gerber.cpp:431 msgid "Units = mm" msgstr "Unités = mm" #: pcbnew/tool_modedit.cpp:230 -#: pcbnew/tool_pcb.cpp:344 +#: pcbnew/tool_pcb.cpp:343 #: eeschema/tool_sch.cpp:269 #: gerbview/tool_gerber.cpp:437 msgid "Change Cursor Shape" msgstr "Sélection de la forme du curseur" #: pcbnew/tool_modedit.cpp:238 -#: pcbnew/tool_pcb.cpp:366 +#: pcbnew/tool_pcb.cpp:365 msgid "Show Pads Sketch" msgstr "Afficher pastilles en contour" @@ -1838,7 +1838,7 @@ msgid "Show Edges Sketch" msgstr "Afficher Modules en contour" #: pcbnew/tool_modedit.cpp:285 -#: pcbnew/tool_pcb.cpp:567 +#: pcbnew/tool_pcb.cpp:566 #: eeschema/plotps.cpp:169 #: share/zoom.cpp:367 msgid "Auto" @@ -1860,7 +1860,7 @@ msgid "Grid %.3f" msgstr "Grille %.3f" #: pcbnew/tool_modedit.cpp:314 -#: pcbnew/tool_pcb.cpp:601 +#: pcbnew/tool_pcb.cpp:600 msgid "User Grid" msgstr "Grille perso" @@ -1888,7 +1888,7 @@ msgid "Error: Unexpected end of file !" msgstr "Erreur: Fin de fichier inattendue !" #: pcbnew/dialog_netlist.cpp:135 -#: pcbnew/class_board_item.cpp:76 +#: pcbnew/class_board_item.cpp:75 #: eeschema/onrightclick.cpp:320 #: eeschema/dialog_create_component.cpp:164 #: eeschema/edit_component_in_schematic.cpp:745 @@ -1910,9 +1910,9 @@ msgid "Keep" msgstr "Garder" #: pcbnew/dialog_netlist.cpp:143 -#: pcbnew/onrightclick.cpp:623 -#: pcbnew/onrightclick.cpp:733 -#: pcbnew/onrightclick.cpp:830 +#: pcbnew/onrightclick.cpp:589 +#: pcbnew/onrightclick.cpp:749 +#: pcbnew/onrightclick.cpp:846 #: eeschema/edit_component_in_lib.cpp:239 #: eeschema/edit_component_in_lib.cpp:320 msgid "Delete" @@ -2086,14 +2086,14 @@ msgid "Add Drawing" msgstr "Ajout d'éléments graphiques" #: pcbnew/modedit.cpp:424 -#: pcbnew/edit.cpp:526 +#: pcbnew/edit.cpp:536 #: eeschema/schedit.cpp:455 #: eeschema/libframe.cpp:579 msgid "Delete item" msgstr "Suppression d'éléments" #: pcbnew/modedit_onclick.cpp:207 -#: pcbnew/onrightclick.cpp:151 +#: pcbnew/onrightclick.cpp:150 #: eeschema/onrightclick.cpp:126 #: eeschema/libedit_onrightclick.cpp:53 #: gerbview/onrightclick.cpp:42 @@ -2101,7 +2101,7 @@ msgid "End Tool" msgstr "Fin Outil" #: pcbnew/modedit_onclick.cpp:217 -#: pcbnew/onrightclick.cpp:504 +#: pcbnew/onrightclick.cpp:469 #: eeschema/onrightclick.cpp:587 #: eeschema/libedit_onrightclick.cpp:237 #: gerbview/onrightclick.cpp:51 @@ -2109,13 +2109,13 @@ msgid "Cancel Block" msgstr "Annuler Bloc" #: pcbnew/modedit_onclick.cpp:219 -#: pcbnew/onrightclick.cpp:506 +#: pcbnew/onrightclick.cpp:471 #: gerbview/onrightclick.cpp:52 msgid "Zoom Block (Midd butt drag)" msgstr "Zoom Bloc (drag+bouton milieu)" #: pcbnew/modedit_onclick.cpp:222 -#: pcbnew/onrightclick.cpp:509 +#: pcbnew/onrightclick.cpp:474 #: eeschema/onrightclick.cpp:595 #: eeschema/libedit_onrightclick.cpp:245 #: gerbview/onrightclick.cpp:54 @@ -2123,7 +2123,7 @@ msgid "Place Block" msgstr "Place Bloc" #: pcbnew/modedit_onclick.cpp:224 -#: pcbnew/onrightclick.cpp:511 +#: pcbnew/onrightclick.cpp:476 #: eeschema/onrightclick.cpp:604 #: eeschema/libedit_onrightclick.cpp:251 msgid "Copy Block (shift + drag mouse)" @@ -2134,18 +2134,18 @@ msgid "Mirror Block (alt + drag mouse)" msgstr "Bloc Miroir (alt + drag mouse)" #: pcbnew/modedit_onclick.cpp:228 -#: pcbnew/onrightclick.cpp:515 +#: pcbnew/onrightclick.cpp:480 msgid "Rotate Block (ctrl + drag mouse)" msgstr "Rotation Bloc (ctrl + drag mouse)" #: pcbnew/modedit_onclick.cpp:230 -#: pcbnew/onrightclick.cpp:517 +#: pcbnew/onrightclick.cpp:482 msgid "Delete Block (shift+ctrl + drag mouse)" msgstr "Effacement Bloc (shift+ctrl + drag mouse)" #: pcbnew/modedit_onclick.cpp:252 -#: pcbnew/onrightclick.cpp:727 -#: pcbnew/onrightclick.cpp:824 +#: pcbnew/onrightclick.cpp:743 +#: pcbnew/onrightclick.cpp:840 msgid "Rotate" msgstr "Rotation" @@ -2170,17 +2170,17 @@ msgid "Move Pad" msgstr "Déplace Pad" #: pcbnew/modedit_onclick.cpp:274 -#: pcbnew/onrightclick.cpp:766 +#: pcbnew/onrightclick.cpp:782 msgid "Edit Pad" msgstr "Edit Pad" #: pcbnew/modedit_onclick.cpp:276 -#: pcbnew/onrightclick.cpp:770 +#: pcbnew/onrightclick.cpp:786 msgid "New Pad Settings" msgstr "Nouvelles Caract. Pads" #: pcbnew/modedit_onclick.cpp:278 -#: pcbnew/onrightclick.cpp:772 +#: pcbnew/onrightclick.cpp:788 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:777 +#: pcbnew/onrightclick.cpp:793 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:695 -#: pcbnew/onrightclick.cpp:729 -#: pcbnew/onrightclick.cpp:826 +#: pcbnew/onrightclick.cpp:711 +#: pcbnew/onrightclick.cpp:745 +#: pcbnew/onrightclick.cpp:842 #: eeschema/onrightclick.cpp:313 msgid "Edit" msgstr "Editer" @@ -2263,7 +2263,7 @@ msgid "RefP" msgstr "RefP" #: pcbnew/class_pad.cpp:979 -#: pcbnew/class_board_item.cpp:36 +#: pcbnew/class_board_item.cpp:35 msgid "Net" msgstr "Net" @@ -2284,7 +2284,7 @@ msgid "Shape" msgstr "Forme" #: pcbnew/classpcb.cpp:199 -#: pcbnew/class_board_item.cpp:108 +#: pcbnew/class_board_item.cpp:107 #: pcbnew/class_track.cpp:776 #: pcbnew/dialog_pad_edit.cpp:176 #: pcbnew/dialog_pad_edit.cpp:196 @@ -2565,7 +2565,7 @@ msgid "Footprint name:" msgstr "Nom Module: " #: pcbnew/modules.cpp:281 -#: pcbnew/onrightclick.cpp:701 +#: pcbnew/onrightclick.cpp:717 msgid "Delete Module" msgstr "Supprimer Module" @@ -2874,385 +2874,394 @@ msgstr "&Divers" msgid "P&ostprocess" msgstr "P&ostprocesseurs" -#: pcbnew/onrightclick.cpp:83 +#: pcbnew/onrightclick.cpp:82 #, c-format msgid "Track %.1f" msgstr "Piste %.1f" -#: pcbnew/onrightclick.cpp:85 +#: pcbnew/onrightclick.cpp:84 #, c-format msgid "Track %.3f" msgstr "Piste %.3f" -#: pcbnew/onrightclick.cpp:101 +#: pcbnew/onrightclick.cpp:100 #, c-format msgid "Via %.1f" msgstr "Via %.1f" -#: pcbnew/onrightclick.cpp:103 +#: pcbnew/onrightclick.cpp:102 #, c-format msgid "Via %.3f" msgstr "Via %.3f" -#: pcbnew/onrightclick.cpp:219 +#: pcbnew/onrightclick.cpp:218 msgid "Lock Module" msgstr "Verrouiller Modules" -#: pcbnew/onrightclick.cpp:227 +#: pcbnew/onrightclick.cpp:226 msgid "Unlock Module" msgstr "Déverrouiller Modules" -#: pcbnew/onrightclick.cpp:235 +#: pcbnew/onrightclick.cpp:234 msgid "Auto place Module" msgstr "Auto place Module" -#: pcbnew/onrightclick.cpp:241 +#: pcbnew/onrightclick.cpp:240 msgid "Autoroute" msgstr "Autoroute" -#: pcbnew/onrightclick.cpp:257 +#: pcbnew/onrightclick.cpp:256 msgid "Move Drawing" msgstr "Déplace Tracé" -#: pcbnew/onrightclick.cpp:262 +#: pcbnew/onrightclick.cpp:261 msgid "End Drawing" msgstr "Fin tracé" -#: pcbnew/onrightclick.cpp:264 +#: pcbnew/onrightclick.cpp:263 msgid "Edit Drawing" msgstr "Edit Tracé" -#: pcbnew/onrightclick.cpp:265 +#: pcbnew/onrightclick.cpp:264 msgid "Delete Drawing" msgstr "Supprimer Tracé" -#: pcbnew/onrightclick.cpp:272 -msgid "End edge zone" -msgstr "Fin contour Zone" - -#: pcbnew/onrightclick.cpp:275 -msgid "Delete edge zone" -msgstr "Supprimer Contour Zone" - -#: pcbnew/onrightclick.cpp:284 -msgid "Place Corner" -msgstr "Place Sommet" - -#: pcbnew/onrightclick.cpp:294 -msgid "Move Corner" -msgstr "Déplace Sommet" - -#: pcbnew/onrightclick.cpp:296 -msgid "Delete Corner" -msgstr "Supprimer Sommet" - -#: pcbnew/onrightclick.cpp:302 -msgid "Create Corner" -msgstr "Créer Sommet" - -#: pcbnew/onrightclick.cpp:306 -msgid "Fill zone" -msgstr "Remplir zone" - -#: pcbnew/onrightclick.cpp:309 -msgid "Edit Zone Params" -msgstr "Editer Paramètres de la Zone" - -#: pcbnew/onrightclick.cpp:311 -msgid "Delete Zone Outline" -msgstr "Supprimer Contour de Zone" - -#: pcbnew/onrightclick.cpp:328 +#: pcbnew/onrightclick.cpp:269 msgid "Delete Zone" msgstr "Supprimer Zone" -#: pcbnew/onrightclick.cpp:333 +#: pcbnew/onrightclick.cpp:276 +msgid "End edge zone" +msgstr "Fin contour Zone" + +#: pcbnew/onrightclick.cpp:279 +msgid "Delete edge zone" +msgstr "Supprimer Contour Zone" + +#: pcbnew/onrightclick.cpp:298 msgid "Delete Marker" msgstr "Effacer Marqueur" -#: pcbnew/onrightclick.cpp:340 +#: pcbnew/onrightclick.cpp:305 msgid "Edit Dimension" msgstr "Edit Cote" -#: pcbnew/onrightclick.cpp:343 +#: pcbnew/onrightclick.cpp:308 msgid "Delete Dimension" msgstr "Suppression Cote" -#: pcbnew/onrightclick.cpp:350 +#: pcbnew/onrightclick.cpp:315 msgid "Move Target" msgstr "Déplacer Mire" -#: pcbnew/onrightclick.cpp:353 +#: pcbnew/onrightclick.cpp:318 msgid "Edit Target" msgstr "Editer Mire" -#: pcbnew/onrightclick.cpp:355 +#: pcbnew/onrightclick.cpp:320 msgid "Delete Target" msgstr "Supprimer Mire" -#: pcbnew/onrightclick.cpp:382 +#: pcbnew/onrightclick.cpp:347 msgid "Get and Move Footprint" msgstr "Sel et Dépl.t module" -#: pcbnew/onrightclick.cpp:396 +#: pcbnew/onrightclick.cpp:361 msgid "Fill or Refill All Zones" msgstr "Remplir ou Re-remplir Toutes les Zones" -#: pcbnew/onrightclick.cpp:401 -#: pcbnew/onrightclick.cpp:412 -#: pcbnew/onrightclick.cpp:425 -#: pcbnew/onrightclick.cpp:486 +#: pcbnew/onrightclick.cpp:366 +#: pcbnew/onrightclick.cpp:377 +#: pcbnew/onrightclick.cpp:390 +#: pcbnew/onrightclick.cpp:451 msgid "Select Working Layer" msgstr "Sélection de la couche de travail" -#: pcbnew/onrightclick.cpp:410 -#: pcbnew/onrightclick.cpp:483 +#: pcbnew/onrightclick.cpp:375 +#: pcbnew/onrightclick.cpp:448 msgid "Select Track Width" msgstr "Sélection Epais. Piste" -#: pcbnew/onrightclick.cpp:414 +#: pcbnew/onrightclick.cpp:379 msgid "Select layer pair for vias" msgstr "Selection couple de couches pour Vias" -#: pcbnew/onrightclick.cpp:431 +#: pcbnew/onrightclick.cpp:396 msgid "Footprint documentation" msgstr "Documentation des modules" -#: pcbnew/onrightclick.cpp:441 +#: pcbnew/onrightclick.cpp:406 msgid "Glob Move and Place" msgstr "Move et Place Globaux" -#: pcbnew/onrightclick.cpp:443 +#: pcbnew/onrightclick.cpp:408 msgid "Unlock All Modules" msgstr "Déverrouiller tous les Modules" -#: pcbnew/onrightclick.cpp:445 +#: pcbnew/onrightclick.cpp:410 msgid "Lock All Modules" msgstr "Verrouiller tous les Modules" -#: pcbnew/onrightclick.cpp:448 +#: pcbnew/onrightclick.cpp:413 msgid "Move All Modules" msgstr "Déplace tous les Modules" -#: pcbnew/onrightclick.cpp:449 +#: pcbnew/onrightclick.cpp:414 msgid "Move New Modules" msgstr "Déplace nouveaux Modules" -#: pcbnew/onrightclick.cpp:451 +#: pcbnew/onrightclick.cpp:416 msgid "Autoplace All Modules" msgstr "Autoplace Tous Modules" -#: pcbnew/onrightclick.cpp:452 +#: pcbnew/onrightclick.cpp:417 msgid "Autoplace New Modules" msgstr "AutoPlace nouveaux Modules" -#: pcbnew/onrightclick.cpp:453 +#: pcbnew/onrightclick.cpp:418 msgid "Autoplace Next Module" msgstr "Autoplace Module suivant" -#: pcbnew/onrightclick.cpp:456 +#: pcbnew/onrightclick.cpp:421 msgid "Orient All Modules" msgstr "Oriente Tous Modules" -#: pcbnew/onrightclick.cpp:463 +#: pcbnew/onrightclick.cpp:428 msgid "Global Autoroute" msgstr "Autoroutage global" -#: pcbnew/onrightclick.cpp:465 +#: pcbnew/onrightclick.cpp:430 msgid "Select layer pair" msgstr "Selection couple de couches" -#: pcbnew/onrightclick.cpp:467 +#: pcbnew/onrightclick.cpp:432 msgid "Autoroute All Modules" msgstr "Autoroute Tous Modules" -#: pcbnew/onrightclick.cpp:469 +#: pcbnew/onrightclick.cpp:434 msgid "Reset Unrouted" msgstr "Réinit Non routés" -#: pcbnew/onrightclick.cpp:474 +#: pcbnew/onrightclick.cpp:439 msgid "Global AutoRouter" msgstr "Autorouteur Global" -#: pcbnew/onrightclick.cpp:476 +#: pcbnew/onrightclick.cpp:441 msgid "Read Global AutoRouter Data" msgstr "Lire Données de L'autorouteur global" -#: pcbnew/onrightclick.cpp:513 +#: pcbnew/onrightclick.cpp:478 msgid "Flip Block (alt + drag mouse)" msgstr "Inversion Bloc (alt + drag mouse)" -#: pcbnew/onrightclick.cpp:536 +#: pcbnew/onrightclick.cpp:501 msgid "Drag Via" msgstr "Drag Via" -#: pcbnew/onrightclick.cpp:540 -#: pcbnew/onrightclick.cpp:604 +#: pcbnew/onrightclick.cpp:505 +#: pcbnew/onrightclick.cpp:569 msgid "Edit Via" msgstr "Edit Via" -#: pcbnew/onrightclick.cpp:542 +#: pcbnew/onrightclick.cpp:507 msgid "Set via hole to Default" msgstr "Ajuste perçage via à défaut" -#: pcbnew/onrightclick.cpp:544 +#: pcbnew/onrightclick.cpp:509 msgid "Set via hole to alt value" msgstr "Ajuste perçage via à valeur alternative" -#: pcbnew/onrightclick.cpp:546 +#: pcbnew/onrightclick.cpp:511 msgid "Set the via hole alt value" msgstr "Ajuste la valeur alt. perçage via" -#: pcbnew/onrightclick.cpp:548 +#: pcbnew/onrightclick.cpp:513 msgid "Export Via hole to alt value" msgstr "Exporte perçage via à valeur alt." -#: pcbnew/onrightclick.cpp:550 +#: pcbnew/onrightclick.cpp:515 msgid "Export via hole to others id vias" msgstr "Exporte perçage via aux autres semblables." -#: pcbnew/onrightclick.cpp:552 +#: pcbnew/onrightclick.cpp:517 msgid "Set ALL via holes to default" msgstr "Ajuste perçage TOUTES vias au défaut" -#: pcbnew/onrightclick.cpp:565 +#: pcbnew/onrightclick.cpp:530 msgid "Move Node" msgstr "Déplace Noeud" -#: pcbnew/onrightclick.cpp:570 +#: pcbnew/onrightclick.cpp:535 msgid "Drag Segments, keep slope" msgstr "Drag Segments, garder direction" -#: pcbnew/onrightclick.cpp:572 +#: pcbnew/onrightclick.cpp:537 msgid "Drag Segment" msgstr "Drag Segment" -#: pcbnew/onrightclick.cpp:575 +#: pcbnew/onrightclick.cpp:540 msgid "Move Segment" msgstr "Déplace Segment" -#: pcbnew/onrightclick.cpp:578 +#: pcbnew/onrightclick.cpp:543 msgid "Break Track" msgstr "Briser piste" -#: pcbnew/onrightclick.cpp:585 +#: pcbnew/onrightclick.cpp:550 msgid "Place Node" msgstr "Place noeud" -#: pcbnew/onrightclick.cpp:592 +#: pcbnew/onrightclick.cpp:557 msgid "End Track" msgstr "Terminer Piste" -#: pcbnew/onrightclick.cpp:595 +#: pcbnew/onrightclick.cpp:560 msgid "Place Via" msgstr "Place Via" -#: pcbnew/onrightclick.cpp:602 +#: pcbnew/onrightclick.cpp:567 msgid "Change Width" msgstr "Change Largeur" -#: pcbnew/onrightclick.cpp:604 +#: pcbnew/onrightclick.cpp:570 msgid "Edit Segment" msgstr "Edit Segment" -#: pcbnew/onrightclick.cpp:609 +#: pcbnew/onrightclick.cpp:575 msgid "Edit Track" msgstr "Editer Piste" -#: pcbnew/onrightclick.cpp:611 +#: pcbnew/onrightclick.cpp:577 msgid "Edit Net" msgstr "Edit Net" -#: pcbnew/onrightclick.cpp:613 +#: pcbnew/onrightclick.cpp:579 msgid "Edit ALL Tracks and Vias" msgstr "Editer TOUTES Pistes et Vias" -#: pcbnew/onrightclick.cpp:615 +#: pcbnew/onrightclick.cpp:581 msgid "Edit ALL Vias (no track)" msgstr "Editer TOUTES Vias (pas les pistes)" -#: pcbnew/onrightclick.cpp:617 +#: pcbnew/onrightclick.cpp:583 msgid "Edit ALL Tracks (no via)" msgstr "Editer TOUTES Pistes (pas les vias)" -#: pcbnew/onrightclick.cpp:625 +#: pcbnew/onrightclick.cpp:591 msgid "Delete Via" msgstr "Suppression Via" -#: pcbnew/onrightclick.cpp:625 +#: pcbnew/onrightclick.cpp:591 msgid "Delete Segment" msgstr "SupprimerSegment" -#: pcbnew/onrightclick.cpp:632 +#: pcbnew/onrightclick.cpp:598 msgid "Delete Track" msgstr "Effacer Piste" -#: pcbnew/onrightclick.cpp:636 +#: pcbnew/onrightclick.cpp:602 msgid "Delete Net" msgstr "Supprimer Net" -#: pcbnew/onrightclick.cpp:641 +#: pcbnew/onrightclick.cpp:607 msgid "Set Flags" msgstr "Ajust. Flags" -#: pcbnew/onrightclick.cpp:642 +#: pcbnew/onrightclick.cpp:608 msgid "Locked: Yes" msgstr "Verrou: Oui" -#: pcbnew/onrightclick.cpp:643 +#: pcbnew/onrightclick.cpp:609 msgid "Locked: No" msgstr "Verrou: Non" -#: pcbnew/onrightclick.cpp:653 +#: pcbnew/onrightclick.cpp:619 msgid "Track Locked: Yes" msgstr "Piste verrouillée: Oui" -#: pcbnew/onrightclick.cpp:654 +#: pcbnew/onrightclick.cpp:620 msgid "Track Locked: No" msgstr "Piste verrouillée: Non" -#: pcbnew/onrightclick.cpp:656 +#: pcbnew/onrightclick.cpp:622 msgid "Net Locked: Yes" msgstr "Net verrouillé: Oui" -#: pcbnew/onrightclick.cpp:657 +#: pcbnew/onrightclick.cpp:623 msgid "Net Locked: No" msgstr "Net verrouillé: Non" -#: pcbnew/onrightclick.cpp:679 -#: pcbnew/onrightclick.cpp:724 -#: pcbnew/onrightclick.cpp:762 -#: pcbnew/onrightclick.cpp:821 +#: pcbnew/onrightclick.cpp:638 +msgid "Place Corner" +msgstr "Place Sommet" + +#: pcbnew/onrightclick.cpp:648 +msgid "Move Corner" +msgstr "Déplace Sommet" + +#: pcbnew/onrightclick.cpp:650 +msgid "Delete Corner" +msgstr "Supprimer Sommet" + +#: pcbnew/onrightclick.cpp:656 +msgid "Create Corner" +msgstr "Créer Sommet" + +#: pcbnew/onrightclick.cpp:661 +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" + +#: pcbnew/onrightclick.cpp:668 +msgid "Fill Zone" +msgstr "Remplir Zone" + +#: pcbnew/onrightclick.cpp:671 +msgid "Edit Zone Params" +msgstr "Editer Paramètres de la Zone" + +#: pcbnew/onrightclick.cpp:673 +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 msgid "Move" msgstr "Move" -#: pcbnew/onrightclick.cpp:682 -#: pcbnew/onrightclick.cpp:764 +#: pcbnew/onrightclick.cpp:698 +#: pcbnew/onrightclick.cpp:780 msgid "Drag" msgstr "Drag" -#: pcbnew/onrightclick.cpp:686 +#: pcbnew/onrightclick.cpp:702 msgid "Rotate +" msgstr "Rotation +" -#: pcbnew/onrightclick.cpp:690 +#: pcbnew/onrightclick.cpp:706 #: eeschema/onrightclick.cpp:301 msgid "Rotate -" msgstr "Rotation -" -#: pcbnew/onrightclick.cpp:691 +#: pcbnew/onrightclick.cpp:707 msgid "Flip" msgstr "Change côté" -#: pcbnew/onrightclick.cpp:781 +#: pcbnew/onrightclick.cpp:797 msgid "delete" msgstr "Effacer" -#: pcbnew/onrightclick.cpp:788 +#: pcbnew/onrightclick.cpp:804 msgid "Autoroute Pad" msgstr "Autoroute Pad" -#: pcbnew/onrightclick.cpp:789 +#: pcbnew/onrightclick.cpp:805 msgid "Autoroute Net" msgstr "Autoroute Net" @@ -3565,131 +3574,131 @@ msgstr "Le texte est la REFERENCE!" msgid "Text is VALUE!" msgstr "Le texte est la VALEUR!" -#: pcbnew/class_board_item.cpp:41 +#: pcbnew/class_board_item.cpp:40 #: eeschema/dialog_build_BOM.cpp:300 #: eeschema/component_class.cpp:56 #: eeschema/edit_component_in_schematic.cpp:826 msgid "Footprint" msgstr "Module" -#: pcbnew/class_board_item.cpp:47 +#: pcbnew/class_board_item.cpp:46 msgid "Pad" msgstr "Pad" -#: pcbnew/class_board_item.cpp:50 +#: pcbnew/class_board_item.cpp:49 msgid "all copper layers" msgstr "Toutes Couches Cuivre" -#: pcbnew/class_board_item.cpp:52 +#: pcbnew/class_board_item.cpp:51 msgid "copper layer" msgstr "Couche Cuivre" -#: pcbnew/class_board_item.cpp:54 +#: pcbnew/class_board_item.cpp:53 msgid "cmp layer" msgstr "Couche Cmp" -#: pcbnew/class_board_item.cpp:55 +#: pcbnew/class_board_item.cpp:54 msgid "???" msgstr "???" -#: pcbnew/class_board_item.cpp:56 +#: pcbnew/class_board_item.cpp:55 msgid ") of " msgstr ") de " -#: pcbnew/class_board_item.cpp:60 +#: pcbnew/class_board_item.cpp:59 msgid "Pcb Graphic" msgstr "Pcb Graphic" -#: pcbnew/class_board_item.cpp:60 -#: pcbnew/class_board_item.cpp:69 -#: pcbnew/class_board_item.cpp:146 -#: pcbnew/class_board_item.cpp:165 -#: pcbnew/class_board_item.cpp:181 -#: pcbnew/class_board_item.cpp:208 -#: pcbnew/class_board_item.cpp:225 -#: pcbnew/class_board_item.cpp:231 +#: 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 msgid " on " msgstr " sur " -#: pcbnew/class_board_item.cpp:64 +#: pcbnew/class_board_item.cpp:63 msgid "Pcb Text" msgstr "Texte Pcb" -#: pcbnew/class_board_item.cpp:80 -#: pcbnew/class_board_item.cpp:86 -#: pcbnew/class_board_item.cpp:130 +#: pcbnew/class_board_item.cpp:79 +#: pcbnew/class_board_item.cpp:85 +#: pcbnew/class_board_item.cpp:129 msgid " of " msgstr " de " -#: pcbnew/class_board_item.cpp:93 +#: pcbnew/class_board_item.cpp:92 msgid "Graphic" msgstr "Graphique" -#: pcbnew/class_board_item.cpp:102 +#: pcbnew/class_board_item.cpp:101 #: pcbnew/dialog_pad_edit.cpp:198 msgid "Rect" msgstr "Rect" -#: pcbnew/class_board_item.cpp:105 +#: pcbnew/class_board_item.cpp:104 msgid "Arc" msgstr "Arc" -#: pcbnew/class_board_item.cpp:140 +#: pcbnew/class_board_item.cpp:139 #: pcbnew/pcbframe.cpp:447 #: pcbnew/class_track.cpp:739 msgid "Track" msgstr "Piste" -#: pcbnew/class_board_item.cpp:147 +#: pcbnew/class_board_item.cpp:146 #: pcbnew/dialog_zones_by_polygon.cpp:220 msgid "Net:" msgstr "Net:" -#: pcbnew/class_board_item.cpp:148 +#: pcbnew/class_board_item.cpp:147 msgid "Length:" msgstr "Long.:" -#: pcbnew/class_board_item.cpp:153 +#: pcbnew/class_board_item.cpp:152 #: pcbnew/class_zone.cpp:385 msgid "Zone Outline" msgstr "Contour de Zone" -#: pcbnew/class_board_item.cpp:169 +#: pcbnew/class_board_item.cpp:168 #: pcbnew/class_track.cpp:743 msgid "Zone" msgstr "Zone" -#: pcbnew/class_board_item.cpp:187 +#: pcbnew/class_board_item.cpp:186 #: pcbnew/pcbframe.cpp:479 msgid "Via" msgstr "Via" -#: pcbnew/class_board_item.cpp:191 +#: pcbnew/class_board_item.cpp:190 msgid "Blind" msgstr "Enterrée" -#: pcbnew/class_board_item.cpp:193 +#: pcbnew/class_board_item.cpp:192 msgid "Buried" msgstr "Borgne" -#: pcbnew/class_board_item.cpp:215 +#: pcbnew/class_board_item.cpp:214 #: pcbnew/class_marker.cpp:112 msgid "Marker" msgstr "Marqueur" -#: pcbnew/class_board_item.cpp:220 +#: pcbnew/class_board_item.cpp:219 msgid "Dimension" msgstr "Dimension" -#: pcbnew/class_board_item.cpp:225 +#: pcbnew/class_board_item.cpp:224 msgid "Target" msgstr "Mire" -#: pcbnew/class_board_item.cpp:226 +#: pcbnew/class_board_item.cpp:225 msgid "size" msgstr "dimension" -#: pcbnew/class_board_item.cpp:231 +#: pcbnew/class_board_item.cpp:230 msgid "Edge Zone" msgstr "Contour Zone" @@ -3780,7 +3789,7 @@ msgid "Do not Show Zones" msgstr "Ne pas monter Zones" #: pcbnew/pcbframe.cpp:416 -#: pcbnew/tool_pcb.cpp:361 +#: pcbnew/tool_pcb.cpp:360 #: pcbnew/set_color.h:423 msgid "Show Zones" msgstr "Monter Zones" @@ -3806,7 +3815,7 @@ msgid "Normal Contrast Mode Display" msgstr "Mode d'affichage Contraste normal" #: pcbnew/pcbframe.cpp:437 -#: pcbnew/tool_pcb.cpp:374 +#: pcbnew/tool_pcb.cpp:373 msgid "Hight Contrast Mode Display" msgstr "Mode d'affichage Haut Contraste" @@ -3865,7 +3874,7 @@ msgstr "Pads" #: pcbnew/class_track.cpp:765 #: pcbnew/zones.cpp:873 -#: pcbnew/zones_by_polygon.cpp:612 +#: pcbnew/zones_by_polygon.cpp:705 #: pcbnew/class_zone.cpp:398 msgid "NetName" msgstr "NetName" @@ -4424,22 +4433,74 @@ msgid "Delete Current Zone Edges" msgstr "Effacer contour zone courant" #: pcbnew/zones.cpp:871 -#: pcbnew/zones_by_polygon.cpp:610 +#: pcbnew/zones_by_polygon.cpp:703 msgid "No Net" msgstr "No Net" -#: pcbnew/dsn.cpp:455 +#: pcbnew/dsn.cpp:456 msgid "Line length exceeded" msgstr "Longueur de ligne dépassée" -#: pcbnew/dsn.cpp:530 -msgid "String delimiter char must be a single char" -msgstr "Le caractère de délimitation de ligne doit être un seul caractère" +#: pcbnew/dsn.cpp:518 +msgid "'quoted text delimiter'" +msgstr "'delimiteur de texte balisé'" -#: pcbnew/dsn.cpp:590 +#: 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 +msgid "Expecting" +msgstr "Attendu" + +#: pcbnew/specctra.cpp:300 +#, 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/move_or_drag_track.cpp:714 msgid "Unable to drag this segment: too many segments connected" msgstr "Impossible de drag ce segment: trop de segments connectés" @@ -4856,7 +4917,7 @@ msgstr "Module %s trouv msgid "Delete module?" msgstr "Effacer Module?" -#: pcbnew/tool_pcb.cpp:51 +#: pcbnew/tool_pcb.cpp:50 msgid "" "Show active layer selections\n" "and select layer pair for route and place via" @@ -4864,101 +4925,101 @@ msgstr "" "Affiche selections couche active\n" "et selection paire de couches pour routage and placement via" -#: pcbnew/tool_pcb.cpp:239 +#: pcbnew/tool_pcb.cpp:238 msgid "New Board" msgstr "Nouveau Circuit Imprimé" -#: pcbnew/tool_pcb.cpp:241 +#: pcbnew/tool_pcb.cpp:240 msgid "Open existing Board" msgstr "Ouvrir C.I. existant" -#: pcbnew/tool_pcb.cpp:242 +#: pcbnew/tool_pcb.cpp:241 msgid "Save Board" msgstr "Sauver Circuit Imprimé" -#: pcbnew/tool_pcb.cpp:246 +#: pcbnew/tool_pcb.cpp:245 #: eeschema/tool_sch.cpp:65 #: gerbview/tool_gerber.cpp:232 msgid "page settings (size, texts)" msgstr "Ajustage de la feuille de dessin (dimensions, textes)" -#: pcbnew/tool_pcb.cpp:250 +#: pcbnew/tool_pcb.cpp:249 msgid "Open Module Editor" msgstr "Ouvrir Editeur de modules" -#: pcbnew/tool_pcb.cpp:253 +#: pcbnew/tool_pcb.cpp:252 #: eeschema/tool_sch.cpp:81 #: gerbview/tool_gerber.cpp:243 msgid "Cut selected item" msgstr "Suppression des éléments sélectionnés" -#: pcbnew/tool_pcb.cpp:257 +#: pcbnew/tool_pcb.cpp:256 #: eeschema/tool_sch.cpp:84 #: gerbview/tool_gerber.cpp:248 msgid "Copy selected item" msgstr "Copie des éléments sélectionnés" -#: pcbnew/tool_pcb.cpp:259 +#: pcbnew/tool_pcb.cpp:258 #: eeschema/tool_sch.cpp:87 #: gerbview/tool_gerber.cpp:254 msgid "Paste" msgstr "Copie des éléments sauvegardés" -#: pcbnew/tool_pcb.cpp:262 +#: pcbnew/tool_pcb.cpp:261 #: gerbview/tool_gerber.cpp:261 msgid "Undelete" msgstr "Annulation du dernier effacement" -#: pcbnew/tool_pcb.cpp:265 +#: pcbnew/tool_pcb.cpp:264 msgid "Print Board" msgstr "Imprimer C.I." -#: pcbnew/tool_pcb.cpp:267 +#: pcbnew/tool_pcb.cpp:266 msgid "Plot (HPGL, PostScript, or GERBER format)" msgstr "Tracer en format HPGL, POSTSCRIPT ou GERBER" -#: pcbnew/tool_pcb.cpp:286 +#: pcbnew/tool_pcb.cpp:285 #: eeschema/tool_sch.cpp:125 msgid "Find components and texts" msgstr "Recherche de composants et textes" -#: pcbnew/tool_pcb.cpp:292 +#: pcbnew/tool_pcb.cpp:291 msgid "Read Netlist" msgstr "Lire Netliste" -#: pcbnew/tool_pcb.cpp:294 +#: pcbnew/tool_pcb.cpp:293 msgid "Pcb Design Rules Check" msgstr "Controle des règles de conception" -#: pcbnew/tool_pcb.cpp:305 +#: pcbnew/tool_pcb.cpp:304 msgid "Mode Module: Manual and Automatic Move or Place for modules" msgstr "Mode Module: Déplacements ou Placement Manuel ou Automatique des modules" -#: pcbnew/tool_pcb.cpp:308 +#: pcbnew/tool_pcb.cpp:307 msgid "Mode Track and Autorouting" msgstr "Mode Pistes and Autoroutage" -#: pcbnew/tool_pcb.cpp:332 +#: pcbnew/tool_pcb.cpp:331 msgid "Drc OFF" msgstr "Drc DESACTIVEE" -#: pcbnew/tool_pcb.cpp:349 +#: pcbnew/tool_pcb.cpp:348 msgid "Show General Ratsnest" msgstr "Monter le chevelu général" -#: pcbnew/tool_pcb.cpp:352 +#: pcbnew/tool_pcb.cpp:351 msgid "Show Module Ratsnest when moving" msgstr "Monter le chevelu du module pendant déplacement" -#: pcbnew/tool_pcb.cpp:357 +#: pcbnew/tool_pcb.cpp:356 msgid "Enable Auto Del Track" msgstr "Autoriser l'effacement automatique des pistes" -#: pcbnew/tool_pcb.cpp:370 +#: pcbnew/tool_pcb.cpp:369 msgid "Show Tracks Sketch" msgstr "Afficher pistes en contour" -#: pcbnew/tool_pcb.cpp:383 +#: pcbnew/tool_pcb.cpp:382 msgid "" "Display auxiliary vertical toolbar (tools for micro wave applications)\n" " This is a very experimental feature (under development)" @@ -4966,68 +5027,68 @@ msgstr "" "Affiche toolbar vertical auxiliaire (outils pour applications micro-ondes)\n" "C'est un outil expérimental (en cours de développement)" -#: pcbnew/tool_pcb.cpp:412 +#: pcbnew/tool_pcb.cpp:411 msgid "Net highlight" msgstr "Surbrillance des équipotentielles" -#: pcbnew/tool_pcb.cpp:416 +#: pcbnew/tool_pcb.cpp:415 msgid "Display local ratsnest (pad or module)" msgstr "Afficher le chevelu local (pastilles ou modules)" -#: pcbnew/tool_pcb.cpp:421 +#: pcbnew/tool_pcb.cpp:420 msgid "Add modules" msgstr "Addition de Modules" -#: pcbnew/tool_pcb.cpp:425 +#: pcbnew/tool_pcb.cpp:424 msgid "Add tracks and vias" msgstr "Ajouter pistes et vias" -#: pcbnew/tool_pcb.cpp:429 +#: pcbnew/tool_pcb.cpp:428 msgid "Add zones" msgstr "Addition de Zones" -#: pcbnew/tool_pcb.cpp:446 +#: pcbnew/tool_pcb.cpp:445 msgid "Add text" msgstr "Ajout de Texte" -#: pcbnew/tool_pcb.cpp:451 +#: pcbnew/tool_pcb.cpp:450 msgid "Add dimension" msgstr "Ajout des cotes" -#: pcbnew/tool_pcb.cpp:455 +#: pcbnew/tool_pcb.cpp:454 #: gerbview/tool_gerber.cpp:378 msgid "Add layer alignment target" msgstr "Ajouter Mire de superposition" -#: pcbnew/tool_pcb.cpp:465 +#: pcbnew/tool_pcb.cpp:464 msgid "Offset adjust for drill and place files" msgstr "Ajuste offset pour fichier de perçage et placement" -#: pcbnew/tool_pcb.cpp:490 +#: pcbnew/tool_pcb.cpp:489 msgid "Create line of specified length for microwave applications" msgstr "Creation de lignes de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:496 +#: pcbnew/tool_pcb.cpp:495 msgid "Create gap of specified length for microwave applications" msgstr "Creation de gaps de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:504 +#: pcbnew/tool_pcb.cpp:503 msgid "Create stub of specified length for microwave applications" msgstr "Creation de stub de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:510 +#: pcbnew/tool_pcb.cpp:509 msgid "Create stub (arc) of specified length for microwave applications" msgstr "Creation de stub (arc) de longueur spécifiée (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:517 +#: pcbnew/tool_pcb.cpp:516 msgid "Create a polynomial shape for microwave applications" msgstr "Creation de formes polynomiales (pour applications micro-ondes)" -#: pcbnew/tool_pcb.cpp:571 +#: pcbnew/tool_pcb.cpp:570 msgid "Zoom " msgstr "Zoom " -#: pcbnew/tool_pcb.cpp:585 +#: pcbnew/tool_pcb.cpp:584 #: eeschema/eelayer.cpp:223 #: pcbnew/set_color.h:414 #: eeschema/eelayer.h:210 @@ -5035,7 +5096,7 @@ msgstr "Zoom " msgid "Grid" msgstr "Grille" -#: pcbnew/tool_pcb.cpp:676 +#: pcbnew/tool_pcb.cpp:675 msgid "+/- to switch" msgstr "+/- pour commuter" @@ -9330,10 +9391,6 @@ msgstr "Contour Pcb" msgid "--- " msgstr "--- " -#: common/gestfich.cpp:621 -msgid "No default editor found, you must choose it" -msgstr "Pas d'éditeur par défaut trouvé, vous devez en choisir un" - #: common/basicframe.cpp:216 #, c-format msgid "Help file %s not found" @@ -9453,6 +9510,10 @@ msgstr "Inversion Bloc" msgid "Block Mirror" msgstr "Bloc Miroir" +#: common/gestfich.cpp:621 +msgid "No default editor found, you must choose it" +msgstr "Pas d'éditeur par défaut trouvé, vous devez en choisir un" + #: common/confirm.cpp:106 msgid "Infos:" msgstr "Infos:" @@ -10010,18 +10071,6 @@ msgstr "Options de nettoyage" msgid "General Options" msgstr "Options générales" -#: pcbnew/dsn.h:595 -msgid "in file" -msgstr "dans le fichier" - -#: pcbnew/dsn.h:596 -msgid "on line" -msgstr "en ligne" - -#: pcbnew/dsn.h:597 -msgid "at offset" -msgstr "a l'offset" - #: pcbnew/set_color.h:38 msgid "Pcbnew Layer Colors:" msgstr "Pcbnew: Couleur desCouches" diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 3b0b5d729b..1acd983a91 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -224,6 +224,123 @@ public: void Show( int nestLevel, std::ostream& os ); #endif + + /* Functions used in test, merge and cut outlines */ + /** + * Function AddArea + * add empty copper area to net + * @return pointer to the new area + */ + ZONE_CONTAINER* AddArea( int netcode, int layer, int x, int y, int hatch ); + + /** + * remove copper area from net + * @param area = area to remove + * @return 0 + */ + int RemoveArea( ZONE_CONTAINER* area_to_remove ); + + /** + * Function InsertArea + * add empty copper area to net, inserting after m_ZoneDescriptorList[iarea] + * @return pointer to the new area + */ + ZONE_CONTAINER* InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ); + + /** + Function CompleteArea + * complete copper area contour by adding a line from last to first corner + * if there is only 1 or 2 corners, remove (delete) the area + * @param area_to_complete = area to complete or remove + * @param style = style of last corner + * @return 1 if Ok, 0 if area removed + */ + int CompleteArea( ZONE_CONTAINER* area_to_complete, int style ); + + /** + * Function TestAreaPolygon + * Test an area for self-intersection. + * + * @param CurrArea = copper area to test + * @return : + * -1 if arcs intersect other sides + * 0 if no intersecting sides + * 1 if intersecting sides, but no intersecting arcs + * Also sets utility2 flag of area with return value + */ + int TestAreaPolygon( ZONE_CONTAINER* CurrArea ); + + /** + * Function ClipAreaPolygon + * Process an area that has been modified, by clipping its polygon against itself. + * This may change the number and order of copper areas in the net. + * @param bMessageBoxInt == TRUE, shows message when clipping occurs. + * @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs. + * @return: + * -1 if arcs intersect other sides, so polygon can't be clipped + * 0 if no intersecting sides + * 1 if intersecting sides + * Also sets areas->utility1 flags if areas are modified + */ + int ClipAreaPolygon( ZONE_CONTAINER* CurrArea, + bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs = TRUE ); + + /** + * Process an area that has been modified, by clipping its polygon against + * itself and the polygons for any other areas on the same net. + * This may change the number and order of copper areas in the net. + * @param modified_area = area to test + * @param bMessageBox : if TRUE, shows message boxes when clipping occurs. + * @return : + * -1 if arcs intersect other sides, so polygon can't be clipped + * 0 if no intersecting sides + * 1 if intersecting sides, polygon clipped + */ + int AreaPolygonModified( ZONE_CONTAINER* modified_area, + bool bMessageBoxArc, + bool bMessageBoxInt ); + + /** + * Function CombineAllAreasInNet + * Checks all copper areas in net for intersections, combining them if found + * @param aNetCode = net to consider + * @param bMessageBox : if true display warning message box + * @param bUseUtility : if true, don't check areas if both utility flags are 0 + * Sets utility flag = 1 for any areas modified + * If an area has self-intersecting arcs, doesn't try to combine it + */ + int CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility ); + + /** + * Function TestAreaIntersections + * Check for intersection of a given copper area with other areas in same net + * @param area_to_test = area to compare to all other areas in the same net + */ + bool TestAreaIntersections( ZONE_CONTAINER* area_to_test ); + + /** + * Function TestAreaIntersection + * Test for intersection of 2 copper areas + * area_to_test must be after area_ref in m_ZoneDescriptorList + * @param area_ref = area reference + * @param area_to_test = area to compare for intersection calculations + * @return : 0 if no intersection + * 1 if intersection + * 2 if arcs intersect + */ + int TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ); + + /** + * Function CombineAreas + * If possible, combine 2 copper areas + * area_ref must be BEFORE area_to_combine + * area_to_combine will be deleted, if areas are combined + * @return : 0 if no intersection + * 1 if intersection + * 2 if arcs intersect + */ + int CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine ); + }; #endif // #ifndef CLASS_BOARD_H diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index e82ee1bf8f..38483e3ed2 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -8,30 +8,9 @@ #include "gr_basic.h" #include "common.h" +#include "PolyLine.h" #include "pcbnew.h" -/************************/ -/* class ZONE_CONTAINER */ -/************************/ - -ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) : - BOARD_ITEM( parent, TYPEZONE_CONTAINER ) - , CPolyLine( NULL ) - -{ - m_NetCode = -1; // Net number for fast comparisons - m_CornerSelection = -1; - m_ZoneClearance = 200; // a reasonnable clerance value - m_GridFillValue = 50; // a reasonnable grid used for filling - m_PadOption = THERMAL_PAD; -} - - -ZONE_CONTAINER::~ZONE_CONTAINER() -{ -} - - /**********************/ /* Class EDGE_ZONE */ /**********************/ @@ -49,7 +28,6 @@ EDGE_ZONE:: ~EDGE_ZONE() { } - /****************************************/ bool EDGE_ZONE::Save( FILE* aFile ) const /****************************************/ @@ -57,6 +35,51 @@ bool EDGE_ZONE::Save( FILE* aFile ) const return true; } + +/************************/ +/* class ZONE_CONTAINER */ +/************************/ + +ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) : + BOARD_ITEM( parent, TYPEZONE_CONTAINER ) + +{ + m_NetCode = -1; // Net number for fast comparisons + m_CornerSelection = -1; + m_ZoneClearance = 200; // a reasonnable clerance value + m_GridFillValue = 50; // a reasonnable grid used for filling + m_PadOption = THERMAL_PAD; + utility = 0; // flags used in polygon calculations + utility2 = 0; // flags used in polygon calculations + m_Poly = new CPolyLine( NULL ); // Outlines + +} + + +ZONE_CONTAINER::~ZONE_CONTAINER() +{ + delete m_Poly; + m_Poly = NULL; +} + + +/*******************************************/ +void ZONE_CONTAINER::SetNet( int anet_code ) +/*******************************************/ +{ + m_NetCode = anet_code; + if ( m_Parent ) + { + EQUIPOT* net = ((BOARD*) m_Parent)->FindNet( g_HightLigth_NetCode ); + if( net ) + m_Netname = net->m_Netname; + else m_Netname.Empty(); + } + else m_Netname.Empty(); +} + + + /********************************************/ bool ZONE_CONTAINER::Save( FILE* aFile ) const /********************************************/ @@ -66,7 +89,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const unsigned item_pos; int ret; - unsigned corners_count = corner.size(); + unsigned corners_count = m_Poly->corner.size(); int outline_hatch; fprintf( aFile, "$CZONE_OUTLINE\n"); @@ -79,16 +102,16 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const ret = fprintf( aFile, "ZLayer %d\n", m_Layer ); if ( ret < 1 ) return false; // Save the ouline aux info - switch ( m_HatchStyle ) + switch ( m_Poly->GetHatchStyle() ) { default: - case NO_HATCH: + case CPolyLine::NO_HATCH: outline_hatch = 'N'; break; - case DIAGONAL_EDGE: + case CPolyLine::DIAGONAL_EDGE: outline_hatch = 'E'; break; - case DIAGONAL_FULL: + case CPolyLine::DIAGONAL_FULL: outline_hatch = 'F'; break; } @@ -99,8 +122,8 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const for ( item_pos = 0; item_pos < corners_count; item_pos++ ) { ret = fprintf( aFile, "ZCorner %d %d %d \n", - corner[item_pos].x, corner[item_pos].y, - corner[item_pos].end_contour ); + m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].y, + m_Poly->corner[item_pos].end_contour ); if ( ret < 3 ) return false; } fprintf( aFile, "$endCZONE_OUTLINE\n"); @@ -122,7 +145,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) char netname_buffer[1024]; int ret; int n_corner_item = 0; - int outline_hatch = NO_HATCH; + int outline_hatch = CPolyLine::NO_HATCH; bool error = false, has_corner = false; netname_buffer[0] = 0; @@ -137,13 +160,13 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) else { if ( ! has_corner ) - Start( m_Layer, 0, 0, + m_Poly->Start( m_Layer, 0, 0, x, y, outline_hatch ); else - AppendCorner( x, y ); + m_Poly->AppendCorner( x, y ); has_corner = true; - if ( flag ) Close(); + if ( flag ) m_Poly->Close(); } } if( strnicmp(Line, "ZInfo", 5 ) == 0 ) // general info found @@ -182,15 +205,15 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) { case 'n': case 'N': - outline_hatch = NO_HATCH; + outline_hatch = CPolyLine::NO_HATCH; break; case 'e': case 'E': - outline_hatch = DIAGONAL_EDGE; + outline_hatch = CPolyLine::DIAGONAL_EDGE; break; case 'f': case 'F': - outline_hatch = DIAGONAL_FULL; + outline_hatch = CPolyLine::DIAGONAL_FULL; break; } } @@ -245,32 +268,32 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& off // draw the lines int i_start_contour = 0; - for( unsigned ic = 0; ic < corner.size(); ic++ ) + for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ ) { - int xi = corner[ic].x + offset.x; - int yi = corner[ic].y + offset.y; + int xi = m_Poly->corner[ic].x + offset.x; + int yi = m_Poly->corner[ic].y + offset.y; int xf, yf; - if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 ) + if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 ) { - xf = corner[ic + 1].x + offset.x; - yf = corner[ic + 1].y + offset.y; + xf = m_Poly->corner[ic + 1].x + offset.x; + yf = m_Poly->corner[ic + 1].y + offset.y; } else { - xf = corner[i_start_contour].x + offset.x; - yf = corner[i_start_contour].y + offset.y; + xf = m_Poly->corner[i_start_contour].x + offset.x; + yf = m_Poly->corner[i_start_contour].y + offset.y; i_start_contour = ic + 1; } GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color ); } // draw hatches - for( unsigned ic = 0; ic < m_HatchLines.size(); ic++ ) + for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ ) { - int xi = m_HatchLines[ic].xi + offset.x; - int yi = m_HatchLines[ic].yi + offset.y; - int xf = m_HatchLines[ic].xf + offset.x; - int yf =m_HatchLines[ic].yf + offset.y; + int xi = m_Poly->m_HatchLines[ic].xi + offset.x; + int yi = m_Poly->m_HatchLines[ic].yi + offset.y; + int xf = m_Poly->m_HatchLines[ic].xf + offset.x; + int yf =m_Poly->m_HatchLines[ic].yf + offset.y; GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color ); } @@ -307,7 +330,7 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) #define MIN_DIST_IN_PIXELS 5 int dist; unsigned item_pos, lim; - lim = corner.size(); + lim = m_Poly->corner.size(); // Min distance to hit = MIN_DIST_IN_PIXELS pixels : WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame; @@ -315,7 +338,7 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) for ( item_pos = 0; item_pos < lim; item_pos++ ) { - dist = abs( corner[item_pos].x - refPos.x ) + abs( corner[item_pos].y - refPos.y ); + dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y ); if( dist <= min_dist ) return item_pos; } @@ -335,7 +358,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) #define MIN_DIST_IN_PIXELS 5 int dist; unsigned item_pos, lim; - lim = corner.size(); + lim = m_Poly->corner.size(); // Min distance to hit = MIN_DIST_IN_PIXELS pixels : WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame; @@ -351,7 +374,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) * the last segment of the current outline starts at current corner, and ends * at the first corner of the outline */ - if( corner[item_pos].end_contour || end_segm >= lim) + if( m_Poly->corner[item_pos].end_contour || end_segm >= lim) { unsigned tmp = first_corner_pos; first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline @@ -361,10 +384,10 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) /* test the dist between segment and ref point */ dist = (int) GetPointToLineSegmentDistance( refPos.x, refPos.y, - corner[item_pos].x, - corner[item_pos].y, - corner[end_segm].x, - corner[end_segm].y ); + m_Poly->corner[item_pos].x, + m_Poly->corner[item_pos].y, + m_Poly->corner[end_segm].x, + m_Poly->corner[end_segm].y ); if( dist <= min_dist ) return item_pos; } @@ -407,10 +430,10 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) Affiche_1_Parametre( frame, text_pos, _( "Layer" ), msg, BROWN ); text_pos += 8; - msg.Printf( wxT( "%d" ), corner.size() ); + msg.Printf( wxT( "%d" ), m_Poly->corner.size() ); Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE ); text_pos += 8; - msg.Printf( wxT( "%d" ), m_HatchLines.size() ); + msg.Printf( wxT( "%d" ), m_Poly->m_HatchLines.size() ); Affiche_1_Parametre( frame, text_pos, _( "Hatch lines" ), msg, BLUE ); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index d1682ea2a9..1e22dbfd97 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -15,7 +15,7 @@ * others polygons inside this main polygon are holes. */ -class ZONE_CONTAINER : public BOARD_ITEM, public CPolyLine +class ZONE_CONTAINER : public BOARD_ITEM { public: enum m_PadInZone { // How pads are covered by copper in zone @@ -24,10 +24,12 @@ public: PAD_IN_ZONE // pads are covered by copper }; wxString m_Netname; // Net Name + CPolyLine * m_Poly; // outlines int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection int m_ZoneClearance; // clearance value int m_GridFillValue; // Grid used for filling m_PadInZone m_PadOption; // see m_PadInZone + int utility, utility2; // flags used in polygon calculations private: int m_NetCode; // Net number for fast comparisons @@ -55,7 +57,7 @@ public: const wxPoint& offset, int draw_mode ); int GetNet( void ) { return m_NetCode; } - void SetNet( int anet_code ) { m_NetCode = anet_code; } + void SetNet( int anet_code ); /** * Function HitTest * tests if the given wxPoint is within the bounds of this object. @@ -90,7 +92,6 @@ public: * @return error level (0 = no error) */ int Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose = TRUE); - }; /*******************/ diff --git a/pcbnew/dialog_zones_by_polygon.cpp b/pcbnew/dialog_zones_by_polygon.cpp index 41d2db44e5..41db468485 100644 --- a/pcbnew/dialog_zones_by_polygon.cpp +++ b/pcbnew/dialog_zones_by_polygon.cpp @@ -281,7 +281,7 @@ void WinEDA_ZoneFrame::CreateControls() } if ( m_Zone_Container ) - s_Zone_Hatching = m_Zone_Container->GetHatch(); + s_Zone_Hatching = m_Zone_Container->m_Poly->GetHatchStyle(); switch( s_Zone_Hatching ) { case CPolyLine::NO_HATCH: diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index d69e194900..677afea236 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -450,11 +450,13 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE: - wxMessageBox(wxT("ToDo")); + DrawPanel->MouseToCursorSchema(); + Add_Similar_Zone( &dc, (ZONE_CONTAINER*) GetCurItem() ); break; case ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE: - wxMessageBox(wxT("ToDo")); + DrawPanel->MouseToCursorSchema(); + Add_Zone_Cutout( &dc, (ZONE_CONTAINER*) GetCurItem() ); break; case ID_POPUP_PCB_DELETE_ZONE_CONTAINER: @@ -469,23 +471,9 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) } case ID_POPUP_PCB_DELETE_ZONE_CORNER: - { - DrawPanel->MouseToCursorSchema(); - ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem(); - zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR); - if ( zone_cont->GetNumCorners() <= 3 ) - { - Delete_Zone( &dc, NULL, zone_cont->m_TimeStamp ); - m_Pcb->Delete( zone_cont ); - } - else - { - zone_cont->DeleteCorner(zone_cont->m_CornerSelection); - zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR); - } + Remove_Zone_Corner( &dc, (ZONE_CONTAINER*)GetCurItem() ); SetCurItem( NULL ); break; - } case ID_POPUP_PCB_MOVE_ZONE_CORNER: { @@ -505,7 +493,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) * and start move the new corner */ zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR); - zone_cont->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y ); + zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y ); zone_cont->m_CornerSelection++; zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR); Start_Move_Zone_Corner(&dc, zone_cont, zone_cont->m_CornerSelection, true); diff --git a/pcbnew/makefile.include b/pcbnew/makefile.include index 65994031bf..6c184f38d7 100644 --- a/pcbnew/makefile.include +++ b/pcbnew/makefile.include @@ -10,8 +10,10 @@ LIBVIEWER3D = ../3d-viewer/3d-viewer.a ZONE_FILES = zones_by_polygon.o #ZONE_FILES = zones.o + OBJECTS= $(TARGET).o classpcb.o\ $(ZONE_FILES)\ + zones_test_and_combine_areas.o\ zone_filling_algorithm.o\ lay2plot.o\ modedit_undo_redo.o\ diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index fd934948ab..e860974626 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -658,10 +658,10 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu aPopMenu->AppendSeparator(); ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE, - _( "Add Similar Zone" ), fill_zone_xpm ); + _( "Add Similar Zone" ), add_zone_xpm ); ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE, - _( "Add Cutout Zone" ), add_zone_cutout ); + _( "Add Cutout Area" ), add_zone_cutout ); aPopMenu->AppendSeparator(); ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ZONE, diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 07f45b43cc..5fdf426a9e 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -112,20 +112,20 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose ) // trace the zone edges into the routing matrix int i_start_contour = 0; - for( unsigned ic = 0; ic < corner.size(); ic++ ) + for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ ) { - int xi = corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x; - int yi = corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y; + int xi = m_Poly->corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x; + int yi = m_Poly->corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y; int xf, yf; - if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 ) + if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 ) { - xf = corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x; - yf = corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y; + xf = m_Poly->corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x; + yf = m_Poly->corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y; } else { - xf = corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x; - yf = corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y; + xf = m_Poly->corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x; + yf = m_Poly->corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y; i_start_contour = ic + 1; } TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); @@ -136,9 +136,8 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose ) int cells_count = 0; for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ ) { - int icont = 0; wxPoint pos; - if( TestPointInsideContour( icont, (*pad)->m_Pos.x, (*pad)->m_Pos.y ) ) + if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) ) { ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + (g_GridRoutingSize / 2) ) / g_GridRoutingSize; @@ -196,20 +195,20 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose ) /* Recreate zone limits on the routing matrix * (could be deleted by PlaceCells()) : */ i_start_contour = 0; - for( unsigned ic = 0; ic < corner.size(); ic++ ) + for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ ) { - int xi = corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x; - int yi = corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y; + int xi = m_Poly->corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x; + int yi = m_Poly->corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y; int xf, yf; - if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 ) + if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 ) { - xf = corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x; - yf = corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y; + xf = m_Poly->corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x; + yf = m_Poly->corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y; } else { - xf = corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x; - yf = corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y; + xf = m_Poly->corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x; + yf = m_Poly->corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y; i_start_contour = ic + 1; } TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); @@ -219,9 +218,8 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose ) * (could be deleted by PlaceCells()) : */ for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ ) { - int icont = 0; wxPoint pos; - if( TestPointInsideContour( icont, (*pad)->m_Pos.x, (*pad)->m_Pos.y ) ) + if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) ) { ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + (g_GridRoutingSize / 2) ) / g_GridRoutingSize; diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index baff23a8b7..a17bf2d5ec 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -27,10 +27,9 @@ using namespace std; #include "common.h" #include "pcbnew.h" - #include "autorout.h" -#include "cell.h" -#include "trigo.h" + +#include "id.h" #include "protos.h" @@ -45,13 +44,15 @@ static void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC ); static void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); /* Local variables */ -static bool Zone_45_Only = FALSE; +static bool Zone_45_Only = FALSE; static ZONE_CONTAINER::m_PadInZone s_Zone_Pad_Options = ZONE_CONTAINER::THERMAL_PAD; -static int s_Zone_Layer; // Layer used to create the current zone -static int s_Zone_Hatching; // Option to show the zone area (outlines only, short hatches or full hatches -static int s_NetcodeSelection; // Net code selection for the current zone -static wxPoint s_CornerInitialPosition; // Used to abort a move corner command -static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted) +static int s_Zone_Layer; // Layer used to create the current zone +static int s_Zone_Hatching; // Option to show the zone area (outlines only, short hatches or full hatches +static int s_NetcodeSelection; // Net code selection for the current zone +static wxPoint s_CornerInitialPosition; // Used to abort a move corner command +static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted) +static bool s_AddCutoutToCurrentZone; // if true, the next outline will be addes to s_CurrentZone +static ZONE_CONTAINER* s_CurrentZone; // if != NULL, these ZONE_CONTAINER params will be used for the next zone // key used to store net sort option in config file : #define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" ) @@ -63,6 +64,44 @@ enum zone_cmd { #include "dialog_zones_by_polygon.cpp" +/**********************************************************************************/ +void WinEDA_PcbFrame::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 + */ +{ + s_AddCutoutToCurrentZone = false; + s_CurrentZone = zone_container; + wxCommandEvent evt; + evt.SetId( ID_PCB_ZONES_BUTT ); + Process_Special_Functions( evt ); +} + + +/**********************************************************************************/ +void WinEDA_PcbFrame::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 + */ +{ + s_AddCutoutToCurrentZone = true; + s_CurrentZone = zone_container; + wxCommandEvent evt; + evt.SetId( ID_PCB_ZONES_BUTT ); + Process_Special_Functions( evt ); +} + /*****************************************************************************/ void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone, long aTimestamp ) @@ -174,6 +213,8 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC ) Panel->ManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL; pcbframe->SetCurItem( NULL ); + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; } @@ -228,9 +269,11 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con zone_container->m_Flags = IN_EDIT; DrawPanel->ManageCurseur = Show_Zone_Corner_While_Move_Mouse; DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner; - s_CornerInitialPosition.x = zone_container->GetX( corner_id ); - s_CornerInitialPosition.y = zone_container->GetY( corner_id ); + s_CornerInitialPosition.x = zone_container->m_Poly->GetX( corner_id ); + s_CornerInitialPosition.y = zone_container->m_Poly->GetY( corner_id ); s_CornerIsNew = IsNewCorner; + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; } @@ -248,6 +291,72 @@ void WinEDA_PcbFrame::End_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_conta DrawPanel->ForceCloseManageCurseur = NULL; zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); GetScreen()->SetModify(); + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; + + SetCurItem( NULL ); // This outine can be deleted when merging outlines + + /* Combine zones if possible */ + int layer = zone_container->GetLayer(); + + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); + } + + m_Pcb->AreaPolygonModified( zone_container, true, false ); + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + } +} + + +/*************************************************************************************/ +void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_container ) +/*************************************************************************************/ +/** + * Function End_Move_Zone_Corner + * Remove the currently selected corner in a zone outline + * the .m_CornerSelection is used as corner selection + */ +{ + if ( zone_container->m_Poly->GetNumCorners() <= 3 ) + { + Delete_Zone( DC, NULL, zone_container->m_TimeStamp ); + m_Pcb->Delete( zone_container ); + return; + } + + int layer = zone_container->GetLayer(); + + if ( DC ) + { + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); + } + } + + zone_container->m_Poly->DeleteCorner(zone_container->m_CornerSelection); + + // modify zones outlines accordiing to the new zone_container shape + m_Pcb->AreaPolygonModified( zone_container, true, false ); + if ( DC ) + { + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + } + } } @@ -267,19 +376,21 @@ void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC ) if( s_CornerIsNew ) { - zone_container->DeleteCorner( zone_container->m_CornerSelection ); + zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection ); } else { wxPoint pos = s_CornerInitialPosition; - zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y ); + zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y ); } zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR ); Panel->ManageCurseur = NULL; Panel->ForceCloseManageCurseur = NULL; pcbframe->SetCurItem( NULL ); - zone_container->m_Flags = 0; + zone_container->m_Flags = 0; + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; } @@ -299,7 +410,7 @@ void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* Panel, wxDC* DC, bool } wxPoint pos = pcbframe->GetScreen()->m_Curseur; - zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y ); + zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y ); zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR ); } @@ -317,36 +428,61 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC ) EDGE_ZONE* oldedge; EDGE_ZONE* newedge = NULL; + // verify if s_CurrentZone exists: + unsigned ii; + + for( ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + if( s_CurrentZone == m_Pcb->m_ZoneDescriptorList[ii] ) + break; + } + + if( ii == m_Pcb->m_ZoneDescriptorList.size() ) // Not found: coul be deleted since last selection + { + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; + } + oldedge = m_Pcb->m_CurrentLimitZone; if( m_Pcb->m_CurrentLimitZone == NULL ) /* Start a new contour: init zone params (net and layer) */ { - DrawPanel->m_IgnoreMouseEvents = TRUE; - WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this ); + if( s_CurrentZone == NULL ) + { + DrawPanel->m_IgnoreMouseEvents = TRUE; + WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this ); - int diag = frame->ShowModal(); - frame->Destroy(); - DrawPanel->MouseToCursorSchema(); - DrawPanel->m_IgnoreMouseEvents = FALSE; - - if( diag == ZONE_ABORT ) - return NULL; - - GetScreen()->m_Active_Layer = s_Zone_Layer; + int diag = frame->ShowModal(); + frame->Destroy(); + DrawPanel->MouseToCursorSchema(); + DrawPanel->m_IgnoreMouseEvents = FALSE; + if( diag == ZONE_ABORT ) + return NULL; + } + else /* Start a new contour: init zone params (net and layer) from an existing zone */ + { + GetScreen()->m_Active_Layer = s_Zone_Layer = s_CurrentZone->GetLayer(); + s_Zone_Hatching = s_CurrentZone->m_Poly->GetHatchStyle(); + } /* Show the Net */ if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) ) { Hight_Light( DC ); // Remove old hightlight selection } + if( s_CurrentZone ) + s_NetcodeSelection = s_CurrentZone->GetNet(); g_HightLigth_NetCode = s_NetcodeSelection; if( !g_HightLigt_Status ) Hight_Light( DC ); + + if( !s_AddCutoutToCurrentZone ) + s_CurrentZone = NULL; // the zone is used only once } // if first segment - if( (m_Pcb->m_CurrentLimitZone == NULL ) /* Initial startt of a new outline */ + if( (m_Pcb->m_CurrentLimitZone == NULL ) /* Initial start of a new outline */ || (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */ { newedge = new EDGE_ZONE( m_Pcb ); @@ -400,6 +536,7 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC ) */ { EDGE_ZONE* edge; + int layer = GetScreen()->m_Active_Layer; if( m_Pcb->m_CurrentLimitZone ) { @@ -431,39 +568,74 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC ) DrawPanel->ManageCurseur = NULL; DrawPanel->ForceCloseManageCurseur = NULL; - /* Put edges in list */ - ZONE_CONTAINER* polygon = new ZONE_CONTAINER( m_Pcb ); - polygon->SetLayer( GetScreen()->m_Active_Layer ); - polygon->SetNet( g_HightLigth_NetCode ); - polygon->m_TimeStamp = GetTimeStamp(); - - EQUIPOT* net = m_Pcb->FindNet( g_HightLigth_NetCode ); - if( net ) - polygon->m_Netname = net->m_Netname; - edge = m_Pcb->m_CurrentLimitZone; - polygon->Start( GetScreen()->m_Active_Layer, 0, 0, - edge->m_Start.x, edge->m_Start.y, - s_Zone_Hatching ); - edge = edge->Next(); - while( edge ) + // Undraw old drawings, because they can have important changes + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) { - polygon->AppendCorner( edge->m_Start.x, edge->m_Start.y ); - edge = edge->Next(); + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); } - polygon->Close(); // Close the current corner list - polygon->SetHatch( s_Zone_Hatching ); - polygon->m_PadOption = s_Zone_Pad_Options; - polygon->m_ZoneClearance = g_DesignSettings.m_ZoneClearence; - polygon->m_GridFillValue = g_GridRoutingSize; + /* Put edges in list */ + ZONE_CONTAINER* new_zone_container; + if( s_CurrentZone == NULL ) + { + new_zone_container = new ZONE_CONTAINER( m_Pcb ); + new_zone_container->SetLayer( layer ); + new_zone_container->SetNet( g_HightLigth_NetCode ); + new_zone_container->m_TimeStamp = GetTimeStamp(); - m_Pcb->m_ZoneDescriptorList.push_back( polygon ); + edge = m_Pcb->m_CurrentLimitZone; + new_zone_container->m_Poly->Start( layer, 0, 0, + edge->m_Start.x, edge->m_Start.y, + s_Zone_Hatching ); + edge = edge->Next(); + while( edge ) + { + new_zone_container->m_Poly->AppendCorner( edge->m_Start.x, edge->m_Start.y ); + edge = edge->Next(); + } + + new_zone_container->m_Poly->Close(); // Close the current corner list + new_zone_container->m_Poly->SetHatch( s_Zone_Hatching ); + new_zone_container->m_PadOption = s_Zone_Pad_Options; + new_zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence; + new_zone_container->m_GridFillValue = g_GridRoutingSize; + + m_Pcb->m_ZoneDescriptorList.push_back( new_zone_container ); + } + else // Append this outline as a cutout to an existing zone + { + new_zone_container = s_CurrentZone; + edge = m_Pcb->m_CurrentLimitZone; + while( edge ) + { + new_zone_container->m_Poly->AppendCorner( edge->m_Start.x, edge->m_Start.y ); + edge = edge->Next(); + } + + new_zone_container->m_Poly->Close(); // Close the current corner list + } + + s_AddCutoutToCurrentZone = false; + s_CurrentZone = NULL; /* Remove the current temporary list */ DelLimitesZone( DC, TRUE ); - /* Redraw the real edge zone */ - polygon->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + new_zone_container->m_Flags = 0; + SetCurItem( NULL ); // This outine can be deleted when merging outlines + + // Combine zones if possible : + m_Pcb->AreaPolygonModified( new_zone_container, true, false ); + + // Redraw the real edge zone : + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + if( layer == edge_zone->GetLayer() ) + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + } GetScreen()->SetModify(); } @@ -540,19 +712,32 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container if( diag == ZONE_ABORT ) return; - zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); + // Undraw old zone outlines + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR ); + } zone_container->SetLayer( s_Zone_Layer ); zone_container->SetNet( s_NetcodeSelection ); EQUIPOT* net = m_Pcb->FindNet( s_NetcodeSelection ); if( net ) zone_container->m_Netname = net->m_Netname; - zone_container->SetHatch( s_Zone_Hatching ); + zone_container->m_Poly->SetHatch( s_Zone_Hatching ); zone_container->m_PadOption = s_Zone_Pad_Options; zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence; zone_container->m_GridFillValue = g_GridRoutingSize; - zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + // Combine zones if possible : + m_Pcb->AreaPolygonModified( zone_container, true, false ); + + // Redraw the real new zone outlines: + for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) + { + ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii]; + edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR ); + } GetScreen()->SetModify(); } @@ -587,11 +772,11 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v s_NetcodeSelection = zone_container->GetNet(); if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) && DC ) { - Hight_Light( DC ); // Remove old hightlight selection + Hight_Light( DC ); // Remove old hightlight selection } g_HightLigth_NetCode = s_NetcodeSelection; - if( !g_HightLigt_Status && DC) + if( !g_HightLigt_Status && DC ) Hight_Light( DC ); if( g_HightLigth_NetCode > 0 ) @@ -613,7 +798,7 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v msg = _( "No Net" ); Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED ); - wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor) + wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor) zone_container->m_PadOption = s_Zone_Pad_Options; zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence; zone_container->m_GridFillValue = g_GridRoutingSize; @@ -641,22 +826,22 @@ int WinEDA_PcbFrame::Fill_All_Zones( wxDC* DC, bool verbose ) ZONE_CONTAINER* zone_container; int error_level = 0; - // Remove all zones : - if ( m_Pcb->m_Zone ) - { - m_Pcb->m_Zone->DeleteStructList(); - m_Pcb->m_Zone = NULL; - m_Pcb->m_NbSegmZone = 0; - } + // Remove all zones : + if( m_Pcb->m_Zone ) + { + m_Pcb->m_Zone->DeleteStructList(); + m_Pcb->m_Zone = NULL; + m_Pcb->m_NbSegmZone = 0; + } for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ ) { zone_container = m_Pcb->m_ZoneDescriptorList[ii]; error_level = Fill_Zone( NULL, zone_container, verbose ); - if( error_level && ! verbose ) + if( error_level && !verbose ) break; } - DrawPanel->Refresh(true); + DrawPanel->Refresh( true ); return error_level; } diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp new file mode 100644 index 0000000000..35e3bcef6d --- /dev/null +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -0,0 +1,975 @@ +/****************************************************************************/ +/* functions to test, merges and cut polygons used as copper areas outlines */ +/****************************************************************************/ + +#include + +#include "fctsys.h" + +#include "common.h" +#include "pcbnew.h" + +using namespace std; + +#undef ASSERT +#define ASSERT wxASSERT + +bool bDontShowSelfIntersectionArcsWarning; +bool bDontShowSelfIntersectionWarning; +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 + * @return pointer to the new area + */ +ZONE_CONTAINER* BOARD::AddArea( int netcode, int layer, int x, int y, int hatch ) +{ + ZONE_CONTAINER* new_area = InsertArea( netcode, m_ZoneDescriptorList.size( + ) - 1, layer, x, y, hatch ); + + return new_area; +} + + +/** + * remove copper area from net + * @param area = area to remove + * @return 0 + */ +int BOARD::RemoveArea( ZONE_CONTAINER* area_to_remove ) +{ + Delete( area_to_remove ); + return 0; +} + + +/** + * Function InsertArea + * add empty copper area to net, inserting after m_ZoneDescriptorList[iarea] + * @return pointer to the new area + */ +ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ) +{ + ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); + + new_area->SetNet( netcode ); + new_area->SetLayer( layer ); + new_area->m_TimeStamp = GetTimeStamp(); + if( iarea < (int) ( m_ZoneDescriptorList.size() - 1) ) + m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area ); + else + m_ZoneDescriptorList.push_back( new_area ); + + new_area->poly->Start( layer, 1, 10 * NM_PER_MIL, x, y, + hatch ); + return new_area; +} + + +/** + * Function CompleteArea + * complete copper area contour by adding a line from last to first corner + * if there is only 1 or 2 corners, remove (delete) the area + * @param area_to_complete = area to complete or remove + * @param style = style of last corner + * @return 1 if Ok, 0 if area removed + */ +int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style ) +{ + if( area_to_complete->poly->GetNumCorners() > 2 ) + { + area_to_complete->poly->Close( style ); + return 1; + } + else + { + RemoveArea( area_to_complete ); + } + return 0; +} + + +/** + * Function TestAreaPolygon + * Test an area for self-intersection. + * + * @param CurrArea = copper area to test + * @return : + * -1 if arcs intersect other sides + * 0 if no intersecting sides + * 1 if intersecting sides, but no intersecting arcs + * Also sets utility2 flag of area with return value + */ +int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) +{ + CPolyLine* p = CurrArea->poly; + + // first, check for sides intersecting other sides, especially arcs + bool bInt = false; + bool bArcInt = false; + int n_cont = p->GetNumContours(); + + // make bounding rect for each contour + std::vector cr; + cr.reserve( n_cont ); + for( int icont = 0; icontGetCornerBounds( icont ) ); + + for( int icont = 0; icontGetContourStart( icont ); + int is_end = p->GetContourEnd( icont ); + for( int is = is_start; is<=is_end; is++ ) + { + int is_prev = is - 1; + if( is_prev < is_start ) + is_prev = is_end; + int is_next = is + 1; + if( is_next > is_end ) + is_next = is_start; + int style = p->GetSideStyle( is ); + int x1i = p->GetX( is ); + int y1i = p->GetY( is ); + int x1f = p->GetX( is_next ); + int y1f = p->GetY( is_next ); + + // check for intersection with any other sides + for( int icont2 = icont; icont2 cr[icont2].right + || cr[icont].bottom > cr[icont2].top + || cr[icont2].left > cr[icont].right + || cr[icont2].bottom > cr[icont].top ) + { + // rectangles don't overlap, do nothing + } + else + { + int is2_start = p->GetContourStart( icont2 ); + int is2_end = p->GetContourEnd( icont2 ); + for( int is2 = is2_start; is2<=is2_end; is2++ ) + { + int is2_prev = is2 - 1; + if( is2_prev < is2_start ) + is2_prev = is2_end; + int is2_next = is2 + 1; + if( is2_next > is2_end ) + is2_next = is2_start; + if( icont != icont2 + || (is2 != is && is2 != is_prev && is2 != is_next && is != is2_prev + && is != + is2_next ) ) + { + int style2 = p->GetSideStyle( is2 ); + int x2i = p->GetX( is2 ); + int y2i = p->GetY( is2 ); + int x2f = p->GetX( is2_next ); + int y2f = p->GetY( is2_next ); + int ret = FindSegmentIntersections( x1i, + y1i, + x1f, + y1f, + style, + x2i, + y2i, + x2f, + y2f, + style2 ); + if( ret ) + { + // intersection between non-adjacent sides + bInt = TRUE; + if( style != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT ) + { + bArcInt = TRUE; + break; + } + } + } + } + } + if( bArcInt ) + break; + } + + if( bArcInt ) + break; + } + + if( bArcInt ) + break; + } + + if( bArcInt ) + CurrArea->utility2 = -1; + else if( bInt ) + CurrArea->utility2 = 1; + else + CurrArea->utility2 = 0; + return CurrArea->utility2; +} + + +/** + * Function ClipAreaPolygon + * Process an area that has been modified, by clipping its polygon against itself. + * This may change the number and order of copper areas in the net. + * @param bMessageBoxInt == TRUE, shows message when clipping occurs. + * @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs. + * @return: + * -1 if arcs intersect other sides, so polygon can't be clipped + * 0 if no intersecting sides + * 1 if intersecting sides + * Also sets areas->utility1 flags if areas are modified + */ +int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, + bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs ) +{ + CPolyLine* p = CurrArea->poly; + int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag + + if( test == -1 && !bRetainArcs ) + test = 1; + if( test == -1 ) + { + // arc intersections, don't clip unless bRetainArcs == false + if( bMessageBoxArc && bDontShowSelfIntersectionArcsWarning == false ) + { + wxString str; + str.Printf( wxT( "Area %X of net \"%s\" has arcs intersecting other sides.\n" ), + CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() ); + str += wxT( "This may cause problems with other editing operations,\n" ); + str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" ); + str += wxT( "Manual correction is recommended." ); + wxMessageBox( str ); + +// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState; + } + return -1; // arcs intersect with other sides, error + } + + // mark all areas as unmodified except this one + for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) + m_ZoneDescriptorList[ia]->utility = 0; + + CurrArea->utility = 1; + + if( test == 1 ) + { + // non-arc intersections, clip the polygon + if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false ) + { + wxString str; + str.Printf( wxT( "Area %d of net \"%s\" is self-intersecting and will be clipped.\n" ), + CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() ); + str += wxT( "This may result in splitting the area.\n" ); + str += wxT( "If the area is complex, this may take a few seconds." ); + wxMessageBox( str ); + +// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState; + } + } + +//** TODO test for cutouts outside of area +//** if( test == 1 ) + { + std::vector * pa = new std::vector; + p->Undraw(); + int n_poly = CurrArea->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++ ) + { + // create new copper area and copy poly into it + CPolyLine* new_p = (*pa)[ip - 1]; + CurrArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 ); + + // 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(); + CurrArea->utility = 1; + } + } + p->Draw(); + delete pa; + } + return test; +} + + +/** + * Process an area that has been modified, by clipping its polygon against + * itself and the polygons for any other areas on the same net. + * This may change the number and order of copper areas in the net. + * @param modified_area = area to test + * @param bMessageBox : if TRUE, shows message boxes when clipping occurs. + * @return : + * -1 if arcs intersect other sides, so polygon can't be clipped + * 0 if no intersecting sides + * 1 if intersecting sides, polygon clipped + */ +int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area, + bool bMessageBoxArc, + bool bMessageBoxInt ) +{ + // clip polygon against itself + int test = ClipAreaPolygon( modified_area, bMessageBoxArc, bMessageBoxInt ); + + if( test == -1 ) + return test; + + // now see if we need to clip against other areas + bool bCheckAllAreas = false; + if( test == 1 ) + bCheckAllAreas = TRUE; + else + bCheckAllAreas = TestAreaIntersections( modified_area ); + if( bCheckAllAreas ) + CombineAllAreasInNet( modified_area->GetNet(), bMessageBoxInt, TRUE ); + + return test; +} + + +/** + * Function CombineAllAreasInNet + * Checks all copper areas in net for intersections, combining them if found + * @param aNetCode = net to consider + * @param bMessageBox : if true display warning message box + * @param bUseUtility : if true, don't check areas if both utility flags are 0 + * Sets utility flag = 1 for any areas modified + * If an area has self-intersecting arcs, doesn't try to combine it + */ +int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility ) +{ + if( m_ZoneDescriptorList.size() > 1 ) + { + // start by testing all area polygons to set utility2 flags + for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) + if( m_ZoneDescriptorList[ia]->GetNet() == aNetCode ) + TestAreaPolygon( m_ZoneDescriptorList[ia] ); + + // now loop through all combinations + for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) + { + ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; + if( curr_area->GetNet() != aNetCode ) + continue; + + // legal polygon + CRect b1 = curr_area->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() + && curr_area->utility2 != -1 && area2->utility2 != -1 ) + { + CRect b2 = area2->poly->GetCornerBounds(); + if( !( b1.left > b2.right || b1.right < b2.left + || b1.bottom > b2.top || b1.top < b2.bottom ) ) + { + // check ia2 against 1a1 + if( curr_area->utility || area2->utility || bUseUtility == + false ) + { + int ret = TestAreaIntersection( curr_area, area2 ); + if( ret == 1 ) + ret = CombineAreas( curr_area, area2 ); + if( ret == 1 ) + { + if( bMessageBox && bDontShowIntersectionWarning == false ) + { + wxString str; + str.Printf( + wxT( + "Areas %d and %d of net \"%s\" intersect and will be combined.\n" ), + ia1 + 1, + ia2 + 1, + curr_area->m_Netname.GetData() ); + str += wxT( + "If they are complex, this may take a few seconds." ); + wxMessageBox( str ); + +// bDontShowIntersectionWarning = dlg.bDontShowBoxState; + } + mod_ia1 = TRUE; + } + else if( ret == 2 ) + { + if( bMessageBox && bDontShowIntersectionArcsWarning == false ) + { + wxString str; + str.Printf( + wxT( + "Areas %d and %d of net \"%s\" intersect, but some of the intersecting sides are arcs.\n" ), + ia1 + 1, + ia2 + 1, + curr_area->m_Netname.GetData() ); + str += wxT( "Therefore, these areas can't be combined." ); + wxMessageBox( str ); + +// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState; + } + } + } + } + } + } + + if( mod_ia1 ) + ia1--; // if modified, we need to check it again + } + } + return 0; +} + + +/** + * Function TestAreaIntersections + * Check for intersection of a given copper area with other areas in same net + * @param area_to_test = area to compare to all other areas in the same net + */ +bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) +{ + CPolyLine* poly1 = area_to_test->poly; + + for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) + { + ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; + if( area_to_test->GetNet() != area_to_test->GetNet() ) + continue; + if( area_to_test != area2 ) + { + // see if areas are on same layer + if( area_to_test->GetLayer() != area2->GetLayer() ) + continue; + + CPolyLine* poly2 = area2->poly; + + // test bounding rects + CRect b1 = poly1->GetCornerBounds(); + CRect b2 = poly2->GetCornerBounds(); + if( b1.bottom > b2.top + || b1.top < b2.bottom + || b1.left > b2.right + || b1.right < b2.left ) + continue; + + // test for intersecting segments + for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + { + int is1 = poly1->GetContourStart( icont1 ); + int ie1 = poly1->GetContourEnd( icont1 ); + for( int ic1 = is1; ic1<=ie1; ic1++ ) + { + int xi1 = poly1->GetX( ic1 ); + int yi1 = poly1->GetY( ic1 ); + int xf1, yf1, style1; + if( ic1 < ie1 ) + { + xf1 = poly1->GetX( ic1 + 1 ); + yf1 = poly1->GetY( ic1 + 1 ); + } + else + { + xf1 = poly1->GetX( is1 ); + yf1 = poly1->GetY( is1 ); + } + style1 = poly1->GetSideStyle( ic1 ); + for( int icont2 = 0; icont2GetNumContours(); icont2++ ) + { + int is2 = poly2->GetContourStart( icont2 ); + int ie2 = poly2->GetContourEnd( icont2 ); + for( int ic2 = is2; ic2<=ie2; ic2++ ) + { + int xi2 = poly2->GetX( ic2 ); + int yi2 = poly2->GetY( ic2 ); + int xf2, yf2, style2; + if( ic2 < ie2 ) + { + xf2 = poly2->GetX( ic2 + 1 ); + yf2 = poly2->GetY( ic2 + 1 ); + } + else + { + xf2 = poly2->GetX( is2 ); + yf2 = poly2->GetY( is2 ); + } + style2 = poly2->GetSideStyle( ic2 ); + int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1, + xi2, yi2, xf2, yf2, style2 ); + if( n_int ) + return TRUE; + } + } + } + } + } + } + + return false; +} + + +/** + * Function TestAreaIntersection + * Test for intersection of 2 copper areas + * area_to_test must be after area_ref in m_ZoneDescriptorList + * @param area_ref = area reference + * @param area_to_test = area to compare for intersection calculations + * @return : 0 if no intersection + * 1 if intersection + * 2 if arcs intersect + */ +int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ) +{ + // see if areas are on same layer + if( area_ref->GetLayer() != area_to_test->GetLayer() ) + return 0; + + CPolyLine* poly1 = area_ref->poly; + CPolyLine* poly2 = area_to_test->poly; + + // test bounding rects + CRect b1 = poly1->GetCornerBounds(); + CRect b2 = poly2->GetCornerBounds(); + if( b1.bottom > b2.top + || b1.top < b2.bottom + || b1.left > b2.right + || b1.right < b2.left ) + return 0; + + // now test for intersecting segments + bool bInt = false; + bool bArcInt = false; + for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + { + int is1 = poly1->GetContourStart( icont1 ); + int ie1 = poly1->GetContourEnd( icont1 ); + for( int ic1 = is1; ic1<=ie1; ic1++ ) + { + int xi1 = poly1->GetX( ic1 ); + int yi1 = poly1->GetY( ic1 ); + int xf1, yf1, style1; + if( ic1 < ie1 ) + { + xf1 = poly1->GetX( ic1 + 1 ); + yf1 = poly1->GetY( ic1 + 1 ); + } + else + { + xf1 = poly1->GetX( is1 ); + yf1 = poly1->GetY( is1 ); + } + style1 = poly1->GetSideStyle( ic1 ); + for( int icont2 = 0; icont2GetNumContours(); icont2++ ) + { + int is2 = poly2->GetContourStart( icont2 ); + int ie2 = poly2->GetContourEnd( icont2 ); + for( int ic2 = is2; ic2<=ie2; ic2++ ) + { + int xi2 = poly2->GetX( ic2 ); + int yi2 = poly2->GetY( ic2 ); + int xf2, yf2, style2; + if( ic2 < ie2 ) + { + xf2 = poly2->GetX( ic2 + 1 ); + yf2 = poly2->GetY( ic2 + 1 ); + } + else + { + xf2 = poly2->GetX( is2 ); + yf2 = poly2->GetY( is2 ); + } + style2 = poly2->GetSideStyle( ic2 ); + int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1, + xi2, yi2, xf2, yf2, style2 ); + if( n_int ) + { + bInt = TRUE; + if( style1 != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT ) + bArcInt = TRUE; + break; + } + } + + if( bArcInt ) + break; + } + + if( bArcInt ) + break; + } + + if( bArcInt ) + break; + } + + if( !bInt ) + return 0; + if( bArcInt ) + return 2; + return 1; +} + + +/** + * Function CombineAreas + * If possible, combine 2 copper areas + * area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList + * area_to_combine will be deleted, if areas are combined + * @return : 0 if no intersection + * 1 if intersection + * 2 if arcs intersect + */ +int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine ) +{ + if( area_ref == area_to_combine ) + ASSERT( 0 ); +#if 0 + + // test for intersection + int test = TestAreaIntersection( area_ref, area_to_combine ); + if( test != 1 ) + return test; // no intersection +#endif + + // polygons intersect, combine them + CPolyLine* poly1 = area_ref->poly; + CPolyLine* poly2 = area_to_combine->poly; + std::vector arc_array1; + std::vector arc_array2; + poly1->MakeGpcPoly( -1, &arc_array1 ); + poly2->MakeGpcPoly( -1, &arc_array2 ); + int n_ext_cont1 = 0; + for( int ic = 0; icGetGpcPoly()->num_contours; ic++ ) + if( !( (poly1->GetGpcPoly()->hole)[ic] ) ) + n_ext_cont1++; + + int n_ext_cont2 = 0; + for( int ic = 0; icGetGpcPoly()->num_contours; ic++ ) + if( !( (poly2->GetGpcPoly()->hole)[ic] ) ) + n_ext_cont2++; + + gpc_polygon* union_gpc = new gpc_polygon; + gpc_polygon_clip( GPC_UNION, poly1->GetGpcPoly(), poly2->GetGpcPoly(), union_gpc ); + + // get number of outside contours + int n_union_ext_cont = 0; + for( int ic = 0; icnum_contours; ic++ ) + if( !( (union_gpc->hole)[ic] ) ) + n_union_ext_cont++; + + // if no intersection, free new gpc and return + if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 ) + { + gpc_free_polygon( union_gpc ); + delete union_gpc; + return 0; + } + + // intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine + RemoveArea( area_to_combine ); + area_ref->m_Poly->RemoveAllContours(); + + // create area with external contour + for( int ic = 0; icnum_contours; ic++ ) + { + if( !(union_gpc->hole)[ic] ) + { + // external contour, replace this poly + for( int i = 0; icontour[ic].num_vertices; i++ ) + { + int x = ( (union_gpc->contour)[ic].vertex )[i].x; + int y = ( (union_gpc->contour)[ic].vertex )[i].y; + if( i==0 ) + { + area_ref->m_Poly->Start( area_ref->GetLayer(), 0, 0, x, y, area_ref->m_Poly->GetHatchStyle() ); + } + else + area_ref->m_Poly->AppendCorner( x, y ); + } + + area_ref->m_Poly->Close(); + } + } + + // add holes + for( int ic = 0; icnum_contours; ic++ ) + { + if( (union_gpc->hole)[ic] ) + { + // hole + for( int i = 0; icontour[ic].num_vertices; i++ ) + { + int x = ( (union_gpc->contour)[ic].vertex )[i].x; + int y = ( (union_gpc->contour)[ic].vertex )[i].y; + area_ref->m_Poly->AppendCorner( x, y ); + } + + area_ref->m_Poly->Close(); + } + } + + area_ref->utility = 1; + area_ref->m_Poly->RestoreArcs( &arc_array1 ); + area_ref->m_Poly->RestoreArcs( &arc_array2 ); + area_ref->m_Poly->Draw(); + gpc_free_polygon( union_gpc ); + delete union_gpc; + return 1; +} + + +#if 0 +void dra_areas( CDlgLog* log, int copper_layers, + int units, BOOL check_unrouted, + CArray * board_outline, + DesignRules* dr, DRErrorList* drelist ) +{ + CString d_str, x_str, y_str; + CString str; + CString str2; + long nerrors = 0; + + // now iterate through all areas + for( int ia = 0; ianareas; ia++ ) + { + carea* a = &net->area[ia]; + + // iterate through all nets again + POSITION pos2 = pos; + void* ptr2; + CString name2; + while( pos2 != NULL ) + { + m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 ); + cnet* net2 = (cnet*) ptr2; + for( int ia2 = 0; ia2nareas; ia2++ ) + { + carea* a2 = &net2->area[ia2]; + + // test for same layer + if( a->poly->GetLayer() == a2->poly->GetLayer() ) + { + // test for points inside one another + for( int ic = 0; icpoly->GetNumCorners(); ic++ ) + { + int x = a->poly->GetX( ic ); + int y = a->poly->GetY( ic ); + if( a2->poly->TestPointInside( x, y ) ) + { + // COPPERAREA_COPPERAREA error + id id_a = net->id; + id_a.st = ID_AREA; + id_a.i = ia; + id_a.sst = ID_SEL_CORNER; + id_a.ii = ic; + str.Format( + "%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n", + nerrors + 1, + net->name, + net2->name ); + DRError* dre = drelist->Add( nerrors, + DRError::COPPERAREA_INSIDE_COPPERAREA, + &str, + &net->name, + &net2->name, + id_a, + id_a, + x, + y, + x, + y, + 0, + 0 ); + if( dre ) + { + nerrors++; + if( log ) + log->AddLine( str ); + } + } + } + + for( int ic2 = 0; ic2poly->GetNumCorners(); ic2++ ) + { + int x = a2->poly->GetX( ic2 ); + int y = a2->poly->GetY( ic2 ); + if( a->poly->TestPointInside( x, y ) ) + { + // COPPERAREA_COPPERAREA error + id id_a = net2->id; + id_a.st = ID_AREA; + id_a.i = ia2; + id_a.sst = ID_SEL_CORNER; + id_a.ii = ic2; + str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n", + nerrors + 1, net2->name, net->name ); + DRError* dre = drelist->Add( nerrors, + DRError::COPPERAREA_INSIDE_COPPERAREA, + &str, + &net2->name, + &net->name, + id_a, + id_a, + x, + y, + x, + y, + 0, + 0 ); + if( dre ) + { + nerrors++; + if( log ) + log->AddLine( str ); + } + } + } + + // now test spacing between areas + for( int icont = 0; icontpoly->GetNumContours(); icont++ ) + { + int ic_start = a->poly->GetContourStart( icont ); + int ic_end = a->poly->GetContourEnd( icont ); + for( int ic = ic_start; ic<=ic_end; ic++ ) + { + id id_a = net->id; + id_a.st = ID_AREA; + 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 ax2, ay2; + if( ic == ic_end ) + { + ax2 = a->poly->GetX( ic_start ); + ay2 = a->poly->GetY( ic_start ); + } + else + { + ax2 = a->poly->GetX( ic + 1 ); + ay2 = a->poly->GetY( ic + 1 ); + } + int astyle = a->poly->GetSideStyle( ic ); + for( int icont2 = 0; icont2poly->GetNumContours(); icont2++ ) + { + int ic_start2 = a2->poly->GetContourStart( icont2 ); + int ic_end2 = a2->poly->GetContourEnd( icont2 ); + for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) + { + id id_b = net2->id; + id_b.st = ID_AREA; + 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 bx2, by2; + if( ic2 == ic_end2 ) + { + bx2 = a2->poly->GetX( ic_start2 ); + by2 = a2->poly->GetY( ic_start2 ); + } + else + { + bx2 = a2->poly->GetX( ic2 + 1 ); + by2 = a2->poly->GetY( ic2 + 1 ); + } + int bstyle = a2->poly->GetSideStyle( ic2 ); + int x, y; + int d = ::GetClearanceBetweenSegments( bx1, + by1, + bx2, + by2, + bstyle, + 0, + ax1, + ay1, + ax2, + ay2, + astyle, + 0, + dr->copper_copper, + &x, + &y ); + if( d < dr->copper_copper ) + { + // COPPERAREA_COPPERAREA error + ::MakeCStringFromDimension( &d_str, + d, + units, + TRUE, + TRUE, + TRUE, + 1 ); + ::MakeCStringFromDimension( &x_str, + x, + units, + FALSE, + TRUE, + TRUE, + 1 ); + ::MakeCStringFromDimension( &y_str, + y, + units, + FALSE, + TRUE, + TRUE, + 1 ); + str.Format( + "%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n", + nerrors + 1, + net->name, + net2->name, + d_str, + x_str, + y_str ); + DRError* dre = drelist->Add( + nerrors, + DRError:: + COPPERAREA_COPPERAREA, + &str, + &net->name, + &net2->name, + id_a, + id_b, + x, + y, + x, + y, + 0, + 0 ); + if( dre ) + { + nerrors++; + if( log ) + log->AddLine( str ); + } + } + } + } + } + } + } + } + } + } +} + + +#endif diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 6e3d8000d4..1d3a4a8a74 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -748,6 +748,19 @@ void CPolyLine::RemoveContour( int icont ) Draw(); } + +void CPolyLine::RemoveAllContours( void ) +/** + * function RemoveAllContours + * removes all corners from the lists. + * Others params are not chnaged + */ +{ + corner.clear( ); + side_style.clear( ); +} + + /** Function InsertCorner * insert a new corner between two existing corners * @param ic = index for the insertion point: the corner is inserted AFTER ic diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index 63361fac02..ed29344910 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -81,6 +81,7 @@ public: void MoveCorner( int ic, int x, int y ); void Close( int style = STRAIGHT, BOOL bDraw=TRUE ); void RemoveContour( int icont ); + void RemoveAllContours( void ); // drawing functions void HighlightSide( int is ); @@ -107,6 +108,7 @@ public: // access functions + int GetLayer() { return m_layer;} int GetNumCorners(); int GetNumSides(); int GetClosed(); @@ -125,7 +127,7 @@ public: id GetId(); int GetSelBoxSize(); CDisplayList * GetDisplayList(){ return m_dlist; }; - int GetHatch(){ return m_HatchStyle; } + 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 ); @@ -159,14 +161,14 @@ private: int m_Width; // line width int m_sel_box; // corner selection box width/2 int utility; -protected: +public: std::vector corner; // array of points for corners std::vector side_style; // array of styles for sides private: std::vector dl_side; // graphic elements std::vector dl_side_sel; std::vector dl_corner_sel; -protected: +public: int m_HatchStyle; // hatch style, see enum above std::vector m_HatchLines; // hatch lines private: