diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 690c4a9f23..34e2588360 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -33,6 +33,7 @@ #include #include #include +#include /** * Oblique angle for DXF native text @@ -61,47 +62,520 @@ static const double DXF_OBLIQUE_ANGLE = 15; */ static const struct { - const char *name; - int color; -} dxf_layer[NBCOLORS] = + const char* name; + int index; +} acad_dxf_color_names[]= { - { "BLACK", 7 }, // In DXF, color 7 is *both* white and black! - { "GRAY1", 251 }, - { "GRAY2", 8 }, - { "GRAY3", 9 }, - { "WHITE", 7 }, - { "LYELLOW", 51 }, - { "LORANGE", 41 }, - { "BLUE1", 178 }, - { "GREEN1", 98 }, - { "CYAN1", 138 }, - { "RED1", 18 }, - { "MAGENTA1", 228 }, - { "BROWN1", 58 }, - { "ORANGE1", 34 }, - { "BLUE2", 5 }, - { "GREEN2", 3 }, - { "CYAN2", 4 }, - { "RED2", 1 }, - { "MAGENTA2", 6 }, - { "BROWN2", 54 }, - { "ORANGE2", 42 }, - { "BLUE3", 171 }, - { "GREEN3", 91 }, - { "CYAN3", 131 }, - { "RED3", 11 }, - { "MAGENTA3", 221 }, - { "YELLOW3", 2 }, - { "ORANGE3", 32 }, - { "BLUE4", 5 }, - { "GREEN4", 3 }, - { "CYAN4", 4 }, - { "RED4", 1 }, - { "MAGENTA4", 6 }, - { "YELLOW4", 2 }, - { "ORANGE4", 40 } + { "BLACK", 250 }, + { "RED", 14 }, + { "YELLOW", 52 }, + { "GREEN", 94 }, + { "CYAN", 134 }, + { "BLUE", 174 }, + { "MAGENTA", 214 }, + { "WHITE", 250 }, + { "BROWN", 54 }, + { "ORANGE", 32 }, + { "LIGHTRED", 12 }, + { "LIGHTYELLOW", 51 }, + { "LIGHTGREEN", 92 }, + { "LIGHTCYAN", 132 }, + { "LIGHTBLUE", 172 }, + { "LIGHTMAGENTA", 212 }, + { "LIGHTORANGE", 30 }, + { "LIGHTGRAY", 9 }, + { "DARKRED", 16 }, + { "DARKYELLOW", 41 }, + { "DARKGREEN", 96 }, + { "DARKCYAN", 136 }, + { "DARKBLUE", 176 }, + { "DARKMAGENTA", 216 }, + { "DARKBROWN", 56 }, + { "DARKORANGE", 34 }, + { "DARKGRAY", 8 }, + { "PURERED", 1 }, + { "PUREYELLOW", 2 }, + { "PUREGREEN", 3 }, + { "PURECYAN", 4 }, + { "PUREBLUE", 5 }, + { "PUREMAGENTA", 6 }, + { "PUREORANGE", 40 }, + { "PUREGRAY", 57 }, + { "REDONE", 11 }, + { "REDTWO", 13 }, + { "REDTHREE", 15 }, + { "REDFOUR", 17 }, + { "REDFIVE", 18 }, + { "REDSIX", 19 }, + { "ORANGEONE", 20 }, + { "ORANGETWO", 21 }, + { "ORANGETHREE", 22 }, + { "ORANGEFOUR", 23 }, + { "ORANGEFIVE", 24 }, + { "REDSEVEN", 25 }, + { "REDEIGHT", 26 }, + { "ORANGESIX", 27 }, + { "REDNINE", 28 }, + { "ORANGESEVEN", 29 }, + { "ORANGEEIGHT", 31 }, + { "ORANGENINE", 33 }, + { "ORANGETEN", 35 }, + { "ORANGEELEVEN", 36 }, + { "ORANGETWELVE", 37 }, + { "ORANGETHIRTEEN", 38 }, + { "ORANGEFOURTEEN", 39 }, + { "YELLOWONE", 42 }, + { "YELLOWTWO", 43 }, + { "YELLOWTHREE", 44 }, + { "YELLOWFOUR", 45 }, + { "YELLOWFIVE", 46 }, + { "YELLOWSIX", 47 }, + { "YELLOWSEVEN", 48 }, + { "YELLOWEIGHT", 49 }, + { "YELLOWNINE", 53 }, + { "YELLOWTEN", 55 }, + { "YELLOWELEVEN", 58 }, + { "YELLOWTWELVE", 59 }, + { "YELLOWTHIRTEEN", 60 }, + { "YELLOWFOURTEEN", 61 }, + { "GREENONE", 62 }, + { "GREENTWO", 63 }, + { "GREENTHREE", 64 }, + { "GREENFOUR", 65 }, + { "GREENFIVE", 66 }, + { "GREENSIX", 67 }, + { "GREENSEVEN", 68 }, + { "GREENEIGHT", 69 }, + { "GREENNINE", 70 }, + { "GREENTEN", 71 }, + { "GREENELEVEN", 72 }, + { "GREENTWELVE", 73 }, + { "GREENTHIRTEEN", 74 }, + { "GREENFOURTEEN", 75 }, + { "GREENFIFTEEN", 76 }, + { "GREENSIXTEEN", 77 }, + { "GREENSEVENTEEN", 78 }, + { "GREENEIGHTEEN", 79 }, + { "GREENNINETEEN", 80 }, + { "GREENTWENTY", 81 }, + { "GREENTWENTYONE", 82 }, + { "GREENTWENTYTWO", 83 }, + { "GREENTWENTYTHREE", 84 }, + { "GREENTWENTYFOUR", 85 }, + { "GREENTWENTYFIVE", 86 }, + { "GREENTWENTYSIX", 87 }, + { "GREENTWENTYSEVEN", 88 }, + { "GREENTWENTYEIGHT", 89 }, + { "GREENTWENTYNINE", 90 }, + { "GREENTHIRTY", 91 }, + { "GREENTHIRTYONE", 93 }, + { "GREENTHIRTYTWO", 95 }, + { "GREENTHIRTYTHREE", 97 }, + { "GREENTHIRTYFOUR", 98 }, + { "GREENTHIRTYFIVE", 99 }, + { "GREENTHIRTYSIX", 100 }, + { "GREENTHIRTYSEVEN", 101 }, + { "GREENTHIRTYEIGHT", 102 }, + { "GREENTHIRTYNINE", 103 }, + { "GREENFORTY", 104 }, + { "GREENFORTYONE", 105 }, + { "GREENFORTYTWO", 106 }, + { "GREENFORTYTHREE", 107 }, + { "GREENFORTYFOUR", 108 }, + { "GREENFORTYFIVE", 109 }, + { "GREENFORTYSIX", 110 }, + { "GREENFORTYSEVEN", 111 }, + { "GREENFORTYEIGHT", 112 }, + { "GREENFORTYNINE", 113 }, + { "GREENFIFTY", 114 }, + { "GREENFIFTYONE", 115 }, + { "GREENFIFTYTWO", 116 }, + { "GREENFIFTYTHREE", 117 }, + { "GREENFIFTYFOUR", 118 }, + { "GREENFIFTYFIVE", 119 }, + { "GREENFIFTYSIX", 120 }, + { "GREENFIFTYSEVEN", 121 }, + { "GREENFIFTYEIGHT", 122 }, + { "GREENFIFTYNINE", 123 }, + { "GREENSIXTY", 124 }, + { "GREENSIXTYONE", 125 }, + { "GREENSIXTYTWO", 126 }, + { "GREENSIXTYTHREE", 127 }, + { "GREENSIXTYFOUR", 128 }, + { "GREENSIXTYFIVE", 129 }, + { "CYANONE", 131 }, + { "CYANTWO", 133 }, + { "CYANTHREE", 135 }, + { "CYANFOUR", 137 }, + { "CYANFIVE", 138 }, + { "CYANSIX", 139 }, + { "CYANSEVEN", 140 }, + { "BLUEONE", 141 }, + { "BLUETWO", 142 }, + { "BLUETHREE", 143 }, + { "BLUEFOUR", 144 }, + { "BLUEFIVE", 145 }, + { "BLUESIX", 146 }, + { "BLUESEVEN", 147 }, + { "BLUEEIGHT", 148 }, + { "BLUENINE", 149 }, + { "BLUETEN", 150 }, + { "BLUEELEVEN", 151 }, + { "BLUETWELVE", 152 }, + { "BLUETHIRTEEN", 153 }, + { "BLUEFOURTEEN", 154 }, + { "BLUEFIFTEEN", 155 }, + { "BLUESIXTEEN", 156 }, + { "BLUESEVENTEEN", 157 }, + { "BLUEEIGHTEEN", 158 }, + { "BLUENINETEEN", 159 }, + { "BLUETWENTY", 160 }, + { "BLUETWENTYONE", 161 }, + { "BLUETWENTYTWO", 162 }, + { "BLUETWENTYTHREE", 163 }, + { "BLUETWENTYFOUR", 164 }, + { "BLUETWENTYFIVE", 165 }, + { "BLUETWENTYSIX", 166 }, + { "BLUETWENTYSEVEN", 167 }, + { "BLUETWENTYEIGHT", 168 }, + { "BLUETWENTYNINE", 169 }, + { "BLUETHIRTY", 170 }, + { "BLUETHIRTYONE", 171 }, + { "BLUETHIRTYTWO", 177 }, + { "BLUETHIRTYETHREE", 178 }, + { "BLUETHIRTYFOUR", 179 }, + { "VIOLETONE", 180 }, + { "VIOLETTWO", 181 }, + { "VIOLETTHREE", 182 }, + { "VIOLETFOUR", 183 }, + { "VIOLETFIVE", 184 }, + { "VIOLETSIX", 185 }, + { "VIOLETSEVEN", 186 }, + { "VIOLETEIGHT", 187 }, + { "VIOLETNINE", 188 }, + { "VIOLETTEN", 189 }, + { "VIOLETELEVEN", 190 }, + { "VIOLETTWELVE", 191 }, + { "VIOLETTHIRTEEN", 192 }, + { "VIOLETFOURTEEN", 193 }, + { "VIOLETFIFTEEN", 194 }, + { "VIOLETSIXTEEN", 195 }, + { "VIOLETSEVENTEEN", 196 }, + { "VIOLETEIGHTEEN", 197 }, + { "VIOLETNINETEEN", 198 }, + { "VIOLETTWENTY", 199 }, + { "VIOLETTWENTYONE", 200 }, + { "VIOLETTWENTYTWO", 201 }, + { "VIOLETTWENTYTHREE", 202 }, + { "VIOLETTWENTYFOUR", 203 }, + { "VIOLETTWENTYFIVE", 204 }, + { "VIOLETTWENTYSIX", 205 }, + { "VIOLETTWENTYSEVEN", 206 }, + { "VIOLETTWENTYEIGHT", 207 }, + { "VIOLETTWENTYNINE", 208 }, + { "VIOLETTHIRTY", 209 }, + { "MAGENTAONE", 210 }, + { "MAGENTATWO", 211 }, + { "MAGENTATHREE", 213 }, + { "MAGENTAFOUR", 215 }, + { "MAGENTAFIVE", 217 }, + { "MAGENTASIX", 218 }, + { "MAGENTASEVEN", 219 }, + { "MAGENTAEIGHT", 220 }, + { "MAGENTANINE", 221 }, + { "MAGENTATEN", 222 }, + { "MAGENTAELEVEN", 223 }, + { "MAGENTATWELVE", 224 }, + { "MAGENTATHIRTEEN", 225 }, + { "MAGENTAFOURTEEN", 226 }, + { "REDTEN", 227 }, + { "REDELEVEN", 228 }, + { "VIOLETFIFTEEN", 229 }, + { "REDTWELVE", 230 }, + { "REDTHIRTEEN", 231 }, + { "REDFOURTEEN", 232 }, + { "REDFIFTEEN", 233 }, + { "REDSIXTEEN", 234 }, + { "REDSEVENTEEN", 235 }, + { "REDEIGHTEEN", 236 }, + { "REDNINETEEN", 237 }, + { "REDTWENTY", 238 }, + { "REDTWENTYONE", 239 }, + { "REDTWENTYTWO", 240 }, + { "REDTWENTYTHREE", 241 }, + { "REDTWENTYFOUR", 242 }, + { "REDTWENTYFIVE", 243 }, + { "REDTWENTYSIX", 244 }, + { "REDTWENTYSEVEN", 245 }, + { "REDTWENTYEIGHT", 246 }, + { "REDTWENTYNINE", 247 }, + { "REDTHIRTY", 248 }, + { "REDTHIRTYONE", 249 }, + { "GRAYONE", 251 }, + { "GRAYTWO", 252 }, + { "GRAYTHREE", 253 }, + { "GRAYFOUR", 254 } }; +// Array of predefined DXF color values, each entry containing blue, green, red components and a corresponding color number. +static const struct +{ + int blue; + int green; + int red; + DXF_COLOR_T colorNumber; +} acad_dxf_color_values[] = +{ + { 0, 0, 0, DXF_COLOR_T::BLACK }, + { 0, 0, 127, DXF_COLOR_T::RED, }, + { 0, 165, 165, DXF_COLOR_T::YELLOW, }, + { 0, 127, 0, DXF_COLOR_T::GREEN, }, + { 127, 127, 0, DXF_COLOR_T::CYAN, }, + { 127, 0, 0, DXF_COLOR_T::BLUE, }, + { 127, 0, 127, DXF_COLOR_T::MAGENTA, }, + { 255, 255, 255, DXF_COLOR_T::WHITE, }, + { 0, 127, 127, DXF_COLOR_T::BROWN, }, + { 0, 82, 165, DXF_COLOR_T::ORANGE, }, + { 0, 0, 165, DXF_COLOR_T::LIGHTRED, }, + { 127, 255, 255, DXF_COLOR_T::LIGHTYELLOW, }, + { 0, 165, 0, DXF_COLOR_T::LIGHTGREEN, }, + { 165, 165, 0, DXF_COLOR_T::LIGHTCYAN, }, + { 165, 0, 0, DXF_COLOR_T::LIGHTBLUE, }, + { 165, 0, 165, DXF_COLOR_T::LIGHTMAGENTA, }, + { 0, 127, 255, DXF_COLOR_T::LIGHTORANGE, }, + { 192, 192, 192, DXF_COLOR_T::LIGHTGRAY, }, + { 0, 0, 76, DXF_COLOR_T::DARKRED, }, + { 127, 223, 255, DXF_COLOR_T::DARKYELLOW, }, + { 0, 76, 0, DXF_COLOR_T::DARKGREEN, }, + { 76, 76, 0, DXF_COLOR_T::DARKCYAN, }, + { 76, 0, 0, DXF_COLOR_T::DARKBLUE, }, + { 76, 0, 76, DXF_COLOR_T::DARKMAGENTA, }, + { 0, 76, 76, DXF_COLOR_T::DARKBROWN, }, + { 0, 63, 127, DXF_COLOR_T::DARKORANGE, }, + { 128, 128, 128, DXF_COLOR_T::DARKGRAY, }, + { 0, 0, 255, DXF_COLOR_T::PURERED, }, + { 0, 255, 255, DXF_COLOR_T::PUREYELLOW, }, + { 0, 255, 0, DXF_COLOR_T::PUREGREEN, }, + { 255, 255, 0, DXF_COLOR_T::PURECYAN, }, + { 255, 0, 0, DXF_COLOR_T::PUREBLUE, }, + { 255, 0, 255, DXF_COLOR_T::PUREMAGENTA, }, + { 0, 191, 255, DXF_COLOR_T::PUREORANGE, }, + { 38, 76, 76, DXF_COLOR_T::PUREGRAY, }, + { 127, 127, 255, DXF_COLOR_T::REDONE, }, + { 82, 82, 165, DXF_COLOR_T::REDTWO, }, + { 63, 63, 127, DXF_COLOR_T::REDTHREE, }, + { 38, 38, 76, DXF_COLOR_T::REDFOUR, }, + { 0, 0, 38, DXF_COLOR_T::REDFIVE, }, + { 19, 19, 38, DXF_COLOR_T::REDSIX, }, + { 0, 63, 255, DXF_COLOR_T::ORANGEONE, }, + { 127, 159, 255, DXF_COLOR_T::ORANGETWO, }, + { 0, 41, 165, DXF_COLOR_T::ORANGETHREE, }, + { 82, 103, 165, DXF_COLOR_T::ORANGEFOUR, }, + { 0, 31, 127, DXF_COLOR_T::ORANGEFIVE, }, + { 63, 79, 127, DXF_COLOR_T::REDSEVEN, }, + { 0, 19, 76, DXF_COLOR_T::REDEIGHT, }, + { 38, 47, 76, DXF_COLOR_T::ORANGESIX, }, + { 0, 9, 38, DXF_COLOR_T::REDNINE, }, + { 19, 23, 38, DXF_COLOR_T::ORANGESEVEN, }, + { 127, 191, 255, DXF_COLOR_T::ORANGEEIGHT, }, + { 82, 124, 165, DXF_COLOR_T::ORANGENINE, }, + { 63, 95, 127, DXF_COLOR_T::ORANGETEN, }, + { 0, 38, 76, DXF_COLOR_T::ORANGEELEVEN, }, + { 38, 57, 76, DXF_COLOR_T::ORANGETWELVE, }, + { 0, 19, 38, DXF_COLOR_T::ORANGETHIRTEEN, }, + { 19, 28, 38, DXF_COLOR_T::ORANGEFOURTEEN, }, + { 0, 124, 165, DXF_COLOR_T::YELLOWONE, }, + { 82, 145, 165, DXF_COLOR_T::YELLOWTWO, }, + { 0, 95, 127, DXF_COLOR_T::YELLOWTHREE, }, + { 63, 111, 127, DXF_COLOR_T::YELLOWFOUR, }, + { 0, 57, 76, DXF_COLOR_T::YELLOWFIVE, }, + { 38, 66, 76, DXF_COLOR_T::YELLOWSIX, }, + { 0, 28, 38, DXF_COLOR_T::YELLOWSEVEN, }, + { 19, 33, 38, DXF_COLOR_T::YELLOWEIGHT, }, + { 82, 165, 165, DXF_COLOR_T::YELLOWNINE, }, + { 63, 127, 127, DXF_COLOR_T::YELLOWTEN, }, + { 0, 38, 38, DXF_COLOR_T::YELLOWELEVEN, }, + { 19, 38, 38, DXF_COLOR_T::YELLOWTWELVE, }, + { 0, 255, 191, DXF_COLOR_T::YELLOWTHIRTEEN, }, + { 127, 255, 223, DXF_COLOR_T::YELLOWFOURTEEN, }, + { 0, 165, 124, DXF_COLOR_T::GREENONE, }, + { 82, 165, 145, DXF_COLOR_T::GREENTWO, }, + { 0, 127, 95, DXF_COLOR_T::GREENTHREE, }, + { 63, 127, 111, DXF_COLOR_T::GREENFOUR, }, + { 0, 76, 57, DXF_COLOR_T::GREENFIVE, }, + { 38, 76, 66, DXF_COLOR_T::GREENSIX, }, + { 0, 38, 28, DXF_COLOR_T::GREENSEVEN, }, + { 19, 38, 33, DXF_COLOR_T::GREENEIGHT, }, + { 0, 255, 127, DXF_COLOR_T::GREENNINE, }, + { 127, 255, 191, DXF_COLOR_T::GREENTEN, }, + { 0, 165, 82, DXF_COLOR_T::GREENELEVEN, }, + { 82, 165, 124, DXF_COLOR_T::GREENTWELVE, }, + { 0, 127, 63, DXF_COLOR_T::GREENTHIRTEEN, }, + { 63, 127, 95, DXF_COLOR_T::GREENFOURTEEN, }, + { 0, 76, 38, DXF_COLOR_T::GREENFIFTEEN, }, + { 38, 76, 57, DXF_COLOR_T::GREENSIXTEEN, }, + { 0, 38, 19, DXF_COLOR_T::GREENSEVENTEEN, }, + { 19, 38, 28, DXF_COLOR_T::GREENEIGHTEEN, }, + { 0, 255, 63, DXF_COLOR_T::GREENNINETEEN, }, + { 127, 255, 159, DXF_COLOR_T::GREENTWENTY, }, + { 0, 165, 41, DXF_COLOR_T::GREENTWENTYONE, }, + { 82, 165, 103, DXF_COLOR_T::GREENTWENTYTWO, }, + { 0, 127, 31, DXF_COLOR_T::GREENTWENTYTHREE, }, + { 63, 127, 79, DXF_COLOR_T::GREENTWENTYFOUR, }, + { 0, 76, 19, DXF_COLOR_T::GREENTWENTYFIVE, }, + { 38, 76, 47, DXF_COLOR_T::GREENTWENTYSIX, }, + { 0, 38, 9, DXF_COLOR_T::GREENTWENTYSEVEN, }, + { 19, 38, 23, DXF_COLOR_T::GREENTWENTYEIGHT, }, + { 0, 255, 0, DXF_COLOR_T::GREENTWENTYNINE, }, + { 127, 255, 127, DXF_COLOR_T::GREENTHIRTY, }, + { 82, 165, 82, DXF_COLOR_T::GREENTHIRTYONE, }, + { 63, 127, 63, DXF_COLOR_T::GREENTHIRTYTWO, }, + { 38, 76, 38, DXF_COLOR_T::GREENTHIRTYTHREE, }, + { 0, 38, 0, DXF_COLOR_T::GREENTHIRTYFOUR, }, + { 19, 38, 19, DXF_COLOR_T::GREENTHIRTYFIVE, }, + { 63, 255, 0, DXF_COLOR_T::GREENTHIRTYSIX, }, + { 159, 255, 127, DXF_COLOR_T::GREENTHIRTYSEVEN, }, + { 41, 165, 0, DXF_COLOR_T::GREENTHIRTYEIGHT, }, + { 103, 165, 82, DXF_COLOR_T::GREENTHIRTYNINE, }, + { 31, 127, 0, DXF_COLOR_T::GREENFORTY, }, + { 79, 127, 63, DXF_COLOR_T::GREENFORTYONE, }, + { 19, 76, 0, DXF_COLOR_T::GREENFORTYTWO, }, + { 47, 76, 38, DXF_COLOR_T::GREENFORTYTHREE, }, + { 9, 38, 0, DXF_COLOR_T::GREENFORTYFOUR, }, + { 23, 88, 19, DXF_COLOR_T::GREENFORTYFIVE, }, + { 127, 255, 0, DXF_COLOR_T::GREENFORTYSIX, }, + { 191, 255, 127, DXF_COLOR_T::GREENFORTYSEVEN, }, + { 82, 165, 0, DXF_COLOR_T::GREENFORTYEIGHT, }, + { 95, 127, 63, DXF_COLOR_T::GREENFORTYNINE, }, + { 63, 127, 0, DXF_COLOR_T::GREENFIFTY, }, + { 95, 127, 63, DXF_COLOR_T::GREENFIFTYONE, }, + { 38, 76, 0, DXF_COLOR_T::GREENFIFTYTWO, }, + { 57, 76, 38, DXF_COLOR_T::GREENFIFTYTHREE, }, + { 19, 38, 0, DXF_COLOR_T::GREENFIFTYFOUR, }, + { 28, 88, 19, DXF_COLOR_T::GREENFIFTYFIVE, }, + { 191, 255, 0, DXF_COLOR_T::GREENFIFTYSIX, }, + { 223, 255, 127, DXF_COLOR_T::GREENFIFTYSEVEN, }, + { 124, 165, 0, DXF_COLOR_T::GREENFIFTYEIGHT, }, + { 145, 165, 82, DXF_COLOR_T::GREENFIFTYNINE, }, + { 95, 127, 0, DXF_COLOR_T::GREENSIXTY, }, + { 111, 127, 63, DXF_COLOR_T::GREENSIXTYONE, }, + { 57, 76, 0, DXF_COLOR_T::GREENSIXTYTWO, }, + { 66, 76, 38, DXF_COLOR_T::GREENSIXTYTHREE, }, + { 28, 38, 0, DXF_COLOR_T::GREENSIXTYFOUR, }, + { 88, 88, 19, DXF_COLOR_T::GREENSIXTYFIVE, }, + { 255, 255, 127, DXF_COLOR_T::CYANONE, }, + { 165, 165, 82, DXF_COLOR_T::CYANTWO, }, + { 127, 127, 63, DXF_COLOR_T::CYANTHREE, }, + { 76, 76, 38, DXF_COLOR_T::CYANFOUR, }, + { 38, 38, 0, DXF_COLOR_T::CYANFIVE, }, + { 88, 88, 19, DXF_COLOR_T::CYANSIX, }, + { 255, 191, 0, DXF_COLOR_T::CYANSEVEN, }, + { 255, 223, 127, DXF_COLOR_T::BLUEONE, }, + { 165, 124, 0, DXF_COLOR_T::BLUETWO, }, + { 165, 145, 82, DXF_COLOR_T::BLUETHREE, }, + { 127, 95, 0, DXF_COLOR_T::BLUEFOUR, }, + { 127, 111, 63, DXF_COLOR_T::BLUEFIVE, }, + { 76, 57, 0, DXF_COLOR_T::BLUESIX, }, + { 126, 66, 38, DXF_COLOR_T::BLUESEVEN, }, + { 38, 28, 0, DXF_COLOR_T::BLUEEIGHT, }, + { 88, 88, 19, DXF_COLOR_T::BLUENINE, }, + { 255, 127, 0, DXF_COLOR_T::BLUETEN, }, + { 255, 191, 127, DXF_COLOR_T::BLUEELEVEN, }, + { 165, 82, 0, DXF_COLOR_T::BLUETWELVE, }, + { 165, 124, 82, DXF_COLOR_T::BLUETHIRTEEN, }, + { 127, 63, 0, DXF_COLOR_T::BLUEFOURTEEN, }, + { 127, 95, 63, DXF_COLOR_T::BLUEFIFTEEN, }, + { 76, 38, 0, DXF_COLOR_T::BLUESIXTEEN, }, + { 126, 57, 38, DXF_COLOR_T::BLUESEVENTEEN, }, + { 38, 19, 0, DXF_COLOR_T::BLUEEIGHTEEN, }, + { 88, 28, 19, DXF_COLOR_T::BLUENINETEEN, }, + { 255, 63, 0, DXF_COLOR_T::BLUETWENTY, }, + { 255, 159, 127, DXF_COLOR_T::BLUETWENTYONE, }, + { 165, 41, 0, DXF_COLOR_T::BLUETWENTYTWO, }, + { 165, 103, 82, DXF_COLOR_T::BLUETWENTYTHREE, }, + { 127, 31, 0, DXF_COLOR_T::BLUETWENTYFOUR, }, + { 127, 79, 63, DXF_COLOR_T::BLUETWENTYFIVE, }, + { 76, 19, 0, DXF_COLOR_T::BLUETWENTYSIX, }, + { 126, 47, 38, DXF_COLOR_T::BLUETWENTYSEVEN, }, + { 38, 9, 0, DXF_COLOR_T::BLUETWENTYEIGHT, }, + { 88, 23, 19, DXF_COLOR_T::BLUETWENTYNINE, }, + { 255, 0, 0, DXF_COLOR_T::BLUETHIRTY, }, + { 255, 127, 127, DXF_COLOR_T::BLUETHIRTYONE, }, + { 126, 38, 38, DXF_COLOR_T::BLUETHIRTYTWO, }, + { 38, 0, 0, DXF_COLOR_T::BLUETHIRTYETHREE, }, + { 88, 19, 19, DXF_COLOR_T::BLUETHIRTYFOUR, }, + { 255, 0, 63, DXF_COLOR_T::VIOLETONE, }, + { 255, 127, 159, DXF_COLOR_T::VIOLETTWO, }, + { 165, 0, 41, DXF_COLOR_T::VIOLETTHREE, }, + { 165, 82, 103, DXF_COLOR_T::VIOLETFOUR, }, + { 127, 0, 31, DXF_COLOR_T::VIOLETFIVE, }, + { 127, 63, 79, DXF_COLOR_T::VIOLETSIX, }, + { 76, 0, 19, DXF_COLOR_T::VIOLETSEVEN, }, + { 126, 38, 47, DXF_COLOR_T::VIOLETEIGHT, }, + { 38, 0, 9, DXF_COLOR_T::VIOLETNINE, }, + { 88, 19, 23, DXF_COLOR_T::VIOLETTEN, }, + { 255, 0, 127, DXF_COLOR_T::VIOLETELEVEN, }, + { 255, 127, 191, DXF_COLOR_T::VIOLETTWELVE, }, + { 165, 0, 82, DXF_COLOR_T::VIOLETTHIRTEEN, }, + { 165, 82, 124, DXF_COLOR_T::VIOLETFOURTEEN, }, + { 127, 0, 63, DXF_COLOR_T::VIOLETFIFTEEN, }, + { 127, 63, 95, DXF_COLOR_T::VIOLETSIXTEEN, }, + { 76, 0, 38, DXF_COLOR_T::VIOLETSEVENTEEN, }, + { 126, 38, 57, DXF_COLOR_T::VIOLETEIGHTEEN, }, + { 38, 0, 19, DXF_COLOR_T::VIOLETNINETEEN, }, + { 88, 19, 28, DXF_COLOR_T::VIOLETTWENTY, }, + { 255, 0, 191, DXF_COLOR_T::VIOLETTWENTYONE, }, + { 255, 127, 223, DXF_COLOR_T::VIOLETTWENTYTWO, }, + { 165, 0, 124, DXF_COLOR_T::VIOLETTWENTYTHREE, }, + { 165, 82, 145, DXF_COLOR_T::VIOLETTWENTYFOUR, }, + { 127, 0, 95, DXF_COLOR_T::VIOLETTWENTYFIVE, }, + { 127, 63, 111, DXF_COLOR_T::VIOLETTWENTYSIX, }, + { 76, 0, 57, DXF_COLOR_T::VIOLETTWENTYSEVEN, }, + { 76, 38, 66, DXF_COLOR_T::VIOLETTWENTYEIGHT, }, + { 38, 0, 28, DXF_COLOR_T::VIOLETTWENTYNINE, }, + { 88, 19, 88, DXF_COLOR_T::VIOLETTHIRTY, }, + { 255, 0, 255, DXF_COLOR_T::MAGENTAONE, }, + { 255, 127, 255, DXF_COLOR_T::MAGENTATWO, }, + { 165, 82, 165, DXF_COLOR_T::MAGENTATHREE, }, + { 127, 63, 127, DXF_COLOR_T::MAGENTAFOUR, }, + { 76, 38, 76, DXF_COLOR_T::MAGENTAFIVE, }, + { 38, 0, 38, DXF_COLOR_T::MAGENTASIX, }, + { 88, 19, 88, DXF_COLOR_T::MAGENTASEVEN, }, + { 191, 0, 255, DXF_COLOR_T::MAGENTAEIGHT, }, + { 223, 127, 255, DXF_COLOR_T::MAGENTANINE, }, + { 124, 0, 165, DXF_COLOR_T::MAGENTATEN, }, + { 145, 82, 165, DXF_COLOR_T::MAGENTAELEVEN, }, + { 95, 0, 127, DXF_COLOR_T::MAGENTATWELVE, }, + { 111, 63, 127, DXF_COLOR_T::MAGENTATHIRTEEN, }, + { 57, 0, 76, DXF_COLOR_T::MAGENTAFOURTEEN, }, + { 66, 38, 76, DXF_COLOR_T::REDTEN, }, + { 28, 0, 38, DXF_COLOR_T::REDELEVEN, }, + { 88, 19, 88, DXF_COLOR_T::VIOLETFIFTEEN, }, + { 127, 0, 255, DXF_COLOR_T::REDTWELVE, }, + { 191, 127, 255, DXF_COLOR_T::REDTHIRTEEN, }, + { 82, 0, 165, DXF_COLOR_T::REDFOURTEEN, }, + { 124, 82, 165, DXF_COLOR_T::REDFIFTEEN, }, + { 63, 0, 127, DXF_COLOR_T::REDSIXTEEN, }, + { 95, 63, 127, DXF_COLOR_T::REDSEVENTEEN, }, + { 38, 0, 76, DXF_COLOR_T::REDEIGHTEEN, }, + { 57, 38, 76, DXF_COLOR_T::REDNINETEEN, }, + { 19, 0, 38, DXF_COLOR_T::REDTWENTY, }, + { 28, 19, 88, DXF_COLOR_T::REDTWENTYONE, }, + { 63, 0, 255, DXF_COLOR_T::REDTWENTYTWO, }, + { 159, 127, 255, DXF_COLOR_T::REDTWENTYTHREE, }, + { 41, 0, 165, DXF_COLOR_T::REDTWENTYFOUR, }, + { 103, 82, 165, DXF_COLOR_T::REDTWENTYFIVE, }, + { 31, 0, 127, DXF_COLOR_T::REDTWENTYSIX, }, + { 79, 63, 127, DXF_COLOR_T::REDTWENTYSEVEN, }, + { 19, 0, 76, DXF_COLOR_T::REDTWENTYEIGHT, }, + { 47, 38, 76, DXF_COLOR_T::REDTWENTYNINE, }, + { 9, 0, 38, DXF_COLOR_T::REDTHIRTY, }, + { 23, 19, 88, DXF_COLOR_T::REDTHIRTYONE, }, + { 101, 101, 101, DXF_COLOR_T::GRAYONE, }, + { 102, 102, 102, DXF_COLOR_T::GRAYTWO, }, + { 153, 153, 153, DXF_COLOR_T::GRAYTHREE, }, + { 204, 204, 204, DXF_COLOR_T::GRAYFOUR, } +}; static const char* getDXFLineType( LINE_STYLE aType ) { @@ -124,16 +598,97 @@ static const char* getDXFLineType( LINE_STYLE aType ) } } - -// A helper function to create a color name acceptable in DXF files -// DXF files do not use a RGB definition -static wxString getDXFColorName( const COLOR4D& aColor ) +int DXF_PLOTTER::FindNearestLegacyColor( int aR, int aG, int aB ) { - EDA_COLOR_T color = COLOR4D::FindNearestLegacyColor( int( aColor.r * 255 ), - int( aColor.g * 255 ), - int( aColor.b * 255 ) ); - wxString cname( dxf_layer[color].name ); - return cname; + int nearestColorValueIndex = static_cast(DXF_COLOR_T::BLACK); + + int nearestDistance = std::numeric_limits::max(); + + for( int trying = static_cast(DXF_COLOR_T::BLACK); trying < static_cast(DXF_COLOR_T::NBCOLORS); trying++ ) + { + auto c = acad_dxf_color_values[trying]; + int distance = ( aR - c.red ) * ( aR - c.red ) + ( aG - c.green ) * ( aG - c.green ) + + ( aB - c.blue ) * ( aB - c.blue ); + + if( distance < nearestDistance ) + { + nearestDistance = distance; + nearestColorValueIndex = trying; + } + } + + return nearestColorValueIndex; +} + + +/** + * @brief Retrieves the current layer name or layer color name for DXF plotting. + * + * This function returns the appropriate layer name or layer color name depending on the specified + * DXF_LAYER_OUTPUT_MODE. DXF files do not use RGB definitions for colors, so this function converts + * the color to the nearest legacy color name acceptable in DXF files. + * + * @param mode The mode determining whether to return the layer name or layer color name. + * @param layerId Optional parameter specifying the layer ID to use. If not provided, the current layer ID is used. + * @return The layer name or color name as a wxString. + * + * The function operates in two main modes: + * 1. Layer_Name or Current_Layer_Name: Returns the name of the specified layer or the current layer. + * - Searches through the `m_layersToExport` list to find the matching layer ID. + * - If the layer ID is found, returns the corresponding layer name. + * - If not found, defaults to "BLACK". + * + * 2. Layer_Color_Name or Current_Layer_Color_Name: Returns the color name of the specified layer or the current layer. + * - Retrieves the color of the layer from the render settings. + * - Finds the nearest legacy color that matches the layer's color. + * - Returns the name of the nearest legacy color. + * + * If the mode is unknown, returns "Unknown Mode". + */ +wxString DXF_PLOTTER::GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE aMode, std::optional alayerId ) +{ + PCB_LAYER_ID actualLayerId = ( alayerId.has_value() ) ? alayerId.value() : m_layer; + + switch( aMode ) + { + case DXF_LAYER_OUTPUT_MODE::Layer_Name: + case DXF_LAYER_OUTPUT_MODE::Current_Layer_Name: + { + if( m_layersToExport.empty() ) + { + COLOR4D layerColor = ( aMode == DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ) + ? m_currentColor + : RenderSettings()->GetLayerColor( actualLayerId ); + + int color = FindNearestLegacyColor( + int( layerColor.r * 255 ), int( layerColor.g * 255 ), int( layerColor.b * 255 ) ); + return wxString( acad_dxf_color_names[color].name ); + } + + auto it = std::find_if( m_layersToExport.begin(), m_layersToExport.end(), + [actualLayerId]( const std::pair& element ) + { + return element.first == actualLayerId; + } ); + + return ( it != m_layersToExport.end() ) ? it->second : wxString( "BLACK" ); + } + + case DXF_LAYER_OUTPUT_MODE::Layer_Color_Name: + case DXF_LAYER_OUTPUT_MODE::Current_Layer_Color_Name: + { + COLOR4D layerColor = ( aMode == DXF_LAYER_OUTPUT_MODE::Current_Layer_Color_Name ) + ? RenderSettings()->GetLayerColor( GetLayer() ) + : RenderSettings()->GetLayerColor( actualLayerId ); + + int color = FindNearestLegacyColor( + int( layerColor.r * 255 ), int( layerColor.g * 255 ), int( layerColor.b * 255 ) ); + wxString cname( acad_dxf_color_names[color].name ); + return cname; + } + + default: return wxString( "Unknown Mode" ); + } } @@ -208,117 +763,117 @@ bool DXF_PLOTTER::StartPlot( const wxString& aPageNumber ) // Defines the minimum for drawing i.e. the angle system and the // 4 linetypes (CONTINUOUS, DOTDASH, DASHED and DOTTED) fmt::print( m_outputFile, - " 0\n" - "SECTION\n" - " 2\n" - "HEADER\n" - " 9\n" - "$ANGBASE\n" - " 50\n" - "0.0\n" - " 9\n" - "$ANGDIR\n" - " 70\n" - "1\n" - " 9\n" - "$MEASUREMENT\n" - " 70\n" - "{}\n" - " 0\n" - "ENDSEC\n" - " 0\n" - "SECTION\n" - " 2\n" - "TABLES\n" - " 0\n" - "TABLE\n" - " 2\n" - "LTYPE\n" - " 70\n" - "4\n" - " 0\n" - "LTYPE\n" - " 5\n" - "40F\n" - " 2\n" - "CONTINUOUS\n" - " 70\n" - "0\n" - " 3\n" - "Solid line\n" - " 72\n" - "65\n" - " 73\n" - "0\n" - " 40\n" - "0.0\n" - " 0\n" - "LTYPE\n" - " 5\n" - "410\n" - " 2\n" - "DASHDOT\n" - " 70\n" - "0\n" - " 3\n" - "Dash Dot ____ _ ____ _\n" - " 72\n" - "65\n" - " 73\n" - "4\n" - " 40\n" - "2.0\n" - " 49\n" - "1.25\n" - " 49\n" - "-0.25\n" - " 49\n" - "0.25\n" - " 49\n" - "-0.25\n" - " 0\n" - "LTYPE\n" - " 5\n" - "411\n" - " 2\n" - "DASHED\n" - " 70\n" - "0\n" - " 3\n" - "Dashed __ __ __ __ __\n" - " 72\n" - "65\n" - " 73\n" - "2\n" - " 40\n" - "0.75\n" - " 49\n" - "0.5\n" - " 49\n" - "-0.25\n" - " 0\n" - "LTYPE\n" - " 5\n" - "43B\n" - " 2\n" - "DOTTED\n" - " 70\n" - "0\n" - " 3\n" - "Dotted . . . .\n" - " 72\n" - "65\n" - " 73\n" - "2\n" - " 40\n" - "0.2\n" - " 49\n" - "0.0\n" - " 49\n" - "-0.2\n" - " 0\n" - "ENDTAB\n", - GetMeasurementDirective() ); + " 0\n" + "SECTION\n" + " 2\n" + "HEADER\n" + " 9\n" + "$ANGBASE\n" + " 50\n" + "0.0\n" + " 9\n" + "$ANGDIR\n" + " 70\n" + "1\n" + " 9\n" + "$MEASUREMENT\n" + " 70\n" + "{}\n" + " 0\n" + "ENDSEC\n" + " 0\n" + "SECTION\n" + " 2\n" + "TABLES\n" + " 0\n" + "TABLE\n" + " 2\n" + "LTYPE\n" + " 70\n" + "4\n" + " 0\n" + "LTYPE\n" + " 5\n" + "40F\n" + " 2\n" + "CONTINUOUS\n" + " 70\n" + "0\n" + " 3\n" + "Solid line\n" + " 72\n" + "65\n" + " 73\n" + "0\n" + " 40\n" + "0.0\n" + " 0\n" + "LTYPE\n" + " 5\n" + "410\n" + " 2\n" + "DASHDOT\n" + " 70\n" + "0\n" + " 3\n" + "Dash Dot ____ _ ____ _\n" + " 72\n" + "65\n" + " 73\n" + "4\n" + " 40\n" + "2.0\n" + " 49\n" + "1.25\n" + " 49\n" + "-0.25\n" + " 49\n" + "0.25\n" + " 49\n" + "-0.25\n" + " 0\n" + "LTYPE\n" + " 5\n" + "411\n" + " 2\n" + "DASHED\n" + " 70\n" + "0\n" + " 3\n" + "Dashed __ __ __ __ __\n" + " 72\n" + "65\n" + " 73\n" + "2\n" + " 40\n" + "0.75\n" + " 49\n" + "0.5\n" + " 49\n" + "-0.25\n" + " 0\n" + "LTYPE\n" + " 5\n" + "43B\n" + " 2\n" + "DOTTED\n" + " 70\n" + "0\n" + " 3\n" + "Dotted . . . .\n" + " 72\n" + "65\n" + " 73\n" + "2\n" + " 40\n" + "0.2\n" + " 49\n" + "0.0\n" + " 49\n" + "-0.2\n" + " 0\n" + "ENDTAB\n", + GetMeasurementDirective() ); // Text styles table // Defines 4 text styles, one for each bold/italic combination @@ -359,11 +914,12 @@ bool DXF_PLOTTER::StartPlot( const wxString& aPageNumber ) style_name[i], i < 2 ? 0 : DXF_OBLIQUE_ANGLE ); } - EDA_COLOR_T numLayers = NBCOLORS; + int numLayers = static_cast( !m_layersToExport.empty() ? m_layersToExport.size() : static_cast(DXF_COLOR_T::NBCOLORS) ); // If printing in monochrome, only output the black layer - if( !GetColorMode() ) - numLayers = static_cast( 1 ); + if( !GetColorMode() && m_layersToExport.empty() ) + numLayers = 1; + // Layer table - one layer per color fmt::print( m_outputFile, @@ -383,22 +939,69 @@ bool DXF_PLOTTER::StartPlot( const wxString& aPageNumber ) - Greys (251 - 255) */ - wxASSERT( numLayers <= NBCOLORS ); + wxString layerName; + int colorNumber; - for( EDA_COLOR_T i = BLACK; i < numLayers; i = static_cast( int( i ) + 1 ) ) + bool hasActualColor = false; + COLOR4D actualColor; + + for( int i = 0; i < numLayers; i++ ) { + if( !m_layersToExport.empty() ) + { + layerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Layer_Name, m_layersToExport.at( i ).first ); + wxString colorName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Layer_Color_Name, m_layersToExport.at( i ).first ); + + auto it = std::find_if( std::begin( acad_dxf_color_names ), std::end( acad_dxf_color_names ), + [colorName](const auto& layer) + { + return std::strcmp( layer.name, colorName.ToStdString().c_str() ) == 0; + }); + + if( it != std::end( acad_dxf_color_names ) ) + colorNumber = it->index; + else + colorNumber = 7; // Default to white/black + + actualColor = RenderSettings()->GetLayerColor( m_layersToExport.at( i ).first ); + hasActualColor = true; + } + else + { + layerName = wxString( acad_dxf_color_names[i].name ); + colorNumber = acad_dxf_color_names[i].index; + } + fmt::print( m_outputFile, - " 0\n" - "LAYER\n" - " 2\n" - "{}\n" // Layer name - " 70\n" - "0\n" // Standard flags - " 62\n" - "{}\n" // Color number - " 6\n" - "CONTINUOUS\n",// Linetype name - dxf_layer[i].name, dxf_layer[i].color ); + " 0\n" + "LAYER\n" + " 2\n" + "{}\n" // Layer name + " 70\n" + "0\n" // Standard flags + " 62\n" + "{}\n", // Color number + TO_UTF8( layerName ), + colorNumber ); + + if( hasActualColor ) + { + // Add the true color value as an extended data entry + int r = static_cast( actualColor.r * 255 ); + int g = static_cast( actualColor.g * 255 ); + int b = static_cast( actualColor.b * 255 ); + + int trueColorValue = ( r << 16 ) | ( g << 8 ) | b; + + fmt::print( m_outputFile, + " 420\n" + "{}\n", + trueColorValue ); + } + + fmt::print( m_outputFile, + " 6\n" + "CONTINUOUS\n");// Linetype name } // End of layer table, begin entities @@ -474,13 +1077,14 @@ void DXF_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int else { // Draw as a point - wxString cname = getDXFColorName( m_currentColor ); + wxString cLayerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ); + VECTOR2D point_dev = userToDeviceCoordinates( p1 ); - fmt::print( m_outputFile, "0\nPOINT\n8\n{}\n10\n{}\n20\n{}\n", - TO_UTF8( cname ), - formatCoord( point_dev.x ), - formatCoord( point_dev.y ) ); + fmt::print( m_outputFile, "0\nPOINT\n8\n{}\n10\n{}\n20\n", + TO_UTF8( cLayerName ), + formatCoord( point_dev.x ), + formatCoord( point_dev.y ) ); } } @@ -491,14 +1095,14 @@ void DXF_PLOTTER::Circle( const VECTOR2I& centre, int diameter, FILL_T fill, int double radius = userToDeviceSize( diameter / 2 ); VECTOR2D centre_dev = userToDeviceCoordinates( centre ); - wxString cname = getDXFColorName( m_currentColor ); + wxString cLayerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ); if( radius > 0 ) { if( fill == FILL_T::NO_FILL ) { fmt::print( m_outputFile, "0\nCIRCLE\n8\n{}\n10\n{}\n20\n{}\n40\n{}\n", - TO_UTF8( cname ), + TO_UTF8( cLayerName ), formatCoord( centre_dev.x ), formatCoord( centre_dev.y ), formatCoord( radius ) ); @@ -507,26 +1111,25 @@ void DXF_PLOTTER::Circle( const VECTOR2I& centre, int diameter, FILL_T fill, int { double r = radius * 0.5; fmt::print( m_outputFile, "0\nPOLYLINE\n" ); - fmt::print( m_outputFile, "8\n{}\n66\n1\n70\n1\n", TO_UTF8( cname ) ); + fmt::print( m_outputFile, "8\n{}\n66\n1\n70\n1\n", TO_UTF8( cLayerName ) ); fmt::print( m_outputFile, "40\n{}\n41\n{}\n", - formatCoord( radius ), - formatCoord( radius ) ); - fmt::print( m_outputFile, "0\nVERTEX\n8\n{}\n", TO_UTF8( cname ) ); + formatCoord( radius ), + formatCoord( radius ) ); + fmt::print( m_outputFile, "0\nVERTEX\n8\n{}\n", TO_UTF8( cLayerName ) ); fmt::print( m_outputFile, "10\n{}\n 20\n{}\n42\n1.0\n", - formatCoord( centre_dev.x-r ), - formatCoord( centre_dev.y ) ); - fmt::print( m_outputFile, "0\nVERTEX\n8\n{}\n", TO_UTF8( cname ) ); + formatCoord( centre_dev.x-r ), + formatCoord( centre_dev.y ) ); + fmt::print( m_outputFile, "0\nVERTEX\n8\n{}\n", TO_UTF8( cLayerName ) ); fmt::print( m_outputFile, "10\n{}\n 20\n{}\n42\n1.0\n", - formatCoord( centre_dev.x+r ), - formatCoord( centre_dev.y ) ); + formatCoord( centre_dev.x+r ), + formatCoord( centre_dev.y ) ); fmt::print( m_outputFile, "0\nSEQEND\n" ); } } else { // Draw as a point - fmt::print( m_outputFile, "0\nPOINT\n8\n{}\n10\n{}\n20\n{}\n", - TO_UTF8( cname ), + fmt::print( m_outputFile, "0\nPOINT\n8\n{}\n10\n{}\n20\n{}\n", TO_UTF8( cLayerName ), formatCoord( centre_dev.x ), formatCoord( centre_dev.y ) ); } @@ -572,7 +1175,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector& aCornerList, FILL_T aFi for( unsigned ii = 1; ii < aCornerList.size(); ii++ ) { TransformOvalToPolygon( bufferOutline, aCornerList[ ii - 1 ], aCornerList[ ii ], - aWidth, GetPlotterArcHighDef(), ERROR_INSIDE ); + aWidth, GetPlotterArcHighDef(), ERROR_INSIDE ); } // enter the initial polygon: @@ -711,11 +1314,11 @@ void DXF_PLOTTER::PenTo( const VECTOR2I& pos, char plume ) && m_currentLineType <= LINE_STYLE::LAST_TYPE ); // DXF LINE - wxString cname = getDXFColorName( m_currentColor ); + wxString cLayerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ); + const char* lname = getDXFLineType( static_cast( m_currentLineType ) ); fmt::print( m_outputFile, "0\nLINE\n8\n{}\n6\n{}\n10\n{}\n20\n{}\n11\n{}\n21\n{}\n", - TO_UTF8( cname ), - lname, + TO_UTF8( cLayerName ), lname, formatCoord( pen_lastpos_dev.x ), formatCoord( pen_lastpos_dev.y ), formatCoord( pos_dev.x ), @@ -755,10 +1358,10 @@ void DXF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle, double radius_device = userToDeviceSize( aRadius ); // Emit a DXF ARC entity - wxString cname = getDXFColorName( m_currentColor ); + wxString cLayerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ); fmt::print( m_outputFile, "0\nARC\n8\n{}\n10\n{}\n20\n{}\n40\n{}\n50\n{:.8f}\n51\n{:.8f}\n", - TO_UTF8( cname ), + TO_UTF8( cLayerName ), formatCoord( centre_device.x ), formatCoord( centre_device.y ), formatCoord( radius_device ), @@ -1141,7 +1744,8 @@ void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor more useful as a CAD object */ VECTOR2D origin_dev = userToDeviceCoordinates( aPos ); SetColor( aColor ); - wxString cname = getDXFColorName( m_currentColor ); + wxString cLayerName = GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE::Current_Layer_Name ); + VECTOR2D size_dev = userToDeviceSize( aAttributes.m_Size ); int h_code = 0, v_code = 0; @@ -1204,8 +1808,9 @@ void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor "{}\n" // H alignment " 73\n" "{}\n", // V alignment - textStyle, - TO_UTF8( cname ), + aAttributes.m_Bold ? ( aAttributes.m_Italic ? "KICADBI" : "KICADB" ) + : ( aAttributes.m_Italic ? "KICADI" : "KICAD" ), + TO_UTF8( cLayerName ), formatCoord( origin_dev.x ), formatCoord( origin_dev.x ), formatCoord( origin_dev.y ), diff --git a/include/gal/color4d.h b/include/gal/color4d.h index adcc0a9ee1..7df89a2370 100644 --- a/include/gal/color4d.h +++ b/include/gal/color4d.h @@ -76,11 +76,12 @@ enum EDA_COLOR_T ORANGE, LIGHTORANGE, PUREORANGE, - NBCOLORS, ///< Number of colors - HIGHLIGHT_FLAG = ( 1<<19 ), - MASKCOLOR = 31 ///< mask for color index into colorRefs()[] + NBCOLORS, ///< Number of colors + HIGHLIGHT_FLAG = ( 1 << 19 ), + MASKCOLOR = 31 ///< mask for color index into colorRefs()[] }; + struct KICOMMON_API StructColors { unsigned char m_Blue; diff --git a/include/plotters/plotter.h b/include/plotters/plotter.h index d155f6ec2c..55165ef83f 100644 --- a/include/plotters/plotter.h +++ b/include/plotters/plotter.h @@ -111,6 +111,21 @@ public: }; +/** + * @enum DXF_LAYER_OUTPUT_MODE + * @brief Specifies the output mode for the DXF layer. + * + * This enumeration is used to define the mode of output for the DXF layer. + * It allows the user to choose between retrieving the layer name or the color name. + */ +enum class DXF_LAYER_OUTPUT_MODE +{ + Layer_Name, + Layer_Color_Name, + Current_Layer_Name, + Current_Layer_Color_Name +}; + /** * Base plotter engine class. General rule: all the interface with the caller * is done in IU, the IU size is specified with SetViewport. Internal and @@ -206,8 +221,39 @@ public: virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) = 0; + /** + * Sets the list of layers to export to the specified vector. + * + * This function updates the member variable m_layersToExport with the + * vector provided in aLayersToExport. + * + * @param aLayersToExport The vector containing the names of layers to export. + * This updates the internal list of layers that will + * be processed for export. + */ + void SetLayersToExport( const std::vector>& aLayersToExport ) { m_layersToExport = aLayersToExport; } + + /** + * @brief Gets the ID of the current layer. + * + * This function returns the ID of the layer that the current item is on. + * + * @return PCB_LAYER_ID The ID of the current layer. + */ + PCB_LAYER_ID GetLayer() const { return m_layer; } + + /** + * @brief Sets the ID of the current layer. + * + * This function sets the ID of the layer for the current item. + * + * @param aLayer The ID of the layer to be set. + */ + void SetLayer( PCB_LAYER_ID aLayer ) { m_layer = aLayer; } + /** * Open or create the plot file \a aFullFilename. + * . * * @param aFullFilename is the full file name of the file to create. * @return true if success, false if the file cannot be created/opened. @@ -646,7 +692,7 @@ protected: // variables used in most of plotters: * because in Eeschema there are 0.1 IUs in a decimil (Eeschema * always works in mils internally) while PcbNew can work in decimil * or nanometers, so this value would be >= 1 */ - double m_IUsPerDecimil; + double m_IUsPerDecimil; double m_iuPerDeviceUnit; // Device scale (from IUs to plotter device units; // usually decimils) @@ -679,6 +725,9 @@ protected: // variables used in most of plotters: RENDER_SETTINGS* m_renderSettings; const PROJECT* m_project; + std::vector> m_layersToExport; + + PCB_LAYER_ID m_layer; }; diff --git a/include/plotters/plotter_dxf.h b/include/plotters/plotter_dxf.h index 01e6d10d21..e5f851f0c2 100644 --- a/include/plotters/plotter_dxf.h +++ b/include/plotters/plotter_dxf.h @@ -21,6 +21,262 @@ #include "plotter.h" +/** + * Legacy colors for DXF file. + */ +enum class DXF_COLOR_T +{ + BLACK = 0, + RED, + YELLOW, + GREEN, + CYAN, + BLUE, + MAGENTA, + WHITE, + BROWN, + ORANGE, + LIGHTRED, + LIGHTYELLOW, + LIGHTGREEN, + LIGHTCYAN, + LIGHTBLUE, + LIGHTMAGENTA, + LIGHTORANGE, + LIGHTGRAY, + DARKRED, + DARKYELLOW, + DARKGREEN, + DARKCYAN, + DARKBLUE, + DARKMAGENTA, + DARKBROWN, + DARKORANGE, + DARKGRAY, + PURERED, + PUREYELLOW, + PUREGREEN, + PURECYAN, + PUREBLUE, + PUREMAGENTA, + PUREORANGE, + PUREGRAY, + REDONE, + REDTWO, + REDTHREE, + REDFOUR, + REDFIVE, + REDSIX, + ORANGEONE, + ORANGETWO, + ORANGETHREE, + ORANGEFOUR, + ORANGEFIVE, + REDSEVEN, + REDEIGHT, + ORANGESIX, + REDNINE, + ORANGESEVEN, + ORANGEEIGHT, + ORANGENINE, + ORANGETEN, + ORANGEELEVEN, + ORANGETWELVE, + ORANGETHIRTEEN, + ORANGEFOURTEEN, + YELLOWONE, + YELLOWTWO, + YELLOWTHREE, + YELLOWFOUR, + YELLOWFIVE, + YELLOWSIX, + YELLOWSEVEN, + YELLOWEIGHT, + YELLOWNINE, + YELLOWTEN, + YELLOWELEVEN, + YELLOWTWELVE, + YELLOWTHIRTEEN, + YELLOWFOURTEEN, + GREENONE, + GREENTWO, + GREENTHREE, + GREENFOUR, + GREENFIVE, + GREENSIX, + GREENSEVEN, + GREENEIGHT, + GREENNINE, + GREENTEN, + GREENELEVEN, + GREENTWELVE, + GREENTHIRTEEN, + GREENFOURTEEN, + GREENFIFTEEN, + GREENSIXTEEN, + GREENSEVENTEEN, + GREENEIGHTEEN, + GREENNINETEEN, + GREENTWENTY, + GREENTWENTYONE, + GREENTWENTYTWO, + GREENTWENTYTHREE, + GREENTWENTYFOUR, + GREENTWENTYFIVE, + GREENTWENTYSIX, + GREENTWENTYSEVEN, + GREENTWENTYEIGHT, + GREENTWENTYNINE, + GREENTHIRTY, + GREENTHIRTYONE, + GREENTHIRTYTWO, + GREENTHIRTYTHREE, + GREENTHIRTYFOUR, + GREENTHIRTYFIVE, + GREENTHIRTYSIX, + GREENTHIRTYSEVEN, + GREENTHIRTYEIGHT, + GREENTHIRTYNINE, + GREENFORTY, + GREENFORTYONE, + GREENFORTYTWO, + GREENFORTYTHREE, + GREENFORTYFOUR, + GREENFORTYFIVE, + GREENFORTYSIX, + GREENFORTYSEVEN, + GREENFORTYEIGHT, + GREENFORTYNINE, + GREENFIFTY, + GREENFIFTYONE, + GREENFIFTYTWO, + GREENFIFTYTHREE, + GREENFIFTYFOUR, + GREENFIFTYFIVE, + GREENFIFTYSIX, + GREENFIFTYSEVEN, + GREENFIFTYEIGHT, + GREENFIFTYNINE, + GREENSIXTY, + GREENSIXTYONE, + GREENSIXTYTWO, + GREENSIXTYTHREE, + GREENSIXTYFOUR, + GREENSIXTYFIVE, + CYANONE, + CYANTWO, + CYANTHREE, + CYANFOUR, + CYANFIVE, + CYANSIX, + CYANSEVEN, + BLUEONE, + BLUETWO, + BLUETHREE, + BLUEFOUR, + BLUEFIVE, + BLUESIX, + BLUESEVEN, + BLUEEIGHT, + BLUENINE, + BLUETEN, + BLUEELEVEN, + BLUETWELVE, + BLUETHIRTEEN, + BLUEFOURTEEN, + BLUEFIFTEEN, + BLUESIXTEEN, + BLUESEVENTEEN, + BLUEEIGHTEEN, + BLUENINETEEN, + BLUETWENTY, + BLUETWENTYONE, + BLUETWENTYTWO, + BLUETWENTYTHREE, + BLUETWENTYFOUR, + BLUETWENTYFIVE, + BLUETWENTYSIX, + BLUETWENTYSEVEN, + BLUETWENTYEIGHT, + BLUETWENTYNINE, + BLUETHIRTY, + BLUETHIRTYONE, + BLUETHIRTYTWO, + BLUETHIRTYETHREE, + BLUETHIRTYFOUR, + VIOLETONE, + VIOLETTWO, + VIOLETTHREE, + VIOLETFOUR, + VIOLETFIVE, + VIOLETSIX, + VIOLETSEVEN, + VIOLETEIGHT, + VIOLETNINE, + VIOLETTEN, + VIOLETELEVEN, + VIOLETTWELVE, + VIOLETTHIRTEEN, + VIOLETFOURTEEN, + VIOLETFIFTEEN, + VIOLETSIXTEEN, + VIOLETSEVENTEEN, + VIOLETEIGHTEEN, + VIOLETNINETEEN, + VIOLETTWENTY, + VIOLETTWENTYONE, + VIOLETTWENTYTWO, + VIOLETTWENTYTHREE, + VIOLETTWENTYFOUR, + VIOLETTWENTYFIVE, + VIOLETTWENTYSIX, + VIOLETTWENTYSEVEN, + VIOLETTWENTYEIGHT, + VIOLETTWENTYNINE, + VIOLETTHIRTY, + MAGENTAONE, + MAGENTATWO, + MAGENTATHREE, + MAGENTAFOUR, + MAGENTAFIVE, + MAGENTASIX, + MAGENTASEVEN, + MAGENTAEIGHT, + MAGENTANINE, + MAGENTATEN, + MAGENTAELEVEN, + MAGENTATWELVE, + MAGENTATHIRTEEN, + MAGENTAFOURTEEN, + REDTEN, + REDELEVEN, + VIOLETTHIRTYONE, + REDTWELVE, + REDTHIRTEEN, + REDFOURTEEN, + REDFIFTEEN, + REDSIXTEEN, + REDSEVENTEEN, + REDEIGHTEEN, + REDNINETEEN, + REDTWENTY, + REDTWENTYONE, + REDTWENTYTWO, + REDTWENTYTHREE, + REDTWENTYFOUR, + REDTWENTYFIVE, + REDTWENTYSIX, + REDTWENTYSEVEN, + REDTWENTYEIGHT, + REDTWENTYNINE, + REDTHIRTY, + REDTHIRTYONE, + GRAYONE, + GRAYTWO, + GRAYTHREE, + GRAYFOUR, + NBCOLORS ///< Number of colors +}; class DXF_PLOTTER : public PLOTTER { @@ -220,6 +476,12 @@ public: return m_measurementDirective; } + // Finds the nearest legacy color to the given RGB values (aR, aG, aB). + int FindNearestLegacyColor( int aR, int aG, int aB ); + + // Retrieves the current layer name based on the output mode and optional layer ID. + wxString GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE aMode, std::optional aLayerId = std::nullopt ); + protected: void plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText, const TEXT_ATTRIBUTES& aAttrs ); diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 4c5c621c70..eb23ce7801 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -207,28 +207,28 @@ DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, JOB_EXP m_plotAllLayersList->SetClientObject( list_idx, new PCB_LAYER_ID_CLIENT_DATA( layer_id ) ); } - sbSizer->Add( m_plotAllLayersList, 1, wxALL | wxEXPAND | wxFIXED_MINSIZE, 3 ); + sbSizer->Add( m_plotAllLayersList, 1, wxALL | wxEXPAND | wxFIXED_MINSIZE, 3 ); - wxBoxSizer* bButtonSizer; - bButtonSizer = new wxBoxSizer( wxHORIZONTAL ); + wxBoxSizer* bButtonSizer; + bButtonSizer = new wxBoxSizer( wxHORIZONTAL ); - m_bpMoveUp = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, + m_bpMoveUp = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 ); - m_bpMoveUp->SetToolTip( _( "Move current selection up" ) ); + m_bpMoveUp->SetToolTip( _( "Move current selection up" ) ); m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) ); - bButtonSizer->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3 ); + bButtonSizer->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3 ); - m_bpMoveDown = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, + m_bpMoveDown = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 ); - m_bpMoveDown->SetToolTip( _( "Move current selection down" ) ); + m_bpMoveDown->SetToolTip( _( "Move current selection down" ) ); m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) ); - bButtonSizer->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); + bButtonSizer->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 ); sbSizer->Add( bButtonSizer, 0, wxALL | wxEXPAND, 3 ); - bmiddleSizer->Insert( 1, sbSizer, 1, wxALL | wxEXPAND, 5 ); + bmiddleSizer->Insert( 1, sbSizer, 1, wxALL | wxEXPAND, 5 ); m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) ); m_openDirButton->SetBitmap( KiBitmapBundle( BITMAPS::small_new_window ) ); @@ -450,7 +450,8 @@ void DIALOG_PLOT::transferPlotParamsToJob() : JOB_EXPORT_PCB_DXF::DXF_UNITS::MM; dxfJob->m_plotGraphicItemsUsingContours = m_plotOpts.GetDXFPlotMode() == DXF_OUTLINE_MODE::SKETCH; dxfJob->m_polygonMode = m_plotOpts.GetDXFPlotPolygonMode(); - dxfJob->m_genMode = JOB_EXPORT_PCB_DXF::GEN_MODE::MULTI; + dxfJob->m_genMode = m_plotOpts.GetDXFMultiLayeredExportOption() ? JOB_EXPORT_PCB_DXF::GEN_MODE::SINGLE + : JOB_EXPORT_PCB_DXF::GEN_MODE::MULTI; } if( m_job->m_plotFormat == JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::POST ) @@ -1005,6 +1006,8 @@ void DIALOG_PLOT::applyPlotSettings() tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ? PLOT_TEXT_MODE::DEFAULT : PLOT_TEXT_MODE::NATIVE ); + tempOptions.SetDXFMultiLayeredExportOption( m_DXF_exportAsMultiLayeredFile->GetValue() ); + if( getPlotFormat() == PLOT_FORMAT::SVG ) { tempOptions.SetBlackAndWhite( m_SVGColorChoice->GetSelection() == 1 ); diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp index dfd87ecd87..7d9ec89c56 100644 --- a/pcbnew/dialogs/dialog_plot_base.cpp +++ b/pcbnew/dialogs/dialog_plot_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -304,17 +304,18 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr m_DXF_plotModeOpt = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Plot graphic items using their contours"), wxDefaultPosition, wxDefaultSize, 0 ); m_DXF_plotModeOpt->SetValue(true); m_DXF_plotModeOpt->SetToolTip( _("Uncheck to plot graphic items using their center lines") ); + m_DXF_plotModeOpt->SetMinSize( wxSize( 300,-1 ) ); gbSizer5->Add( m_DXF_plotModeOpt, wxGBPosition( 0, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); DXF_exportUnitsLabel = new wxStaticText( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Export units:"), wxDefaultPosition, wxDefaultSize, 0 ); DXF_exportUnitsLabel->Wrap( -1 ); - gbSizer5->Add( DXF_exportUnitsLabel, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 40 ); + gbSizer5->Add( DXF_exportUnitsLabel, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); wxString m_DXF_plotUnitsChoices[] = { _("Inches"), _("Millimeters") }; int m_DXF_plotUnitsNChoices = sizeof( m_DXF_plotUnitsChoices ) / sizeof( wxString ); m_DXF_plotUnits = new wxChoice( m_SizerDXF_options->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DXF_plotUnitsNChoices, m_DXF_plotUnitsChoices, 0 ); - m_DXF_plotUnits->SetSelection( 0 ); + m_DXF_plotUnits->SetSelection( 1 ); m_DXF_plotUnits->SetToolTip( _("The units to use for the exported DXF file") ); gbSizer5->Add( m_DXF_plotUnits, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); @@ -324,6 +325,11 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr gbSizer5->Add( m_DXF_plotTextStrokeFontOpt, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + m_DXF_exportAsMultiLayeredFile = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Single document"), wxDefaultPosition, wxDefaultSize, 0 ); + m_DXF_exportAsMultiLayeredFile->SetToolTip( _("Export selected layers into a single DXF") ); + + gbSizer5->Add( m_DXF_exportAsMultiLayeredFile, wxGBPosition( 2, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + m_SizerDXF_options->Add( gbSizer5, 1, wxEXPAND|wxBOTTOM, 5 ); diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp index 0c8733ca7d..519a280ce9 100644 --- a/pcbnew/dialogs/dialog_plot_base.fbp +++ b/pcbnew/dialogs/dialog_plot_base.fbp @@ -3060,7 +3060,7 @@ 0 - + 300,-1 1 m_DXF_plotModeOpt 1 @@ -3087,7 +3087,7 @@ - 40 + 5 1 2 wxALIGN_CENTER_VERTICAL|wxLEFT @@ -3203,7 +3203,7 @@ 1 Resizable - 0 + 1 1 @@ -3262,7 +3262,7 @@ 0 - + -1,-1 1 m_DXF_plotTextStrokeFontOpt 1 @@ -3287,6 +3287,74 @@ + + 5 + 2 + 0 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 2 + 1 + + 1 + 1 + 1 + 1 + 0 + + 0 + 0 + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Single document + + 0 + + + 0 + + 1 + m_DXF_exportAsMultiLayeredFile + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Export selected layers into a single DXF + + wxFILTER_NONE + wxDefaultValidator + + + + + + diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h index 852d10f6f4..0c052d8d27 100644 --- a/pcbnew/dialogs/dialog_plot_base.h +++ b/pcbnew/dialogs/dialog_plot_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6) +// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -106,6 +106,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM wxStaticText* DXF_exportUnitsLabel; wxChoice* m_DXF_plotUnits; wxCheckBox* m_DXF_plotTextStrokeFontOpt; + wxCheckBox* m_DXF_exportAsMultiLayeredFile; wxStaticBoxSizer* m_svgOptionsSizer; wxStaticText* svgPrecisionLabel; wxSpinCtrl* m_svgPrecsision; diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index cb90e10ee6..a362a3b158 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -116,6 +116,8 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() m_colors = m_default_colors.get(); m_blackAndWhite = true; + + m_DXFExportAsMultiLayeredFile = false; } @@ -340,6 +342,9 @@ bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams ) const if( !m_outputDirectory.IsSameAs( aPcbPlotParams.m_outputDirectory ) ) return false; + if( m_DXFExportAsMultiLayeredFile != aPcbPlotParams.m_DXFExportAsMultiLayeredFile ) + return false; + return true; } diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h index eff83ac666..dcbad7921b 100644 --- a/pcbnew/pcb_plot_params.h +++ b/pcbnew/pcb_plot_params.h @@ -184,6 +184,18 @@ public: void SetDashedLineGapRatio( double aVal ) { m_dashedLineGapRatio = aVal; } double GetDashedLineGapRatio() const { return m_dashedLineGapRatio; } + void SetDXFMultiLayeredExportOption( bool aFlag ) { m_DXFExportAsMultiLayeredFile = aFlag; } + bool GetDXFMultiLayeredExportOption() const { return m_DXFExportAsMultiLayeredFile; } + + void SetLayersToExport( std::vector> & aVal ) { m_layersToExport = aVal; } + std::vector> GetLayersToExport() const { return m_layersToExport; } + + /** + * Return the layer this item is on. + */ + PCB_LAYER_ID GetLayer() const { return m_layer; } + void SetLayer( PCB_LAYER_ID aLayer ) { m_layer = aLayer; } + void SetPDFBackgroundColor( const COLOR4D& aColor ) { m_PDFBackgroundColor = aColor; } COLOR4D GetPDFBackgroundColor() const { return m_PDFBackgroundColor; } @@ -291,6 +303,12 @@ private: /// Dummy colors object that can be created if there is no Pgm context std::shared_ptr m_default_colors; + + bool m_DXFExportAsMultiLayeredFile; + + std::vector> m_layersToExport; + + PCB_LAYER_ID m_layer; }; diff --git a/pcbnew/pcb_plotter.cpp b/pcbnew/pcb_plotter.cpp index e7ca03f919..847dcf27eb 100644 --- a/pcbnew/pcb_plotter.cpp +++ b/pcbnew/pcb_plotter.cpp @@ -101,7 +101,7 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, LSEQ layersToPlot; LSEQ commonLayers; - if( aOutputPathIsSingle ) + if( aOutputPathIsSingle && !m_plotOpts.GetDXFMultiLayeredExportOption() ) { layersToPlot.push_back( aLayersToPlot[0] ); @@ -115,13 +115,17 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, } int finalPageCount = 0; + std::vector> layersToExport; + // Skip the disabled copper layers and build the layer ID -> layer name mapping for plotter + // DXF plotter will use this information to name its layers for( PCB_LAYER_ID layer : layersToPlot ) { if( copperLayerShouldBeSkipped( layer ) ) continue; finalPageCount++; + layersToExport.emplace_back( layer, m_board->GetLayerName( layer ) ); } std::unique_ptr jobfile_writer; @@ -129,6 +133,7 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && !aOutputPathIsSingle ) jobfile_writer = std::make_unique( m_board, m_reporter ); + PLOT_FORMAT plot_format = m_plotOpts.GetFormat(); wxString fileExt( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) ); wxString sheetPath; wxString msg; @@ -161,8 +166,10 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && aUseGerberFileExtensions ) fileExt = GetGerberProtelExtension( layer ); - if( m_plotOpts.GetFormat() == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle ) + if( plot_format == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle ) fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) ); + else if ( plot_format == PLOT_FORMAT::DXF && m_plotOpts.GetDXFMultiLayeredExportOption() ) + fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) ); else BuildPlotFileName( &fn, aOutputPath, layerName, fileExt ); } @@ -173,10 +180,11 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, jobfile_writer->AddGbrFile( layer, fullname ); } - if( m_plotOpts.GetFormat() != PLOT_FORMAT::PDF - || !m_plotOpts.m_PDFSingle - || ( pageNum == 1 && m_plotOpts.GetFormat() == PLOT_FORMAT::PDF - && m_plotOpts.m_PDFSingle ) ) + if( ( plot_format != PLOT_FORMAT::PDF && plot_format != PLOT_FORMAT::DXF ) + || ( !m_plotOpts.m_PDFSingle && !m_plotOpts.GetDXFMultiLayeredExportOption() ) + || ( pageNum == 1 + && ( ( plot_format == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle ) + || ( plot_format == PLOT_FORMAT::DXF && m_plotOpts.GetDXFMultiLayeredExportOption() ) ) ) ) { // this will only be used by pdf wxString pageNumber = wxString::Format( "%d", pageNum ); @@ -195,12 +203,14 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, if( aSheetPath.has_value() ) sheetPath = aSheetPath.value(); + m_plotOpts.SetLayersToExport( layersToExport ); plotter = StartPlotBoard( m_board, &m_plotOpts, layer, layerName, fn.GetFullPath(), sheetName, sheetPath, pageName, pageNumber, finalPageCount ); } if( plotter ) { + plotter->SetLayer( layer ); plotter->SetTitle( ExpandTextVars( m_board->GetTitleBlock().GetTitle(), &textResolver ) ); if( m_plotOpts.m_PDFMetadata ) @@ -253,8 +263,8 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot, } // last page - if( m_plotOpts.GetFormat() != PLOT_FORMAT::PDF - || !m_plotOpts.m_PDFSingle + if( (plot_format != PLOT_FORMAT::PDF && plot_format != PLOT_FORMAT::DXF) + || (!m_plotOpts.m_PDFSingle && !m_plotOpts.GetDXFMultiLayeredExportOption()) || i == aLayersToPlot.size() - 1 || pageNum == finalPageCount ) { @@ -415,6 +425,7 @@ void PCB_PLOTTER::PlotJobToPlotOpts( PCB_PLOT_PARAMS& aOpts, JOB_EXPORT_PCB_PLOT aOpts.SetDXFPlotMode( dxfJob->m_plotGraphicItemsUsingContours ? DXF_OUTLINE_MODE::SKETCH : DXF_OUTLINE_MODE::FILLED ); aOpts.SetDXFPlotPolygonMode( dxfJob->m_polygonMode ); + aOpts.SetDXFMultiLayeredExportOption( dxfJob->m_genMode == JOB_EXPORT_PCB_DXF::GEN_MODE::SINGLE ); } if( aJob->m_plotFormat == JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::PDF ) diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 808b433578..f11772655f 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -337,7 +337,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask bool onBackFab = ( LSET( { B_Fab } ) & aLayerMask ).any(); bool sketchPads = ( onFrontFab || onBackFab ) && aPlotOpt.GetSketchPadsOnFabLayers(); - // Plot edge layer and graphic items + // Plot edge layer and graphic items for( const BOARD_ITEM* item : aBoard->Drawings() ) itemplotter.PlotBoardGraphicItem( item ); @@ -1240,6 +1240,9 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts, int aL DXF_plotter->SetUnits( aPlotOpts->GetDXFPlotUnits() ); plotter = DXF_plotter; + + if( !aPlotOpts->GetLayersToExport().empty() ) + plotter->SetLayersToExport( aPlotOpts->GetLayersToExport() ); break; case PLOT_FORMAT::POST: