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/>.
*/
#ifndef LIBREPCB_CORE_NETSEGMENTSIMPLIFIER_H
#define LIBREPCB_CORE_NETSEGMENTSIMPLIFIER_H
/*******************************************************************************
* Includes
******************************************************************************/
#include "../types/point.h"
#include <QtCore>
/*******************************************************************************
* Namespace / Forward Declarations
******************************************************************************/
namespace librepcb {
class Layer;
/*******************************************************************************
* Class NetSegmentSimplifier
******************************************************************************/
/**
* @brief Algorithm to clean/simplify net segment lines
*
* Performed operations:
* - Remove redundant junctions (same position, same layer)
* - Remove redundant lines (same anchors, same layer), keeping the thickest
* - Remove zero-length lines
* - Remove useless junctions within straight line segments (join line
* segments into the same direction to a single line)
* - Split lines to connect with junctions on the path between start and end
* points
* - Split intersecting lines, placing a new junction to connect them (only
* orthogonal intersections for now)
*/
class NetSegmentSimplifier final {
Q_DECLARE_TR_FUNCTIONS(NetSegmentSimplifier)
public:
// Types
enum class AnchorType : int {
// Value is important for the sort algorithm, do not change!
Via = 0,
Fixed = 1,
Junction = 2,
};
struct Line {
int id = 0;
int p1 = 0;
int p2 = 0;
const Layer* layer = nullptr;
Length width;
bool modified = false;
};
struct Result {
QList<Line> lines;
QMap<int, Point> newJunctions;
QSet<int> disconnectedFixedAnchors;
bool modified = false;
};
// Constructors / Destructor
/**
* @brief Default constructor
*/
NetSegmentSimplifier() noexcept;
/**
* @brief Copy constructor
*
* @param other Another ::librepcb::NetSegmentSimplifier object
*/
NetSegmentSimplifier(const NetSegmentSimplifier& other) = delete;
/**
* Destructor
*/
~NetSegmentSimplifier() noexcept;
/**
* @brief Add a line anchor
*
* @param type Type of the anchor.
* @param pos Position.
* @param start Start (most upper) layer of the anchors or `nullptr`
* for schematic netsegment simplifications
* @param end End (most lower) layer of the anchors or `nullptr`
* for schematic netsegment simplifications
*
* @return The ID of the added anchors.
*/
int addAnchor(AnchorType type, const Point& pos, const Layer* start,
const Layer* end) noexcept;
/**
* @brief Add a line between two anchors
*
* @param p1 ID of first anchors.
* @param p2 ID of second anchors.
* @param layer Layer of the line (`nullptr` for schematic netsegment
* simplification).
* @param width Line width.
*
* @return The ID of the added line.
*/
int addLine(int p1, int p2, const Layer* layer, const Length& width) noexcept;
/**
* @brief Perform the simplification
*
* @note This method also resets the state, so the object can be reused for
* the next net segment.
*
* @attention When lines are split, new anchor- and line IDs will be
* generated on the fly! So the returned lines may contain IDs
* which you didn't know yet from #addAnchor() and #addLine()!.
*
* @return Any remaining lines after the simplification.
*/
Result simplify() noexcept;
// Operator overloadings
NetSegmentSimplifier& operator=(const NetSegmentSimplifier& rhs) = delete;
private:
// Types
struct Anchor {
int id = 0;
AnchorType type = AnchorType::Junction;
Point pos;
const Layer* startLayer = nullptr;
const Layer* endLayer = nullptr;
bool isNew = false;
};
// Methods
QSet<int> getConnectedFixedAnchors() const noexcept;
void addJunctionsAtLineIntersections() noexcept;
void splitLinesAtAnchors() noexcept;
void removeDuplicateJunctions() noexcept;
void removeRedundantLines() noexcept;
bool mergeNextLines() noexcept;
const Anchor* findAnchor(const Point& pos, const Layer* layer) noexcept;
static bool isAnchorOnLayer(const Anchor& anchor,
const Layer* layer) noexcept;
static bool isStraightLine(const Point& p0, const Point& p1,
const Point& p2) noexcept;
// Data input
QList<Anchor> mAnchors;
QMap<int, Line> mLines;
int mNextFreeLineId;
// State
QHash<Point, QVector<Anchor>> mAnchorMap;
QSet<int> mPinsOrPads;
bool mModified;
};
/*******************************************************************************
* End of File
******************************************************************************/
} // namespace librepcb
#endif
9ac9868b1This file is pinned to the selected release. Download the original to open it in your design tool.