131 std::vector<LIST_MOD> list;
143 if( footprint->GetExcludedFromPosFilesForVariant(
m_variant ) )
162 item.
m_Reference = footprint->Reference().GetShownText(
false );
163 item.
m_Value = footprint->Value().GetShownText(
false );
164 item.
m_Layer = footprint->GetLayer();
166 lenRefText = std::max( lenRefText, (
int) item.
m_Reference.length() );
167 lenValText = std::max( lenValText, (
int) item.
m_Value.length() );
170 list.push_back( std::move( item ) );
173 if( list.size() > 1 )
181 wxChar csv_sep =
',';
184 snprintf( line,
sizeof(line),
"Ref%cVal%cPackage%cPosX%cPosY%cRot%cSide\n",
185 csv_sep, csv_sep, csv_sep, csv_sep, csv_sep, csv_sep );
192 footprint_pos = list[ii].m_Footprint->GetPosition();
195 int layer = list[ii].m_Footprint->GetLayer();
199 footprint_pos.
x = - footprint_pos.
x;
201 wxLine = wxT(
"\"" ) + list[ii].m_Reference;
202 wxLine << wxT(
"\"" ) << csv_sep;
203 wxLine << wxT(
"\"" ) << list[ii].m_Value;
204 wxLine << wxT(
"\"" ) << csv_sep;
205 wxLine << wxT(
"\"" ) << list[ii].m_Footprint->GetFPID().GetLibItemName().wx_str();
206 wxLine << wxT(
"\"" ) << csv_sep;
208 wxLine << wxString::Format( wxT(
"%f%c%f%c%f" ),
209 footprint_pos.
x * conv_unit,
213 -footprint_pos.
y * conv_unit,
215 list[ii].m_Footprint->GetOrientation().AsDegrees() );
228 snprintf( line,
sizeof(line),
"### Footprint positions - created on %s ###\n",
234 snprintf( line,
sizeof(line),
"### Printed by KiCad version %s\n",
TO_UTF8( Title ) );
238 buffer +=
"## Side : ";
251 snprintf( line,
sizeof(line),
"%-*s %-*s %-*s %9.9s %9.9s %8.8s %s\n",
254 lenPkgText,
"Package",
255 "PosX",
"PosY",
"Rot",
"Side" );
261 footprint_pos = list[ii].m_Footprint->GetPosition();
264 int layer = list[ii].m_Footprint->GetLayer();
268 footprint_pos.
x = - footprint_pos.
x;
270 wxString ref = list[ii].m_Reference;
271 wxString val = list[ii].m_Value;
272 wxString pkg = list[ii].m_Footprint->GetFPID().GetLibItemName();
273 ref.Replace( wxT(
" " ), wxT(
"_" ) );
274 val.Replace( wxT(
" " ), wxT(
"_" ) );
275 pkg.Replace( wxT(
" " ), wxT(
"_" ) );
276 wxLine.Printf( wxT(
"%-*s %-*s %-*s %9.4f %9.4f %8.4f %s\n" ),
277 lenRefText, std::move( ref ),
278 lenValText, std::move( val ),
279 lenPkgText, std::move( pkg ),
280 footprint_pos.
x * conv_unit,
282 -footprint_pos.
y * conv_unit,
283 list[ii].m_Footprint->GetOrientation().AsDegrees(),
289 buffer +=
"## End\n";
313 buffer += fmt::format(
"## Printed by KiCad version {}\n",
TO_UTF8( Title ) );
317 buffer +=
"\n$BeginDESCRIPTION\n";
319 BOX2I bbbox =
m_board->ComputeBoundingBox(
false,
true );
321 buffer +=
"\n$BOARD\n";
323 buffer += fmt::format(
"upper_left_corner {:9.6f} {:9.6f}\n",
324 bbbox.
GetX() * conv_unit,
325 bbbox.
GetY() * conv_unit );
327 buffer +=
"$EndBOARD\n\n";
329 std::vector<FOOTPRINT*> sortedFootprints;
332 sortedFootprints.push_back( footprint );
334 std::sort( sortedFootprints.begin(), sortedFootprints.end(),
337 return StrNumCmp( a->GetReference(), b->GetReference(), true ) < 0;
340 for(
FOOTPRINT* footprint : sortedFootprints )
342 wxString ref = footprint->Reference().GetShownText(
false );
343 wxString value = footprint->Value().GetShownText(
false );
345 buffer += fmt::format(
"$MODULE {}\n",
TO_UTF8( ref ) );
347 buffer += fmt::format(
"reference {}\n",
TO_UTF8( ref ) );
348 buffer += fmt::format(
"value {}\n",
TO_UTF8( value ) );
349 buffer += fmt::format(
"footprint {}\n", footprint->GetFPID().Format().c_str() );
351 buffer +=
"attribut";
354 buffer +=
" virtual";
356 if( footprint->GetAttributes() &
FP_SMD )
364 VECTOR2I footprint_pos = footprint->GetPosition();
367 buffer += fmt::format(
"position {:9.6f} {:9.6f} orientation {:.2f}\n",
368 footprint_pos.
x * conv_unit,
369 footprint_pos.
y * conv_unit,
370 footprint->GetOrientation().AsDegrees() );
372 if( footprint->GetLayer() ==
F_Cu )
373 buffer +=
"layer front\n";
374 else if( footprint->GetLayer() ==
B_Cu )
375 buffer +=
"layer back\n";
377 buffer +=
"layer other\n";
379 std::vector<PAD*> sortedPads;
381 for(
PAD*
pad : footprint->Pads() )
382 sortedPads.push_back(
pad );
384 std::sort( sortedPads.begin(), sortedPads.end(),
385 [](
PAD* a,
PAD* b ) ->
bool
387 return StrNumCmp( a->GetNumber(), b->GetNumber(), true ) < 0;
390 for(
PAD*
pad : sortedPads )
392 buffer += fmt::format(
"$PAD \"{}\"\n",
TO_UTF8(
pad->GetNumber() ) );
403 static const char* layer_name[4] = {
"nocopper",
"back",
"front",
"both" };
404 buffer += fmt::format(
"Shape {} Layer {}\n",
410 buffer += fmt::format(
"position {:9.6f} {:9.6f} size {:9.6f} {:9.6f} orientation {:.2f}\n",
411 padPos.
x * conv_unit,
412 padPos.
y * conv_unit,
415 pad->GetOrientation().AsDegrees() );
417 buffer += fmt::format(
"drill {:9.6f}\n",
pad->GetDrillSize().x * conv_unit );
419 buffer += fmt::format(
"shape_offset {:9.6f} {:9.6f}\n",
423 buffer +=
"$EndPAD\n";
426 buffer += fmt::format(
"$EndMODULE {}\n\n",
TO_UTF8( ref ) );
430 buffer +=
"$EndDESCRIPTION\n";
PLACE_FILE_EXPORTER(BOARD *aBoard, bool aUnitsMM, bool aOnlySMD, bool aExcludeAllTH, bool aExcludeDNP, bool aExcludeBOM, bool aTopSide, bool aBottomSide, bool aFormatCSV, bool aUseAuxOrigin, bool aNegateBottomX)
Create a PLACE_FILE_EXPORTER.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.