Loading files
/*
* LibrePCB - Professional EDA for everyone!
* Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
* https://librepcb.org/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "projectjsonexport.h"
#include "../library/pkg/footprint.h"
#include "../library/pkg/footprintpad.h"
#include "../types/layer.h"
#include "../types/pcbcolor.h"
#include "board/board.h"
#include "board/items/bi_device.h"
#include "board/items/bi_hole.h"
#include "board/items/bi_netsegment.h"
#include "board/items/bi_pad.h"
#include "board/items/bi_plane.h"
#include "board/items/bi_polygon.h"
#include "board/items/bi_via.h"
#include "circuit/assemblyvariant.h"
#include "circuit/circuit.h"
#include "project.h"
#include <QtCore>
/*******************************************************************************
* Namespace
******************************************************************************/
namespace librepcb {
/*******************************************************************************
* Constructors / Destructor
******************************************************************************/
ProjectJsonExport::ProjectJsonExport() noexcept {
}
ProjectJsonExport::~ProjectJsonExport() noexcept {
}
/*******************************************************************************
* General Methods
******************************************************************************/
QJsonArray ProjectJsonExport::toJson(const QStringList& obj) const {
return QJsonArray::fromStringList(obj);
}
QJsonValue ProjectJsonExport::toJson(const Length& obj) const {
return QJsonValue(obj.toMm());
}
QJsonValue ProjectJsonExport::toJson(const std::optional<Length>& obj) const {
return obj ? QJsonValue(obj->toMm()) : QJsonValue(QJsonValue::Null);
}
QJsonArray ProjectJsonExport::toJson(const QSet<Length>& obj) const {
QJsonArray json;
foreach (const Length& value, Toolbox::sortedQSet(obj)) {
json.append(toJson(value));
}
return json;
}
QJsonValue ProjectJsonExport::toJson(const PcbColor* obj) const {
// Not returning Null to distinguish from unknown resp. parsing failure.
return obj ? QJsonValue(obj->getId()) : QJsonValue("none");
}
QJsonObject ProjectJsonExport::toJson(const AssemblyVariant& obj) const {
QJsonObject json;
json["uuid"] = obj.getUuid().toStr();
json["name"] = *obj.getName();
json["description"] = obj.getDescription();
return json;
}
QJsonValue ProjectJsonExport::toJson(const BoundingBox& obj) const {
if (const auto& points = obj.points) {
QJsonObject json;
json["x"] = toJson(std::min(points->first.getX(), points->second.getX()));
json["y"] = toJson(std::min(points->first.getY(), points->second.getY()));
const Point size = points->second - points->first;
json["width"] = toJson(size.getX().abs());
json["height"] = toJson(size.getY().abs());
return json;
} else {
return QJsonValue();
}
}
QJsonObject ProjectJsonExport::toJson(const ToolList& obj) const {
return {
{"count", obj.diameters.count()},
{"diameters", toJson(Toolbox::toSet(obj.diameters))},
};
}
QJsonObject ProjectJsonExport::toJson(const Board& obj) const {
ToolList thtVias;
ToolList blindVias;
ToolList buriedVias;
ToolList pthDrills;
ToolList pthSlots;
ToolList npthDrills;
ToolList npthSlots;
int platedCutoutsCount = 0;
QSet<Length> copperWidths;
foreach (const BI_NetSegment* netSegment, obj.getNetSegments()) {
foreach (const BI_Pad* pad, netSegment->getPads()) {
for (const PadHole& hole : pad->getProperties().getHoles()) {
if (hole.isSlot()) {
pthSlots.diameters.append(*hole.getDiameter());
} else {
pthDrills.diameters.append(*hole.getDiameter());
}
}
}
foreach (const BI_Via* via, netSegment->getVias()) {
if (auto span = via->getDrillLayerSpan()) {
if (span->first->isTop() && span->second->isBottom()) {
thtVias.diameters.append(*via->getActualDrillDiameter());
} else if (span->first->isTop() || span->second->isBottom()) {
blindVias.diameters.append(*via->getActualDrillDiameter());
} else {
buriedVias.diameters.append(*via->getActualDrillDiameter());
}
}
}
foreach (const BI_NetLine* netLine, netSegment->getNetLines()) {
copperWidths.insert(*netLine->getWidth());
}
}
foreach (const BI_Device* device, obj.getDeviceInstances()) {
foreach (const BI_Pad* pad, device->getPads()) {
for (const PadHole& hole : pad->getProperties().getHoles()) {
if (hole.isSlot()) {
pthSlots.diameters.append(*hole.getDiameter());
} else {
pthDrills.diameters.append(*hole.getDiameter());
}
}
}
for (const Hole& hole : device->getLibFootprint().getHoles()) {
if (hole.isSlot()) {
npthSlots.diameters.append(*hole.getDiameter());
} else {
npthDrills.diameters.append(*hole.getDiameter());
}
}
for (const Polygon& polygon : device->getLibFootprint().getPolygons()) {
if (polygon.getLayer() == Layer::boardPlatedCutouts()) {
++platedCutoutsCount;
}
}
for (const Circle& circle : device->getLibFootprint().getCircles()) {
if (circle.getLayer() == Layer::boardPlatedCutouts()) {
++platedCutoutsCount;
}
}
}
foreach (const BI_Hole* hole, obj.getHoles()) {
if (hole->getData().isSlot()) {
npthSlots.diameters.append(*hole->getData().getDiameter());
} else {
npthDrills.diameters.append(*hole->getData().getDiameter());
}
}
foreach (const BI_Plane* plane, obj.getPlanes()) {
copperWidths.insert(*plane->getMinWidth());
}
for (const BI_Polygon* polygon : obj.getPolygons()) {
if (polygon->getData().getLayer() == Layer::boardPlatedCutouts()) {
++platedCutoutsCount;
}
}
const std::optional<Length> minCopperWidth = copperWidths.isEmpty()
? std::nullopt
: std::make_optional(
*std::min_element(copperWidths.begin(), copperWidths.end()));
QJsonObject json;
json["uuid"] = obj.getUuid().toStr();
json["name"] = *obj.getName();
json["directory"] = obj.getDirectoryName();
json["inner_layers"] = obj.getInnerLayerCount();
json["pcb_thickness"] = obj.getPcbThickness()->toMm();
json["solder_resist"] = toJson(obj.getSolderResist());
json["silkscreen_top"] = toJson(obj.getSilkscreenColorTop());
json["silkscreen_bottom"] = toJson(obj.getSilkscreenColorBot());
json["bounding_box"] = toJson(BoundingBox{obj.calculateBoundingRect()});
json["vias_tht"] = toJson(thtVias);
json["vias_blind"] = toJson(blindVias);
json["vias_buried"] = toJson(buriedVias);
json["pth_drills"] = toJson(pthDrills);
json["pth_slots"] = toJson(pthSlots);
json["npth_drills"] = toJson(npthDrills);
json["npth_slots"] = toJson(npthSlots);
json["plated_cutouts"] = platedCutoutsCount;
json["min_copper_width"] = toJson(minCopperWidth);
return json;
}
QJsonObject ProjectJsonExport::toJson(const Project& obj) const {
QJsonObject json;
json["filename"] = obj.getFileName();
json["uuid"] = obj.getUuid().toStr();
json["name"] = *obj.getName();
json["author"] = obj.getAuthor();
json["version"] = *obj.getVersion();
json["created"] = obj.getCreated().toUTC().toString(Qt::ISODate);
json["locales"] = toJson(obj.getLocaleOrder());
json["norms"] = toJson(obj.getNormOrder());
{
QJsonArray jsonChild;
for (const AssemblyVariant& av : obj.getCircuit().getAssemblyVariants()) {
jsonChild.append(toJson(av));
}
json["variants"] = jsonChild;
}
{
QJsonArray jsonChild;
foreach (const Board* board, obj.getBoards()) {
jsonChild.append(toJson(*board));
}
json["boards"] = jsonChild;
}
return json;
}
QByteArray ProjectJsonExport::toUtf8(const Project& obj) const {
QJsonObject json;
json["format"] = QJsonObject{
{"major", 1}, // Only increment (when needed) for new major releases!!!
{"minor", 0}, // Increment on every backwards-compatible format addition.
{"type", "librepcb-project"},
};
json["project"] = toJson(obj);
return QJsonDocument(json).toJson(QJsonDocument::Indented);
}
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace librepcb
bae9c0e4eThis file is pinned to the selected release. Download the original to open it in your design tool.