mirror of
https://github.com/rgriebl/brickstore.git
synced 2026-05-24 09:48:23 -05:00
Modernize: use unique_ptr and array
This commit is contained in:
@@ -28,7 +28,7 @@ namespace BrickLink {
|
||||
|
||||
PictureCache *Picture::s_cache = nullptr;
|
||||
|
||||
Picture::Picture(const Item *item, const Color *color)
|
||||
Picture::Picture(Private, const Item *item, const Color *color)
|
||||
: m_item(item)
|
||||
, m_color(color)
|
||||
{ }
|
||||
@@ -320,11 +320,11 @@ Picture *PictureCache::picture(const Item *item, const Color *color, bool highPr
|
||||
bool needToLoad = !pic || (!pic->isValid() && (pic->updateStatus() == UpdateStatus::UpdateFailed));
|
||||
|
||||
if (!pic) {
|
||||
pic = new Picture(item, color);
|
||||
int cost = pic->cost();
|
||||
if (!d->m_cache.insert(key, pic, cost)) {
|
||||
qCWarning(LogCache, "Can not add picture to cache (cache max/cur: %d/%d, item cost/id: %d/%s)",
|
||||
int(d->m_cache.maxCost()), int(d->m_cache.totalCost()), int(cost), item->id().constData());
|
||||
auto newPic = std::make_unique<Picture>(Picture::Private { }, item, color);
|
||||
pic = d->m_cache.insert(key, std::move(newPic), 1 /* start with roughly 1KB cost */);
|
||||
if (!pic) {
|
||||
qCWarning(LogCache, "Can not add picture to cache (cache max/cur: %d/%d, item id: %s)",
|
||||
int(d->m_cache.maxCost()), int(d->m_cache.totalCost()), item->id().constData());
|
||||
return nullptr;
|
||||
}
|
||||
AppStatistics::inst()->update(d->m_cacheStatId, d->m_cache.size());
|
||||
|
||||
@@ -29,6 +29,8 @@ class Picture : public QObject, protected Ref
|
||||
Q_PROPERTY(BrickLink::UpdateStatus updateStatus READ updateStatus NOTIFY updateStatusChanged FINAL)
|
||||
Q_PROPERTY(QImage image READ image NOTIFY imageChanged FINAL)
|
||||
|
||||
struct Private { };
|
||||
|
||||
public:
|
||||
const Item *item() const { return m_item; }
|
||||
const Color *color() const { return m_color; }
|
||||
@@ -44,7 +46,7 @@ public:
|
||||
|
||||
int cost() const;
|
||||
|
||||
Picture(std::nullptr_t) : Picture(nullptr, nullptr) { } // for scripting only!
|
||||
Picture(Private, const Item *item, const Color *color);
|
||||
~Picture() override;
|
||||
Q_DISABLE_COPY_MOVE(Picture)
|
||||
|
||||
@@ -76,8 +78,6 @@ private:
|
||||
static PictureCache *s_cache;
|
||||
|
||||
private:
|
||||
Picture(const Item *item, const Color *color);
|
||||
|
||||
void setIsValid(bool valid);
|
||||
void setUpdateStatus(UpdateStatus status);
|
||||
void setLastUpdated(const QDateTime &dt);
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace BrickLink {
|
||||
|
||||
PriceGuideCache *PriceGuide::s_cache = nullptr;
|
||||
|
||||
PriceGuide::PriceGuide(const Item *item, const Color *color, VatType vatType)
|
||||
PriceGuide::PriceGuide(Private, const Item *item, const Color *color, VatType vatType)
|
||||
: m_item(item)
|
||||
, m_color(color)
|
||||
, m_vatType(vatType)
|
||||
@@ -725,10 +725,11 @@ PriceGuide *PriceGuideCache::priceGuide(const Item *item, const Color *color, Va
|
||||
bool needToLoad = !pg || (!pg->isValid() && (pg->updateStatus() == UpdateStatus::UpdateFailed));
|
||||
|
||||
if (!pg) {
|
||||
pg = new PriceGuide(item, color, vatType);
|
||||
if (!d->m_cache.insert(key, pg)) {
|
||||
qCWarning(LogCache, "Can not add price guide to cache (cache max/cur: %d/%d, cost: %d)",
|
||||
int(d->m_cache.maxCost()), int(d->m_cache.totalCost()), 1);
|
||||
auto newPg = std::make_unique<PriceGuide>(PriceGuide::Private { }, item, color, vatType);
|
||||
pg = d->m_cache.insert(key, std::move(newPg));
|
||||
if (!pg) {
|
||||
qCWarning(LogCache, "Can not add price guide to cache (cache max/cur: %d/%d, item id: %s)",
|
||||
int(d->m_cache.maxCost()), int(d->m_cache.totalCost()), item->id().constData());
|
||||
return nullptr;
|
||||
}
|
||||
AppStatistics::inst()->update(d->m_cacheStatId, d->m_cache.size());
|
||||
|
||||
@@ -29,6 +29,8 @@ class PriceGuide : public QObject, public Ref
|
||||
Q_PROPERTY(QDateTime lastUpdated READ lastUpdated NOTIFY lastUpdatedChanged FINAL)
|
||||
Q_PROPERTY(BrickLink::UpdateStatus updateStatus READ updateStatus NOTIFY updateStatusChanged FINAL)
|
||||
|
||||
struct Private { };
|
||||
|
||||
public:
|
||||
const Item *item() const { return m_item; }
|
||||
const Color *color() const { return m_color; }
|
||||
@@ -45,7 +47,7 @@ public:
|
||||
Q_INVOKABLE int lots(BrickLink::Time t, BrickLink::Condition c) const { return m_data.lots[int(t)][int(c)]; }
|
||||
Q_INVOKABLE double price(BrickLink::Time t, BrickLink::Condition c, BrickLink::Price p) const { return m_data.prices[int(t)][int(c)][int(p)]; }
|
||||
|
||||
PriceGuide(std::nullptr_t) : PriceGuide(nullptr, nullptr, VatType::Excluded) { } // for scripting only!
|
||||
PriceGuide(Private, const Item *item, const Color *color, VatType vatType);
|
||||
~PriceGuide() override;
|
||||
Q_DISABLE_COPY_MOVE(PriceGuide)
|
||||
|
||||
@@ -84,8 +86,6 @@ private:
|
||||
static PriceGuideCache *s_cache;
|
||||
|
||||
private:
|
||||
PriceGuide(const Item *item, const Color *color, VatType vatType);
|
||||
|
||||
void setIsValid(bool valid);
|
||||
void setUpdateStatus(UpdateStatus status);
|
||||
void setLastUpdated(const QDateTime &dt);
|
||||
|
||||
+69
-125
@@ -10,27 +10,18 @@
|
||||
|
||||
namespace LDraw {
|
||||
|
||||
template <typename T, const int N> static T *parseVectors(const QStringList &list)
|
||||
template <typename T> static T *parseVectors(const QStringList &list)
|
||||
{
|
||||
QVector3D v[N];
|
||||
std::array<QVector3D, T::PointCount> v;
|
||||
|
||||
for (int i = 0; i < N; ++i)
|
||||
for (int i = 0; i < T::PointCount; ++i)
|
||||
v[i] = QVector3D(list[3*i + 1].toFloat(), list[3*i + 2].toFloat(), list[3*i + 3].toFloat());
|
||||
return T::create(list[0].toInt(), v);
|
||||
}
|
||||
|
||||
Element *Element::fromString(const QString &line, const QString &dir)
|
||||
std::unique_ptr<Element> Element::fromString(const QString &line, const QString &dir)
|
||||
{
|
||||
Element *e = nullptr;
|
||||
|
||||
static const int element_count_lut[] = {
|
||||
0,
|
||||
14,
|
||||
7,
|
||||
10,
|
||||
13,
|
||||
13,
|
||||
};
|
||||
std::unique_ptr<Element> e;
|
||||
|
||||
auto list = line.simplified().split(u' ');
|
||||
|
||||
@@ -39,40 +30,29 @@ Element *Element::fromString(const QString &line, const QString &dir)
|
||||
list.removeFirst();
|
||||
|
||||
if (t >= 0 && t <= 5) {
|
||||
int count = element_count_lut[t];
|
||||
if ((count == 0) || (list.size() == count)) {
|
||||
switch (t) {
|
||||
case 0: {
|
||||
const QString cmd = line.mid(1).trimmed();
|
||||
if (cmd.startsWith(u"PE_TEX_")) // Stud.io textures do not have fallbacks
|
||||
break;
|
||||
e = CommentElement::create(cmd);
|
||||
switch (t) {
|
||||
case 0: {
|
||||
const QString cmd = line.mid(1).trimmed();
|
||||
if (cmd.startsWith(u"PE_TEX_")) // Stud.io textures do not have fallbacks
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
QMatrix4x4 m {
|
||||
list[4].toFloat(), list[5].toFloat(), list[6].toFloat(), list[1].toFloat(),
|
||||
list[7].toFloat(), list[8].toFloat(), list[9].toFloat(), list[2].toFloat(),
|
||||
list[10].toFloat(), list[11].toFloat(), list[12].toFloat(), list[3].toFloat(),
|
||||
0, 0, 0, 1
|
||||
};
|
||||
m.optimize();
|
||||
e = PartElement::create(list[0].toInt(), m, list[13], dir);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
e = parseVectors<LineElement, 2>(list);
|
||||
break;
|
||||
case 3:
|
||||
e = parseVectors<TriangleElement, 3>(list);
|
||||
break;
|
||||
case 4:
|
||||
e = parseVectors<QuadElement, 4>(list);
|
||||
break;
|
||||
case 5:
|
||||
e = parseVectors<CondLineElement, 4>(list);
|
||||
break;
|
||||
}
|
||||
e = CommentElement::create(cmd);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
e = PartElement::create(list, dir);
|
||||
break;
|
||||
case 2:
|
||||
e = LineElement::create<LineElement>(list);
|
||||
break;
|
||||
case 3:
|
||||
e = TriangleElement::create<TriangleElement>(list);
|
||||
break;
|
||||
case 4:
|
||||
e = QuadElement::create<QuadElement>(list);
|
||||
break;
|
||||
case 5:
|
||||
e = CondLineElement::create<CondLineElement>(list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,7 +61,7 @@ Element *Element::fromString(const QString &line, const QString &dir)
|
||||
|
||||
|
||||
|
||||
CommentElement::CommentElement(const QString &text)
|
||||
CommentElement::CommentElement(Private, const QString &text)
|
||||
: CommentElement(Type::Comment, text)
|
||||
{ }
|
||||
|
||||
@@ -90,16 +70,16 @@ CommentElement::CommentElement(Element::Type t, const QString &text)
|
||||
, m_comment(text)
|
||||
{ }
|
||||
|
||||
CommentElement *CommentElement::create(const QString &text)
|
||||
std::unique_ptr<CommentElement> CommentElement::create(const QString &text)
|
||||
{
|
||||
if (text.startsWith(u"BFC "))
|
||||
return new BfcCommandElement(text);
|
||||
return BfcCommandElement::create(text);
|
||||
else
|
||||
return new CommentElement(text);
|
||||
return std::make_unique<CommentElement>(Private { }, text);
|
||||
}
|
||||
|
||||
|
||||
BfcCommandElement::BfcCommandElement(const QString &text)
|
||||
BfcCommandElement::BfcCommandElement(Private, const QString &text)
|
||||
: CommentElement(Type::BfcCommand, text)
|
||||
{
|
||||
auto c = text.split(u' ');
|
||||
@@ -117,64 +97,13 @@ BfcCommandElement::BfcCommandElement(const QString &text)
|
||||
}
|
||||
}
|
||||
|
||||
BfcCommandElement *BfcCommandElement::create(const QString &text)
|
||||
std::unique_ptr<BfcCommandElement> BfcCommandElement::create(const QString &text)
|
||||
{
|
||||
return new BfcCommandElement(text);
|
||||
return std::make_unique<BfcCommandElement>(Private { }, text);
|
||||
}
|
||||
|
||||
|
||||
LineElement::LineElement(int color, const QVector3D *v)
|
||||
: Element(Type::Line), m_color(color)
|
||||
{
|
||||
memcpy(m_points, v, sizeof(m_points));
|
||||
}
|
||||
|
||||
LineElement *LineElement::create(int color, const QVector3D *v)
|
||||
{
|
||||
return new LineElement(color, v);
|
||||
}
|
||||
|
||||
|
||||
CondLineElement::CondLineElement(int color, const QVector3D *v)
|
||||
: Element(Type::CondLine), m_color(color)
|
||||
{
|
||||
memcpy(m_points, v, sizeof(m_points));
|
||||
}
|
||||
|
||||
CondLineElement *CondLineElement::create(int color, const QVector3D *v)
|
||||
{
|
||||
return new CondLineElement(color, v);
|
||||
}
|
||||
|
||||
|
||||
TriangleElement::TriangleElement(int color, const QVector3D *v)
|
||||
: Element(Type::Triangle), m_color(color)
|
||||
{
|
||||
Q_ASSERT(color >= 0);
|
||||
memcpy(m_points, v, sizeof(m_points));
|
||||
}
|
||||
|
||||
TriangleElement *TriangleElement::create(int color, const QVector3D *v)
|
||||
{
|
||||
return new TriangleElement(color, v);
|
||||
}
|
||||
|
||||
|
||||
QuadElement::QuadElement(int color, const QVector3D *v)
|
||||
: Element(Type::Quad), m_color(color)
|
||||
{
|
||||
Q_ASSERT(color >= 0);
|
||||
memcpy(m_points, v, sizeof(m_points));
|
||||
}
|
||||
|
||||
QuadElement *QuadElement::create(int color, const QVector3D *v)
|
||||
{
|
||||
return new QuadElement(color, v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PartElement::PartElement(int color, const QMatrix4x4 &matrix, Part *p)
|
||||
PartElement::PartElement(Private, int color, const QMatrix4x4 &matrix, Part *p)
|
||||
: Element(Type::Part), m_matrix(matrix), m_part(p), m_color(color)
|
||||
{
|
||||
if (m_part)
|
||||
@@ -187,24 +116,30 @@ PartElement::~PartElement()
|
||||
m_part->release();
|
||||
}
|
||||
|
||||
PartElement *PartElement::create(int color, const QMatrix4x4 &matrix,
|
||||
const QString &filename, const QString &parentdir)
|
||||
std::unique_ptr<PartElement> PartElement::create(const QStringList &list, const QString &parentdir)
|
||||
{
|
||||
PartElement *e = nullptr;
|
||||
if (list.size() != 14)
|
||||
return { };
|
||||
|
||||
QMatrix4x4 m {
|
||||
list[4].toFloat(), list[5].toFloat(), list[6].toFloat(), list[1].toFloat(),
|
||||
list[7].toFloat(), list[8].toFloat(), list[9].toFloat(), list[2].toFloat(),
|
||||
list[10].toFloat(), list[11].toFloat(), list[12].toFloat(), list[3].toFloat(),
|
||||
0, 0, 0, 1
|
||||
};
|
||||
m.optimize();
|
||||
const QString filename = list[13];
|
||||
const int color = list[0].toInt();
|
||||
|
||||
if (Part *p = library()->findPart(filename, parentdir))
|
||||
e = new PartElement(color, matrix, p);
|
||||
return e;
|
||||
return std::make_unique<PartElement>(Private { }, color, m, p);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Part::~Part()
|
||||
std::unique_ptr<Part> Part::parse(const QByteArray &data, const QString &dir)
|
||||
{
|
||||
qDeleteAll(m_elements);
|
||||
}
|
||||
|
||||
Part *Part::parse(const QByteArray &data, const QString &dir)
|
||||
{
|
||||
Part *p = new Part();
|
||||
auto p = std::make_unique<Part>(Private { });
|
||||
QTextStream ts(data);
|
||||
|
||||
QString line;
|
||||
@@ -214,23 +149,32 @@ Part *Part::parse(const QByteArray &data, const QString &dir)
|
||||
lineno++;
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
if (Element *e = Element::fromString(line, dir)) {
|
||||
p->m_elements.append(e);
|
||||
if (std::unique_ptr<Element> e = Element::fromString(line, dir)) {
|
||||
p->m_cost += int(e->size());
|
||||
p->m_elements.emplace_back(std::move(e));
|
||||
} else {
|
||||
qCWarning(LogLDraw) << "Could not parse line" << lineno << ":" << line;
|
||||
delete p;
|
||||
return nullptr;
|
||||
p.reset();
|
||||
return { };
|
||||
}
|
||||
}
|
||||
|
||||
if (p->m_elements.isEmpty()) {
|
||||
delete p;
|
||||
p = nullptr;
|
||||
if (p->m_elements.empty()) {
|
||||
p.reset();
|
||||
return { };
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
QVector<const Element *> Part::elements() const
|
||||
{
|
||||
QVector<const Element *> v { qsizetype(m_elements.size()) };
|
||||
int i = 0;
|
||||
for (const auto &ue : m_elements)
|
||||
v[i++] = ue.get();
|
||||
return v;
|
||||
}
|
||||
|
||||
int Part::cost() const
|
||||
{
|
||||
return m_cost;
|
||||
|
||||
+59
-89
@@ -18,24 +18,26 @@ class Element;
|
||||
class PartElement;
|
||||
|
||||
|
||||
class Part : public Ref
|
||||
class Part final : public Ref
|
||||
{
|
||||
struct Private { };
|
||||
public:
|
||||
~Part() override;
|
||||
Part(Private) { };
|
||||
~Part() override = default;
|
||||
|
||||
inline const QVector<Element *> &elements() const { return m_elements; }
|
||||
QVector<const Element *> elements() const;
|
||||
int cost() const;
|
||||
|
||||
protected:
|
||||
Part() = default;
|
||||
static std::unique_ptr<Part> parse(const QByteArray &data, const QString &dir);
|
||||
|
||||
private:
|
||||
|
||||
static Part *parse(const QByteArray &data, const QString &dir);
|
||||
friend class PartElement;
|
||||
friend class Library;
|
||||
|
||||
static void calculateBoundingBox(const Part *part, const QMatrix4x4 &matrix, QVector3D &vmin, QVector3D &vmax);
|
||||
|
||||
QVector<Element *> m_elements;
|
||||
std::vector<std::unique_ptr<Element>> m_elements;
|
||||
int m_cost = 0;
|
||||
|
||||
Q_DISABLE_COPY_MOVE(Part)
|
||||
@@ -55,7 +57,7 @@ public:
|
||||
CondLine
|
||||
};
|
||||
|
||||
static Element *fromString(const QString &line, const QString &dir);
|
||||
static std::unique_ptr<Element> fromString(const QString &line, const QString &dir);
|
||||
inline Type type() const { return m_type; }
|
||||
virtual ~Element() = default;
|
||||
virtual uint size() const = 0;
|
||||
@@ -65,31 +67,35 @@ protected:
|
||||
: m_type(t) { }
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(Element)
|
||||
Q_DISABLE_COPY_MOVE(Element)
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
|
||||
class CommentElement : public Element
|
||||
{
|
||||
struct Private { };
|
||||
public:
|
||||
QString comment() const { return m_comment; }
|
||||
uint size() const override { return int(sizeof(*this)) + uint(m_comment.size() * 2); }
|
||||
|
||||
static CommentElement *create(const QString &text);
|
||||
static std::unique_ptr<CommentElement> create(const QString &text);
|
||||
|
||||
CommentElement(Private, const QString &text);
|
||||
~CommentElement() override = default;
|
||||
|
||||
protected:
|
||||
CommentElement(Type t, const QString &text);
|
||||
CommentElement(const QString &);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(CommentElement)
|
||||
Q_DISABLE_COPY_MOVE(CommentElement)
|
||||
QString m_comment;
|
||||
};
|
||||
|
||||
|
||||
class BfcCommandElement : public CommentElement
|
||||
{
|
||||
struct Private { };
|
||||
public:
|
||||
bool certify() const { return m_certify; }
|
||||
bool noCertify() const { return m_nocertify; }
|
||||
@@ -99,13 +105,13 @@ public:
|
||||
bool cw() const { return m_cw; }
|
||||
bool invertNext() const { return m_invertNext; }
|
||||
|
||||
static BfcCommandElement *create(const QString &text);
|
||||
static std::unique_ptr<BfcCommandElement> create(const QString &text);
|
||||
|
||||
protected:
|
||||
BfcCommandElement(const QString &);
|
||||
BfcCommandElement(Private, const QString &);
|
||||
~BfcCommandElement() override = default;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(BfcCommandElement)
|
||||
Q_DISABLE_COPY_MOVE(BfcCommandElement)
|
||||
bool m_certify : 1 = false;
|
||||
bool m_nocertify : 1 = false;
|
||||
bool m_clip : 1 = false;
|
||||
@@ -117,103 +123,67 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class LineElement : public Element
|
||||
template<Element::Type ELEMENT_TYPE, int POINT_COUNT>
|
||||
class PointElement : public Element
|
||||
{
|
||||
struct Private { };
|
||||
public:
|
||||
static constexpr int PointCount = POINT_COUNT;
|
||||
|
||||
int color() const { return m_color; }
|
||||
const QVector3D *points() const { return m_points;}
|
||||
uint size() const override { return sizeof(*this); }
|
||||
const std::array<QVector3D, POINT_COUNT> &points() const { return m_points;}
|
||||
|
||||
static LineElement *create(int color, const QVector3D *points);
|
||||
template <typename T> static std::unique_ptr<T> create(const QStringList &list)
|
||||
{
|
||||
std::array<QVector3D, T::PointCount> v;
|
||||
|
||||
protected:
|
||||
LineElement(int color, const QVector3D *points);
|
||||
if (list.size() != (1 + 3 * T::PointCount))
|
||||
return nullptr;
|
||||
|
||||
for (int i = 0; i < T::PointCount; ++i)
|
||||
v[i] = QVector3D(list[3*i + 1].toFloat(), list[3*i + 2].toFloat(), list[3*i + 3].toFloat());
|
||||
return std::make_unique<T>(Private { }, list[0].toInt(), v);
|
||||
}
|
||||
|
||||
PointElement(Private, int color, const std::array<QVector3D, POINT_COUNT> &points)
|
||||
: Element(ELEMENT_TYPE)
|
||||
, m_points(points)
|
||||
, m_color(color)
|
||||
{ }
|
||||
|
||||
~PointElement() override = default;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(LineElement)
|
||||
QVector3D m_points[2];
|
||||
int m_color;
|
||||
};
|
||||
|
||||
|
||||
class CondLineElement : public Element
|
||||
{
|
||||
public:
|
||||
int color() const { return m_color; }
|
||||
const QVector3D *points() const { return m_points;}
|
||||
uint size() const override { return sizeof(*this); }
|
||||
|
||||
static CondLineElement *create(int color, const QVector3D *points);
|
||||
|
||||
protected:
|
||||
CondLineElement(int color, const QVector3D *points);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(CondLineElement)
|
||||
QVector3D m_points[4];
|
||||
int m_color;
|
||||
};
|
||||
|
||||
|
||||
class TriangleElement : public Element
|
||||
{
|
||||
public:
|
||||
int color() const { return m_color; }
|
||||
const QVector3D *points() const { return m_points;}
|
||||
uint size() const override { return sizeof(*this); }
|
||||
|
||||
static TriangleElement *create(int color, const QVector3D *points);
|
||||
|
||||
protected:
|
||||
TriangleElement(int color, const QVector3D *points);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(TriangleElement)
|
||||
QVector3D m_points[3];
|
||||
int m_color;
|
||||
};
|
||||
|
||||
|
||||
class QuadElement : public Element
|
||||
{
|
||||
public:
|
||||
int color() const { return m_color; }
|
||||
const QVector3D *points() const { return m_points;}
|
||||
uint size() const override { return sizeof(*this); }
|
||||
|
||||
static QuadElement *create(int color, const QVector3D *points);
|
||||
|
||||
protected:
|
||||
QuadElement(int color, const QVector3D *points);
|
||||
|
||||
private:
|
||||
QVector3D m_points[4];
|
||||
int m_color;
|
||||
Q_DISABLE_COPY(QuadElement)
|
||||
Q_DISABLE_COPY_MOVE(PointElement)
|
||||
std::array<QVector3D, POINT_COUNT> m_points { };
|
||||
int m_color = 0;
|
||||
};
|
||||
|
||||
using LineElement = PointElement<Element::Type::Line, 2>;
|
||||
using CondLineElement = PointElement<Element::Type::CondLine, 4>;
|
||||
using TriangleElement = PointElement<Element::Type::Triangle, 3>;
|
||||
using QuadElement = PointElement<Element::Type::Quad, 4>;
|
||||
|
||||
class PartElement : public Element
|
||||
{
|
||||
struct Private { };
|
||||
public:
|
||||
int color() const { return m_color; }
|
||||
const QMatrix4x4 &matrix() const { return m_matrix; }
|
||||
Part *part() const { return m_part; }
|
||||
uint size() const override { return sizeof(*this); }
|
||||
|
||||
static PartElement *create(int color, const QMatrix4x4 &m, const QString &filename,
|
||||
const QString &parentdir);
|
||||
static std::unique_ptr<PartElement> create(const QStringList &list, const QString &parentdir);
|
||||
|
||||
PartElement(Private, int color, const QMatrix4x4 &m, Part *part);
|
||||
~PartElement() override;
|
||||
|
||||
protected:
|
||||
PartElement(int color, const QMatrix4x4 &m, Part *part);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(PartElement)
|
||||
Q_DISABLE_COPY_MOVE(PartElement)
|
||||
QMatrix4x4 m_matrix;
|
||||
Part * m_part;
|
||||
int m_color;
|
||||
Part * m_part = nullptr;
|
||||
int m_color = 0;
|
||||
};
|
||||
|
||||
} // namespace LDraw
|
||||
|
||||
@@ -32,7 +32,7 @@ RenderController::RenderController(QObject *parent)
|
||||
, m_lines(new QmlRenderLineInstancing())
|
||||
, m_clearColor(Qt::white)
|
||||
{
|
||||
static const float lineGeo[] = {
|
||||
static const std::array<float, 6 * 3> lineGeo = {
|
||||
0, -0.5, 0,
|
||||
0, -0.5, 1,
|
||||
0, 0.5, 1,
|
||||
@@ -44,7 +44,8 @@ RenderController::RenderController(QObject *parent)
|
||||
m_lineGeo->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Triangles);
|
||||
m_lineGeo->setStride(3 * sizeof(float));
|
||||
m_lineGeo->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0, QQuick3DGeometry::Attribute::F32Type);
|
||||
m_lineGeo->setVertexData(QByteArray::fromRawData(reinterpret_cast<const char *>(lineGeo), sizeof(lineGeo)));
|
||||
m_lineGeo->setVertexData(QByteArray::fromRawData(reinterpret_cast<const char *>(lineGeo.data()),
|
||||
qsizetype(lineGeo.size() * sizeof(decltype(lineGeo)::value_type))));
|
||||
}
|
||||
|
||||
RenderController::~RenderController()
|
||||
@@ -205,9 +206,9 @@ RenderController::RenderData RenderController::calculateRenderData(Part *part, c
|
||||
const BrickLink::Color *surfaceColor = it.key();
|
||||
const bool isTextured = surfaceColor->hasParticles() || (surfaceColor->id() == 0);
|
||||
|
||||
const int stride = (3 + 3 + (isTextured ? 2 : 0)) * sizeof(float);
|
||||
const int stride = (3 + 3 + (isTextured ? 2 : 0)) * int(sizeof(float));
|
||||
|
||||
auto geo = new QmlRenderGeometry(surfaceColor);
|
||||
auto geo = std::make_unique<QmlRenderGeometry>(surfaceColor);
|
||||
|
||||
// calculate bounding box
|
||||
static constexpr auto fmin = std::numeric_limits<float>::min();
|
||||
@@ -239,17 +240,17 @@ RenderController::RenderData RenderController::calculateRenderData(Part *part, c
|
||||
if (isTextured) {
|
||||
geo->addAttribute(QQuick3DGeometry::Attribute::TexCoord0Semantic, 6 * sizeof(float), QQuick3DGeometry::Attribute::F32Type);
|
||||
|
||||
QQuick3DTextureData *texData = generateMaterialTextureData(surfaceColor);
|
||||
texData->setParentItem(geo); // 3D scene parent
|
||||
texData->setParent(geo); // owning parent
|
||||
geo->setTextureData(texData);
|
||||
auto texData = generateMaterialTextureData(surfaceColor);
|
||||
texData->setParentItem(geo.get()); // 3D scene parent
|
||||
texData->setParent(geo.get()); // owning parent
|
||||
geo->setTextureData(texData.release());
|
||||
}
|
||||
geo->setBounds(vmin, vmax);
|
||||
geo->setCenter(surfaceCenter);
|
||||
geo->setRadius(surfaceRadius);
|
||||
geo->setVertexData(data);
|
||||
|
||||
geos.append(geo);
|
||||
geos.append(geo.release());
|
||||
}
|
||||
|
||||
for (auto *geo : std::as_const(geos)) {
|
||||
@@ -378,7 +379,7 @@ void RenderController::fillVertexBuffers(Part *part, const BrickLink::Color *mod
|
||||
return Qt::black;
|
||||
};
|
||||
|
||||
const auto &elements = part->elements();
|
||||
const auto elements = part->elements();
|
||||
for (const Element *e : elements) {
|
||||
bool isBFCCommand = false;
|
||||
bool isBFCInvertNext = false;
|
||||
@@ -428,9 +429,9 @@ void RenderController::fillVertexBuffers(Part *part, const BrickLink::Color *mod
|
||||
const auto color = mapColor(qe->color());
|
||||
const auto p = qe->points();
|
||||
const auto p0m = matrix.map(p[0]);
|
||||
const auto p1m = matrix.map(p[ccw ? 3 : 1]);
|
||||
const auto p1m = matrix.map(ccw ? p[3] : p[1]);
|
||||
const auto p2m = matrix.map(p[2]);
|
||||
const auto p3m = matrix.map(p[ccw ? 1 : 3]);
|
||||
const auto p3m = matrix.map(ccw ? p[1] : p[3]);
|
||||
const auto n = QVector3D::normal(p0m, p1m, p2m);
|
||||
|
||||
if (color->hasParticles() || (color->id() == 0)) {
|
||||
@@ -491,7 +492,7 @@ void RenderController::fillVertexBuffers(Part *part, const BrickLink::Color *mod
|
||||
}
|
||||
}
|
||||
|
||||
QQuick3DTextureData *RenderController::generateMaterialTextureData(const BrickLink::Color *color)
|
||||
std::unique_ptr<QQuick3DTextureData> RenderController::generateMaterialTextureData(const BrickLink::Color *color)
|
||||
{
|
||||
static constexpr int GeneratorVersion = 1;
|
||||
|
||||
@@ -611,7 +612,7 @@ QQuick3DTextureData *RenderController::generateMaterialTextureData(const BrickLi
|
||||
s_materialTextureDatas.insert(color, texImage);
|
||||
}
|
||||
|
||||
auto texData = new QQuick3DTextureData();
|
||||
auto texData = std::make_unique<QQuick3DTextureData>();
|
||||
texData->setFormat(QQuick3DTextureData::RGBA8);
|
||||
texData->setSize(texImage.size());
|
||||
texData->setHasTransparency(color->ldrawColor().alpha() < 255);
|
||||
@@ -619,7 +620,7 @@ QQuick3DTextureData *RenderController::generateMaterialTextureData(const BrickLi
|
||||
texImage.sizeInBytes() });
|
||||
return texData;
|
||||
}
|
||||
return nullptr;
|
||||
return { };
|
||||
}
|
||||
|
||||
void RenderController::resetCamera()
|
||||
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
const BrickLink::Color *baseColor, const QMatrix4x4 &matrix,
|
||||
bool inverted, QHash<const BrickLink::Color *, QByteArray> &surfaceBuffers,
|
||||
QByteArray &lineBuffer);
|
||||
static QQuick3DTextureData *generateMaterialTextureData(const BrickLink::Color *color);
|
||||
static std::unique_ptr<QQuick3DTextureData> generateMaterialTextureData(const BrickLink::Color *color);
|
||||
static std::vector<std::pair<float, float> > uvMapToNearestPlane(const QVector3D &normal,
|
||||
std::initializer_list<const QVector3D> vectors);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user