mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 16:47:26 +00:00
Add options for tweaking graph layout. (#2246)
* Fix overview refresh when switching layout.
This commit is contained in:
parent
1d8c9de37c
commit
e28ee3bebd
@ -758,6 +758,22 @@ void Configuration::setBitmapExportScaleFactor(double inputValueGraph)
|
|||||||
s.setValue("bitmapGraphExportScale", inputValueGraph);
|
s.setValue("bitmapGraphExportScale", inputValueGraph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Configuration::setGraphSpacing(QPoint blockSpacing, QPoint edgeSpacing)
|
||||||
|
{
|
||||||
|
s.setValue("graph.blockSpacing", blockSpacing);
|
||||||
|
s.setValue("graph.edgeSpacing", edgeSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Configuration::getGraphBlockSpacing()
|
||||||
|
{
|
||||||
|
return s.value("graph.blockSpacing", QPoint(10, 40)).value<QPoint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Configuration::getGraphEdgeSpacing()
|
||||||
|
{
|
||||||
|
return s.value("graph.edgeSpacing", QPoint(10, 10)).value<QPoint>();
|
||||||
|
}
|
||||||
|
|
||||||
void Configuration::setOutputRedirectionEnabled(bool enabled)
|
void Configuration::setOutputRedirectionEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
this->outputRedirectEnabled = enabled;
|
this->outputRedirectEnabled = enabled;
|
||||||
|
@ -43,6 +43,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
bool outputRedirectEnabled = true;
|
bool outputRedirectEnabled = true;
|
||||||
|
|
||||||
|
Configuration();
|
||||||
// Colors
|
// Colors
|
||||||
void loadBaseThemeNative();
|
void loadBaseThemeNative();
|
||||||
void loadBaseThemeDark();
|
void loadBaseThemeDark();
|
||||||
@ -60,7 +61,6 @@ public:
|
|||||||
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
static const QHash<QString, QHash<ColorFlags, QColor>> cutterOptionColors;
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
Configuration();
|
|
||||||
static Configuration *instance();
|
static Configuration *instance();
|
||||||
|
|
||||||
void loadInitial();
|
void loadInitial();
|
||||||
@ -129,16 +129,6 @@ public:
|
|||||||
// Asm Options
|
// Asm Options
|
||||||
void resetToDefaultAsmOptions();
|
void resetToDefaultAsmOptions();
|
||||||
|
|
||||||
// Graph
|
|
||||||
int getGraphBlockMaxChars() const
|
|
||||||
{
|
|
||||||
return s.value("graph.maxcols", 100).toInt();
|
|
||||||
}
|
|
||||||
void setGraphBlockMaxChars(int ch)
|
|
||||||
{
|
|
||||||
s.setValue("graph.maxcols", ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString getColorTheme() const { return s.value("theme", "cutter").toString(); }
|
QString getColorTheme() const { return s.value("theme", "cutter").toString(); }
|
||||||
void setColorTheme(const QString &theme);
|
void setColorTheme(const QString &theme);
|
||||||
/**
|
/**
|
||||||
@ -179,6 +169,16 @@ public:
|
|||||||
bool getDecompilerAutoRefreshEnabled();
|
bool getDecompilerAutoRefreshEnabled();
|
||||||
void setDecompilerAutoRefreshEnabled(bool enabled);
|
void setDecompilerAutoRefreshEnabled(bool enabled);
|
||||||
|
|
||||||
|
// Graph
|
||||||
|
int getGraphBlockMaxChars() const
|
||||||
|
{
|
||||||
|
return s.value("graph.maxcols", 100).toInt();
|
||||||
|
}
|
||||||
|
void setGraphBlockMaxChars(int ch)
|
||||||
|
{
|
||||||
|
s.setValue("graph.maxcols", ch);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Getters and setters for the transaparent option state and scale factor for bitmap graph exports.
|
* @brief Getters and setters for the transaparent option state and scale factor for bitmap graph exports.
|
||||||
*/
|
*/
|
||||||
@ -186,6 +186,9 @@ public:
|
|||||||
double getBitmapExportScaleFactor();
|
double getBitmapExportScaleFactor();
|
||||||
void setBitmapTransparentState(bool inputValueGraph);
|
void setBitmapTransparentState(bool inputValueGraph);
|
||||||
void setBitmapExportScaleFactor(double inputValueGraph);
|
void setBitmapExportScaleFactor(double inputValueGraph);
|
||||||
|
void setGraphSpacing(QPoint blockSpacing, QPoint edgeSpacing);
|
||||||
|
QPoint getGraphBlockSpacing();
|
||||||
|
QPoint getGraphEdgeSpacing();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable or disable Cutter output redirection.
|
* @brief Enable or disable Cutter output redirection.
|
||||||
|
@ -21,7 +21,15 @@ GraphOptionsWidget::GraphOptionsWidget(PreferencesDialog *dialog)
|
|||||||
connect<void(QDoubleSpinBox::*)(double)>(ui->bitmapGraphScale, (&QDoubleSpinBox::valueChanged), this, &GraphOptionsWidget::bitmapGraphScaleValueChanged);
|
connect<void(QDoubleSpinBox::*)(double)>(ui->bitmapGraphScale, (&QDoubleSpinBox::valueChanged), this, &GraphOptionsWidget::bitmapGraphScaleValueChanged);
|
||||||
connect(ui->checkTransparent, &QCheckBox::stateChanged, this, &GraphOptionsWidget::checkTransparentStateChanged);
|
connect(ui->checkTransparent, &QCheckBox::stateChanged, this, &GraphOptionsWidget::checkTransparentStateChanged);
|
||||||
|
|
||||||
connect(Core(), SIGNAL(graphOptionsChanged()), this, SLOT(updateOptionsFromVars()));
|
connect(Core(), &CutterCore::graphOptionsChanged, this, &GraphOptionsWidget::updateOptionsFromVars);
|
||||||
|
QSpinBox* graphSpacingWidgets[] = {
|
||||||
|
ui->horizontalEdgeSpacing, ui->horizontalBlockSpacing,
|
||||||
|
ui->verticalEdgeSpacing, ui->verticalBlockSpacing
|
||||||
|
};
|
||||||
|
for (auto widget: graphSpacingWidgets) {
|
||||||
|
connect<void(QSpinBox::*)(int)>(widget, &QSpinBox::valueChanged,
|
||||||
|
this, &GraphOptionsWidget::layoutSpacingChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphOptionsWidget::~GraphOptionsWidget() {}
|
GraphOptionsWidget::~GraphOptionsWidget() {}
|
||||||
@ -67,3 +75,11 @@ void GraphOptionsWidget::bitmapGraphScaleValueChanged(double value)
|
|||||||
Config()->setBitmapExportScaleFactor(value_decimal);
|
Config()->setBitmapExportScaleFactor(value_decimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphOptionsWidget::layoutSpacingChanged()
|
||||||
|
{
|
||||||
|
QPoint blockSpacing{ui->horizontalBlockSpacing->value(), ui->verticalBlockSpacing->value()};
|
||||||
|
QPoint edgeSpacing{ui->horizontalEdgeSpacing->value(), ui->verticalEdgeSpacing->value()};
|
||||||
|
Config()->setGraphSpacing(blockSpacing, edgeSpacing);
|
||||||
|
triggerOptionsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ private slots:
|
|||||||
|
|
||||||
void checkTransparentStateChanged(int checked);
|
void checkTransparentStateChanged(int checked);
|
||||||
void bitmapGraphScaleValueChanged(double value);
|
void bitmapGraphScaleValueChanged(double value);
|
||||||
|
void layoutSpacingChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>557</width>
|
<width>403</width>
|
||||||
<height>175</height>
|
<height>296</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -65,43 +65,139 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QCheckBox" name="graphOffsetCheckBox">
|
||||||
<property name="sizePolicy">
|
<property name="text">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<string>Show offsets (graph.offset)</string>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<widget class="QCheckBox" name="graphOffsetCheckBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>208</width>
|
|
||||||
<height>24</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Show offsets (graph.offset)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QCheckBox" name="checkTransparent">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>30</y>
|
|
||||||
<width>361</width>
|
|
||||||
<height>31</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Export Transparent Bitmap Graphs</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkTransparent">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export Transparent Bitmap Graphs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Layout</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Horizontal</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Block spacing</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edge spacing</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="horizontalBlockSpacing">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QSpinBox" name="verticalBlockSpacing">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>40</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="horizontalEdgeSpacing">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QSpinBox" name="verticalEdgeSpacing">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Vertical</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>maxColsSpinBox</tabstop>
|
||||||
|
<tabstop>bitmapGraphScale</tabstop>
|
||||||
|
<tabstop>graphOffsetCheckBox</tabstop>
|
||||||
|
<tabstop>checkTransparent</tabstop>
|
||||||
|
<tabstop>horizontalBlockSpacing</tabstop>
|
||||||
|
<tabstop>verticalBlockSpacing</tabstop>
|
||||||
|
<tabstop>horizontalEdgeSpacing</tabstop>
|
||||||
|
<tabstop>verticalEdgeSpacing</tabstop>
|
||||||
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -215,8 +215,8 @@ DisassemblerGraphView::~DisassemblerGraphView()
|
|||||||
void DisassemblerGraphView::refreshView()
|
void DisassemblerGraphView::refreshView()
|
||||||
{
|
{
|
||||||
initFont();
|
initFont();
|
||||||
|
setLayoutConfig(getLayoutConfig());
|
||||||
loadCurrentGraph();
|
loadCurrentGraph();
|
||||||
viewport()->update();
|
|
||||||
emit viewRefreshed();
|
emit viewRefreshed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
cleanupEdges();
|
cleanupEdges();
|
||||||
|
|
||||||
if (!func["blocks"].toArray().isEmpty()) {
|
if (!func["blocks"].toArray().isEmpty()) {
|
||||||
computeGraph(entry);
|
computeGraphPlacement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,6 +877,18 @@ void DisassemblerGraphView::seekInstruction(bool previous_instr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GraphLayout::LayoutConfig DisassemblerGraphView::getLayoutConfig()
|
||||||
|
{
|
||||||
|
auto blockSpacing = Config()->getGraphBlockSpacing();
|
||||||
|
auto edgeSpacing = Config()->getGraphEdgeSpacing();
|
||||||
|
GraphLayout::LayoutConfig layoutConfig;
|
||||||
|
layoutConfig.blockHorizontalSpacing = blockSpacing.x();
|
||||||
|
layoutConfig.blockVerticalSpacing = blockSpacing.y();
|
||||||
|
layoutConfig.edgeHorizontalSpacing = edgeSpacing.x();
|
||||||
|
layoutConfig.edgeVerticalSpacing = edgeSpacing.y();
|
||||||
|
return layoutConfig;
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblerGraphView::nextInstr()
|
void DisassemblerGraphView::nextInstr()
|
||||||
{
|
{
|
||||||
seekInstruction(false);
|
seekInstruction(false);
|
||||||
@ -1161,7 +1173,9 @@ void DisassemblerGraphView::onActionUnhighlightBITriggered()
|
|||||||
void DisassemblerGraphView::updateLayout()
|
void DisassemblerGraphView::updateLayout()
|
||||||
{
|
{
|
||||||
setGraphLayout(GraphView::makeGraphLayout(graphLayout, horizontalLayoutAction->isChecked()));
|
setGraphLayout(GraphView::makeGraphLayout(graphLayout, horizontalLayoutAction->isChecked()));
|
||||||
refreshView();
|
setLayoutConfig(getLayoutConfig());
|
||||||
|
computeGraphPlacement();
|
||||||
|
emit viewRefreshed();
|
||||||
onSeekChanged(this->seekable->getOffset()); // try to keep the view on current block
|
onSeekChanged(this->seekable->getOffset()); // try to keep the view on current block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +203,8 @@ private:
|
|||||||
DisassemblyBlock *blockForAddress(RVA addr);
|
DisassemblyBlock *blockForAddress(RVA addr);
|
||||||
void seekLocal(RVA addr, bool update_viewport = true);
|
void seekLocal(RVA addr, bool update_viewport = true);
|
||||||
void seekInstruction(bool previous_instr);
|
void seekInstruction(bool previous_instr);
|
||||||
|
GraphLayout::LayoutConfig getLayoutConfig();
|
||||||
|
|
||||||
CutterSeekable *seekable = nullptr;
|
CutterSeekable *seekable = nullptr;
|
||||||
QList<QShortcut *> shortcuts;
|
QList<QShortcut *> shortcuts;
|
||||||
QList<RVA> breakpoints;
|
QList<RVA> breakpoints;
|
||||||
|
@ -130,12 +130,11 @@ void GraphView::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This calculates the full graph starting at block entry.
|
void GraphView::computeGraphPlacement()
|
||||||
void GraphView::computeGraph(ut64 entry)
|
|
||||||
{
|
{
|
||||||
graphLayoutSystem->CalculateLayout(blocks, entry, width, height);
|
graphLayoutSystem->CalculateLayout(blocks, entry, width, height);
|
||||||
|
setCacheDirty();
|
||||||
ready = true;
|
ready = true;
|
||||||
|
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,7 +427,6 @@ void GraphView::saveAsSvg(QString path)
|
|||||||
p.end();
|
p.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GraphView::center()
|
void GraphView::center()
|
||||||
{
|
{
|
||||||
centerX(false);
|
centerX(false);
|
||||||
@ -522,6 +520,11 @@ void GraphView::setGraphLayout(std::unique_ptr<GraphLayout> layout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphView::setLayoutConfig(const GraphLayout::LayoutConfig &config)
|
||||||
|
{
|
||||||
|
graphLayoutSystem->setLayoutConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<GraphLayout> GraphView::makeGraphLayout(GraphView::Layout layout, bool horizontal)
|
std::unique_ptr<GraphLayout> GraphView::makeGraphLayout(GraphView::Layout layout, bool horizontal)
|
||||||
{
|
{
|
||||||
std::unique_ptr<GraphLayout> result;
|
std::unique_ptr<GraphLayout> result;
|
||||||
|
@ -78,11 +78,14 @@ public:
|
|||||||
|
|
||||||
void setGraphLayout(std::unique_ptr<GraphLayout> layout);
|
void setGraphLayout(std::unique_ptr<GraphLayout> layout);
|
||||||
GraphLayout& getGraphLayout() const { return *graphLayoutSystem; }
|
GraphLayout& getGraphLayout() const { return *graphLayoutSystem; }
|
||||||
|
void setLayoutConfig(const GraphLayout::LayoutConfig& config);
|
||||||
|
|
||||||
void paint(QPainter &p, QPoint offset, QRect area, qreal scale = 1.0, bool interactive = true);
|
void paint(QPainter &p, QPoint offset, QRect area, qreal scale = 1.0, bool interactive = true);
|
||||||
|
|
||||||
void saveAsBitmap(QString path, const char *format = nullptr, double scaler = 1.0, bool transparent = false);
|
void saveAsBitmap(QString path, const char *format = nullptr, double scaler = 1.0, bool transparent = false);
|
||||||
void saveAsSvg(QString path);
|
void saveAsSvg(QString path);
|
||||||
|
|
||||||
|
void computeGraphPlacement();
|
||||||
protected:
|
protected:
|
||||||
std::unordered_map<ut64, GraphBlock> blocks;
|
std::unordered_map<ut64, GraphBlock> blocks;
|
||||||
QColor backgroundColor = QColor(Qt::white);
|
QColor backgroundColor = QColor(Qt::white);
|
||||||
@ -94,7 +97,6 @@ protected:
|
|||||||
|
|
||||||
void addBlock(GraphView::GraphBlock block);
|
void addBlock(GraphView::GraphBlock block);
|
||||||
void setEntry(ut64 e);
|
void setEntry(ut64 e);
|
||||||
void computeGraph(ut64 entry);
|
|
||||||
|
|
||||||
// Callbacks that should be overridden
|
// Callbacks that should be overridden
|
||||||
/**
|
/**
|
||||||
|
@ -176,6 +176,7 @@ void GraphvizLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &block
|
|||||||
if (auto spl = ED_spl(e)) {
|
if (auto spl = ED_spl(e)) {
|
||||||
for (int i = 0; i < 1 && i < spl->size; i++) {
|
for (int i = 0; i < 1 && i < spl->size; i++) {
|
||||||
auto bz = spl->list[i];
|
auto bz = spl->list[i];
|
||||||
|
edge.polyline.clear();
|
||||||
edge.polyline.reserve(bz.size + 1);
|
edge.polyline.reserve(bz.size + 1);
|
||||||
for (int j = 0; j < bz.size; j++) {
|
for (int j = 0; j < bz.size; j++) {
|
||||||
edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y));
|
edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y));
|
||||||
|
Loading…
Reference in New Issue
Block a user