diff --git a/application/sources/about_widget.cc b/application/sources/about_widget.cc index 58285361..ac780827 100644 --- a/application/sources/about_widget.cc +++ b/application/sources/about_widget.cc @@ -1,22 +1,22 @@ +#include #include #include -#include #include "about_widget.h" -#include "version.h" #include "model_widget.h" +#include "version.h" AboutWidget::AboutWidget() { - QTextEdit *versionInfoLabel = new QTextEdit; + QTextEdit* versionInfoLabel = new QTextEdit; versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg(ModelWidget::m_openGLVersion).arg(ModelWidget::m_openGLShadingLanguageVersion).arg(ModelWidget::m_openGLIsCoreProfile ? "true" : "false")); versionInfoLabel->setReadOnly(true); - - QVBoxLayout *mainLayout = new QVBoxLayout; + + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(versionInfoLabel); - + setLayout(mainLayout); setFixedSize(QSize(350, 100)); - + setWindowTitle(applicationTitle(tr("About"))); } diff --git a/application/sources/about_widget.h b/application/sources/about_widget.h index 4e650a00..53117a48 100644 --- a/application/sources/about_widget.h +++ b/application/sources/about_widget.h @@ -3,8 +3,7 @@ #include -class AboutWidget : public QDialog -{ +class AboutWidget : public QDialog { Q_OBJECT public: AboutWidget(); diff --git a/application/sources/ccd_ik_resolver.cc b/application/sources/ccd_ik_resolver.cc index 40395eb9..b34e614b 100644 --- a/application/sources/ccd_ik_resolver.cc +++ b/application/sources/ccd_ik_resolver.cc @@ -1,9 +1,9 @@ -#include -#include -#include -#include -#include #include "ccd_ik_resolver.h" +#include +#include +#include +#include +#include CcdIkSolver::CcdIkSolver() { @@ -15,9 +15,9 @@ void CcdIkSolver::setSolveFrom(int fromNodeIndex) } void CcdIkSolver::setNodeHingeConstraint(int nodeIndex, - const QVector3D &axis, double minLimitDegrees, double maxLimitDegrees) + const QVector3D& axis, double minLimitDegrees, double maxLimitDegrees) { - auto &node = m_nodes[nodeIndex]; + auto& node = m_nodes[nodeIndex]; node.axis = axis; node.minLimitDegrees = minLimitDegrees; node.maxLimitDegrees = maxLimitDegrees; @@ -33,7 +33,7 @@ void CcdIkSolver::setDistanceThreshod(float threshold) m_distanceThreshold2 = threshold * threshold; } -int CcdIkSolver::addNodeInOrder(const QVector3D &position) +int CcdIkSolver::addNodeInOrder(const QVector3D& position) { CcdIkNode node; node.position = position; @@ -42,13 +42,13 @@ int CcdIkSolver::addNodeInOrder(const QVector3D &position) return nodeCount; } -void CcdIkSolver::solveTo(const QVector3D &position) +void CcdIkSolver::solveTo(const QVector3D& position) { //qDebug() << "solveTo:" << position; m_destination = position; float lastDistance2 = 0; for (int i = 0; i < m_maxRound; i++) { - const auto &endEffector = m_nodes[m_nodes.size() - 1]; + const auto& endEffector = m_nodes[m_nodes.size() - 1]; float distance2 = (endEffector.position - m_destination).lengthSquared(); //qDebug() << "Round:" << i << " distance2:" << distance2; if (distance2 <= m_distanceThreshold2) @@ -60,7 +60,7 @@ void CcdIkSolver::solveTo(const QVector3D &position) } } -const QVector3D &CcdIkSolver::getNodeSolvedPosition(int index) +const QVector3D& CcdIkSolver::getNodeSolvedPosition(int index) { Q_ASSERT(index >= 0 && index < (int)m_nodes.size()); return m_nodes[index].position; @@ -82,18 +82,18 @@ float CcdIkSolver::angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, Q void CcdIkSolver::iterate() { - auto rotateChildren = [&](const QQuaternion &quaternion, int i) { - const auto &origin = m_nodes[i]; + auto rotateChildren = [&](const QQuaternion& quaternion, int i) { + const auto& origin = m_nodes[i]; for (size_t j = i + 1; j <= m_nodes.size() - 1; j++) { - auto &next = m_nodes[j]; + auto& next = m_nodes[j]; const auto offset = next.position - origin.position; next.position = origin.position + quaternion.rotatedVector(offset); } }; - + for (int i = m_nodes.size() - 2; i >= m_fromNodeIndex; i--) { - const auto &origin = m_nodes[i]; - const auto &endEffector = m_nodes[m_nodes.size() - 1]; + const auto& origin = m_nodes[i]; + const auto& endEffector = m_nodes[m_nodes.size() - 1]; QVector3D from = (endEffector.position - origin.position).normalized(); QVector3D to = (m_destination - origin.position).normalized(); auto quaternion = QQuaternion::rotationTo(from, to); @@ -111,12 +111,10 @@ void CcdIkSolver::iterate() int childIndex = i + 1; if (childIndex >= m_nodes.size()) continue; - const auto &parent = m_nodes[parentIndex]; - const auto &child = m_nodes[childIndex]; - QVector3D angleFrom = (QVector3D(0.0, parent.position.y(), parent.position.z()) - - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized(); - QVector3D angleTo = (QVector3D(0.0, child.position.y(), child.position.z()) - - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized(); + const auto& parent = m_nodes[parentIndex]; + const auto& child = m_nodes[childIndex]; + QVector3D angleFrom = (QVector3D(0.0, parent.position.y(), parent.position.z()) - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized(); + QVector3D angleTo = (QVector3D(0.0, child.position.y(), child.position.z()) - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized(); float degrees = angleInRangle360BetweenTwoVectors(angleFrom, angleTo, QVector3D(1.0, 0.0, 0.0)); if (degrees < origin.minLimitDegrees) { auto quaternion = QQuaternion::fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), origin.minLimitDegrees - degrees); diff --git a/application/sources/ccd_ik_resolver.h b/application/sources/ccd_ik_resolver.h index 151d91aa..2f605712 100644 --- a/application/sources/ccd_ik_resolver.h +++ b/application/sources/ccd_ik_resolver.h @@ -1,31 +1,30 @@ #ifndef DUST3D_APPLICATION_CCD_IK_SOLVER_H_ #define DUST3D_APPLICATION_CCD_IK_SOLVER_H_ -#include -#include #include +#include +#include -struct CcdIkNode -{ +struct CcdIkNode { QVector3D position; QVector3D axis; double minLimitDegrees; double maxLimitDegrees; }; -class CcdIkSolver -{ +class CcdIkSolver { public: CcdIkSolver(); void setMaxRound(int maxRound); void setDistanceThreshod(float threshold); - int addNodeInOrder(const QVector3D &position); - void solveTo(const QVector3D &position); - const QVector3D &getNodeSolvedPosition(int index); + int addNodeInOrder(const QVector3D& position); + void solveTo(const QVector3D& position); + const QVector3D& getNodeSolvedPosition(int index); int getNodeCount(); void setNodeHingeConstraint(int nodeIndex, - const QVector3D &axis, double minLimitDegrees, double maxLimitDegrees); + const QVector3D& axis, double minLimitDegrees, double maxLimitDegrees); void setSolveFrom(int fromNodeIndex); + private: float angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, QVector3D planeNormal); void iterate(); diff --git a/application/sources/component_list_model.cc b/application/sources/component_list_model.cc index f066c4d0..c2b16768 100644 --- a/application/sources/component_list_model.cc +++ b/application/sources/component_list_model.cc @@ -1,13 +1,13 @@ -#include -#include #include "component_list_model.h" #include "document.h" +#include +#include -ComponentListModel::ComponentListModel(const Document *document, QObject *parent): - QAbstractListModel(parent), - m_document(document) +ComponentListModel::ComponentListModel(const Document* document, QObject* parent) + : QAbstractListModel(parent) + , m_document(document) { - connect(m_document, &Document::componentPreviewPixmapChanged, [this](const dust3d::Uuid &componentId) { + connect(m_document, &Document::componentPreviewPixmapChanged, [this](const dust3d::Uuid& componentId) { auto findIndex = this->m_componentIdToIndexMap.find(componentId); if (findIndex != this->m_componentIdToIndexMap.end()) { //dust3dDebug << "dataChanged:" << findIndex->second.row(); @@ -18,7 +18,7 @@ ComponentListModel::ComponentListModel(const Document *document, QObject *parent this->setListingComponentId(dust3d::Uuid()); this->reload(); }); - connect(m_document, &Document::componentChildrenChanged, [this](const dust3d::Uuid &componentId) { + connect(m_document, &Document::componentChildrenChanged, [this](const dust3d::Uuid& componentId) { if (componentId != this->listingComponentId()) return; this->reload(); @@ -29,7 +29,7 @@ void ComponentListModel::reload() { beginResetModel(); m_componentIdToIndexMap.clear(); - const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); + const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId); if (nullptr != listingComponent) { for (int i = 0; i < (int)listingComponent->childrenIds.size(); ++i) { m_componentIdToIndexMap[listingComponent->childrenIds[i]] = createIndex(i, 0); @@ -39,7 +39,7 @@ void ComponentListModel::reload() emit layoutChanged(); } -QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid &componentId) const +QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid& componentId) const { auto findIndex = m_componentIdToIndexMap.find(componentId); if (findIndex == m_componentIdToIndexMap.end()) @@ -47,34 +47,34 @@ QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid &component return findIndex->second; } -int ComponentListModel::rowCount(const QModelIndex &parent) const +int ComponentListModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; - const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); + const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId); if (nullptr == listingComponent) return 0; return (int)listingComponent->childrenIds.size(); } -int ComponentListModel::columnCount(const QModelIndex &parent) const +int ComponentListModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return 1; } -const SkeletonComponent *ComponentListModel::modelIndexToComponent(const QModelIndex &index) const +const SkeletonComponent* ComponentListModel::modelIndexToComponent(const QModelIndex& index) const { - const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); + const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId); if (nullptr == listingComponent) return nullptr; if (index.row() >= (int)listingComponent->childrenIds.size()) { dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row(); return nullptr; } - const auto &componentId = listingComponent->childrenIds[index.row()]; - const SkeletonComponent *component = m_document->findComponent(componentId); + const auto& componentId = listingComponent->childrenIds[index.row()]; + const SkeletonComponent* component = m_document->findComponent(componentId); if (nullptr == component) { dust3dDebug << "Component not found:" << componentId.toString(); return nullptr; @@ -82,50 +82,48 @@ const SkeletonComponent *ComponentListModel::modelIndexToComponent(const QModelI return component; } -const dust3d::Uuid ComponentListModel::modelIndexToComponentId(const QModelIndex &index) const +const dust3d::Uuid ComponentListModel::modelIndexToComponentId(const QModelIndex& index) const { - const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); + const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId); if (nullptr == listingComponent) return dust3d::Uuid(); if (index.row() >= (int)listingComponent->childrenIds.size()) { dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row(); return dust3d::Uuid(); } - const auto &componentId = listingComponent->childrenIds[index.row()]; + const auto& componentId = listingComponent->childrenIds[index.row()]; return componentId; } -QVariant ComponentListModel::data(const QModelIndex &index, int role) const +QVariant ComponentListModel::data(const QModelIndex& index, int role) const { switch (role) { case Qt::ToolTipRole: { - const SkeletonComponent *component = modelIndexToComponent(index); - if (nullptr != component) { - return component->name; - } + const SkeletonComponent* component = modelIndexToComponent(index); + if (nullptr != component) { + return component->name; } - break; + } break; case Qt::DecorationRole: { - const SkeletonComponent *component = modelIndexToComponent(index); - if (nullptr != component) { - if (0 == component->previewPixmap.width()) { - static QPixmap s_emptyPixmap; - if (0 == s_emptyPixmap.width()) { - QImage image((int)Theme::partPreviewImageSize, (int)Theme::partPreviewImageSize, QImage::Format_ARGB32); - image.fill(Qt::transparent); - s_emptyPixmap = QPixmap::fromImage(image); - } - return s_emptyPixmap; + const SkeletonComponent* component = modelIndexToComponent(index); + if (nullptr != component) { + if (0 == component->previewPixmap.width()) { + static QPixmap s_emptyPixmap; + if (0 == s_emptyPixmap.width()) { + QImage image((int)Theme::partPreviewImageSize, (int)Theme::partPreviewImageSize, QImage::Format_ARGB32); + image.fill(Qt::transparent); + s_emptyPixmap = QPixmap::fromImage(image); } - return component->previewPixmap; + return s_emptyPixmap; } + return component->previewPixmap; } - break; + } break; } return QVariant(); } -void ComponentListModel::setListingComponentId(const dust3d::Uuid &componentId) +void ComponentListModel::setListingComponentId(const dust3d::Uuid& componentId) { if (m_listingComponentId == componentId) return; diff --git a/application/sources/component_list_model.h b/application/sources/component_list_model.h index 07ee5b67..a9843e02 100644 --- a/application/sources/component_list_model.h +++ b/application/sources/component_list_model.h @@ -1,32 +1,33 @@ #ifndef DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ #define DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ -#include -#include #include +#include +#include class Document; class SkeletonComponent; -class ComponentListModel: public QAbstractListModel -{ +class ComponentListModel : public QAbstractListModel { Q_OBJECT signals: - void listingComponentChanged(const dust3d::Uuid &componentId); + void listingComponentChanged(const dust3d::Uuid& componentId); + public: - ComponentListModel(const Document *document, QObject *parent=nullptr); - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role) const; - const SkeletonComponent *modelIndexToComponent(const QModelIndex &index) const; - QModelIndex componentIdToIndex(const dust3d::Uuid &componentId) const; - const dust3d::Uuid modelIndexToComponentId(const QModelIndex &index) const; + ComponentListModel(const Document* document, QObject* parent = nullptr); + int rowCount(const QModelIndex& parent = QModelIndex()) const; + int columnCount(const QModelIndex& parent = QModelIndex()) const; + QVariant data(const QModelIndex& index, int role) const; + const SkeletonComponent* modelIndexToComponent(const QModelIndex& index) const; + QModelIndex componentIdToIndex(const dust3d::Uuid& componentId) const; + const dust3d::Uuid modelIndexToComponentId(const QModelIndex& index) const; const dust3d::Uuid listingComponentId() const; public slots: - void setListingComponentId(const dust3d::Uuid &componentId); + void setListingComponentId(const dust3d::Uuid& componentId); void reload(); + private: - const Document *m_document = nullptr; + const Document* m_document = nullptr; dust3d::Uuid m_listingComponentId; std::unordered_map m_componentIdToIndexMap; }; diff --git a/application/sources/component_preview_grid_widget.cc b/application/sources/component_preview_grid_widget.cc index fe969721..62e5a441 100644 --- a/application/sources/component_preview_grid_widget.cc +++ b/application/sources/component_preview_grid_widget.cc @@ -1,23 +1,23 @@ -#include #include "component_preview_grid_widget.h" #include "component_list_model.h" #include "document.h" +#include -ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document *document, QWidget *parent): - PreviewGridView(parent), - m_document(document) +ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document* document, QWidget* parent) + : PreviewGridView(parent) + , m_document(document) { m_componentListModel = std::make_unique(m_document); setModel(m_componentListModel.get()); - connect(this, &ComponentPreviewGridWidget::doubleClicked, [this](const QModelIndex &index) { - const SkeletonComponent *component = this->componentListModel()->modelIndexToComponent(index); + connect(this, &ComponentPreviewGridWidget::doubleClicked, [this](const QModelIndex& index) { + const SkeletonComponent* component = this->componentListModel()->modelIndexToComponent(index); if (nullptr == component) return; if (component->childrenIds.empty()) { std::vector partIds; this->m_document->collectComponentDescendantParts(component->id, partIds); - for (const auto &partId: partIds) + for (const auto& partId : partIds) emit this->selectPartOnCanvas(partId); } else { this->componentListModel()->setListingComponentId(component->id); @@ -25,17 +25,17 @@ ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document *document, QWidg }); } -ComponentListModel *ComponentPreviewGridWidget::componentListModel() +ComponentListModel* ComponentPreviewGridWidget::componentListModel() { return m_componentListModel.get(); } -std::vector ComponentPreviewGridWidget::getSelectedComponents() const +std::vector ComponentPreviewGridWidget::getSelectedComponents() const { - std::vector components; + std::vector components; QModelIndexList selected = selectionModel()->selectedIndexes(); - for (const auto &it: selected) { - const auto &component = m_componentListModel->modelIndexToComponent(it); + for (const auto& it : selected) { + const auto& component = m_componentListModel->modelIndexToComponent(it); if (nullptr == component) continue; components.push_back(component); @@ -47,8 +47,8 @@ std::vector ComponentPreviewGridWidget::getSelectedComponentIds() { std::vector componentIds; QModelIndexList selected = selectionModel()->selectedIndexes(); - for (const auto &it: selected) { - const auto &componentId = m_componentListModel->modelIndexToComponentId(it); + for (const auto& it : selected) { + const auto& componentId = m_componentListModel->modelIndexToComponentId(it); if (componentId.isNull()) continue; componentIds.push_back(componentId); @@ -60,7 +60,7 @@ std::vector ComponentPreviewGridWidget::getSelectedPartIds() const { auto selectedComponents = getSelectedComponents(); std::vector partIds; - for (const auto &component: selectedComponents) { + for (const auto& component : selectedComponents) { if (component->linkToPartId.isNull()) continue; partIds.push_back(component->linkToPartId); diff --git a/application/sources/component_preview_grid_widget.h b/application/sources/component_preview_grid_widget.h index 2393d928..97e355a3 100644 --- a/application/sources/component_preview_grid_widget.h +++ b/application/sources/component_preview_grid_widget.h @@ -1,30 +1,31 @@ #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ #define DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ -#include -#include -#include -#include "preview_grid_view.h" #include "component_list_model.h" +#include "preview_grid_view.h" +#include +#include +#include class Document; class SkeletonComponent; -class ComponentPreviewGridWidget: public PreviewGridView -{ +class ComponentPreviewGridWidget : public PreviewGridView { Q_OBJECT signals: void unselectAllOnCanvas(); - void selectPartOnCanvas(const dust3d::Uuid &partId); + void selectPartOnCanvas(const dust3d::Uuid& partId); + public: - ComponentPreviewGridWidget(Document *document, QWidget *parent=nullptr); - ComponentListModel *componentListModel(); - std::vector getSelectedComponents() const; + ComponentPreviewGridWidget(Document* document, QWidget* parent = nullptr); + ComponentListModel* componentListModel(); + std::vector getSelectedComponents() const; std::vector getSelectedComponentIds() const; std::vector getSelectedPartIds() const; + private: std::unique_ptr m_componentListModel; - Document *m_document = nullptr; + Document* m_document = nullptr; }; #endif diff --git a/application/sources/component_preview_images_decorator.cc b/application/sources/component_preview_images_decorator.cc index 790b37a4..6cfed23b 100644 --- a/application/sources/component_preview_images_decorator.cc +++ b/application/sources/component_preview_images_decorator.cc @@ -1,7 +1,7 @@ -#include -#include -#include "theme.h" #include "component_preview_images_decorator.h" +#include "theme.h" +#include +#include ComponentPreviewImagesDecorator::ComponentPreviewImagesDecorator(std::unique_ptr> previewInputs) { @@ -21,7 +21,7 @@ void ComponentPreviewImagesDecorator::decorate() m_resultImages = std::make_unique>>(); QPointF iconOffset(Theme::previewIconMargin, 0); - for (auto &it: *m_previewInputs) { + for (auto& it : *m_previewInputs) { if (it.isDirectory) { QPainter painter(it.image.get()); painter.setRenderHints(QPainter::Antialiasing); diff --git a/application/sources/component_preview_images_decorator.h b/application/sources/component_preview_images_decorator.h index 7de8179f..6f07cb7c 100644 --- a/application/sources/component_preview_images_decorator.h +++ b/application/sources/component_preview_images_decorator.h @@ -1,17 +1,15 @@ #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ #define DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ +#include +#include #include #include -#include -#include -class ComponentPreviewImagesDecorator: public QObject -{ +class ComponentPreviewImagesDecorator : public QObject { Q_OBJECT public: - struct PreviewInput - { + struct PreviewInput { dust3d::Uuid id; std::unique_ptr image; bool isDirectory = false; @@ -23,6 +21,7 @@ signals: void finished(); public slots: void process(); + private: std::unique_ptr> m_previewInputs; std::unique_ptr>> m_resultImages; diff --git a/application/sources/component_property_widget.cc b/application/sources/component_property_widget.cc index 704e0e5b..c01fe500 100644 --- a/application/sources/component_property_widget.cc +++ b/application/sources/component_property_widget.cc @@ -1,96 +1,96 @@ -#include -#include -#include -#include +#include "component_property_widget.h" +#include "document.h" +#include "float_number_widget.h" +#include "theme.h" #include #include -#include "component_property_widget.h" -#include "float_number_widget.h" -#include "document.h" -#include "theme.h" +#include +#include +#include +#include -ComponentPropertyWidget::ComponentPropertyWidget(Document *document, - const std::vector &componentIds, - QWidget *parent): - QWidget(parent), - m_document(document), - m_componentIds(componentIds) +ComponentPropertyWidget::ComponentPropertyWidget(Document* document, + const std::vector& componentIds, + QWidget* parent) + : QWidget(parent) + , m_document(document) + , m_componentIds(componentIds) { preparePartIds(); m_color = lastColor(); - QPushButton *colorPreviewArea = new QPushButton; + QPushButton* colorPreviewArea = new QPushButton; colorPreviewArea->setStyleSheet("QPushButton {background-color: " + m_color.name() + "; border-radius: 0;}"); colorPreviewArea->setFixedSize(Theme::toolIconSize * 1.8, Theme::toolIconSize); - QPushButton *colorPickerButton = new QPushButton(QChar(fa::eyedropper)); + QPushButton* colorPickerButton = new QPushButton(QChar(fa::eyedropper)); Theme::initIconButton(colorPickerButton); connect(colorPickerButton, &QPushButton::clicked, this, &ComponentPropertyWidget::showColorDialog); - QHBoxLayout *colorLayout = new QHBoxLayout; + QHBoxLayout* colorLayout = new QHBoxLayout; colorLayout->addWidget(colorPreviewArea); colorLayout->addWidget(colorPickerButton); colorLayout->addStretch(); colorLayout->setSizeConstraint(QLayout::SetFixedSize); - QGroupBox *deformGroupBox = nullptr; + QGroupBox* deformGroupBox = nullptr; if (nullptr != m_part) { - FloatNumberWidget *thicknessWidget = new FloatNumberWidget; + FloatNumberWidget* thicknessWidget = new FloatNumberWidget; thicknessWidget->setItemName(tr("Thickness")); thicknessWidget->setRange(0, 2); thicknessWidget->setValue(m_part->deformThickness); - + connect(thicknessWidget, &FloatNumberWidget::valueChanged, [=](float value) { emit setPartDeformThickness(m_partId, value); emit groupOperationAdded(); }); - - FloatNumberWidget *widthWidget = new FloatNumberWidget; + + FloatNumberWidget* widthWidget = new FloatNumberWidget; widthWidget->setItemName(tr("Width")); widthWidget->setRange(0, 2); widthWidget->setValue(m_part->deformWidth); - + connect(widthWidget, &FloatNumberWidget::valueChanged, [=](float value) { emit setPartDeformWidth(m_partId, value); emit groupOperationAdded(); }); - - QPushButton *thicknessEraser = new QPushButton(QChar(fa::eraser)); + + QPushButton* thicknessEraser = new QPushButton(QChar(fa::eraser)); Theme::initIconButton(thicknessEraser); - + connect(thicknessEraser, &QPushButton::clicked, [=]() { thicknessWidget->setValue(1.0); emit groupOperationAdded(); }); - - QPushButton *widthEraser = new QPushButton(QChar(fa::eraser)); + + QPushButton* widthEraser = new QPushButton(QChar(fa::eraser)); Theme::initIconButton(widthEraser); - + connect(widthEraser, &QPushButton::clicked, [=]() { widthWidget->setValue(1.0); emit groupOperationAdded(); }); - - QVBoxLayout *deformLayout = new QVBoxLayout; - - QHBoxLayout *thicknessLayout = new QHBoxLayout; - QHBoxLayout *widthLayout = new QHBoxLayout; + + QVBoxLayout* deformLayout = new QVBoxLayout; + + QHBoxLayout* thicknessLayout = new QHBoxLayout; + QHBoxLayout* widthLayout = new QHBoxLayout; thicknessLayout->addWidget(thicknessEraser); thicknessLayout->addWidget(thicknessWidget); widthLayout->addWidget(widthEraser); widthLayout->addWidget(widthWidget); - - QCheckBox *deformUnifyStateBox = new QCheckBox(); + + QCheckBox* deformUnifyStateBox = new QCheckBox(); Theme::initCheckbox(deformUnifyStateBox); deformUnifyStateBox->setText(tr("Unified")); deformUnifyStateBox->setChecked(m_part->deformUnified); - + connect(deformUnifyStateBox, &QCheckBox::stateChanged, this, [=]() { emit setPartDeformUnified(m_partId, deformUnifyStateBox->isChecked()); emit groupOperationAdded(); }); - - QHBoxLayout *deformUnifyLayout = new QHBoxLayout; + + QHBoxLayout* deformUnifyLayout = new QHBoxLayout; deformUnifyLayout->addStretch(); deformUnifyLayout->addWidget(deformUnifyStateBox); @@ -102,85 +102,85 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document, deformGroupBox->setLayout(deformLayout); } - QGroupBox *cutFaceGroupBox = nullptr; + QGroupBox* cutFaceGroupBox = nullptr; if (nullptr != m_part) { - FloatNumberWidget *rotationWidget = new FloatNumberWidget; + FloatNumberWidget* rotationWidget = new FloatNumberWidget; rotationWidget->setItemName(tr("Rotation")); rotationWidget->setRange(-1, 1); rotationWidget->setValue(m_part->cutRotation); - + connect(rotationWidget, &FloatNumberWidget::valueChanged, [=](float value) { emit setPartCutRotation(m_partId, value); emit groupOperationAdded(); }); - - QPushButton *rotationEraser = new QPushButton(QChar(fa::eraser)); + + QPushButton* rotationEraser = new QPushButton(QChar(fa::eraser)); Theme::initIconButton(rotationEraser); - + connect(rotationEraser, &QPushButton::clicked, [=]() { rotationWidget->setValue(0.0); emit groupOperationAdded(); }); - - QPushButton *rotationMinus5Button = new QPushButton(QChar(fa::rotateleft)); + + QPushButton* rotationMinus5Button = new QPushButton(QChar(fa::rotateleft)); Theme::initIconButton(rotationMinus5Button); - + connect(rotationMinus5Button, &QPushButton::clicked, [=]() { rotationWidget->setValue(-0.5); emit groupOperationAdded(); }); - - QPushButton *rotation5Button = new QPushButton(QChar(fa::rotateright)); + + QPushButton* rotation5Button = new QPushButton(QChar(fa::rotateright)); Theme::initIconButton(rotation5Button); - + connect(rotation5Button, &QPushButton::clicked, [=]() { rotationWidget->setValue(0.5); emit groupOperationAdded(); }); - QHBoxLayout *rotationLayout = new QHBoxLayout; + QHBoxLayout* rotationLayout = new QHBoxLayout; rotationLayout->addWidget(rotationEraser); rotationLayout->addWidget(rotationWidget); rotationLayout->addWidget(rotationMinus5Button); rotationLayout->addWidget(rotation5Button); - QCheckBox *subdivStateBox = new QCheckBox(); + QCheckBox* subdivStateBox = new QCheckBox(); Theme::initCheckbox(subdivStateBox); subdivStateBox->setText(tr("Subdivided")); subdivStateBox->setChecked(m_part->subdived); - + connect(subdivStateBox, &QCheckBox::stateChanged, this, [=]() { emit setPartSubdivState(m_partId, subdivStateBox->isChecked()); emit groupOperationAdded(); }); - QCheckBox *chamferStateBox = new QCheckBox(); + QCheckBox* chamferStateBox = new QCheckBox(); Theme::initCheckbox(chamferStateBox); chamferStateBox->setText(tr("Chamfered")); chamferStateBox->setChecked(m_part->chamfered); - + connect(chamferStateBox, &QCheckBox::stateChanged, this, [=]() { emit setPartChamferState(m_partId, chamferStateBox->isChecked()); emit groupOperationAdded(); }); - QCheckBox *roundEndStateBox = new QCheckBox(); + QCheckBox* roundEndStateBox = new QCheckBox(); Theme::initCheckbox(roundEndStateBox); roundEndStateBox->setText(tr("Round end")); roundEndStateBox->setChecked(m_part->rounded); - + connect(roundEndStateBox, &QCheckBox::stateChanged, this, [=]() { emit setPartRoundState(m_partId, roundEndStateBox->isChecked()); emit groupOperationAdded(); }); - QHBoxLayout *optionsLayout = new QHBoxLayout; + QHBoxLayout* optionsLayout = new QHBoxLayout; optionsLayout->addStretch(); optionsLayout->addWidget(roundEndStateBox); optionsLayout->addWidget(chamferStateBox); optionsLayout->addWidget(subdivStateBox); - QVBoxLayout *cutFaceLayout = new QVBoxLayout; + QVBoxLayout* cutFaceLayout = new QVBoxLayout; cutFaceLayout->addLayout(rotationLayout); cutFaceLayout->addLayout(optionsLayout); @@ -188,7 +188,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document, cutFaceGroupBox->setLayout(cutFaceLayout); } - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addLayout(colorLayout); if (nullptr != deformGroupBox) mainLayout->addWidget(deformGroupBox); @@ -216,10 +216,10 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document, void ComponentPropertyWidget::preparePartIds() { std::unordered_set addedPartIdSet; - for (const auto &componentId: m_componentIds) { + for (const auto& componentId : m_componentIds) { std::vector partIds; m_document->collectComponentDescendantParts(componentId, partIds); - for (const auto &it: partIds) { + for (const auto& it : partIds) { if (addedPartIdSet.insert(it).second) m_partIds.emplace_back(it); } @@ -234,18 +234,18 @@ void ComponentPropertyWidget::preparePartIds() QColor ComponentPropertyWidget::lastColor() { QColor color = Qt::white; - std::map colorMap; - for (const auto &partId: m_partIds) { - const SkeletonPart *part = m_document->findPart(partId); + std::map colorMap; + for (const auto& partId : m_partIds) { + const SkeletonPart* part = m_document->findPart(partId); if (nullptr == part) continue; colorMap[part->color.name()]++; } if (!colorMap.empty()) { - color = std::max_element(colorMap.begin(), colorMap.end(), - [](const std::map::value_type &a, const std::map::value_type &b) { - return a.second < b.second; - })->first; + color = std::max_element(colorMap.begin(), colorMap.end(), + [](const std::map::value_type& a, const std::map::value_type& b) { + return a.second < b.second; + })->first; } return color; } @@ -258,7 +258,7 @@ void ComponentPropertyWidget::showColorDialog() if (!color.isValid()) return; - for (const auto &partId: m_partIds) { + for (const auto& partId : m_partIds) { emit setPartColorState(partId, true, color); } emit groupOperationAdded(); diff --git a/application/sources/component_property_widget.h b/application/sources/component_property_widget.h index 078c4d8f..e226a0d9 100644 --- a/application/sources/component_property_widget.h +++ b/application/sources/component_property_widget.h @@ -1,39 +1,40 @@ #ifndef DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_ #define DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_ -#include #include +#include class Document; class SkeletonPart; -class ComponentPropertyWidget: public QWidget -{ +class ComponentPropertyWidget : public QWidget { Q_OBJECT signals: void beginColorPicking(); void endColorPicking(); - void setPartColorState(const dust3d::Uuid &partId, bool hasColor, const QColor &color); - void setPartDeformThickness(const dust3d::Uuid &partId, float thickness); - void setPartDeformWidth(const dust3d::Uuid &partId, float width); - void setPartDeformUnified(const dust3d::Uuid &partId, bool unified); - void setPartSubdivState(const dust3d::Uuid &partId, bool subdived); - void setPartChamferState(const dust3d::Uuid &partId, bool chamfered); - void setPartRoundState(const dust3d::Uuid &partId, bool rounded); - void setPartCutRotation(const dust3d::Uuid &partId, float cutRotation); + void setPartColorState(const dust3d::Uuid& partId, bool hasColor, const QColor& color); + void setPartDeformThickness(const dust3d::Uuid& partId, float thickness); + void setPartDeformWidth(const dust3d::Uuid& partId, float width); + void setPartDeformUnified(const dust3d::Uuid& partId, bool unified); + void setPartSubdivState(const dust3d::Uuid& partId, bool subdived); + void setPartChamferState(const dust3d::Uuid& partId, bool chamfered); + void setPartRoundState(const dust3d::Uuid& partId, bool rounded); + void setPartCutRotation(const dust3d::Uuid& partId, float cutRotation); void groupOperationAdded(); + public: - ComponentPropertyWidget(Document *document, - const std::vector &componentIds, - QWidget *parent=nullptr); + ComponentPropertyWidget(Document* document, + const std::vector& componentIds, + QWidget* parent = nullptr); public slots: void showColorDialog(); + private: - Document *m_document = nullptr; + Document* m_document = nullptr; std::vector m_componentIds; std::vector m_partIds; dust3d::Uuid m_partId; - const SkeletonPart *m_part = nullptr; + const SkeletonPart* m_part = nullptr; QColor m_color; QColor lastColor(); void preparePartIds(); diff --git a/application/sources/cut_face_preview.cc b/application/sources/cut_face_preview.cc index 190d27ed..7c71e54a 100644 --- a/application/sources/cut_face_preview.cc +++ b/application/sources/cut_face_preview.cc @@ -1,15 +1,15 @@ -#include -#include #include "cut_face_preview.h" #include "theme.h" +#include +#include -static std::map g_standardCutFaceMap; +static std::map g_standardCutFaceMap; -QImage *buildCutFaceTemplatePreviewImage(const std::vector &cutTemplate) +QImage* buildCutFaceTemplatePreviewImage(const std::vector& cutTemplate) { - QImage *image = new QImage(Theme::partPreviewImageSize, Theme::partPreviewImageSize, QImage::Format_ARGB32); + QImage* image = new QImage(Theme::partPreviewImageSize, Theme::partPreviewImageSize, QImage::Format_ARGB32); image->fill(Qt::transparent); - + if (cutTemplate.empty()) return image; @@ -17,41 +17,41 @@ QImage *buildCutFaceTemplatePreviewImage(const std::vector &cut painter.begin(image); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::HighQualityAntialiasing); - + QPen pen(Theme::red, 2); painter.setPen(pen); - + QBrush brush; brush.setColor(Theme::white); brush.setStyle(Qt::SolidPattern); - + painter.setBrush(brush); - + const float scale = 0.7f; QPolygon polygon; for (size_t i = 0; i <= cutTemplate.size(); ++i) { - const auto &it = cutTemplate[i % cutTemplate.size()]; - polygon.append(QPoint((it.x() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize, + const auto& it = cutTemplate[i % cutTemplate.size()]; + polygon.append(QPoint((it.x() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize, (it.y() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize)); } - + QPainterPath path; path.addPolygon(polygon); painter.fillPath(path, brush); painter.drawPath(path); - + painter.end(); return image; } -const QImage *cutFacePreviewImage(dust3d::CutFace cutFace) +const QImage* cutFacePreviewImage(dust3d::CutFace cutFace) { auto findItem = g_standardCutFaceMap.find((int)cutFace); if (findItem != g_standardCutFaceMap.end()) return findItem->second; std::vector cutTemplate = dust3d::CutFaceToPoints(cutFace); - QImage *image = buildCutFaceTemplatePreviewImage(cutTemplate); - g_standardCutFaceMap.insert({(int)cutFace, image}); + QImage* image = buildCutFaceTemplatePreviewImage(cutTemplate); + g_standardCutFaceMap.insert({ (int)cutFace, image }); return image; } diff --git a/application/sources/cut_face_preview.h b/application/sources/cut_face_preview.h index 7e29bf1a..0b035527 100644 --- a/application/sources/cut_face_preview.h +++ b/application/sources/cut_face_preview.h @@ -4,7 +4,7 @@ #include #include -QImage *buildCutFaceTemplatePreviewImage(const std::vector &cutTemplate); -const QImage *cutFacePreviewImage(dust3d::CutFace cutFace); +QImage* buildCutFaceTemplatePreviewImage(const std::vector& cutTemplate); +const QImage* cutFacePreviewImage(dust3d::CutFace cutFace); #endif diff --git a/application/sources/dds_file.cc b/application/sources/dds_file.cc index df45b3f4..6195f0ba 100644 --- a/application/sources/dds_file.cc +++ b/application/sources/dds_file.cc @@ -1,10 +1,10 @@ -#include -#include -#include -#include -#include -#include #include "dds_file.h" +#include +#include +#include +#include +#include +#include #ifndef _WIN32 typedef quint32 DWORD; @@ -37,20 +37,20 @@ typedef enum { } DDS_CAPS2_FLAGS; typedef struct { - DWORD dwSize; - DWORD dwFlags; - DWORD dwHeight; - DWORD dwWidth; - DWORD dwPitchOrLinearSize; - DWORD dwDepth; - DWORD dwMipMapCount; - DWORD dwReserved1[11]; + DWORD dwSize; + DWORD dwFlags; + DWORD dwHeight; + DWORD dwWidth; + DWORD dwPitchOrLinearSize; + DWORD dwDepth; + DWORD dwMipMapCount; + DWORD dwReserved1[11]; DDS_PIXELFORMAT ddspf; - DWORD dwCaps; - DWORD dwCaps2; - DWORD dwCaps3; - DWORD dwCaps4; - DWORD dwReserved2; + DWORD dwCaps; + DWORD dwCaps2; + DWORD dwCaps3; + DWORD dwCaps4; + DWORD dwReserved2; } DDS_HEADER; typedef enum { @@ -176,9 +176,9 @@ typedef enum { DXGI_FORMAT_FORCE_UINT } DXGI_FORMAT; -static const char *DxgiFormatToString(DXGI_FORMAT dxgiFormat) +static const char* DxgiFormatToString(DXGI_FORMAT dxgiFormat) { - static const char *names[] = { + static const char* names[] = { "DXGI_FORMAT_UNKNOWN", "DXGI_FORMAT_R32G32B32A32_TYPELESS", "DXGI_FORMAT_R32G32B32A32_FLOAT", @@ -314,9 +314,9 @@ typedef enum { D3D10_RESOURCE_DIMENSION_TEXTURE3D } D3D10_RESOURCE_DIMENSION; -static const char *ResourceDimensionToString(D3D10_RESOURCE_DIMENSION resourceDimension) +static const char* ResourceDimensionToString(D3D10_RESOURCE_DIMENSION resourceDimension) { - static const char *names[] = { + static const char* names[] = { "D3D10_RESOURCE_DIMENSION_UNKNOWN", "D3D10_RESOURCE_DIMENSION_BUFFER", "D3D10_RESOURCE_DIMENSION_TEXTURE1D", @@ -337,9 +337,9 @@ typedef enum { D3D10_RESOURCE_MISC_GDI_COMPATIBLE } D3D10_RESOURCE_MISC_FLAG; -static const char *MiscFlagToString(UINT miscFlag) +static const char* MiscFlagToString(UINT miscFlag) { - static const char *names[] = { + static const char* names[] = { "D3D10_RESOURCE_MISC_GENERATE_MIPS", "D3D10_RESOURCE_MISC_SHARED", "D3D10_RESOURCE_MISC_TEXTURECUBE", @@ -353,76 +353,76 @@ static const char *MiscFlagToString(UINT miscFlag) } typedef struct { - DXGI_FORMAT dxgiFormat; + DXGI_FORMAT dxgiFormat; D3D10_RESOURCE_DIMENSION resourceDimension; - UINT miscFlag; - UINT arraySize; - UINT miscFlags2; + UINT miscFlag; + UINT arraySize; + UINT miscFlags2; } DDS_HEADER_DXT10; typedef struct { - DWORD dwMagic; - DDS_HEADER header; - DDS_HEADER_DXT10 header10; + DWORD dwMagic; + DDS_HEADER header; + DDS_HEADER_DXT10 header10; } DDS_FILE_HEADER; -DdsFileReader::DdsFileReader(const QString &filename) : - m_filename(filename) -{ +DdsFileReader::DdsFileReader(const QString& filename) + : m_filename(filename) +{ } std::unique_ptr>> DdsFileReader::createOpenGLTextures() { QFile file(m_filename); - + if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Open" << m_filename << "failed"; return nullptr; } - + DDS_FILE_HEADER fileHeader; - if (sizeof(fileHeader) != file.read((char *)&fileHeader, sizeof(fileHeader))) { + if (sizeof(fileHeader) != file.read((char*)&fileHeader, sizeof(fileHeader))) { qDebug() << "Read DDS file hader failed"; return nullptr; } - + if (0x20534444 != qFromLittleEndian(&fileHeader.dwMagic)) { qDebug() << "Not a DDS file"; return nullptr; } - + if (0x30315844 != qFromLittleEndian(&fileHeader.header.ddspf.dwFourCC)) { qDebug() << "Unsupported DDS file, expected DX10 file"; return nullptr; } - + auto caps2 = qFromLittleEndian(&fileHeader.header.dwCaps2); if (!(DDSCAPS2_CUBEMAP & caps2)) { qDebug() << "Unsupported DDS file, expected CUBEMAP file"; return nullptr; } - + //qDebug() << "Start anyalize DDS file..."; - + int width = qFromLittleEndian(&fileHeader.header.dwWidth); int height = qFromLittleEndian(&fileHeader.header.dwHeight); - + //qDebug() << "DDS size:" << width << "X" << height; - + //auto pitchOrLinearSize = qFromLittleEndian(&fileHeader.header.dwPitchOrLinearSize); //qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize; - + auto arraySize = qFromLittleEndian(&fileHeader.header10.arraySize); //qDebug() << "DDS array size:" << arraySize; - + auto mipMapCount = qFromLittleEndian(&fileHeader.header.dwMipMapCount); //qDebug() << "DDS mip map count:" << mipMapCount; - + DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian(&fileHeader.header10.dxgiFormat); //qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat); //qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian(&fileHeader.header10.resourceDimension)); //qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian(&fileHeader.header10.miscFlag)); - + quint32 faces = 0; if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) { //qDebug() << "DDS found +x"; @@ -448,20 +448,20 @@ std::unique_ptr>> DdsFileReader::cre //qDebug() << "DDS found -z"; ++faces; } - + if (6 != faces) { qDebug() << "Unsupported DDS file, expected six faces"; return nullptr; } - + if (1 != arraySize) { qDebug() << "Unsupported DDS file, expected one layer"; return nullptr; } - + if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) { qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT"; - return nullptr; + return nullptr; } int components = 8; int oneFaceSize = 0; @@ -479,7 +479,7 @@ std::unique_ptr>> DdsFileReader::cre } int depth = 1; - + auto textures = std::make_unique>>(); textures->resize(6); @@ -488,7 +488,7 @@ std::unique_ptr>> DdsFileReader::cre for (quint32 face = 0; face < faces; ++face) { for (quint32 level = 0; level < mipMapCount; ++level) { if (0 == layer && 0 == level) { - QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); + QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D); texture->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest); texture->setMagnificationFilter(QOpenGLTexture::Nearest); texture->setFormat(QOpenGLTexture::RGBA16F); @@ -504,58 +504,58 @@ std::unique_ptr>> DdsFileReader::cre return std::move(textures); } -QOpenGLTexture *DdsFileReader::createOpenGLTexture() +QOpenGLTexture* DdsFileReader::createOpenGLTexture() { QFile file(m_filename); - + if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Open" << m_filename << "failed"; return nullptr; } - + DDS_FILE_HEADER fileHeader; - if (sizeof(fileHeader) != file.read((char *)&fileHeader, sizeof(fileHeader))) { + if (sizeof(fileHeader) != file.read((char*)&fileHeader, sizeof(fileHeader))) { qDebug() << "Read DDS file hader failed"; return nullptr; } - + if (0x20534444 != qFromLittleEndian(&fileHeader.dwMagic)) { qDebug() << "Not a DDS file"; return nullptr; } - + if (0x30315844 != qFromLittleEndian(&fileHeader.header.ddspf.dwFourCC)) { qDebug() << "Unsupported DDS file, expected DX10 file"; return nullptr; } - + auto caps2 = qFromLittleEndian(&fileHeader.header.dwCaps2); if (!(DDSCAPS2_CUBEMAP & caps2)) { qDebug() << "Unsupported DDS file, expected CUBEMAP file"; return nullptr; } - + //qDebug() << "Start anyalize DDS file..."; - + int width = qFromLittleEndian(&fileHeader.header.dwWidth); int height = qFromLittleEndian(&fileHeader.header.dwHeight); - + //qDebug() << "DDS size:" << width << "X" << height; - + //auto pitchOrLinearSize = qFromLittleEndian(&fileHeader.header.dwPitchOrLinearSize); //qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize; - + auto arraySize = qFromLittleEndian(&fileHeader.header10.arraySize); //qDebug() << "DDS array size:" << arraySize; - + auto mipMapCount = qFromLittleEndian(&fileHeader.header.dwMipMapCount); //qDebug() << "DDS mip map count:" << mipMapCount; - + DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian(&fileHeader.header10.dxgiFormat); //qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat); //qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian(&fileHeader.header10.resourceDimension)); //qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian(&fileHeader.header10.miscFlag)); - + quint32 faces = 0; if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) { //qDebug() << "DDS found +x"; @@ -581,20 +581,20 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture() //qDebug() << "DDS found -z"; ++faces; } - + if (6 != faces) { qDebug() << "Unsupported DDS file, expected six faces"; return nullptr; } - + if (1 != arraySize) { qDebug() << "Unsupported DDS file, expected one layer"; return nullptr; } - + if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) { qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT"; - return nullptr; + return nullptr; } int components = 8; int oneFaceSize = 0; @@ -610,9 +610,9 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture() qDebug() << "DDS file invalid, expected total size:" << totalSize << "read size:" << data.size(); return nullptr; } - + int depth = 1; - + QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap); texture->setFormat(QOpenGLTexture::RGBA16F); texture->setSize(width, height, depth); @@ -620,37 +620,37 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture() texture->setMipBaseLevel(0); texture->setMipMaxLevel(mipMapCount - 1); texture->setMipLevels(mipMapCount); - + if (!texture->create()) { qDebug() << "QOpenGLTexture::create failed"; delete texture; return nullptr; } - + texture->allocateStorage(); if (!texture->isStorageAllocated()) { qDebug() << "QOpenGLTexture::isStorageAllocated false"; delete texture; return nullptr; } - + uint64_t dataOffset = 0; for (quint32 layer = 0; layer < arraySize; ++layer) { for (quint32 face = 0; face < faces; ++face) { for (quint32 level = 0; level < mipMapCount; ++level) { QOpenGLPixelTransferOptions uploadOptions; uploadOptions.setAlignment(1); - texture->setData(level, - layer, - static_cast(QOpenGLTexture::CubeMapPositiveX + face), - QOpenGLTexture::RGBA, - QOpenGLTexture::Float16, - data.constData() + dataOffset, + texture->setData(level, + layer, + static_cast(QOpenGLTexture::CubeMapPositiveX + face), + QOpenGLTexture::RGBA, + QOpenGLTexture::Float16, + data.constData() + dataOffset, &uploadOptions); dataOffset += calculateOneFaceSizeAtLevel(level); } } } - + return texture; } \ No newline at end of file diff --git a/application/sources/dds_file.h b/application/sources/dds_file.h index bf826594..98ac7be8 100644 --- a/application/sources/dds_file.h +++ b/application/sources/dds_file.h @@ -1,16 +1,16 @@ #ifndef DUST3D_APPLICATION_DDS_FILE_H_ #define DUST3D_APPLICATION_DDS_FILE_H_ -#include -#include #include +#include +#include -class DdsFileReader -{ +class DdsFileReader { public: - DdsFileReader(const QString &filename); - QOpenGLTexture *createOpenGLTexture(); + DdsFileReader(const QString& filename); + QOpenGLTexture* createOpenGLTexture(); std::unique_ptr>> createOpenGLTextures(); + private: QString m_filename; }; diff --git a/application/sources/debug.cc b/application/sources/debug.cc index 31e9c510..22b714fe 100644 --- a/application/sources/debug.cc +++ b/application/sources/debug.cc @@ -1,13 +1,13 @@ #include "debug.h" -QDebug operator<<(QDebug debug, const dust3d::Uuid &uuid) +QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid) { QDebugStateSaver stateSaver(debug); debug.nospace() << uuid.toString().c_str(); return debug; } -QDebug operator<<(QDebug debug, const std::string &string) +QDebug operator<<(QDebug debug, const std::string& string) { QDebugStateSaver stateSaver(debug); debug.nospace() << string.c_str(); diff --git a/application/sources/debug.h b/application/sources/debug.h index b5b86535..da4e85f1 100644 --- a/application/sources/debug.h +++ b/application/sources/debug.h @@ -4,7 +4,7 @@ #include #include -QDebug operator<<(QDebug debug, const dust3d::Uuid &uuid); -QDebug operator<<(QDebug debug, const std::string &string); +QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid); +QDebug operator<<(QDebug debug, const std::string& string); #endif diff --git a/application/sources/document.cc b/application/sources/document.cc index c7c9c144..021e23be 100644 --- a/application/sources/document.cc +++ b/application/sources/document.cc @@ -1,34 +1,34 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "document.h" #include "image_forever.h" +#include "material_previews_generator.h" #include "mesh_generator.h" #include "mesh_result_post_processor.h" #include "texture_generator.h" -#include "material_previews_generator.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include unsigned long Document::m_maxSnapshot = 1000; -Document::Document() : - SkeletonDocument() +Document::Document() + : SkeletonDocument() { } Document::~Document() { - delete (dust3d::MeshGenerator::GeneratedCacheContext *)m_generatedCacheContext; + delete (dust3d::MeshGenerator::GeneratedCacheContext*)m_generatedCacheContext; delete m_resultMesh; delete m_postProcessedObject; delete textureImage; @@ -55,7 +55,7 @@ bool Document::originSettled() const return !qFuzzyIsNull(getOriginX()) && !qFuzzyIsNull(getOriginY()) && !qFuzzyIsNull(getOriginZ()); } -const Material *Document::findMaterial(dust3d::Uuid materialId) const +const Material* Document::findMaterial(dust3d::Uuid materialId) const { auto it = materialMap.find(materialId); if (it == materialMap.end()) @@ -104,8 +104,7 @@ void Document::setNodeCutFaceLinkedId(dust3d::Uuid nodeId, dust3d::Uuid linkedId qDebug() << "Node not found:" << nodeId; return; } - if (node->second.cutFace == dust3d::CutFace::UserDefined && - node->second.cutFaceLinkedId == linkedId) + if (node->second.cutFace == dust3d::CutFace::UserDefined && node->second.cutFaceLinkedId == linkedId) return; node->second.setCutFaceLinkedId(linkedId); auto part = partMap.find(node->second.partId); @@ -132,7 +131,7 @@ void Document::clearNodeCutFaceSettings(dust3d::Uuid nodeId) emit skeletonChanged(); } -void Document::updateTurnaround(const QImage &image) +void Document::updateTurnaround(const QImage& image) { turnaround = image; turnaroundPngByteArray.clear(); @@ -149,47 +148,47 @@ void Document::clearTurnaround() emit turnaroundChanged(); } -void Document::updateTextureImage(QImage *image) +void Document::updateTextureImage(QImage* image) { delete textureImageByteArray; textureImageByteArray = nullptr; - + delete textureImage; textureImage = image; } -void Document::updateTextureNormalImage(QImage *image) +void Document::updateTextureNormalImage(QImage* image) { delete textureNormalImageByteArray; textureNormalImageByteArray = nullptr; - + delete textureNormalImage; textureNormalImage = image; } -void Document::updateTextureMetalnessImage(QImage *image) +void Document::updateTextureMetalnessImage(QImage* image) { delete textureMetalnessImageByteArray; textureMetalnessImageByteArray = nullptr; - + delete textureMetalnessImage; textureMetalnessImage = image; } -void Document::updateTextureRoughnessImage(QImage *image) +void Document::updateTextureRoughnessImage(QImage* image) { delete textureRoughnessImageByteArray; textureRoughnessImageByteArray = nullptr; - + delete textureRoughnessImage; textureRoughnessImage = image; } -void Document::updateTextureAmbientOcclusionImage(QImage *image) +void Document::updateTextureAmbientOcclusionImage(QImage* image) { delete textureAmbientOcclusionImageByteArray; textureAmbientOcclusionImageByteArray = nullptr; - + delete textureAmbientOcclusionImage; textureAmbientOcclusionImage = image; } @@ -198,28 +197,27 @@ void Document::setEditMode(SkeletonDocumentEditMode mode) { if (editMode == mode) return; - + editMode = mode; emit editModeChanged(); } -void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set &limitNodeIds, +void Document::toSnapshot(dust3d::Snapshot* snapshot, const std::set& limitNodeIds, DocumentToSnapshotFor forWhat, - const std::set &limitMaterialIds) const + const std::set& limitMaterialIds) const { - if (DocumentToSnapshotFor::Document == forWhat || - DocumentToSnapshotFor::Nodes == forWhat) { + if (DocumentToSnapshotFor::Document == forWhat || DocumentToSnapshotFor::Nodes == forWhat) { std::set limitPartIds; std::set limitComponentIds; - for (const auto &nodeId: limitNodeIds) { - const SkeletonNode *node = findNode(nodeId); + for (const auto& nodeId : limitNodeIds) { + const SkeletonNode* node = findNode(nodeId); if (!node) continue; - const SkeletonPart *part = findPart(node->partId); + const SkeletonPart* part = findPart(node->partId); if (!part) continue; limitPartIds.insert(node->partId); - const SkeletonComponent *component = findComponent(part->componentId); + const SkeletonComponent* component = findComponent(part->componentId); while (component) { limitComponentIds.insert(component->id); if (component->id.isNull()) @@ -227,7 +225,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setparentId); } } - for (const auto &partIt : partMap) { + for (const auto& partIt : partMap) { if (!limitPartIds.empty() && limitPartIds.find(partIt.first) == limitPartIds.end()) continue; std::map part; @@ -281,7 +279,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setparts[part["id"]] = part; } - for (const auto &nodeIt: nodeMap) { + for (const auto& nodeIt : nodeMap) { if (!limitNodeIds.empty() && limitNodeIds.find(nodeIt.first) == limitNodeIds.end()) continue; std::map node; @@ -305,12 +303,10 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setnodes[node["id"]] = node; } - for (const auto &edgeIt: edgeMap) { + for (const auto& edgeIt : edgeMap) { if (edgeIt.second.nodeIds.size() != 2) continue; - if (!limitNodeIds.empty() && - (limitNodeIds.find(edgeIt.second.nodeIds[0]) == limitNodeIds.end() || - limitNodeIds.find(edgeIt.second.nodeIds[1]) == limitNodeIds.end())) + if (!limitNodeIds.empty() && (limitNodeIds.find(edgeIt.second.nodeIds[0]) == limitNodeIds.end() || limitNodeIds.find(edgeIt.second.nodeIds[1]) == limitNodeIds.end())) continue; std::map edge; edge["id"] = edgeIt.second.id.toString(); @@ -321,7 +317,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setedges[edge["id"]] = edge; } - for (const auto &componentIt: componentMap) { + for (const auto& componentIt : componentMap) { if (!limitComponentIds.empty() && limitComponentIds.find(componentIt.first) == limitComponentIds.end()) continue; std::map component; @@ -332,7 +328,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set childIdList; - for (const auto &childId: componentIt.second.childrenIds) { + for (const auto& childId : componentIt.second.childrenIds) { childIdList.push_back(childId.toString()); } std::string children = dust3d::String::join(childIdList, ","); @@ -349,7 +345,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set childIdList; - for (const auto &childId: rootComponent.childrenIds) { + for (const auto& childId : rootComponent.childrenIds) { childIdList.push_back(childId.toString()); } std::string children = dust3d::String::join(childIdList, ","); @@ -357,9 +353,8 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setrootComponent["children"] = children; } } - if (DocumentToSnapshotFor::Document == forWhat || - DocumentToSnapshotFor::Materials == forWhat) { - for (const auto &materialId: materialIdList) { + if (DocumentToSnapshotFor::Document == forWhat || DocumentToSnapshotFor::Materials == forWhat) { + for (const auto& materialId : materialIdList) { if (!limitMaterialIds.empty() && limitMaterialIds.find(materialId) == limitMaterialIds.end()) continue; auto findMaterialResult = materialMap.find(materialId); @@ -367,16 +362,16 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set material; material["id"] = materialIt.second.id.toString(); material["type"] = "MetalRoughness"; if (!materialIt.second.name.isEmpty()) material["name"] = materialIt.second.name.toUtf8().constData(); std::vector, std::vector>>> layers; - for (const auto &layer: materialIt.second.layers) { + for (const auto& layer : materialIt.second.layers) { std::vector> maps; - for (const auto &mapItem: layer.maps) { + for (const auto& mapItem : layer.maps) { std::map textureMap; textureMap["for"] = TextureTypeToString(mapItem.forWhat); textureMap["linkDataType"] = "imageId"; @@ -386,7 +381,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set layerAttributes; if (!qFuzzyCompare((float)layer.tileScale, (float)1.0)) layerAttributes["tileScale"] = std::to_string(layer.tileScale); - layers.push_back({layerAttributes, maps}); + layers.push_back({ layerAttributes, maps }); } snapshot->materials.push_back(std::make_pair(material, layers)); } @@ -400,34 +395,31 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::setsecond)); setOriginY(dust3d::String::toFloat(originYit->second)); setOriginZ(dust3d::String::toFloat(originZit->second)); isOriginChanged = true; } } - + std::set newAddedNodeIds; std::set newAddedEdgeIds; std::set newAddedPartIds; std::set newAddedComponentIds; - + std::set inversePartIds; - + std::map oldNewIdMap; - for (const auto &materialIt: snapshot.materials) { - const auto &materialAttributes = materialIt.first; + for (const auto& materialIt : snapshot.materials) { + const auto& materialAttributes = materialIt.first; auto materialType = dust3d::String::valueOrEmpty(materialAttributes, "type"); if ("MetalRoughness" != materialType) { qDebug() << "Unsupported material type:" << materialType; @@ -437,15 +429,15 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo dust3d::Uuid newMaterialId = SnapshotSource::Import == source ? oldMaterialId : dust3d::Uuid::createUuid(); oldNewIdMap[oldMaterialId] = newMaterialId; if (materialMap.end() == materialMap.find(newMaterialId)) { - auto &newMaterial = materialMap[newMaterialId]; + auto& newMaterial = materialMap[newMaterialId]; newMaterial.id = newMaterialId; newMaterial.name = dust3d::String::valueOrEmpty(materialAttributes, "name").c_str(); - for (const auto &layerIt: materialIt.second) { + for (const auto& layerIt : materialIt.second) { MaterialLayer layer; auto findTileScale = layerIt.first.find("tileScale"); if (findTileScale != layerIt.first.end()) layer.tileScale = dust3d::String::toFloat(findTileScale->second); - for (const auto &mapItem: layerIt.second) { + for (const auto& mapItem : layerIt.second) { auto textureTypeString = dust3d::String::valueOrEmpty(mapItem, "for"); auto textureType = dust3d::TextureTypeFromString(textureTypeString.c_str()); if (dust3d::TextureType::None == textureType) { @@ -470,13 +462,13 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo } } std::map cutFaceLinkedIdModifyMap; - for (const auto &partKv: snapshot.parts) { + for (const auto& partKv : snapshot.parts) { const auto newUuid = dust3d::Uuid::createUuid(); - SkeletonPart &part = partMap[newUuid]; + SkeletonPart& part = partMap[newUuid]; part.id = newUuid; oldNewIdMap[dust3d::Uuid(partKv.first)] = part.id; part.name = dust3d::String::valueOrEmpty(partKv.second, "name").c_str(); - const auto &visibleIt = partKv.second.find("visible"); + const auto& visibleIt = partKv.second.find("visible"); if (visibleIt != partKv.second.end()) { part.visible = dust3d::String::isTrue(visibleIt->second); } else { @@ -490,56 +482,56 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo part.rounded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "rounded")); part.chamfered = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "chamfered")); part.target = dust3d::PartTargetFromString(dust3d::String::valueOrEmpty(partKv.second, "target").c_str()); - const auto &cutRotationIt = partKv.second.find("cutRotation"); + const auto& cutRotationIt = partKv.second.find("cutRotation"); if (cutRotationIt != partKv.second.end()) part.setCutRotation(dust3d::String::toFloat(cutRotationIt->second)); - const auto &cutFaceIt = partKv.second.find("cutFace"); + const auto& cutFaceIt = partKv.second.find("cutFace"); if (cutFaceIt != partKv.second.end()) { dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second); if (cutFaceLinkedId.isNull()) { part.setCutFace(dust3d::CutFaceFromString(cutFaceIt->second.c_str())); } else { part.setCutFaceLinkedId(cutFaceLinkedId); - cutFaceLinkedIdModifyMap.insert({part.id, cutFaceLinkedId}); + cutFaceLinkedIdModifyMap.insert({ part.id, cutFaceLinkedId }); } } if (dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "inverse"))) inversePartIds.insert(part.id); - const auto &colorIt = partKv.second.find("color"); + const auto& colorIt = partKv.second.find("color"); if (colorIt != partKv.second.end()) { part.color = QColor(colorIt->second.c_str()); part.hasColor = true; } - const auto &colorSolubilityIt = partKv.second.find("colorSolubility"); + const auto& colorSolubilityIt = partKv.second.find("colorSolubility"); if (colorSolubilityIt != partKv.second.end()) part.colorSolubility = dust3d::String::toFloat(colorSolubilityIt->second); - const auto &metalnessIt = partKv.second.find("metallic"); + const auto& metalnessIt = partKv.second.find("metallic"); if (metalnessIt != partKv.second.end()) part.metalness = dust3d::String::toFloat(metalnessIt->second); - const auto &roughnessIt = partKv.second.find("roughness"); + const auto& roughnessIt = partKv.second.find("roughness"); if (roughnessIt != partKv.second.end()) part.roughness = dust3d::String::toFloat(roughnessIt->second); - const auto &deformThicknessIt = partKv.second.find("deformThickness"); + const auto& deformThicknessIt = partKv.second.find("deformThickness"); if (deformThicknessIt != partKv.second.end()) part.setDeformThickness(dust3d::String::toFloat(deformThicknessIt->second)); - const auto &deformWidthIt = partKv.second.find("deformWidth"); + const auto& deformWidthIt = partKv.second.find("deformWidth"); if (deformWidthIt != partKv.second.end()) part.setDeformWidth(dust3d::String::toFloat(deformWidthIt->second)); - const auto &deformUnifiedIt = partKv.second.find("deformUnified"); + const auto& deformUnifiedIt = partKv.second.find("deformUnified"); if (deformUnifiedIt != partKv.second.end()) part.deformUnified = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "deformUnified")); - const auto &hollowThicknessIt = partKv.second.find("hollowThickness"); + const auto& hollowThicknessIt = partKv.second.find("hollowThickness"); if (hollowThicknessIt != partKv.second.end()) part.hollowThickness = dust3d::String::toFloat(hollowThicknessIt->second); - const auto &materialIdIt = partKv.second.find("materialId"); + const auto& materialIdIt = partKv.second.find("materialId"); if (materialIdIt != partKv.second.end()) part.materialId = oldNewIdMap[dust3d::Uuid(materialIdIt->second)]; part.countershaded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "countershaded")); part.smooth = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "smooth")); newAddedPartIds.insert(part.id); } - for (const auto &it: cutFaceLinkedIdModifyMap) { - SkeletonPart &part = partMap[it.first]; + for (const auto& it : cutFaceLinkedIdModifyMap) { + SkeletonPart& part = partMap[it.first]; auto findNewLinkedId = oldNewIdMap.find(it.second); if (findNewLinkedId == oldNewIdMap.end()) { if (partMap.find(it.second) == partMap.end()) { @@ -549,12 +541,8 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo part.setCutFaceLinkedId(findNewLinkedId->second); } } - for (const auto &nodeKv: snapshot.nodes) { - if (nodeKv.second.find("radius") == nodeKv.second.end() || - nodeKv.second.find("x") == nodeKv.second.end() || - nodeKv.second.find("y") == nodeKv.second.end() || - nodeKv.second.find("z") == nodeKv.second.end() || - nodeKv.second.find("partId") == nodeKv.second.end()) + for (const auto& nodeKv : snapshot.nodes) { + if (nodeKv.second.find("radius") == nodeKv.second.end() || nodeKv.second.find("x") == nodeKv.second.end() || nodeKv.second.find("y") == nodeKv.second.end() || nodeKv.second.find("z") == nodeKv.second.end() || nodeKv.second.find("partId") == nodeKv.second.end()) continue; dust3d::Uuid oldNodeId = dust3d::Uuid(nodeKv.first); SkeletonNode node(nodeMap.find(oldNodeId) == nodeMap.end() ? oldNodeId : dust3d::Uuid::createUuid()); @@ -565,10 +553,10 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo node.setY(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "y"))); node.setZ(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "z"))); node.partId = oldNewIdMap[dust3d::Uuid(dust3d::String::valueOrEmpty(nodeKv.second, "partId"))]; - const auto &cutRotationIt = nodeKv.second.find("cutRotation"); + const auto& cutRotationIt = nodeKv.second.find("cutRotation"); if (cutRotationIt != nodeKv.second.end()) node.setCutRotation(dust3d::String::toFloat(cutRotationIt->second)); - const auto &cutFaceIt = nodeKv.second.find("cutFace"); + const auto& cutFaceIt = nodeKv.second.find("cutFace"); if (cutFaceIt != nodeKv.second.end()) { dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second); if (cutFaceLinkedId.isNull()) { @@ -588,10 +576,8 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo nodeMap[node.id] = node; newAddedNodeIds.insert(node.id); } - for (const auto &edgeKv: snapshot.edges) { - if (edgeKv.second.find("from") == edgeKv.second.end() || - edgeKv.second.find("to") == edgeKv.second.end() || - edgeKv.second.find("partId") == edgeKv.second.end()) + for (const auto& edgeKv : snapshot.edges) { + if (edgeKv.second.find("from") == edgeKv.second.end() || edgeKv.second.find("to") == edgeKv.second.end() || edgeKv.second.find("partId") == edgeKv.second.end()) continue; dust3d::Uuid oldEdgeId = dust3d::Uuid(edgeKv.first); SkeletonEdge edge(edgeMap.find(oldEdgeId) == edgeMap.end() ? oldEdgeId : dust3d::Uuid::createUuid()); @@ -613,12 +599,12 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo edgeMap[edge.id] = edge; newAddedEdgeIds.insert(edge.id); } - for (const auto &nodeIt: nodeMap) { + for (const auto& nodeIt : nodeMap) { if (newAddedNodeIds.find(nodeIt.first) == newAddedNodeIds.end()) continue; partMap[nodeIt.second.partId].nodeIds.push_back(nodeIt.first); } - for (const auto &componentKv: snapshot.components) { + for (const auto& componentKv : snapshot.components) { QString linkData = dust3d::String::valueOrEmpty(componentKv.second, "linkData").c_str(); QString linkDataType = dust3d::String::valueOrEmpty(componentKv.second, "linkDataType").c_str(); SkeletonComponent component(dust3d::Uuid(), linkData, linkDataType); @@ -642,9 +628,9 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo componentMap.emplace(component.id, std::move(component)); newAddedComponentIds.insert(component.id); } - const auto &rootComponentChildren = snapshot.rootComponent.find("children"); + const auto& rootComponentChildren = snapshot.rootComponent.find("children"); if (rootComponentChildren != snapshot.rootComponent.end()) { - for (const auto &childId: dust3d::String::split(rootComponentChildren->second, ',')) { + for (const auto& childId : dust3d::String::split(rootComponentChildren->second, ',')) { if (childId.empty()) continue; dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(childId)]; @@ -654,11 +640,11 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo rootComponent.addChild(componentId); } } - for (const auto &componentKv: snapshot.components) { + for (const auto& componentKv : snapshot.components) { dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(componentKv.first)]; if (componentMap.find(componentId) == componentMap.end()) continue; - for (const auto &childId: dust3d::String::split(dust3d::String::valueOrEmpty(componentKv.second, "children"), ',')) { + for (const auto& childId : dust3d::String::split(dust3d::String::valueOrEmpty(componentKv.second, "children"), ',')) { if (childId.empty()) continue; dust3d::Uuid childComponentId = oldNewIdMap[dust3d::Uuid(childId)]; @@ -669,34 +655,34 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo componentMap[childComponentId].parentId = componentId; } } - - for (const auto &nodeIt: newAddedNodeIds) { + + for (const auto& nodeIt : newAddedNodeIds) { emit nodeAdded(nodeIt); } - for (const auto &edgeIt: newAddedEdgeIds) { + for (const auto& edgeIt : newAddedEdgeIds) { emit edgeAdded(edgeIt); } - for (const auto &partIt : newAddedPartIds) { + for (const auto& partIt : newAddedPartIds) { emit partAdded(partIt); } - + emit componentChildrenChanged(dust3d::Uuid()); if (isOriginChanged) emit originChanged(); emit skeletonChanged(); - - for (const auto &partIt : newAddedPartIds) { + + for (const auto& partIt : newAddedPartIds) { emit partVisibleStateChanged(partIt); } - + emit uncheckAll(); - for (const auto &nodeIt: newAddedNodeIds) { + for (const auto& nodeIt : newAddedNodeIds) { emit checkNode(nodeIt); } - for (const auto &edgeIt: newAddedEdgeIds) { + for (const auto& edgeIt : newAddedEdgeIds) { emit checkEdge(edgeIt); } - + if (!snapshot.materials.empty()) emit materialListChanged(); } @@ -722,22 +708,22 @@ void Document::reset() emit skeletonChanged(); } -void Document::fromSnapshot(const dust3d::Snapshot &snapshot) +void Document::fromSnapshot(const dust3d::Snapshot& snapshot) { reset(); addFromSnapshot(snapshot, SnapshotSource::Unknown); emit uncheckAll(); } -ModelMesh *Document::takeResultMesh() +ModelMesh* Document::takeResultMesh() { if (nullptr == m_resultMesh) return nullptr; - ModelMesh *resultMesh = new ModelMesh(*m_resultMesh); + ModelMesh* resultMesh = new ModelMesh(*m_resultMesh); return resultMesh; } -MonochromeMesh *Document::takeWireframeMesh() +MonochromeMesh* Document::takeWireframeMesh() { if (nullptr == m_wireframeMesh) return nullptr; @@ -749,51 +735,51 @@ bool Document::isMeshGenerationSucceed() return m_isMeshGenerationSucceed; } -ModelMesh *Document::takeResultTextureMesh() +ModelMesh* Document::takeResultTextureMesh() { if (nullptr == m_resultTextureMesh) return nullptr; - ModelMesh *resultTextureMesh = new ModelMesh(*m_resultTextureMesh); + ModelMesh* resultTextureMesh = new ModelMesh(*m_resultTextureMesh); return resultTextureMesh; } void Document::meshReady() { - ModelMesh *resultMesh = m_meshGenerator->takeResultMesh(); + ModelMesh* resultMesh = m_meshGenerator->takeResultMesh(); m_wireframeMesh.reset(m_meshGenerator->takeWireframeMesh()); - dust3d::Object *object = m_meshGenerator->takeObject(); + dust3d::Object* object = m_meshGenerator->takeObject(); bool isSuccessful = m_meshGenerator->isSuccessful(); - + std::unique_ptr>> componentPreviewMeshes; componentPreviewMeshes.reset(m_meshGenerator->takeComponentPreviewMeshes()); bool componentPreviewsChanged = componentPreviewMeshes && !componentPreviewMeshes->empty(); if (componentPreviewsChanged) { - for (auto &it: *componentPreviewMeshes) { + for (auto& it : *componentPreviewMeshes) { setComponentPreviewMesh(it.first, std::move(it.second)); } emit resultComponentPreviewMeshesChanged(); } - + delete m_resultMesh; m_resultMesh = resultMesh; - + m_isMeshGenerationSucceed = isSuccessful; - + delete m_currentObject; m_currentObject = object; - + if (nullptr == m_resultMesh) { qDebug() << "Result mesh is null"; } - + delete m_meshGenerator; m_meshGenerator = nullptr; - + qDebug() << "Mesh generation done"; - + m_isPostProcessResultObsolete = true; emit resultMeshChanged(); - + if (m_isResultMeshObsolete) { generateMesh(); } @@ -843,18 +829,18 @@ void Document::generateMesh() m_isResultMeshObsolete = true; return; } - + emit meshGenerating(); - + qDebug() << "Mesh generating.."; - + settleOrigin(); - + m_isResultMeshObsolete = false; - - QThread *thread = new QThread; - - dust3d::Snapshot *snapshot = new dust3d::Snapshot; + + QThread* thread = new QThread; + + dust3d::Snapshot* snapshot = new dust3d::Snapshot; toSnapshot(snapshot); resetDirtyFlags(); m_meshGenerator = new MeshGenerator(snapshot); @@ -862,7 +848,7 @@ void Document::generateMesh() m_meshGenerator->setDefaultPartColor(dust3d::Color::createWhite()); if (nullptr == m_generatedCacheContext) m_generatedCacheContext = new MeshGenerator::GeneratedCacheContext; - m_meshGenerator->setGeneratedCacheContext((dust3d::MeshGenerator::GeneratedCacheContext *)m_generatedCacheContext); + m_meshGenerator->setGeneratedCacheContext((dust3d::MeshGenerator::GeneratedCacheContext*)m_generatedCacheContext); if (!m_smoothNormal) { m_meshGenerator->setSmoothShadingThresholdAngleDegrees(0); } @@ -880,16 +866,16 @@ void Document::generateTexture() m_isTextureObsolete = true; return; } - + qDebug() << "Texture guide generating.."; emit textureGenerating(); - + m_isTextureObsolete = false; - - dust3d::Snapshot *snapshot = new dust3d::Snapshot; + + dust3d::Snapshot* snapshot = new dust3d::Snapshot; toSnapshot(snapshot); - - QThread *thread = new QThread; + + QThread* thread = new QThread; m_textureGenerator = new TextureGenerator(*m_postProcessedObject, snapshot); m_textureGenerator->moveToThread(thread); connect(thread, &QThread::started, m_textureGenerator, &TextureGenerator::process); @@ -906,21 +892,21 @@ void Document::textureReady() updateTextureMetalnessImage(m_textureGenerator->takeResultTextureMetalnessImage()); updateTextureRoughnessImage(m_textureGenerator->takeResultTextureRoughnessImage()); updateTextureAmbientOcclusionImage(m_textureGenerator->takeResultTextureAmbientOcclusionImage()); - + delete m_resultTextureMesh; m_resultTextureMesh = m_textureGenerator->takeResultMesh(); - + m_postProcessedObject->alphaEnabled = m_textureGenerator->hasTransparencySettings(); m_textureImageUpdateVersion++; - + delete m_textureGenerator; m_textureGenerator = nullptr; - + qDebug() << "Texture guide generation done"; - + emit resultTextureChanged(); - + if (m_isTextureObsolete) { generateTexture(); } else { @@ -945,7 +931,7 @@ void Document::postProcess() qDebug() << "Post processing.."; emit postProcessing(); - QThread *thread = new QThread; + QThread* thread = new QThread; m_postProcessor = new MeshResultPostProcessor(*m_currentObject); m_postProcessor->moveToThread(thread); connect(thread, &QThread::started, m_postProcessor, &MeshResultPostProcessor::process); @@ -972,7 +958,7 @@ void Document::postProcessedMeshResultReady() } } -const dust3d::Object &Document::currentPostProcessedObject() const +const dust3d::Object& Document::currentPostProcessedObject() const { return *m_postProcessedObject; } @@ -1007,7 +993,7 @@ void Document::setPartSubdivState(dust3d::Uuid partId, bool subdived) emit skeletonChanged(); } -void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRectF *mainProfile, QRectF *sideProfile) +void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile) { float left = 0; bool leftFirstTime = true; @@ -1021,7 +1007,7 @@ void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRec bool zLeftFirstTime = true; float zRight = 0; bool zRightFirstTime = true; - for (const auto &nodeIt: snapshot.nodes) { + for (const auto& nodeIt : snapshot.nodes) { float radius = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "radius")); float x = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "x")); float y = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "y")); @@ -1330,8 +1316,7 @@ void Document::setPartCutFaceLinkedId(dust3d::Uuid partId, dust3d::Uuid linkedId qDebug() << "Part not found:" << partId; return; } - if (part->second.cutFace == dust3d::CutFace::UserDefined && - part->second.cutFaceLinkedId == linkedId) + if (part->second.cutFace == dust3d::CutFace::UserDefined && part->second.cutFaceLinkedId == linkedId) return; part->second.setCutFaceLinkedId(linkedId); part->second.dirty = true; @@ -1370,7 +1355,7 @@ void Document::undo() return; m_redoItems.push_back(m_undoItems.back()); m_undoItems.pop_back(); - const auto &item = m_undoItems.back(); + const auto& item = m_undoItems.back(); fromSnapshot(item.snapshot); qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size(); } @@ -1380,7 +1365,7 @@ void Document::redo() if (m_redoItems.empty()) return; m_undoItems.push_back(m_redoItems.back()); - const auto &item = m_redoItems.back(); + const auto& item = m_redoItems.back(); fromSnapshot(item.snapshot); m_redoItems.pop_back(); qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size(); @@ -1394,12 +1379,12 @@ void Document::clearHistories() void Document::paste() { - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); + const QClipboard* clipboard = QApplication::clipboard(); + const QMimeData* mimeData = clipboard->mimeData(); if (mimeData->hasText()) { dust3d::Snapshot snapshot; std::string text = mimeData->text().toUtf8().constData(); - loadSnapshotFromXmlString(&snapshot, (char *)text.c_str()); + loadSnapshotFromXmlString(&snapshot, (char*)text.c_str()); addFromSnapshot(snapshot, SnapshotSource::Paste); saveSnapshot(); } @@ -1407,8 +1392,8 @@ void Document::paste() bool Document::hasPastableNodesInClipboard() const { - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); + const QClipboard* clipboard = QApplication::clipboard(); + const QMimeData* mimeData = clipboard->mimeData(); if (mimeData->hasText()) { if (-1 != mimeData->text().indexOf("mimeData(); + const QClipboard* clipboard = QApplication::clipboard(); + const QMimeData* mimeData = clipboard->mimeData(); if (mimeData->hasText()) { if (-1 != mimeData->text().indexOf("second.name == name) return; - + findMaterialResult->second.name = name; emit materialNameChanged(materialId); emit materialListChanged(); @@ -1552,10 +1533,10 @@ void Document::generateMaterialPreviews() return; } - QThread *thread = new QThread; + QThread* thread = new QThread; m_materialPreviewsGenerator = new MaterialPreviewsGenerator(); bool hasDirtyMaterial = false; - for (auto &materialIt: materialMap) { + for (auto& materialIt : materialMap) { if (!materialIt.second.dirty) continue; m_materialPreviewsGenerator->addMaterial(materialIt.first, materialIt.second.layers); @@ -1568,9 +1549,9 @@ void Document::generateMaterialPreviews() delete thread; return; } - + qDebug() << "Material previews generating.."; - + m_materialPreviewsGenerator->moveToThread(thread); connect(thread, &QThread::started, m_materialPreviewsGenerator, &MaterialPreviewsGenerator::process); connect(m_materialPreviewsGenerator, &MaterialPreviewsGenerator::finished, this, &Document::materialPreviewsReady); @@ -1581,10 +1562,10 @@ void Document::generateMaterialPreviews() void Document::materialPreviewsReady() { - for (const auto &materialId: m_materialPreviewsGenerator->generatedPreviewMaterialIds()) { + for (const auto& materialId : m_materialPreviewsGenerator->generatedPreviewMaterialIds()) { auto material = materialMap.find(materialId); if (material != materialMap.end()) { - ModelMesh *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId); + ModelMesh* resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId); material->second.updatePreviewMesh(resultPartPreviewMesh); emit materialPreviewChanged(materialId); } @@ -1592,9 +1573,9 @@ void Document::materialPreviewsReady() delete m_materialPreviewsGenerator; m_materialPreviewsGenerator = nullptr; - + qDebug() << "Material previews generation done"; - + generateMaterialPreviews(); } @@ -1619,18 +1600,18 @@ void Document::copyNodes(std::set nodeIdSet) const toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes); std::string snapshotXml; dust3d::saveSnapshotToXmlString(snapshot, snapshotXml); - QClipboard *clipboard = QApplication::clipboard(); + QClipboard* clipboard = QApplication::clipboard(); clipboard->setText(snapshotXml.c_str()); } -void Document::collectCutFaceList(std::vector &cutFaces) const +void Document::collectCutFaceList(std::vector& cutFaces) const { cutFaces.clear(); - + std::vector cutFacePartIdList; - + std::set cutFacePartIds; - for (const auto &it: partMap) { + for (const auto& it : partMap) { if (dust3d::PartTarget::CutFace == it.second.target) { if (cutFacePartIds.find(it.first) != cutFacePartIds.end()) continue; @@ -1644,16 +1625,16 @@ void Document::collectCutFaceList(std::vector &cutFaces) const cutFacePartIdList.push_back(it.second.cutFaceLinkedId); } } - + // Sort cut face by center.x of front view std::map centerOffsetMap; - for (const auto &partId: cutFacePartIdList) { - const SkeletonPart *part = findPart(partId); + for (const auto& partId : cutFacePartIdList) { + const SkeletonPart* part = findPart(partId); if (nullptr == part) continue; float offsetSum = 0; - for (const auto &nodeId: part->nodeIds) { - const SkeletonNode *node = findNode(nodeId); + for (const auto& nodeId : part->nodeIds) { + const SkeletonNode* node = findNode(nodeId); if (nullptr == node) continue; offsetSum += node->getX(); @@ -1663,16 +1644,16 @@ void Document::collectCutFaceList(std::vector &cutFaces) const centerOffsetMap[partId] = offsetSum / part->nodeIds.size(); } std::sort(cutFacePartIdList.begin(), cutFacePartIdList.end(), - [&](const dust3d::Uuid &firstPartId, const dust3d::Uuid &secondPartId) { - return centerOffsetMap[firstPartId] < centerOffsetMap[secondPartId]; - }); - + [&](const dust3d::Uuid& firstPartId, const dust3d::Uuid& secondPartId) { + return centerOffsetMap[firstPartId] < centerOffsetMap[secondPartId]; + }); + size_t cutFaceTypeCount = (size_t)dust3d::CutFace::UserDefined; for (size_t i = 0; i < (size_t)cutFaceTypeCount; ++i) { dust3d::CutFace cutFace = (dust3d::CutFace)i; cutFaces.push_back(QString(dust3d::CutFaceToString(cutFace).c_str())); } - - for (const auto &it: cutFacePartIdList) + + for (const auto& it : cutFacePartIdList) cutFaces.push_back(QString(it.toString().c_str())); } diff --git a/application/sources/document.h b/application/sources/document.h index cc37e7b4..03977fdb 100644 --- a/application/sources/document.h +++ b/application/sources/document.h @@ -1,38 +1,36 @@ #ifndef DUST3D_APPLICATION_DOCUMENT_H_ #define DUST3D_APPLICATION_DOCUMENT_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "material_layer.h" #include "model_mesh.h" #include "monochrome_mesh.h" -#include "theme.h" #include "skeleton_document.h" -#include "material_layer.h" +#include "theme.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include class MaterialPreviewsGenerator; class TextureGenerator; class MeshGenerator; class MeshResultPostProcessor; -class HistoryItem -{ +class HistoryItem { public: dust3d::Snapshot snapshot; }; -class Material -{ +class Material { public: Material() { @@ -45,31 +43,30 @@ public: QString name; bool dirty = true; std::vector layers; - void updatePreviewMesh(ModelMesh *previewMesh) + void updatePreviewMesh(ModelMesh* previewMesh) { delete m_previewMesh; m_previewMesh = previewMesh; } - ModelMesh *takePreviewMesh() const + ModelMesh* takePreviewMesh() const { if (nullptr == m_previewMesh) return nullptr; return new ModelMesh(*m_previewMesh); } + private: Q_DISABLE_COPY(Material); - ModelMesh *m_previewMesh = nullptr; + ModelMesh* m_previewMesh = nullptr; }; -enum class DocumentToSnapshotFor -{ +enum class DocumentToSnapshotFor { Document = 0, Nodes, Materials }; -class Document : public SkeletonDocument -{ +class Document : public SkeletonDocument { Q_OBJECT signals: void nodeCutRotationChanged(dust3d::Uuid nodeId); @@ -121,26 +118,28 @@ signals: void postProcessing(); void textureGenerating(); void textureChanged(); + public: // need initialize - QImage *textureImage = nullptr; - QByteArray *textureImageByteArray = nullptr; - QImage *textureNormalImage = nullptr; - QByteArray *textureNormalImageByteArray = nullptr; - QImage *textureMetalnessImage = nullptr; - QByteArray *textureMetalnessImageByteArray = nullptr; - QImage *textureRoughnessImage = nullptr; - QByteArray *textureRoughnessImageByteArray = nullptr; - QImage *textureAmbientOcclusionImage = nullptr; - QByteArray *textureAmbientOcclusionImageByteArray = nullptr; + QImage* textureImage = nullptr; + QByteArray* textureImageByteArray = nullptr; + QImage* textureNormalImage = nullptr; + QByteArray* textureNormalImageByteArray = nullptr; + QImage* textureMetalnessImage = nullptr; + QByteArray* textureMetalnessImageByteArray = nullptr; + QImage* textureRoughnessImage = nullptr; + QByteArray* textureRoughnessImageByteArray = nullptr; + QImage* textureAmbientOcclusionImage = nullptr; + QByteArray* textureAmbientOcclusionImageByteArray = nullptr; bool weldEnabled = true; float brushMetalness = ModelMesh::m_defaultMetalness; float brushRoughness = ModelMesh::m_defaultRoughness; + public: Document(); ~Document(); std::map materialMap; std::vector materialIdList; - + bool undoable() const override; bool redoable() const override; bool hasPastableNodesInClipboard() const override; @@ -148,39 +147,38 @@ public: bool isNodeEditable(dust3d::Uuid nodeId) const override; bool isEdgeEditable(dust3d::Uuid edgeId) const override; void copyNodes(std::set nodeIdSet) const override; - void toSnapshot(dust3d::Snapshot *snapshot, const std::set &limitNodeIds=std::set(), - DocumentToSnapshotFor forWhat=DocumentToSnapshotFor::Document, - const std::set &limitMaterialIds=std::set()) const; - void fromSnapshot(const dust3d::Snapshot &snapshot); - enum class SnapshotSource - { + void toSnapshot(dust3d::Snapshot* snapshot, const std::set& limitNodeIds = std::set(), + DocumentToSnapshotFor forWhat = DocumentToSnapshotFor::Document, + const std::set& limitMaterialIds = std::set()) const; + void fromSnapshot(const dust3d::Snapshot& snapshot); + enum class SnapshotSource { Unknown, Paste, Import }; - void addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste); - const Material *findMaterial(dust3d::Uuid materialId) const; - ModelMesh *takeResultMesh(); - MonochromeMesh *takeWireframeMesh(); - ModelMesh *takePaintedMesh(); + void addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSource source = SnapshotSource::Paste); + const Material* findMaterial(dust3d::Uuid materialId) const; + ModelMesh* takeResultMesh(); + MonochromeMesh* takeWireframeMesh(); + ModelMesh* takePaintedMesh(); bool isMeshGenerationSucceed(); - ModelMesh *takeResultTextureMesh(); - ModelMesh *takeResultRigWeightMesh(); - void updateTurnaround(const QImage &image); + ModelMesh* takeResultTextureMesh(); + ModelMesh* takeResultRigWeightMesh(); + void updateTurnaround(const QImage& image); void clearTurnaround(); - void updateTextureImage(QImage *image); - void updateTextureNormalImage(QImage *image); - void updateTextureMetalnessImage(QImage *image); - void updateTextureRoughnessImage(QImage *image); - void updateTextureAmbientOcclusionImage(QImage *image); + void updateTextureImage(QImage* image); + void updateTextureNormalImage(QImage* image); + void updateTextureMetalnessImage(QImage* image); + void updateTextureRoughnessImage(QImage* image); + void updateTextureAmbientOcclusionImage(QImage* image); bool hasPastableMaterialsInClipboard() const; - const dust3d::Object ¤tPostProcessedObject() const; + const dust3d::Object& currentPostProcessedObject() const; bool isExportReady() const; bool isPostProcessResultObsolete() const; bool isMeshGenerating() const; bool isPostProcessing() const; bool isTextureGenerating() const; - void collectCutFaceList(std::vector &cutFaces) const; + void collectCutFaceList(std::vector& cutFaces) const; public slots: void undo() override; void redo() override; @@ -233,30 +231,32 @@ public slots: void removeMaterial(dust3d::Uuid materialId); void setMaterialLayers(dust3d::Uuid materialId, std::vector layers); void renameMaterial(dust3d::Uuid materialId, QString name); + private: - void resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRectF *mainProfile, QRectF *sideProfile); + void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile); void settleOrigin(); void checkExportReadyState(); bool m_isResultMeshObsolete = false; - MeshGenerator *m_meshGenerator = nullptr; - ModelMesh *m_resultMesh = nullptr; + MeshGenerator* m_meshGenerator = nullptr; + ModelMesh* m_resultMesh = nullptr; std::unique_ptr m_wireframeMesh; bool m_isMeshGenerationSucceed = true; int m_batchChangeRefCount = 0; - dust3d::Object *m_currentObject = nullptr; + dust3d::Object* m_currentObject = nullptr; bool m_isTextureObsolete = false; - TextureGenerator *m_textureGenerator = nullptr; + TextureGenerator* m_textureGenerator = nullptr; bool m_isPostProcessResultObsolete = false; - MeshResultPostProcessor *m_postProcessor = nullptr; - dust3d::Object *m_postProcessedObject = new dust3d::Object; - ModelMesh *m_resultTextureMesh = nullptr; + MeshResultPostProcessor* m_postProcessor = nullptr; + dust3d::Object* m_postProcessedObject = new dust3d::Object; + ModelMesh* m_resultTextureMesh = nullptr; unsigned long long m_textureImageUpdateVersion = 0; bool m_smoothNormal = false; - MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr; + MaterialPreviewsGenerator* m_materialPreviewsGenerator = nullptr; quint64 m_meshGenerationId = 0; quint64 m_nextMeshGenerationId = 0; - void *m_generatedCacheContext = nullptr; + void* m_generatedCacheContext = nullptr; + private: static unsigned long m_maxSnapshot; std::deque m_undoItems; diff --git a/application/sources/document_saver.cc b/application/sources/document_saver.cc index 49809a2f..07e41054 100644 --- a/application/sources/document_saver.cc +++ b/application/sources/document_saver.cc @@ -1,17 +1,17 @@ -#include +#include "document_saver.h" +#include "image_forever.h" #include #include #include #include -#include "document_saver.h" -#include "image_forever.h" +#include -DocumentSaver::DocumentSaver(const QString *filename, - dust3d::Snapshot *snapshot, - QByteArray *turnaroundPngByteArray) : - m_filename(filename), - m_snapshot(snapshot), - m_turnaroundPngByteArray(turnaroundPngByteArray) +DocumentSaver::DocumentSaver(const QString* filename, + dust3d::Snapshot* snapshot, + QByteArray* turnaroundPngByteArray) + : m_filename(filename) + , m_snapshot(snapshot) + , m_turnaroundPngByteArray(turnaroundPngByteArray) { } @@ -29,12 +29,12 @@ void DocumentSaver::process() emit finished(); } -void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot *snapshot, - std::set &imageIds) +void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot* snapshot, + std::set& imageIds) { - for (const auto &material: snapshot->materials) { - for (auto &layer: material.second) { - for (auto &mapItem: layer.second) { + for (const auto& material : snapshot->materials) { + for (auto& layer : material.second) { + for (auto& mapItem : layer.second) { auto findImageIdString = mapItem.find("linkData"); if (findImageIdString == mapItem.end()) continue; @@ -45,12 +45,12 @@ void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot *snapshot, } } -bool DocumentSaver::save(const QString *filename, - dust3d::Snapshot *snapshot, - const QByteArray *turnaroundPngByteArray) +bool DocumentSaver::save(const QString* filename, + dust3d::Snapshot* snapshot, + const QByteArray* turnaroundPngByteArray) { dust3d::Ds3FileWriter ds3Writer; - + { std::string modelXml; saveSnapshotToXmlString(*snapshot, modelXml); @@ -58,20 +58,20 @@ bool DocumentSaver::save(const QString *filename, ds3Writer.add("model.xml", "model", modelXml.c_str(), modelXml.size()); } } - + if (nullptr != turnaroundPngByteArray && turnaroundPngByteArray->size() > 0) ds3Writer.add("canvas.png", "asset", turnaroundPngByteArray->data(), turnaroundPngByteArray->size()); - + std::set imageIds; collectUsedResourceIds(snapshot, imageIds); - for (const auto &imageId: imageIds) { - const QByteArray *pngByteArray = ImageForever::getPngByteArray(imageId); + for (const auto& imageId : imageIds) { + const QByteArray* pngByteArray = ImageForever::getPngByteArray(imageId); if (nullptr == pngByteArray) continue; if (pngByteArray->size() > 0) ds3Writer.add("images/" + imageId.toString() + ".png", "asset", pngByteArray->data(), pngByteArray->size()); } - + return ds3Writer.save(filename->toUtf8().constData()); } \ No newline at end of file diff --git a/application/sources/document_saver.h b/application/sources/document_saver.h index cce6fa9a..881cf86d 100644 --- a/application/sources/document_saver.h +++ b/application/sources/document_saver.h @@ -1,35 +1,35 @@ #ifndef DUST3D_APPLICATION_DOCUMENT_SAVER_H_ #define DUST3D_APPLICATION_DOCUMENT_SAVER_H_ -#include -#include #include +#include +#include +#include +#include #include #include -#include -#include -class DocumentSaver : public QObject -{ +class DocumentSaver : public QObject { Q_OBJECT public: - DocumentSaver(const QString *filename, - dust3d::Snapshot *snapshot, - QByteArray *turnaroundPngByteArray); + DocumentSaver(const QString* filename, + dust3d::Snapshot* snapshot, + QByteArray* turnaroundPngByteArray); ~DocumentSaver(); - static bool save(const QString *filename, - dust3d::Snapshot *snapshot, - const QByteArray *turnaroundPngByteArray); - static void collectUsedResourceIds(const dust3d::Snapshot *snapshot, - std::set &imageIds); + static bool save(const QString* filename, + dust3d::Snapshot* snapshot, + const QByteArray* turnaroundPngByteArray); + static void collectUsedResourceIds(const dust3d::Snapshot* snapshot, + std::set& imageIds); signals: void finished(); public slots: void process(); + private: - const QString *m_filename = nullptr; - dust3d::Snapshot *m_snapshot = nullptr; - QByteArray *m_turnaroundPngByteArray = nullptr; + const QString* m_filename = nullptr; + dust3d::Snapshot* m_snapshot = nullptr; + QByteArray* m_turnaroundPngByteArray = nullptr; }; #endif diff --git a/application/sources/document_window.cc b/application/sources/document_window.cc index 0a051a8f..bf81f2f2 100644 --- a/application/sources/document_window.cc +++ b/application/sources/document_window.cc @@ -1,80 +1,81 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "document_window.h" +#include "about_widget.h" +#include "cut_face_preview.h" +#include "document.h" +#include "document_saver.h" +#include "fbx_file.h" +#include "float_number_widget.h" +#include "flow_layout.h" +#include "glb_file.h" +#include "horizontal_line_widget.h" +#include "image_forever.h" +#include "log_browser.h" +#include "material_manage_widget.h" +#include "part_manage_widget.h" +#include "preferences.h" +#include "skeleton_graphics_widget.h" +#include "spinnable_toolbar_icon.h" +#include "texture_generator.h" +#include "theme.h" +#include "updates_check_widget.h" +#include "version.h" #include -#include #include -#include -#include -#include #include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include "document_window.h" -#include "skeleton_graphics_widget.h" -#include "theme.h" -#include "log_browser.h" -#include "about_widget.h" -#include "version.h" -#include "glb_file.h" -#include "part_manage_widget.h" -#include "material_manage_widget.h" -#include "image_forever.h" -#include "spinnable_toolbar_icon.h" -#include "fbx_file.h" -#include "float_number_widget.h" -#include "updates_check_widget.h" -#include "document_saver.h" -#include "document.h" -#include "preferences.h" -#include "flow_layout.h" -#include "cut_face_preview.h" -#include "horizontal_line_widget.h" -#include "texture_generator.h" +#include -LogBrowser *g_logBrowser = nullptr; -std::map g_documentWindows; -QTextBrowser *g_acknowlegementsWidget = nullptr; -AboutWidget *g_aboutWidget = nullptr; -QTextBrowser *g_contributorsWidget = nullptr; -QTextBrowser *g_supportersWidget = nullptr; -UpdatesCheckWidget *g_updatesCheckWidget = nullptr; +LogBrowser* g_logBrowser = nullptr; +std::map g_documentWindows; +QTextBrowser* g_acknowlegementsWidget = nullptr; +AboutWidget* g_aboutWidget = nullptr; +QTextBrowser* g_contributorsWidget = nullptr; +QTextBrowser* g_supportersWidget = nullptr; +UpdatesCheckWidget* g_updatesCheckWidget = nullptr; -void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) +void outputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg) { if (g_logBrowser) g_logBrowser->outputMessage(type, msg, context.file, context.line); } -void ensureFileExtension(QString* filename, const QString extension) { +void ensureFileExtension(QString* filename, const QString extension) +{ if (!filename->endsWith(extension)) { filename->append(extension); } } -const std::map &DocumentWindow::documentWindows() +const std::map& DocumentWindow::documentWindows() { return g_documentWindows; } -Document *DocumentWindow::document() +Document* DocumentWindow::document() { return m_document; } @@ -160,21 +161,21 @@ DocumentWindow::DocumentWindow() qInstallMessageHandler(&outputMessage); } - g_documentWindows.insert({this, dust3d::Uuid::createUuid()}); + g_documentWindows.insert({ this, dust3d::Uuid::createUuid() }); m_document = new Document; - - SkeletonGraphicsWidget *canvasGraphicsWidget = new SkeletonGraphicsWidget(m_document); + + SkeletonGraphicsWidget* canvasGraphicsWidget = new SkeletonGraphicsWidget(m_document); m_canvasGraphicsWidget = canvasGraphicsWidget; - QVBoxLayout *toolButtonLayout = new QVBoxLayout; + QVBoxLayout* toolButtonLayout = new QVBoxLayout; toolButtonLayout->setSpacing(0); toolButtonLayout->setContentsMargins(5, 10, 4, 0); - ToolbarButton *addButton = new ToolbarButton(":/resources/toolbar_add.svg"); + ToolbarButton* addButton = new ToolbarButton(":/resources/toolbar_add.svg"); addButton->setToolTip(tr("Add node to canvas")); - ToolbarButton *selectButton = new ToolbarButton(":/resources/toolbar_pointer.svg"); + ToolbarButton* selectButton = new ToolbarButton(":/resources/toolbar_pointer.svg"); selectButton->setToolTip(tr("Select node on canvas")); m_xLockButton = new ToolbarButton(); @@ -188,14 +189,14 @@ DocumentWindow::DocumentWindow() m_zLockButton = new ToolbarButton(); m_zLockButton->setToolTip(tr("Z axis locker")); updateZlockButtonState(); - + m_radiusLockButton = new ToolbarButton(); m_radiusLockButton->setToolTip(tr("Node radius locker")); updateRadiusLockButtonState(); - + m_inprogressIndicator = new SpinnableToolbarIcon(); updateInprogressIndicator(); - + connect(m_document, &Document::meshGenerating, this, &DocumentWindow::updateInprogressIndicator); connect(m_document, &Document::resultMeshChanged, this, [=]() { m_isLastMeshGenerationSucceed = m_document->isMeshGenerationSucceed(); @@ -218,18 +219,17 @@ DocumentWindow::DocumentWindow() toolButtonLayout->addWidget(m_radiusLockButton); toolButtonLayout->addSpacing(20); toolButtonLayout->addWidget(m_inprogressIndicator); - - QLabel *verticalLogoLabel = new QLabel; + QLabel* verticalLogoLabel = new QLabel; QImage verticalLogoImage; verticalLogoImage.load(":/resources/dust3d-vertical.png"); verticalLogoLabel->setPixmap(QPixmap::fromImage(verticalLogoImage)); - QHBoxLayout *logoLayout = new QHBoxLayout; + QHBoxLayout* logoLayout = new QHBoxLayout; logoLayout->addWidget(verticalLogoLabel); logoLayout->setContentsMargins(0, 0, 0, 0); - QVBoxLayout *mainLeftLayout = new QVBoxLayout; + QVBoxLayout* mainLeftLayout = new QVBoxLayout; mainLeftLayout->setSpacing(0); mainLeftLayout->setContentsMargins(0, 0, 0, 0); mainLeftLayout->addLayout(toolButtonLayout); @@ -237,15 +237,15 @@ DocumentWindow::DocumentWindow() mainLeftLayout->addLayout(logoLayout); mainLeftLayout->addSpacing(10); - GraphicsContainerWidget *containerWidget = new GraphicsContainerWidget; + GraphicsContainerWidget* containerWidget = new GraphicsContainerWidget; containerWidget->setGraphicsWidget(canvasGraphicsWidget); - QGridLayout *containerLayout = new QGridLayout; + QGridLayout* containerLayout = new QGridLayout; containerLayout->setSpacing(0); containerLayout->setContentsMargins(1, 0, 0, 0); containerLayout->addWidget(canvasGraphicsWidget); containerWidget->setLayout(containerLayout); containerWidget->setMinimumSize(400, 400); - + m_graphicsContainerWidget = containerWidget; m_modelRenderWidget = new ModelWidget(containerWidget); @@ -256,60 +256,60 @@ DocumentWindow::DocumentWindow() m_modelRenderWidget->disableCullFace(); m_modelRenderWidget->setEyePosition(QVector3D(0.0, 0.0, -4.0)); m_modelRenderWidget->setMoveToPosition(QVector3D(-0.5, -0.5, 0.0)); - + connect(containerWidget, &GraphicsContainerWidget::containerSizeChanged, m_modelRenderWidget, &ModelWidget::canvasResized); m_canvasGraphicsWidget->setModelWidget(m_modelRenderWidget); containerWidget->setModelWidget(m_modelRenderWidget); - + setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East); - QDockWidget *partsDocker = new QDockWidget(tr("Parts"), this); + QDockWidget* partsDocker = new QDockWidget(tr("Parts"), this); partsDocker->setAllowedAreas(Qt::RightDockWidgetArea); m_partManageWidget = new PartManageWidget(m_document); partsDocker->setWidget(m_partManageWidget); addDockWidget(Qt::RightDockWidgetArea, partsDocker); - QDockWidget *materialDocker = new QDockWidget(tr("Materials"), this); + QDockWidget* materialDocker = new QDockWidget(tr("Materials"), this); materialDocker->setAllowedAreas(Qt::RightDockWidgetArea); - MaterialManageWidget *materialManageWidget = new MaterialManageWidget(m_document, materialDocker); + MaterialManageWidget* materialManageWidget = new MaterialManageWidget(m_document, materialDocker); materialDocker->setWidget(materialManageWidget); connect(materialManageWidget, &MaterialManageWidget::registerDialog, this, &DocumentWindow::registerDialog); connect(materialManageWidget, &MaterialManageWidget::unregisterDialog, this, &DocumentWindow::unregisterDialog); addDockWidget(Qt::RightDockWidgetArea, materialDocker); connect(materialDocker, &QDockWidget::topLevelChanged, [=](bool topLevel) { Q_UNUSED(topLevel); - for (const auto &material: m_document->materialMap) + for (const auto& material : m_document->materialMap) emit m_document->materialPreviewChanged(material.first); }); - + tabifyDockWidget(partsDocker, materialDocker); - + partsDocker->raise(); - - QWidget *titleBarWidget = new QWidget; + + QWidget* titleBarWidget = new QWidget; titleBarWidget->setFixedHeight(1); - - QHBoxLayout *titleBarLayout = new QHBoxLayout; + + QHBoxLayout* titleBarLayout = new QHBoxLayout; titleBarLayout->addStretch(); titleBarWidget->setLayout(titleBarLayout); - QVBoxLayout *canvasLayout = new QVBoxLayout; + QVBoxLayout* canvasLayout = new QVBoxLayout; canvasLayout->setSpacing(0); canvasLayout->setContentsMargins(0, 0, 0, 0); canvasLayout->addWidget(titleBarWidget); canvasLayout->addWidget(containerWidget); canvasLayout->setStretch(1, 1); - - QHBoxLayout *mainLayout = new QHBoxLayout; + + QHBoxLayout* mainLayout = new QHBoxLayout; mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addLayout(mainLeftLayout); mainLayout->addLayout(canvasLayout); mainLayout->addSpacing(3); - QWidget *centralWidget = new QWidget; + QWidget* centralWidget = new QWidget; centralWidget->setLayout(mainLayout); setCentralWidget(centralWidget); @@ -322,13 +322,13 @@ DocumentWindow::DocumentWindow() m_fileMenu->addAction(m_newWindowAction); m_newDocumentAction = m_fileMenu->addAction(tr("&New"), - this, &DocumentWindow::newDocument, - QKeySequence::New); + this, &DocumentWindow::newDocument, + QKeySequence::New); m_openAction = m_fileMenu->addAction(tr("&Open..."), - this, &DocumentWindow::open, - QKeySequence::Open); - + this, &DocumentWindow::open, + QKeySequence::Open); + m_openExampleMenu = new QMenu(tr("Open Example")); std::vector exampleModels = { "Addax", @@ -340,19 +340,19 @@ DocumentWindow::DocumentWindow() "Screwdriver", "Seagull" }; - for (const auto &model: exampleModels) { - QAction *openModelAction = new QAction(model, this); + for (const auto& model : exampleModels) { + QAction* openModelAction = new QAction(model, this); connect(openModelAction, &QAction::triggered, this, [this, model]() { openExample("model-" + model.toLower().replace(QChar(' '), QChar('-')) + ".ds3"); }); m_openExampleMenu->addAction(openModelAction); } - + m_fileMenu->addMenu(m_openExampleMenu); m_saveAction = m_fileMenu->addAction(tr("&Save"), - this, &DocumentWindow::save, - QKeySequence::Save); + this, &DocumentWindow::save, + QKeySequence::Save); m_saveAsAction = new QAction(tr("Save As..."), this); connect(m_saveAsAction, &QAction::triggered, this, &DocumentWindow::saveAs, Qt::QueuedConnection); @@ -367,25 +367,25 @@ DocumentWindow::DocumentWindow() m_exportAsObjAction = new QAction(tr("Export as OBJ..."), this); connect(m_exportAsObjAction, &QAction::triggered, this, &DocumentWindow::exportObjResult, Qt::QueuedConnection); m_fileMenu->addAction(m_exportAsObjAction); - + m_exportAsGlbAction = new QAction(tr("Export as GLB..."), this); connect(m_exportAsGlbAction, &QAction::triggered, this, &DocumentWindow::exportGlbResult, Qt::QueuedConnection); m_fileMenu->addAction(m_exportAsGlbAction); - + m_exportAsFbxAction = new QAction(tr("Export as FBX..."), this); connect(m_exportAsFbxAction, &QAction::triggered, this, &DocumentWindow::exportFbxResult, Qt::QueuedConnection); m_fileMenu->addAction(m_exportAsFbxAction); - + m_fileMenu->addSeparator(); m_changeTurnaroundAction = new QAction(tr("Change Reference Sheet..."), this); connect(m_changeTurnaroundAction, &QAction::triggered, this, &DocumentWindow::changeTurnaround, Qt::QueuedConnection); m_fileMenu->addAction(m_changeTurnaroundAction); - + m_fileMenu->addSeparator(); - + for (int i = 0; i < Preferences::instance().maxRecentFiles(); ++i) { - QAction *action = new QAction(this); + QAction* action = new QAction(this); action->setVisible(false); connect(action, &QAction::triggered, this, &DocumentWindow::openRecentFile, Qt::QueuedConnection); m_recentFileActions.push_back(action); @@ -396,8 +396,8 @@ DocumentWindow::DocumentWindow() updateRecentFileActions(); m_quitAction = m_fileMenu->addAction(tr("&Quit"), - this, &DocumentWindow::close, - QKeySequence::Quit); + this, &DocumentWindow::close, + QKeySequence::Quit); connect(m_fileMenu, &QMenu::aboutToShow, [=]() { m_exportAsObjAction->setEnabled(m_canvasGraphicsWidget->hasItems()); @@ -412,56 +412,56 @@ DocumentWindow::DocumentWindow() m_modelRenderWidget->toggleWireframe(); }); m_viewMenu->addAction(m_toggleWireframeAction); - + m_toggleRotationAction = new QAction(tr("Toggle Rotation"), this); connect(m_toggleRotationAction, &QAction::triggered, [=]() { m_modelRenderWidget->toggleRotation(); }); m_viewMenu->addAction(m_toggleRotationAction); - + m_toggleColorAction = new QAction(tr("Toggle Color"), this); connect(m_toggleColorAction, &QAction::triggered, this, &DocumentWindow::toggleRenderColor); m_viewMenu->addAction(m_toggleColorAction); - + m_windowMenu = menuBar()->addMenu(tr("&Window")); - + m_showPartsListAction = new QAction(tr("Parts"), this); connect(m_showPartsListAction, &QAction::triggered, [=]() { partsDocker->show(); partsDocker->raise(); }); m_windowMenu->addAction(m_showPartsListAction); - + m_showMaterialsAction = new QAction(tr("Materials"), this); connect(m_showMaterialsAction, &QAction::triggered, [=]() { materialDocker->show(); materialDocker->raise(); }); m_windowMenu->addAction(m_showMaterialsAction); - - QMenu *dialogsMenu = m_windowMenu->addMenu(tr("Dialogs")); + + QMenu* dialogsMenu = m_windowMenu->addMenu(tr("Dialogs")); connect(dialogsMenu, &QMenu::aboutToShow, [=]() { dialogsMenu->clear(); if (this->m_dialogs.empty()) { - QAction *action = dialogsMenu->addAction(tr("None")); + QAction* action = dialogsMenu->addAction(tr("None")); action->setEnabled(false); return; } - for (const auto &dialog: this->m_dialogs) { - QAction *action = dialogsMenu->addAction(dialog->windowTitle()); + for (const auto& dialog : this->m_dialogs) { + QAction* action = dialogsMenu->addAction(dialog->windowTitle()); connect(action, &QAction::triggered, [=]() { dialog->show(); dialog->raise(); }); } }); - + m_showDebugDialogAction = new QAction(tr("Debug"), this); connect(m_showDebugDialogAction, &QAction::triggered, g_logBrowser, &LogBrowser::showDialog); m_windowMenu->addAction(m_showDebugDialogAction); m_helpMenu = menuBar()->addMenu(tr("&Help")); - + m_gotoHomepageAction = new QAction(tr("Dust3D Homepage"), this); connect(m_gotoHomepageAction, &QAction::triggered, this, &DocumentWindow::gotoHomepage); m_helpMenu->addAction(m_gotoHomepageAction); @@ -469,7 +469,7 @@ DocumentWindow::DocumentWindow() m_viewSourceAction = new QAction(tr("Source Code"), this); connect(m_viewSourceAction, &QAction::triggered, this, &DocumentWindow::viewSource); m_helpMenu->addAction(m_viewSourceAction); - + m_checkForUpdatesAction = new QAction(tr("Check for Updates..."), this); connect(m_checkForUpdatesAction, &QAction::triggered, this, &DocumentWindow::checkForUpdates); m_helpMenu->addAction(m_checkForUpdatesAction); @@ -489,13 +489,13 @@ DocumentWindow::DocumentWindow() m_reportIssuesAction = new QAction(tr("Report Issues"), this); connect(m_reportIssuesAction, &QAction::triggered, this, &DocumentWindow::reportIssues); m_helpMenu->addAction(m_reportIssuesAction); - + m_helpMenu->addSeparator(); m_seeContributorsAction = new QAction(tr("Contributors"), this); connect(m_seeContributorsAction, &QAction::triggered, this, &DocumentWindow::seeContributors); m_helpMenu->addAction(m_seeContributorsAction); - + m_seeSupportersAction = new QAction(tr("Supporters"), this); connect(m_seeSupportersAction, &QAction::triggered, this, &DocumentWindow::seeSupporters); m_helpMenu->addAction(m_seeSupportersAction); @@ -540,15 +540,15 @@ DocumentWindow::DocumentWindow() }); connect(m_document, &Document::editModeChanged, canvasGraphicsWidget, &SkeletonGraphicsWidget::editModeChanged); - + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutToggleWireframe, [=]() { m_modelRenderWidget->toggleWireframe(); }); - + //connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutToggleFlatShading, [=]() { // Preferences::instance().setFlatShading(!Preferences::instance().flatShading()); //}); - + //connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutToggleRotation, this, &DocumentWindow::toggleRotation); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::zoomRenderedModelBy, m_modelRenderWidget, &ModelWidget::zoom); @@ -589,15 +589,15 @@ DocumentWindow::DocumentWindow() connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setXlockState, m_document, &Document::setXlockState); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setYlockState, m_document, &Document::setYlockState); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setZlockState, m_document, &Document::setZlockState); - + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::enableAllPositionRelatedLocks, m_document, &Document::enableAllPositionRelatedLocks); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::disableAllPositionRelatedLocks, m_document, &Document::disableAllPositionRelatedLocks); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::changeTurnaround, this, &DocumentWindow::changeTurnaround); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::open, this, &DocumentWindow::open); - + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::showOrHideAllComponents, m_document, &Document::showOrHideAllComponents); - + connect(m_document, &Document::nodeAdded, canvasGraphicsWidget, &SkeletonGraphicsWidget::nodeAdded); connect(m_document, &Document::nodeRemoved, canvasGraphicsWidget, &SkeletonGraphicsWidget::nodeRemoved); connect(m_document, &Document::edgeAdded, canvasGraphicsWidget, &SkeletonGraphicsWidget::edgeAdded); @@ -639,7 +639,7 @@ DocumentWindow::DocumentWindow() resultTextureMesh->removeColor(); m_modelRenderWidget->updateMesh(resultTextureMesh); }); - + connect(m_document, &Document::resultMeshChanged, [=]() { auto resultMesh = m_document->takeResultMesh(); if (nullptr != resultMesh) @@ -659,7 +659,7 @@ DocumentWindow::DocumentWindow() connect(m_document, &Document::turnaroundChanged, this, &DocumentWindow::documentChanged); connect(m_document, &Document::optionsChanged, this, &DocumentWindow::documentChanged); - connect(m_modelRenderWidget, &ModelWidget::customContextMenuRequested, [=](const QPoint &pos) { + connect(m_modelRenderWidget, &ModelWidget::customContextMenuRequested, [=](const QPoint& pos) { canvasGraphicsWidget->showContextMenu(canvasGraphicsWidget->mapFromGlobal(m_modelRenderWidget->mapToGlobal(pos))); }); @@ -667,7 +667,7 @@ DocumentWindow::DocumentWindow() connect(m_document, &Document::ylockStateChanged, this, &DocumentWindow::updateYlockButtonState); connect(m_document, &Document::zlockStateChanged, this, &DocumentWindow::updateZlockButtonState); connect(m_document, &Document::radiusLockStateChanged, this, &DocumentWindow::updateRadiusLockButtonState); - + connect(m_document, &Document::materialAdded, this, [=](dust3d::Uuid materialId) { Q_UNUSED(materialId); m_document->generateMaterialPreviews(); @@ -680,11 +680,11 @@ DocumentWindow::DocumentWindow() initializeShortcuts(); connect(this, &DocumentWindow::initialized, m_document, &Document::uiReady); - - QTimer *timer = new QTimer(this); + + QTimer* timer = new QTimer(this); timer->setInterval(250); connect(timer, &QTimer::timeout, [=] { - QWidget *focusedWidget = QApplication::focusWidget(); + QWidget* focusedWidget = QApplication::focusWidget(); if (nullptr == focusedWidget && isActiveWindow()) canvasGraphicsWidget->setFocus(); }); @@ -693,11 +693,7 @@ DocumentWindow::DocumentWindow() void DocumentWindow::updateInprogressIndicator() { - bool inprogress = m_document->isMeshGenerating() || - m_document->isPostProcessing() || - m_document->isTextureGenerating() || - nullptr != m_componentPreviewImagesGenerator || - nullptr != m_componentPreviewImagesDecorator; + bool inprogress = m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating() || nullptr != m_componentPreviewImagesGenerator || nullptr != m_componentPreviewImagesDecorator; if (inprogress == m_inprogressIndicator->isSpinning()) return; m_inprogressIndicator->showSpinner(inprogress); @@ -711,9 +707,9 @@ void DocumentWindow::toggleRotation() m_canvasGraphicsWidget->setRotated(!m_canvasGraphicsWidget->rotated()); } -DocumentWindow *DocumentWindow::createDocumentWindow() +DocumentWindow* DocumentWindow::createDocumentWindow() { - DocumentWindow *documentWindow = new DocumentWindow(); + DocumentWindow* documentWindow = new DocumentWindow(); documentWindow->setAttribute(Qt::WA_DeleteOnClose); QSize size = Preferences::instance().documentWindowSize(); @@ -727,9 +723,9 @@ DocumentWindow *DocumentWindow::createDocumentWindow() return documentWindow; } -void DocumentWindow::closeEvent(QCloseEvent *event) +void DocumentWindow::closeEvent(QCloseEvent* event) { - if (! m_documentSaved) { + if (!m_documentSaved) { QMessageBox::StandardButton answer = QMessageBox::question(this, APP_NAME, tr("Do you really want to close while there are unsaved changes?"), @@ -749,7 +745,7 @@ void DocumentWindow::closeEvent(QCloseEvent *event) event->accept(); } -void DocumentWindow::setCurrentFilename(const QString &filename) +void DocumentWindow::setCurrentFilename(const QString& filename) { m_currentFilename = filename; m_documentSaved = true; @@ -796,7 +792,7 @@ void DocumentWindow::newDocument() void DocumentWindow::saveAs() { QString filename = QFileDialog::getSaveFileName(this, QString(), QString(), - tr("Dust3D Document (*.ds3)")); + tr("Dust3D Document (*.ds3)")); if (filename.isEmpty()) { return; } @@ -806,7 +802,7 @@ void DocumentWindow::saveAs() void DocumentWindow::saveAll() { - for (auto &it: g_documentWindows) { + for (auto& it : g_documentWindows) { it.first->save(); } } @@ -866,7 +862,7 @@ DocumentWindow::~DocumentWindow() delete m_document; } -void DocumentWindow::showEvent(QShowEvent *event) +void DocumentWindow::showEvent(QShowEvent* event) { QMainWindow::showEvent(event); if (m_firstShow) { @@ -878,7 +874,7 @@ void DocumentWindow::showEvent(QShowEvent *event) } } -void DocumentWindow::mousePressEvent(QMouseEvent *event) +void DocumentWindow::mousePressEvent(QMouseEvent* event) { QMainWindow::mousePressEvent(event); } @@ -886,7 +882,8 @@ void DocumentWindow::mousePressEvent(QMouseEvent *event) void DocumentWindow::changeTurnaround() { QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), - tr("Image Files (*.png *.jpg *.bmp)")).trimmed(); + tr("Image Files (*.png *.jpg *.bmp)")) + .trimmed(); if (fileName.isEmpty()) return; QImage image; @@ -900,32 +897,31 @@ void DocumentWindow::save() saveTo(m_currentFilename); } -void DocumentWindow::saveTo(const QString &saveAsFilename) +void DocumentWindow::saveTo(const QString& saveAsFilename) { QString filename = saveAsFilename; if (filename.isEmpty()) { filename = QFileDialog::getSaveFileName(this, QString(), QString(), - tr("Dust3D Document (*.ds3)")); + tr("Dust3D Document (*.ds3)")); if (filename.isEmpty()) { return; } ensureFileExtension(&filename, ".ds3"); } - + QApplication::setOverrideCursor(Qt::WaitCursor); dust3d::Snapshot snapshot; m_document->toSnapshot(&snapshot); - if (DocumentSaver::save(&filename, - &snapshot, - (!m_document->turnaround.isNull() && m_document->turnaroundPngByteArray.size() > 0) ? - &m_document->turnaroundPngByteArray : nullptr)) { + if (DocumentSaver::save(&filename, + &snapshot, + (!m_document->turnaround.isNull() && m_document->turnaroundPngByteArray.size() > 0) ? &m_document->turnaroundPngByteArray : nullptr)) { setCurrentFilename(filename); } QApplication::restoreOverrideCursor(); } -void DocumentWindow::openPathAs(const QString &path, const QString &asName) +void DocumentWindow::openPathAs(const QString& path, const QString& asName) { QApplication::setOverrideCursor(Qt::WaitCursor); @@ -933,14 +929,14 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName) m_document->reset(); m_document->clearTurnaround(); m_document->saveSnapshot(); - + QFile file(path); file.open(QFile::ReadOnly); QByteArray fileData = file.readAll(); - - dust3d::Ds3FileReader ds3Reader((const std::uint8_t *)fileData.data(), fileData.size()); + + dust3d::Ds3FileReader ds3Reader((const std::uint8_t*)fileData.data(), fileData.size()); for (int i = 0; i < (int)ds3Reader.items().size(); ++i) { - const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i]; + const dust3d::Ds3ReaderItem& item = ds3Reader.items()[i]; qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type; if (item.type == "asset") { if (dust3d::String::startsWith(item.name, "images/")) { @@ -956,15 +952,15 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName) } } } - + for (int i = 0; i < (int)ds3Reader.items().size(); ++i) { - const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i]; + const dust3d::Ds3ReaderItem& item = ds3Reader.items()[i]; if (item.type == "model") { std::vector data; ds3Reader.loadItem(item.name, &data); data.push_back('\0'); dust3d::Snapshot snapshot; - loadSnapshotFromXmlString(&snapshot, (char *)data.data()); + loadSnapshotFromXmlString(&snapshot, (char*)data.data()); m_document->fromSnapshot(snapshot); m_document->saveSnapshot(); } else if (item.type == "asset") { @@ -975,19 +971,19 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName) } } } - + QApplication::restoreOverrideCursor(); - + if (!asName.isEmpty()) { Preferences::instance().setCurrentFile(path); - for (auto &it: g_documentWindows) { + for (auto& it : g_documentWindows) { it.first->updateRecentFileActions(); } } setCurrentFilename(asName); } -void DocumentWindow::openExample(const QString &modelName) +void DocumentWindow::openExample(const QString& modelName) { if (!m_documentSaved) { QMessageBox::StandardButton answer = QMessageBox::question(this, @@ -998,7 +994,7 @@ void DocumentWindow::openExample(const QString &modelName) if (answer != QMessageBox::Yes) return; } - + openPathAs(":/resources/" + modelName, ""); } @@ -1018,14 +1014,14 @@ void DocumentWindow::open() tr("Dust3D Document (*.ds3)")); if (filename.isEmpty()) return; - + openPathAs(filename, filename); } void DocumentWindow::exportObjResult() { QString filename = QFileDialog::getSaveFileName(this, QString(), QString(), - tr("Wavefront (*.obj)")); + tr("Wavefront (*.obj)")); if (filename.isEmpty()) { return; } @@ -1033,10 +1029,10 @@ void DocumentWindow::exportObjResult() exportObjToFilename(filename); } -void DocumentWindow::exportObjToFilename(const QString &filename) +void DocumentWindow::exportObjToFilename(const QString& filename) { QApplication::setOverrideCursor(Qt::WaitCursor); - ModelMesh *resultMesh = m_document->takeResultMesh(); + ModelMesh* resultMesh = m_document->takeResultMesh(); if (nullptr != resultMesh) { resultMesh->exportAsObj(filename); delete resultMesh; @@ -1047,7 +1043,7 @@ void DocumentWindow::exportObjToFilename(const QString &filename) void DocumentWindow::exportFbxResult() { QString filename = QFileDialog::getSaveFileName(this, QString(), QString(), - tr("Autodesk FBX (*.fbx)")); + tr("Autodesk FBX (*.fbx)")); if (filename.isEmpty()) { return; } @@ -1055,7 +1051,7 @@ void DocumentWindow::exportFbxResult() exportFbxToFilename(filename); } -void DocumentWindow::exportFbxToFilename(const QString &filename) +void DocumentWindow::exportFbxToFilename(const QString& filename) { if (!m_document->isExportReady()) { qDebug() << "Export but document is not export ready"; @@ -1063,7 +1059,7 @@ void DocumentWindow::exportFbxToFilename(const QString &filename) } QApplication::setOverrideCursor(Qt::WaitCursor); dust3d::Object skeletonResult = m_document->currentPostProcessedObject(); - FbxFileWriter fbxFileWriter(skeletonResult, + FbxFileWriter fbxFileWriter(skeletonResult, filename, m_document->textureImage, m_document->textureNormalImage, @@ -1077,7 +1073,7 @@ void DocumentWindow::exportFbxToFilename(const QString &filename) void DocumentWindow::exportGlbResult() { QString filename = QFileDialog::getSaveFileName(this, QString(), QString(), - tr("glTF Binary Format (*.glb)")); + tr("glTF Binary Format (*.glb)")); if (filename.isEmpty()) { return; } @@ -1085,7 +1081,7 @@ void DocumentWindow::exportGlbResult() exportGlbToFilename(filename); } -void DocumentWindow::exportGlbToFilename(const QString &filename) +void DocumentWindow::exportGlbToFilename(const QString& filename) { if (!m_document->isExportReady()) { qDebug() << "Export but document is not export ready"; @@ -1093,10 +1089,9 @@ void DocumentWindow::exportGlbToFilename(const QString &filename) } QApplication::setOverrideCursor(Qt::WaitCursor); dust3d::Object skeletonResult = m_document->currentPostProcessedObject(); - QImage *textureMetalnessRoughnessAmbientOcclusionImage = - TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(m_document->textureMetalnessImage, - m_document->textureRoughnessImage, - m_document->textureAmbientOcclusionImage); + QImage* textureMetalnessRoughnessAmbientOcclusionImage = TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(m_document->textureMetalnessImage, + m_document->textureRoughnessImage, + m_document->textureAmbientOcclusionImage); GlbFileWriter glbFileWriter(skeletonResult, filename, m_document->textureImage, m_document->textureNormalImage, textureMetalnessRoughnessAmbientOcclusionImage); glbFileWriter.save(); @@ -1136,17 +1131,17 @@ void DocumentWindow::updateRadiusLockButtonState() m_radiusLockButton->setIcon(":/resources/toolbar_radius.svg"); } -void DocumentWindow::registerDialog(QWidget *widget) +void DocumentWindow::registerDialog(QWidget* widget) { m_dialogs.push_back(widget); } -void DocumentWindow::unregisterDialog(QWidget *widget) +void DocumentWindow::unregisterDialog(QWidget* widget) { m_dialogs.erase(std::remove(m_dialogs.begin(), m_dialogs.end(), widget), m_dialogs.end()); } -void DocumentWindow::setExportWaitingList(const QStringList &filenames) +void DocumentWindow::setExportWaitingList(const QStringList& filenames) { m_waitingForExportToFilenames = filenames; } @@ -1155,12 +1150,12 @@ void DocumentWindow::checkExportWaitingList() { if (m_waitingForExportToFilenames.empty()) return; - + auto list = m_waitingForExportToFilenames; m_waitingForExportToFilenames.clear(); - + bool isSuccessful = m_document->isMeshGenerationSucceed(); - for (const auto &filename: list) { + for (const auto& filename : list) { if (filename.endsWith(".obj")) { exportObjToFilename(filename); emit waitingExportFinished(filename, isSuccessful); @@ -1182,13 +1177,13 @@ void DocumentWindow::generateComponentPreviewImages() m_isComponentPreviewImagesObsolete = true; return; } - + m_isComponentPreviewImagesObsolete = false; - - QThread *thread = new QThread; - + + QThread* thread = new QThread; + m_componentPreviewImagesGenerator = new MeshPreviewImagesGenerator(new ModelOffscreenRender(m_modelRenderWidget->format())); - for (auto &component: m_document->componentMap) { + for (auto& component : m_document->componentMap) { if (!component.second.isPreviewMeshObsolete) continue; component.second.isPreviewMeshObsolete = false; @@ -1209,16 +1204,16 @@ void DocumentWindow::componentPreviewImagesReady() std::unique_ptr> componentImages; componentImages.reset(m_componentPreviewImagesGenerator->takeImages()); if (nullptr != componentImages) { - for (const auto &it: *componentImages) { + for (const auto& it : *componentImages) { m_document->setComponentPreviewImage(it.first, std::make_unique(std::move(it.second))); } } decorateComponentPreviewImages(); - + delete m_componentPreviewImagesGenerator; m_componentPreviewImagesGenerator = nullptr; - + if (m_isComponentPreviewImagesObsolete) generateComponentPreviewImages(); else @@ -1231,23 +1226,22 @@ void DocumentWindow::decorateComponentPreviewImages() m_isComponentPreviewImageDecorationsObsolete = true; return; } - + m_isComponentPreviewImageDecorationsObsolete = false; - - QThread *thread = new QThread; - + + QThread* thread = new QThread; + auto previewInputs = std::make_unique>(); - for (auto &component: m_document->componentMap) { + for (auto& component : m_document->componentMap) { if (!component.second.isPreviewImageDecorationObsolete) continue; component.second.isPreviewImageDecorationObsolete = false; if (nullptr == component.second.previewImage) continue; previewInputs->emplace_back(ComponentPreviewImagesDecorator::PreviewInput { - component.first, + component.first, std::make_unique(*component.second.previewImage), - !component.second.childrenIds.empty() - }); + !component.second.childrenIds.empty() }); } m_componentPreviewImagesDecorator = std::make_unique(std::move(previewInputs)); m_componentPreviewImagesDecorator->moveToThread(thread); @@ -1264,7 +1258,7 @@ void DocumentWindow::componentPreviewImageDecorationsReady() { auto resultImages = m_componentPreviewImagesDecorator->takeResultImages(); if (nullptr != resultImages) { - for (auto &it: *resultImages) { + for (auto& it : *resultImages) { if (nullptr == it.second) continue; m_document->setComponentPreviewPixmap(it.first, QPixmap::fromImage(*it.second)); @@ -1272,33 +1266,33 @@ void DocumentWindow::componentPreviewImageDecorationsReady() } m_componentPreviewImagesDecorator.reset(); - + if (m_isComponentPreviewImageDecorationsObsolete) decorateComponentPreviewImages(); else updateInprogressIndicator(); } -ModelWidget *DocumentWindow::modelWidget() +ModelWidget* DocumentWindow::modelWidget() { return m_modelRenderWidget; } -QShortcut *DocumentWindow::createShortcut(QKeySequence key) +QShortcut* DocumentWindow::createShortcut(QKeySequence key) { auto shortcutIt = m_shortcutMap.find(key); if (shortcutIt != m_shortcutMap.end()) return shortcutIt->second; - QShortcut *shortcut = new QShortcut(this); + QShortcut* shortcut = new QShortcut(this); shortcut->setKey(key); - m_shortcutMap.insert({key, shortcut}); + m_shortcutMap.insert({ key, shortcut }); return shortcut; } -#define defineShortcut(keyVal, widget, funcName) \ +#define defineShortcut(keyVal, widget, funcName) \ QObject::connect(createShortcut(keyVal), &QShortcut::activated, widget, funcName) - -void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWidget) + +void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget* graphicsWidget) { defineShortcut(Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutAddMode); defineShortcut(Qt::CTRL + Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutSelectAll); @@ -1316,7 +1310,7 @@ void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWid defineShortcut(Qt::Key_Escape, graphicsWidget, &SkeletonGraphicsWidget::shortcutEscape); } -void DocumentWindow::initializeCanvasShortcuts(SkeletonGraphicsWidget *graphicsWidget) +void DocumentWindow::initializeCanvasShortcuts(SkeletonGraphicsWidget* graphicsWidget) { defineShortcut(Qt::Key_Delete, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete); defineShortcut(Qt::Key_Backspace, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete); @@ -1346,7 +1340,7 @@ void DocumentWindow::initializeShortcuts() { initializeToolShortcuts(m_canvasGraphicsWidget); initializeCanvasShortcuts(m_canvasGraphicsWidget); - + defineShortcut(Qt::Key_M, m_canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutXmirrorOnOrOffSelectedPart); defineShortcut(Qt::Key_B, m_canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutSubdivedOrNotSelectedPart); defineShortcut(Qt::Key_U, m_canvasGraphicsWidget, &SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart); @@ -1365,7 +1359,7 @@ void DocumentWindow::openRecentFile() return; } - QAction *action = qobject_cast(sender()); + QAction* action = qobject_cast(sender()); if (action) { QString fileName = action->data().toString(); openPathAs(fileName, fileName); @@ -1375,7 +1369,7 @@ void DocumentWindow::openRecentFile() void DocumentWindow::updateRecentFileActions() { QStringList files = Preferences::instance().recentFileList(); - + for (int i = 0; i < (int)files.size() && i < (int)m_recentFileActions.size(); ++i) { QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); m_recentFileActions[i]->setText(text); @@ -1388,7 +1382,7 @@ void DocumentWindow::updateRecentFileActions() m_recentFileSeparatorAction->setVisible(files.size() > 0); } -QString DocumentWindow::strippedName(const QString &fullFileName) +QString DocumentWindow::strippedName(const QString& fullFileName) { return QFileInfo(fullFileName).fileName(); } @@ -1401,10 +1395,8 @@ bool DocumentWindow::isWorking() void DocumentWindow::toggleRenderColor() { m_modelRemoveColor = !m_modelRemoveColor; - ModelMesh *mesh = nullptr; - if (m_document->isMeshGenerating() || - m_document->isPostProcessing() || - m_document->isTextureGenerating()) { + ModelMesh* mesh = nullptr; + if (m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating()) { mesh = m_document->takeResultMesh(); } else { mesh = m_document->takeResultTextureMesh(); diff --git a/application/sources/document_window.h b/application/sources/document_window.h index 55ec00f2..f9140b96 100644 --- a/application/sources/document_window.h +++ b/application/sources/document_window.h @@ -1,21 +1,21 @@ #ifndef DUST3D_APPLICATION_DOCUMENT_WINDOW_H_ #define DUST3D_APPLICATION_DOCUMENT_WINDOW_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "model_widget.h" +#include "component_preview_images_decorator.h" #include "graphics_container_widget.h" #include "mesh_preview_images_generator.h" -#include "component_preview_images_decorator.h" +#include "model_widget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include class Document; class SkeletonGraphicsWidget; @@ -23,38 +23,39 @@ class PartManageWidget; class ToolbarButton; class SpinnableToolbarIcon; -class DocumentWindow : public QMainWindow -{ +class DocumentWindow : public QMainWindow { Q_OBJECT signals: void initialized(); void uninialized(); - void waitingExportFinished(const QString &filename, bool isSuccessful); + void waitingExportFinished(const QString& filename, bool isSuccessful); void workingStatusChanged(bool isWorking); + public: DocumentWindow(); ~DocumentWindow(); - Document *document(); - ModelWidget *modelWidget(); + Document* document(); + ModelWidget* modelWidget(); bool isWorking(); - static DocumentWindow *createDocumentWindow(); - static const std::map &documentWindows(); + static DocumentWindow* createDocumentWindow(); + static const std::map& documentWindows(); static void showAcknowlegements(); static void showContributors(); static void showSupporters(); static void showAbout(); static size_t total(); + protected: - void showEvent(QShowEvent *event); - void closeEvent(QCloseEvent *event); - void mousePressEvent(QMouseEvent *event); + void showEvent(QShowEvent* event); + void closeEvent(QCloseEvent* event); + void mousePressEvent(QMouseEvent* event); public slots: void changeTurnaround(); void save(); - void saveTo(const QString &saveAsFilename); + void saveTo(const QString& saveAsFilename); void open(); - void openExample(const QString &modelName); - void openPathAs(const QString &path, const QString &asName); + void openExample(const QString& modelName); + void openPathAs(const QString& path, const QString& asName); void exportObjResult(); void exportGlbResult(); void exportFbxResult(); @@ -76,13 +77,13 @@ public slots: void updateYlockButtonState(); void updateZlockButtonState(); void updateRadiusLockButtonState(); - void registerDialog(QWidget *widget); - void unregisterDialog(QWidget *widget); - void setExportWaitingList(const QStringList &filenames); + void registerDialog(QWidget* widget); + void unregisterDialog(QWidget* widget); + void setExportWaitingList(const QStringList& filenames); void checkExportWaitingList(); - void exportObjToFilename(const QString &filename); - void exportFbxToFilename(const QString &filename); - void exportGlbToFilename(const QString &filename); + void exportObjToFilename(const QString& filename); + void exportFbxToFilename(const QString& filename); + void exportGlbToFilename(const QString& filename); void toggleRotation(); void generateComponentPreviewImages(); void componentPreviewImagesReady(); @@ -92,88 +93,88 @@ public slots: void openRecentFile(); void updateRecentFileActions(); void toggleRenderColor(); + private: - void setCurrentFilename(const QString &filename); + void setCurrentFilename(const QString& filename); void updateTitle(); void initializeShortcuts(); - void initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWidget); - void initializeCanvasShortcuts(SkeletonGraphicsWidget *graphicsWidget); - QShortcut *createShortcut(QKeySequence key); - QString strippedName(const QString &fullFileName); - bool openFiles(const QStringList &pathList); + void initializeToolShortcuts(SkeletonGraphicsWidget* graphicsWidget); + void initializeCanvasShortcuts(SkeletonGraphicsWidget* graphicsWidget); + QShortcut* createShortcut(QKeySequence key); + QString strippedName(const QString& fullFileName); + bool openFiles(const QStringList& pathList); - Document *m_document = nullptr; + Document* m_document = nullptr; bool m_firstShow = true; bool m_documentSaved = true; - std::vector m_dialogs; + std::vector m_dialogs; bool m_isLastMeshGenerationSucceed = true; quint64 m_currentUpdatedMeshId = 0; QStringList m_waitingForExportToFilenames; - - QString m_currentFilename; - - ModelWidget *m_modelRenderWidget = nullptr; - SkeletonGraphicsWidget *m_canvasGraphicsWidget = nullptr; - GraphicsContainerWidget *m_graphicsContainerWidget = nullptr; - - QMenu *m_fileMenu = nullptr; - QAction *m_newWindowAction = nullptr; - QAction *m_newDocumentAction = nullptr; - QAction *m_openAction = nullptr; - QMenu *m_openExampleMenu = nullptr; - QAction *m_saveAction = nullptr; - QAction *m_saveAsAction = nullptr; - QAction *m_saveAllAction = nullptr; - QAction *m_changeTurnaroundAction = nullptr; - std::vector m_recentFileActions; - QAction *m_recentFileSeparatorAction = nullptr; - QAction *m_quitAction = nullptr; - QAction *m_exportAsObjAction = nullptr; - QAction *m_exportAsGlbAction = nullptr; - QAction *m_exportAsFbxAction = nullptr; - - QMenu *m_viewMenu = nullptr; - QAction *m_toggleWireframeAction = nullptr; - QAction *m_toggleRotationAction = nullptr; - QAction *m_toggleColorAction = nullptr; + QString m_currentFilename; + + ModelWidget* m_modelRenderWidget = nullptr; + SkeletonGraphicsWidget* m_canvasGraphicsWidget = nullptr; + GraphicsContainerWidget* m_graphicsContainerWidget = nullptr; + + QMenu* m_fileMenu = nullptr; + QAction* m_newWindowAction = nullptr; + QAction* m_newDocumentAction = nullptr; + QAction* m_openAction = nullptr; + QMenu* m_openExampleMenu = nullptr; + QAction* m_saveAction = nullptr; + QAction* m_saveAsAction = nullptr; + QAction* m_saveAllAction = nullptr; + QAction* m_changeTurnaroundAction = nullptr; + std::vector m_recentFileActions; + QAction* m_recentFileSeparatorAction = nullptr; + QAction* m_quitAction = nullptr; + + QAction* m_exportAsObjAction = nullptr; + QAction* m_exportAsGlbAction = nullptr; + QAction* m_exportAsFbxAction = nullptr; + + QMenu* m_viewMenu = nullptr; + QAction* m_toggleWireframeAction = nullptr; + QAction* m_toggleRotationAction = nullptr; + QAction* m_toggleColorAction = nullptr; bool m_modelRemoveColor = false; - - QMenu *m_windowMenu = nullptr; - QAction *m_showPartsListAction = nullptr; - QAction *m_showDebugDialogAction = nullptr; - QAction *m_showMaterialsAction = nullptr; - - QMenu *m_helpMenu = nullptr; - QAction *m_gotoHomepageAction = nullptr; - QAction *m_viewSourceAction = nullptr; - QAction *m_aboutAction = nullptr; - QAction *m_checkForUpdatesAction = nullptr; - QAction *m_reportIssuesAction = nullptr; - QAction *m_seeContributorsAction = nullptr; - QAction *m_seeSupportersAction = nullptr; - QAction *m_seeAcknowlegementsAction = nullptr; - QAction *m_seeReferenceGuideAction = nullptr; - - ToolbarButton *m_xLockButton = nullptr; - ToolbarButton *m_yLockButton = nullptr; - ToolbarButton *m_zLockButton = nullptr; - ToolbarButton *m_radiusLockButton = nullptr; - + + QMenu* m_windowMenu = nullptr; + QAction* m_showPartsListAction = nullptr; + QAction* m_showDebugDialogAction = nullptr; + QAction* m_showMaterialsAction = nullptr; + + QMenu* m_helpMenu = nullptr; + QAction* m_gotoHomepageAction = nullptr; + QAction* m_viewSourceAction = nullptr; + QAction* m_aboutAction = nullptr; + QAction* m_checkForUpdatesAction = nullptr; + QAction* m_reportIssuesAction = nullptr; + QAction* m_seeContributorsAction = nullptr; + QAction* m_seeSupportersAction = nullptr; + QAction* m_seeAcknowlegementsAction = nullptr; + QAction* m_seeReferenceGuideAction = nullptr; + + ToolbarButton* m_xLockButton = nullptr; + ToolbarButton* m_yLockButton = nullptr; + ToolbarButton* m_zLockButton = nullptr; + ToolbarButton* m_radiusLockButton = nullptr; + QMetaObject::Connection m_partListDockerVisibleSwitchConnection; - - MeshPreviewImagesGenerator *m_componentPreviewImagesGenerator = nullptr; + + MeshPreviewImagesGenerator* m_componentPreviewImagesGenerator = nullptr; bool m_isComponentPreviewImagesObsolete = false; std::unique_ptr m_componentPreviewImagesDecorator; bool m_isComponentPreviewImageDecorationsObsolete = false; - - PartManageWidget *m_partManageWidget = nullptr; - - SpinnableToolbarIcon *m_inprogressIndicator = nullptr; - - std::map m_shortcutMap; + + PartManageWidget* m_partManageWidget = nullptr; + + SpinnableToolbarIcon* m_inprogressIndicator = nullptr; + + std::map m_shortcutMap; }; #endif - diff --git a/application/sources/fbx_file.cc b/application/sources/fbx_file.cc index 759dc41f..8bc72b48 100644 --- a/application/sources/fbx_file.cc +++ b/application/sources/fbx_file.cc @@ -1,13 +1,13 @@ +#include "fbx_file.h" +#include "document.h" +#include "version.h" +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include "fbx_file.h" -#include "version.h" -#include "document.h" using namespace fbx; @@ -27,9 +27,9 @@ void FbxFileWriter::createFbxHeader() headerExtension.addPropertyNode("EncryptionType", (int32_t)0); { auto currentDateTime = QDateTime::currentDateTime(); - const auto ¤tDate = currentDateTime.date(); - const auto ¤tTime = currentDateTime.time(); - + const auto& currentDate = currentDateTime.date(); + const auto& currentTime = currentDateTime.time(); + FBXNode creationTimeStamp("CreationTimeStamp"); creationTimeStamp.addPropertyNode("Version", (int32_t)1000); creationTimeStamp.addPropertyNode("Year", (int32_t)currentDate.year()); @@ -45,7 +45,7 @@ void FbxFileWriter::createFbxHeader() headerExtension.addPropertyNode("Creator", APP_NAME " " APP_HUMAN_VER); { FBXNode sceneInfo("SceneInfo"); - sceneInfo.addProperty(std::vector({'G','l','o','b','a','l','I','n','f','o',0,1,'S','c','e','n','e','I','n','f','o'}), 'S'); + sceneInfo.addProperty(std::vector({ 'G', 'l', 'o', 'b', 'a', 'l', 'I', 'n', 'f', 'o', 0, 1, 'S', 'c', 'e', 'n', 'e', 'I', 'n', 'f', 'o' }), 'S'); sceneInfo.addProperty("UserData"); sceneInfo.addPropertyNode("Type", "UserData"); sceneInfo.addPropertyNode("Version", 100); @@ -185,7 +185,7 @@ void FbxFileWriter::createFbxHeader() headerExtension.addChild(sceneInfo); headerExtension.addChild(FBXNode()); } - + m_fbxDocument.nodes.push_back(headerExtension); } @@ -198,7 +198,7 @@ void FbxFileWriter::createCreationTime() void FbxFileWriter::createFileId() { - std::vector fileIdBytes = {40, (uint8_t)-77, 42, (uint8_t)-21, (uint8_t)-74, 36, (uint8_t)-52, (uint8_t)-62, (uint8_t)-65, (uint8_t)-56, (uint8_t)-80, 42, (uint8_t)-87, 43, (uint8_t)-4, (uint8_t)-15}; + std::vector fileIdBytes = { 40, (uint8_t)-77, 42, (uint8_t)-21, (uint8_t)-74, 36, (uint8_t)-52, (uint8_t)-62, (uint8_t)-65, (uint8_t)-56, (uint8_t)-80, 42, (uint8_t)-87, 43, (uint8_t)-4, (uint8_t)-15 }; FBXNode fileId("FileId"); fileId.addProperty(fileIdBytes, 'R'); m_fbxDocument.nodes.push_back(fileId); @@ -415,13 +415,13 @@ void FbxFileWriter::createReferences() } void FbxFileWriter::createDefinitions(size_t deformerCount, - size_t textureCount, - size_t videoCount, - bool hasAnimtion, - size_t animationStackCount, - size_t animationLayerCount, - size_t animationCurveNodeCount, - size_t animationCurveCount) + size_t textureCount, + size_t videoCount, + bool hasAnimtion, + size_t animationStackCount, + size_t animationLayerCount, + size_t animationCurveNodeCount, + size_t animationCurveCount) { FBXNode definitions("Definitions"); definitions.addPropertyNode("Version", (int32_t)100); @@ -2198,15 +2198,15 @@ void FbxFileWriter::createDefinitions(size_t deformerCount, m_fbxDocument.nodes.push_back(definitions); } -FbxFileWriter::FbxFileWriter(dust3d::Object &object, - const QString &filename, - QImage *textureImage, - QImage *normalImage, - QImage *metalnessImage, - QImage *roughnessImage, - QImage *ambientOcclusionImage) : - m_filename(filename), - m_baseName(QFileInfo(m_filename).baseName()) +FbxFileWriter::FbxFileWriter(dust3d::Object& object, + const QString& filename, + QImage* textureImage, + QImage* normalImage, + QImage* metalnessImage, + QImage* roughnessImage, + QImage* ambientOcclusionImage) + : m_filename(filename) + , m_baseName(QFileInfo(m_filename).baseName()) { createFbxHeader(); createFileId(); @@ -2215,24 +2215,24 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, createGlobalSettings(); createDocuments(); createReferences(); - + FBXNode connections("Connections"); - + size_t deformerCount = 0; - + FBXNode geometry("Geometry"); int64_t geometryId = m_next64Id++; geometry.addProperty(geometryId); - geometry.addProperty(std::vector({'u','n','a','m','e','d','m','e','s','h',0,1,'G','e','o','m','e','t','r','y'}), 'S'); + geometry.addProperty(std::vector({ 'u', 'n', 'a', 'm', 'e', 'd', 'm', 'e', 's', 'h', 0, 1, 'G', 'e', 'o', 'm', 'e', 't', 'r', 'y' }), 'S'); geometry.addProperty("Mesh"); std::vector positions; - for (const auto &vertex: object.vertices) { + for (const auto& vertex : object.vertices) { positions.push_back((double)vertex.x()); positions.push_back((double)vertex.y()); positions.push_back((double)vertex.z()); } std::vector indices; - for (const auto &triangle: object.triangles) { + for (const auto& triangle : object.triangles) { indices.push_back(triangle[0]); indices.push_back(triangle[1]); indices.push_back(triangle[2] ^ -1); @@ -2248,7 +2248,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, std::vector normals; for (decltype(triangleVertexNormals->size()) i = 0; i < triangleVertexNormals->size(); ++i) { for (size_t j = 0; j < 3; ++j) { - const auto &n = (*triangleVertexNormals)[i][j]; + const auto& n = (*triangleVertexNormals)[i][j]; normals.push_back((double)n.x()); normals.push_back((double)n.y()); normals.push_back((double)n.z()); @@ -2269,7 +2269,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, //std::vector uvIndices; for (decltype(triangleVertexUvs->size()) i = 0; i < triangleVertexUvs->size(); ++i) { for (size_t j = 0; j < 3; ++j) { - const auto &uv = (*triangleVertexUvs)[i][j]; + const auto& uv = (*triangleVertexUvs)[i][j]; uvs.push_back((double)uv.x()); uvs.push_back((double)1.0 - uv.y()); //uvIndices.push_back(uvIndices.size()); @@ -2285,7 +2285,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, layerElementMaterial.addPropertyNode("Name", ""); layerElementMaterial.addPropertyNode("MappingInformationType", "AllSame"); layerElementMaterial.addPropertyNode("ReferenceInformationType", "IndexToDirect"); - std::vector materials = {(int32_t)0}; + std::vector materials = { (int32_t)0 }; layerElementMaterial.addPropertyNode("Materials", materials); layerElementMaterial.addChild(FBXNode()); FBXNode layer("Layer"); @@ -2323,11 +2323,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, geometry.addChild(layerElementUv); geometry.addChild(layer); geometry.addChild(FBXNode()); - + int64_t modelId = m_next64Id++; FBXNode model("Model"); model.addProperty(modelId); - model.addProperty(std::vector({'u','n','a','m','e','d',0,1,'M','o','d','e','l'}), 'S'); + model.addProperty(std::vector({ 'u', 'n', 'a', 'm', 'e', 'd', 0, 1, 'M', 'o', 'd', 'e', 'l' }), 'S'); model.addProperty("Mesh"); model.addPropertyNode("Version", (int32_t)232); { @@ -2390,7 +2390,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, model.addPropertyNode("Shading", (bool)true); model.addPropertyNode("Culling", "CullingOff"); model.addChild(FBXNode()); - + FBXNode pose("Pose"); int64_t poseId = 0; std::vector deformers; @@ -2401,12 +2401,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, std::vector nodeAttributeIds; int64_t skinId = 0; int64_t armatureId = 0; - - if (deformerCount > 0) - { + + if (deformerCount > 0) { poseId = m_next64Id++; pose.addProperty(poseId); - pose.addProperty(std::vector({'u','n','a','m','e','d',0,1,'P','o','s','e'}), 'S'); + pose.addProperty(std::vector({ 'u', 'n', 'a', 'm', 'e', 'd', 0, 1, 'P', 'o', 's', 'e' }), 'S'); pose.addProperty("BindPose"); pose.addPropertyNode("Type", "BindPose"); pose.addPropertyNode("Version", (int32_t)100); @@ -2427,17 +2426,17 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, } pose.addChild(FBXNode()); } - + size_t textureCount = 0; size_t videoCount = 0; - + std::vector videos; std::vector textures; - + FBXNode material("Material"); int64_t materialId = m_next64Id++; material.addProperty(materialId); - material.addProperty(std::vector({'M','a','t','e','r','i','a','l',0,1,'S','t','i','n','g','r','a','y','P','B','S'}), 'S'); + material.addProperty(std::vector({ 'M', 'a', 't', 'e', 'r', 'i', 'a', 'l', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S' }), 'S'); material.addProperty(""); material.addPropertyNode("Version", (int32_t)102); material.addPropertyNode("ShadingModel", "unknown"); @@ -2696,7 +2695,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, material.addChild(properties); } material.addChild(FBXNode()); - + /* FBXNode material("Material"); int64_t materialId = m_next64Id++; @@ -2833,11 +2832,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, } material.addChild(FBXNode()); */ - + FBXNode implementation("Implementation"); int64_t implementationId = m_next64Id++; implementation.addProperty(implementationId); - implementation.addProperty(std::vector({'I','m','p','l','e','m','e','n','t','a','t','i','o','n',0,1,'S','t','i','n','g','r','a','y','P','B','S','_','I','m','p','l','e','m','e','n','t','a','t','i','o','n'}), 'S'); + implementation.addProperty(std::vector({ 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n', 't', 'a', 't', 'i', 'o', 'n', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S', '_', 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n', 't', 'a', 't', 'i', 'o', 'n' }), 'S'); implementation.addProperty(""); implementation.addPropertyNode("Version", (int32_t)100); { @@ -2896,11 +2895,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, implementation.addChild(properties); } implementation.addChild(FBXNode()); - + FBXNode bindingTable("BindingTable"); int64_t bindingTableId = m_next64Id++; bindingTable.addProperty(bindingTableId); - bindingTable.addProperty(std::vector({'B','i','n','d','i','n','g','T','a','b','l','e',0,1,'S','t','i','n','g','r','a','y','P','B','S','_','B','i','n','d','i','n','g','T','a','b','l','e'}), 'S'); + bindingTable.addProperty(std::vector({ 'B', 'i', 'n', 'd', 'i', 'n', 'g', 'T', 'a', 'b', 'l', 'e', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S', '_', 'B', 'i', 'n', 'd', 'i', 'n', 'g', 'T', 'a', 'b', 'l', 'e' }), 'S'); bindingTable.addProperty(""); bindingTable.addPropertyNode("Version", (int32_t)100); { @@ -3103,8 +3102,8 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, bindingTable.addChild(entry); } bindingTable.addChild(FBXNode()); - - auto addTexture = [&](const QImage *image, const std::vector &clipName, const std::vector &textureName, const QString &filename, const QString &propertyName){ + + auto addTexture = [&](const QImage* image, const std::vector& clipName, const std::vector& textureName, const QString& filename, const QString& propertyName) { FBXNode video("Video"); int64_t videoId = m_next64Id++; video.addProperty(videoId); @@ -3136,7 +3135,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, video.addChild(FBXNode()); videos.push_back(video); videoCount++; - + FBXNode texture("Texture"); int64_t textureId = m_next64Id++; texture.addProperty(textureId); @@ -3195,7 +3194,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, texture.addChild(FBXNode()); textures.push_back(texture); textureCount++; - + { FBXNode p("C"); p.addProperty("OO"); @@ -3214,46 +3213,46 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, }; if (nullptr != textureImage) { addTexture(textureImage, - std::vector({'V','i','d','e','o',0,1,'B','a','s','e','C','o','l','o','r'}), - std::vector({'T','e','x','t','u','r','e',0,1,'B','a','s','e','C','o','l','o','r'}), + std::vector({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'B', 'a', 's', 'e', 'C', 'o', 'l', 'o', 'r' }), + std::vector({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'B', 'a', 's', 'e', 'C', 'o', 'l', 'o', 'r' }), m_baseName + "_color.png", "Maya|TEX_color_map"); } if (nullptr != normalImage) { addTexture(normalImage, - std::vector({'V','i','d','e','o',0,1,'N','o','r','m','a','l'}), - std::vector({'T','e','x','t','u','r','e',0,1,'N','o','r','m','a','l'}), + std::vector({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'N', 'o', 'r', 'm', 'a', 'l' }), + std::vector({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'N', 'o', 'r', 'm', 'a', 'l' }), m_baseName + "_normal.png", "Maya|TEX_normal_map"); } if (nullptr != metalnessImage) { addTexture(metalnessImage, - std::vector({'V','i','d','e','o',0,1,'M','e','t','a','l','l','i','c'}), - std::vector({'T','e','x','t','u','r','e',0,1,'M','e','t','a','l','l','i','c'}), + std::vector({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'M', 'e', 't', 'a', 'l', 'l', 'i', 'c' }), + std::vector({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'M', 'e', 't', 'a', 'l', 'l', 'i', 'c' }), m_baseName + "_metallic.png", "Maya|TEX_metallic_map"); } if (nullptr != roughnessImage) { addTexture(roughnessImage, - std::vector({'V','i','d','e','o',0,1,'R','o','u','g','h','n','e','s','s'}), - std::vector({'T','e','x','t','u','r','e',0,1,'R','o','u','g','h','n','e','s','s'}), + std::vector({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'R', 'o', 'u', 'g', 'h', 'n', 'e', 's', 's' }), + std::vector({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'R', 'o', 'u', 'g', 'h', 'n', 'e', 's', 's' }), m_baseName + "_roughness.png", "Maya|TEX_roughness_map"); } if (nullptr != ambientOcclusionImage) { addTexture(ambientOcclusionImage, - std::vector({'V','i','d','e','o',0,1,'A','o'}), - std::vector({'T','e','x','t','u','r','e',0,1,'A','o'}), + std::vector({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'A', 'o' }), + std::vector({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'A', 'o' }), m_baseName + "_ao.png", "Maya|TEX_ao_map"); } - + bool hasAnimation = false; size_t animationStackCount = 0; size_t animationLayerCount = 0; size_t animationCurveNodeCount = 0; size_t animationCurveCount = 0; - + std::vector animationStacks; std::vector animationLayers; std::vector animationCurveNodes; @@ -3263,11 +3262,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, textureCount, videoCount, hasAnimation, animationStackCount, animationLayerCount, animationCurveNodeCount, animationCurveCount); - + FBXNode objects("Objects"); objects.addChild(geometry); objects.addChild(model); - for (const auto &limbNode: limbNodes) { + for (const auto& limbNode : limbNodes) { objects.addChild(limbNode); } if (deformerCount > 0) @@ -3276,38 +3275,38 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, objects.addChild(implementation); objects.addChild(bindingTable); if (textureCount > 0) { - for (const auto &texture: textures) { + for (const auto& texture : textures) { objects.addChild(texture); } } if (videoCount > 0) { - for (const auto &video: videos) { + for (const auto& video : videos) { objects.addChild(video); } } - for (const auto &deformer: deformers) { + for (const auto& deformer : deformers) { objects.addChild(deformer); } - for (const auto &nodeAttribute: nodeAttributes) { + for (const auto& nodeAttribute : nodeAttributes) { objects.addChild(nodeAttribute); } if (hasAnimation) { - for (const auto &animationStack: animationStacks) { + for (const auto& animationStack : animationStacks) { objects.addChild(animationStack); } - for (const auto &animationLayer: animationLayers) { + for (const auto& animationLayer : animationLayers) { objects.addChild(animationLayer); } - for (const auto &animationCurveNode: animationCurveNodes) { + for (const auto& animationCurveNode : animationCurveNodes) { objects.addChild(animationCurveNode); } - for (const auto &animationCurve: animationCurves) { + for (const auto& animationCurve : animationCurves) { objects.addChild(animationCurve); } } objects.addChild(FBXNode()); m_fbxDocument.nodes.push_back(objects); - + { FBXNode p("C"); p.addProperty("OO"); @@ -3315,8 +3314,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, p.addProperty((int64_t)0); connections.addChild(p); } - if (armatureId > 0) - { + if (armatureId > 0) { FBXNode p("C"); p.addProperty("OO"); p.addProperty(armatureId); @@ -3330,8 +3328,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, p.addProperty(modelId); connections.addChild(p); } - if (skinId > 0) - { + if (skinId > 0) { FBXNode p("C"); p.addProperty("OO"); p.addProperty(skinId); @@ -3375,7 +3372,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object, } connections.addChild(FBXNode()); m_fbxDocument.nodes.push_back(connections); - + createTakes(); } @@ -3394,11 +3391,11 @@ bool FbxFileWriter::save() return true; } -std::vector FbxFileWriter::matrixToVector(const QMatrix4x4 &matrix) +std::vector FbxFileWriter::matrixToVector(const QMatrix4x4& matrix) { std::vector vec; for (size_t col = 0; col < 4; ++col) { - const auto &line = matrix.column(col); + const auto& line = matrix.column(col); vec.push_back(line.x()); vec.push_back(line.y()); vec.push_back(line.z()); diff --git a/application/sources/fbx_file.h b/application/sources/fbx_file.h index f8042666..2b0c6eb5 100644 --- a/application/sources/fbx_file.h +++ b/application/sources/fbx_file.h @@ -1,25 +1,24 @@ #ifndef DUST3D_APPLICATION_FBX_FILE_H_ #define DUST3D_APPLICATION_FBX_FILE_H_ -#include -#include +#include "fbxdocument.h" +#include #include #include -#include +#include #include -#include "fbxdocument.h" +#include -class FbxFileWriter : public QObject -{ +class FbxFileWriter : public QObject { Q_OBJECT public: - FbxFileWriter(dust3d::Object &object, - const QString &filename, - QImage *textureImage=nullptr, - QImage *normalImage=nullptr, - QImage *metalnessImage=nullptr, - QImage *roughnessImage=nullptr, - QImage *ambientOcclusionImage=nullptr); + FbxFileWriter(dust3d::Object& object, + const QString& filename, + QImage* textureImage = nullptr, + QImage* normalImage = nullptr, + QImage* metalnessImage = nullptr, + QImage* roughnessImage = nullptr, + QImage* ambientOcclusionImage = nullptr); bool save(); private: @@ -31,17 +30,17 @@ private: void createDocuments(); void createReferences(); void createDefinitions(size_t deformerCount, - size_t textureCount=0, - size_t videoCount=0, - bool hasAnimtion=false, - size_t animationStackCount=0, - size_t animationLayerCount=0, - size_t animationCurveNodeCount=0, - size_t animationCurveCount=0); + size_t textureCount = 0, + size_t videoCount = 0, + bool hasAnimtion = false, + size_t animationStackCount = 0, + size_t animationLayerCount = 0, + size_t animationCurveNodeCount = 0, + size_t animationCurveCount = 0); void createTakes(); - std::vector matrixToVector(const QMatrix4x4 &matrix); + std::vector matrixToVector(const QMatrix4x4& matrix); int64_t secondsToKtime(double seconds); - + int64_t m_next64Id = 612150000; QString m_filename; QString m_baseName; @@ -51,4 +50,3 @@ private: }; #endif - diff --git a/application/sources/float_number_widget.cc b/application/sources/float_number_widget.cc index c434d561..ef31e320 100644 --- a/application/sources/float_number_widget.cc +++ b/application/sources/float_number_widget.cc @@ -1,11 +1,11 @@ -#include +#include "float_number_widget.h" +#include "theme.h" #include #include -#include "theme.h" -#include "float_number_widget.h" +#include -FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) : - QWidget(parent) +FloatNumberWidget::FloatNumberWidget(QWidget* parent, bool singleLine) + : QWidget(parent) { m_slider = new QSlider(Qt::Horizontal, this); m_slider->setRange(0, 100); @@ -19,8 +19,8 @@ FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) : updateValueLabel(fvalue); emit valueChanged(fvalue); }); - - QBoxLayout *layout = nullptr; + + QBoxLayout* layout = nullptr; if (singleLine) { layout = new QHBoxLayout(this); layout->setMargin(2); @@ -48,7 +48,7 @@ void FloatNumberWidget::updateValueLabel(float value) m_label->setText(m_itemName + ": " + valueString); } -void FloatNumberWidget::setItemName(const QString &name) +void FloatNumberWidget::setItemName(const QString& name) { m_itemName = name; updateValueLabel(value()); diff --git a/application/sources/float_number_widget.h b/application/sources/float_number_widget.h index 6ebb87d7..b1eace8c 100644 --- a/application/sources/float_number_widget.h +++ b/application/sources/float_number_widget.h @@ -6,14 +6,13 @@ QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QSlider) -class FloatNumberWidget : public QWidget -{ +class FloatNumberWidget : public QWidget { Q_OBJECT public: - explicit FloatNumberWidget(QWidget *parent=nullptr, bool singleLine=true); + explicit FloatNumberWidget(QWidget* parent = nullptr, bool singleLine = true); void setRange(float min, float max); float value() const; - void setItemName(const QString &name); + void setItemName(const QString& name); void setSliderFixedWidth(float width); public slots: @@ -23,13 +22,13 @@ public slots: signals: void valueChanged(float value); - + private: void updateValueLabel(float value); private: - QLabel *m_label = nullptr; - QSlider *m_slider = nullptr; + QLabel* m_label = nullptr; + QSlider* m_slider = nullptr; QString m_itemName; }; diff --git a/application/sources/flow_layout.cc b/application/sources/flow_layout.cc index 5265543b..ac25eb4b 100644 --- a/application/sources/flow_layout.cc +++ b/application/sources/flow_layout.cc @@ -52,26 +52,29 @@ #include "flow_layout.h" -FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) - : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) +FlowLayout::FlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing) + : QLayout(parent) + , m_hSpace(hSpacing) + , m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing) + : m_hSpace(hSpacing) + , m_vSpace(vSpacing) { setContentsMargins(margin, margin, margin, margin); } FlowLayout::~FlowLayout() { - QLayoutItem *item; + QLayoutItem* item; while ((item = takeAt(0))) delete item; } -void FlowLayout::addItem(QLayoutItem *item) +void FlowLayout::addItem(QLayoutItem* item) { itemList.append(item); } @@ -99,12 +102,12 @@ int FlowLayout::count() const return itemList.size(); } -QLayoutItem *FlowLayout::itemAt(int index) const +QLayoutItem* FlowLayout::itemAt(int index) const { return itemList.value(index); } -QLayoutItem *FlowLayout::takeAt(int index) +QLayoutItem* FlowLayout::takeAt(int index) { if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); @@ -128,7 +131,7 @@ int FlowLayout::heightForWidth(int width) const return height; } -void FlowLayout::setGeometry(const QRect &rect) +void FlowLayout::setGeometry(const QRect& rect) { QLayout::setGeometry(rect); doLayout(rect, false); @@ -142,15 +145,15 @@ QSize FlowLayout::sizeHint() const QSize FlowLayout::minimumSize() const { QSize size; - QLayoutItem *item; + QLayoutItem* item; foreach (item, itemList) size = size.expandedTo(item->minimumSize()); - size += QSize(2*margin(), 2*margin()); + size += QSize(2 * margin(), 2 * margin()); return size; } -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const +int FlowLayout::doLayout(const QRect& rect, bool testOnly) const { int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); @@ -159,9 +162,9 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const int y = effectiveRect.y(); int lineHeight = 0; - QLayoutItem *item; + QLayoutItem* item; foreach (item, itemList) { - QWidget *wid = item->widget(); + QWidget* wid = item->widget(); int spaceX = horizontalSpacing(); if (spaceX == -1) spaceX = wid->style()->layoutSpacing( @@ -189,13 +192,13 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const { - QObject *parent = this->parent(); + QObject* parent = this->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { - QWidget *pw = static_cast(parent); + QWidget* pw = static_cast(parent); return pw->style()->pixelMetric(pm, 0, pw); } else { - return static_cast(parent)->spacing(); + return static_cast(parent)->spacing(); } } diff --git a/application/sources/flow_layout.h b/application/sources/flow_layout.h index 263f0aaf..1984fee6 100644 --- a/application/sources/flow_layout.h +++ b/application/sources/flow_layout.h @@ -55,31 +55,30 @@ #include #include -class FlowLayout : public QLayout -{ +class FlowLayout : public QLayout { public: - explicit FlowLayout(QWidget *parent, int margin=-1, int hSpacing=-1, int vSpacing=-1); - explicit FlowLayout(int margin=-1, int hSpacing=-1, int vSpacing=-1); + explicit FlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); ~FlowLayout(); - void addItem(QLayoutItem *item) override; + void addItem(QLayoutItem* item) override; int horizontalSpacing() const; int verticalSpacing() const; Qt::Orientations expandingDirections() const override; bool hasHeightForWidth() const override; int heightForWidth(int) const override; int count() const override; - QLayoutItem *itemAt(int index) const override; + QLayoutItem* itemAt(int index) const override; QSize minimumSize() const override; - void setGeometry(const QRect &rect) override; + void setGeometry(const QRect& rect) override; QSize sizeHint() const override; - QLayoutItem *takeAt(int index) override; + QLayoutItem* takeAt(int index) override; private: - int doLayout(const QRect &rect, bool testOnly) const; + int doLayout(const QRect& rect, bool testOnly) const; int smartSpacing(QStyle::PixelMetric pm) const; - QList itemList; + QList itemList; int m_hSpace; int m_vSpace; }; diff --git a/application/sources/glb_file.cc b/application/sources/glb_file.cc index a02a55f0..4f197038 100644 --- a/application/sources/glb_file.cc +++ b/application/sources/glb_file.cc @@ -1,29 +1,29 @@ -#include -#include +#include "glb_file.h" +#include "model_mesh.h" +#include "version.h" #include #include -#include #include +#include +#include +#include #include -#include "glb_file.h" -#include "version.h" -#include "model_mesh.h" bool GlbFileWriter::m_enableComment = false; -GlbFileWriter::GlbFileWriter(dust3d::Object &object, - const QString &filename, - QImage *textureImage, - QImage *normalImage, - QImage *ormImage) : - m_filename(filename) +GlbFileWriter::GlbFileWriter(dust3d::Object& object, + const QString& filename, + QImage* textureImage, + QImage* normalImage, + QImage* ormImage) + : m_filename(filename) { - const std::vector> *triangleVertexNormals = object.triangleVertexNormals(); + const std::vector>* triangleVertexNormals = object.triangleVertexNormals(); if (m_outputNormal) { m_outputNormal = nullptr != triangleVertexNormals; } - - const std::vector> *triangleVertexUvs = object.triangleVertexUvs(); + + const std::vector>* triangleVertexUvs = object.triangleVertexUvs(); if (m_outputUv) { m_outputUv = nullptr != triangleVertexUvs; } @@ -31,35 +31,35 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, QDataStream binStream(&m_binByteArray, QIODevice::WriteOnly); binStream.setFloatingPointPrecision(QDataStream::SinglePrecision); binStream.setByteOrder(QDataStream::LittleEndian); - + auto alignBin = [this, &binStream] { while (0 != this->m_binByteArray.size() % 4) { binStream << (quint8)0; } }; - + QDataStream jsonStream(&m_jsonByteArray, QIODevice::WriteOnly); jsonStream.setFloatingPointPrecision(QDataStream::SinglePrecision); jsonStream.setByteOrder(QDataStream::LittleEndian); - + auto alignJson = [this, &jsonStream] { while (0 != this->m_jsonByteArray.size() % 4) { jsonStream << (quint8)' '; } }; - + int bufferViewIndex = 0; int bufferViewFromOffset; - + m_json["asset"]["version"] = "2.0"; m_json["asset"]["generator"] = APP_NAME " " APP_HUMAN_VER; - m_json["scenes"][0]["nodes"] = {0}; - + m_json["scenes"][0]["nodes"] = { 0 }; + m_json["nodes"][0]["mesh"] = 0; std::vector triangleVertexPositions; std::vector triangleVertexOldIndices; - for (const auto &triangleIndices: object.triangles) { + for (const auto& triangleIndices : object.triangles) { for (size_t j = 0; j < 3; ++j) { triangleVertexOldIndices.push_back(triangleIndices[j]); triangleVertexPositions.push_back(object.vertices[triangleIndices[j]]); @@ -68,7 +68,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, int primitiveIndex = 0; if (!triangleVertexPositions.empty()) { - + m_json["meshes"][0]["primitives"][primitiveIndex]["indices"] = bufferViewIndex; m_json["meshes"][0]["primitives"][primitiveIndex]["material"] = primitiveIndex; int attributeIndex = 0; @@ -93,7 +93,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = 1.0; textureIndex++; } - + primitiveIndex++; bufferViewFromOffset = (int)m_binByteArray.size(); @@ -114,7 +114,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size(); m_json["accessors"][bufferViewIndex]["type"] = "SCALAR"; bufferViewIndex++; - + bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; @@ -124,7 +124,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, float maxY = -100; float minZ = 100; float maxZ = -100; - for (const auto &position: triangleVertexPositions) { + for (const auto& position : triangleVertexPositions) { if (position.x() < minX) minX = position.x(); if (position.x() > maxX) @@ -140,7 +140,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, binStream << (float)position.x() << (float)position.y() << (float)position.z(); } Q_ASSERT((int)triangleVertexPositions.size() * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset); - m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexPositions.size() * 3 * sizeof(float); + m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexPositions.size() * 3 * sizeof(float); m_json["bufferViews"][bufferViewIndex]["target"] = 34962; alignBin(); if (m_enableComment) @@ -148,26 +148,26 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["componentType"] = 5126; - m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size(); + m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size(); m_json["accessors"][bufferViewIndex]["type"] = "VEC3"; - m_json["accessors"][bufferViewIndex]["max"] = {maxX, maxY, maxZ}; - m_json["accessors"][bufferViewIndex]["min"] = {minX, minY, minZ}; + m_json["accessors"][bufferViewIndex]["max"] = { maxX, maxY, maxZ }; + m_json["accessors"][bufferViewIndex]["min"] = { minX, minY, minZ }; bufferViewIndex++; - + if (m_outputNormal) { bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; QStringList normalList; - for (const auto &normals: (*triangleVertexNormals)) { - for (const auto &it: normals) { + for (const auto& normals : (*triangleVertexNormals)) { + for (const auto& it : normals) { binStream << (float)it.x() << (float)it.y() << (float)it.z(); if (m_enableComment && m_outputNormal) normalList.append(QString("<%1,%2,%3>").arg(QString::number(it.x())).arg(QString::number(it.y())).arg(QString::number(it.z()))); } } Q_ASSERT((int)triangleVertexNormals->size() * 3 * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset); - m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexNormals->size() * 3 * 3 * sizeof(float); + m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexNormals->size() * 3 * 3 * sizeof(float); m_json["bufferViews"][bufferViewIndex]["target"] = 34962; alignBin(); if (m_enableComment) @@ -175,17 +175,17 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["componentType"] = 5126; - m_json["accessors"][bufferViewIndex]["count"] = triangleVertexNormals->size() * 3; + m_json["accessors"][bufferViewIndex]["count"] = triangleVertexNormals->size() * 3; m_json["accessors"][bufferViewIndex]["type"] = "VEC3"; bufferViewIndex++; } - + if (m_outputUv) { bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; - for (const auto &uvs: (*triangleVertexUvs)) { - for (const auto &it: uvs) + for (const auto& uvs : (*triangleVertexUvs)) { + for (const auto& it : uvs) binStream << (float)it.x() << (float)it.y(); } m_json["bufferViews"][bufferViewIndex]["byteLength"] = m_binByteArray.size() - bufferViewFromOffset; @@ -195,7 +195,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["componentType"] = 5126; - m_json["accessors"][bufferViewIndex]["count"] = triangleVertexUvs->size() * 3; + m_json["accessors"][bufferViewIndex]["count"] = triangleVertexUvs->size() * 3; m_json["accessors"][bufferViewIndex]["type"] = "VEC2"; bufferViewIndex++; } @@ -205,15 +205,15 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["samplers"][0]["minFilter"] = 9987; m_json["samplers"][0]["wrapS"] = 33648; m_json["samplers"][0]["wrapT"] = 33648; - + int imageIndex = 0; int textureIndex = 0; - + // Images should be put in the end of the buffer, because we are not using accessors if (nullptr != textureImage) { m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["source"] = imageIndex; - + bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; @@ -226,14 +226,14 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["mimeType"] = "image/png"; bufferViewIndex++; - + imageIndex++; textureIndex++; } if (nullptr != normalImage) { m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["source"] = imageIndex; - + bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; @@ -246,14 +246,14 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["mimeType"] = "image/png"; bufferViewIndex++; - + imageIndex++; textureIndex++; } if (nullptr != ormImage) { m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["source"] = imageIndex; - + bufferViewFromOffset = (int)m_binByteArray.size(); m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; @@ -266,13 +266,13 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object, m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["mimeType"] = "image/png"; bufferViewIndex++; - + imageIndex++; textureIndex++; } - + m_json["buffers"][0]["byteLength"] = m_binByteArray.size(); - + auto jsonString = m_enableComment ? m_json.dump(4) : m_json.dump(); jsonStream.writeRawData(jsonString.data(), jsonString.size()); alignJson(); @@ -287,50 +287,48 @@ bool GlbFileWriter::save() QDataStream output(&file); output.setFloatingPointPrecision(QDataStream::SinglePrecision); output.setByteOrder(QDataStream::LittleEndian); - + uint32_t headerSize = 12; uint32_t chunk0DescriptionSize = 8; uint32_t chunk1DescriptionSize = 8; - uint32_t fileSize = headerSize + - chunk0DescriptionSize + m_jsonByteArray.size() + - chunk1DescriptionSize + m_binByteArray.size(); - + uint32_t fileSize = headerSize + chunk0DescriptionSize + m_jsonByteArray.size() + chunk1DescriptionSize + m_binByteArray.size(); + qDebug() << "Chunk 0 data size:" << m_jsonByteArray.size(); qDebug() << "Chunk 1 data size:" << m_binByteArray.size(); qDebug() << "File size:" << fileSize; - + //////////// Header //////////// // magic output << (uint32_t)0x46546C67; - + // version output << (uint32_t)0x00000002; - + // length output << (uint32_t)fileSize; - + //////////// Chunk 0 (Json) //////////// - + // length output << (uint32_t)m_jsonByteArray.size(); - + // type output << (uint32_t)0x4E4F534A; - + // data output.writeRawData(m_jsonByteArray.data(), m_jsonByteArray.size()); - + //////////// Chunk 1 (Binary Buffer) /// - + // length output << (uint32_t)m_binByteArray.size(); - + // type output << (uint32_t)0x004E4942; - + // data output.writeRawData(m_binByteArray.data(), m_binByteArray.size()); - + return true; } diff --git a/application/sources/glb_file.h b/application/sources/glb_file.h index d4288ce2..7bd65ab9 100644 --- a/application/sources/glb_file.h +++ b/application/sources/glb_file.h @@ -1,35 +1,37 @@ #ifndef DUST3D_APPLICATION_GLB_FILE_H_ #define DUST3D_APPLICATION_GLB_FILE_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include "json.hpp" #include "document.h" +#include "json.hpp" +#include +#include +#include +#include +#include +#include +#include +#include -class GlbFileWriter : public QObject -{ +class GlbFileWriter : public QObject { Q_OBJECT public: - GlbFileWriter(dust3d::Object &object, - const QString &filename, - QImage *textureImage=nullptr, - QImage *normalImage=nullptr, - QImage *ormImage=nullptr); + GlbFileWriter(dust3d::Object& object, + const QString& filename, + QImage* textureImage = nullptr, + QImage* normalImage = nullptr, + QImage* ormImage = nullptr); bool save(); + private: QString m_filename; bool m_outputNormal = true; bool m_outputUv = true; QByteArray m_binByteArray; QByteArray m_jsonByteArray; + private: nlohmann::json m_json; + public: static bool m_enableComment; }; diff --git a/application/sources/graphics_container_widget.cc b/application/sources/graphics_container_widget.cc index e80fb826..d30afab7 100644 --- a/application/sources/graphics_container_widget.cc +++ b/application/sources/graphics_container_widget.cc @@ -5,47 +5,47 @@ GraphicsContainerWidget::GraphicsContainerWidget() setMouseTracking(true); } -void GraphicsContainerWidget::resizeEvent(QResizeEvent *event) +void GraphicsContainerWidget::resizeEvent(QResizeEvent* event) { if (m_graphicsWidget && m_graphicsWidget->size() != event->size()) emit containerSizeChanged(event->size()); } -void GraphicsContainerWidget::mousePressEvent(QMouseEvent *event) +void GraphicsContainerWidget::mousePressEvent(QMouseEvent* event) { if (m_modelWidget) m_modelWidget->inputMousePressEventFromOtherWidget(event); } -void GraphicsContainerWidget::mouseMoveEvent(QMouseEvent *event) +void GraphicsContainerWidget::mouseMoveEvent(QMouseEvent* event) { if (m_modelWidget) m_modelWidget->inputMouseMoveEventFromOtherWidget(event); } -void GraphicsContainerWidget::mouseReleaseEvent(QMouseEvent *event) +void GraphicsContainerWidget::mouseReleaseEvent(QMouseEvent* event) { if (m_modelWidget) m_modelWidget->inputMouseReleaseEventFromOtherWidget(event); } -void GraphicsContainerWidget::wheelEvent(QWheelEvent *event) +void GraphicsContainerWidget::wheelEvent(QWheelEvent* event) { if (m_graphicsWidget) { m_graphicsWidget->inputWheelEventFromOtherWidget(event); return; } - + if (m_modelWidget) m_modelWidget->inputWheelEventFromOtherWidget(event); } -void GraphicsContainerWidget::setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget) +void GraphicsContainerWidget::setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget) { m_graphicsWidget = graphicsWidget; } -void GraphicsContainerWidget::setModelWidget(ModelWidget *modelWidget) +void GraphicsContainerWidget::setModelWidget(ModelWidget* modelWidget) { m_modelWidget = modelWidget; } diff --git a/application/sources/graphics_container_widget.h b/application/sources/graphics_container_widget.h index c5e706b5..d82137d8 100644 --- a/application/sources/graphics_container_widget.h +++ b/application/sources/graphics_container_widget.h @@ -1,31 +1,33 @@ #ifndef DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ #define DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ -#include -#include -#include -#include #include "model_widget.h" #include "skeleton_graphics_widget.h" +#include +#include +#include +#include -class GraphicsContainerWidget : public QWidget -{ +class GraphicsContainerWidget : public QWidget { Q_OBJECT signals: void containerSizeChanged(QSize size); + public: GraphicsContainerWidget(); - void setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget); - void setModelWidget(ModelWidget *modelWidget); + void setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget); + void setModelWidget(ModelWidget* modelWidget); + protected: - void resizeEvent(QResizeEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void wheelEvent(QWheelEvent *event) override; + void resizeEvent(QResizeEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + private: - ModelWidget *m_modelWidget = nullptr; - SkeletonGraphicsWidget *m_graphicsWidget = nullptr; + ModelWidget* m_modelWidget = nullptr; + SkeletonGraphicsWidget* m_graphicsWidget = nullptr; }; #endif diff --git a/application/sources/horizontal_line_widget.cc b/application/sources/horizontal_line_widget.cc index 2a11e405..96b11613 100644 --- a/application/sources/horizontal_line_widget.cc +++ b/application/sources/horizontal_line_widget.cc @@ -1,7 +1,7 @@ #include "horizontal_line_widget.h" -HorizontalLineWidget::HorizontalLineWidget() : - QWidget() +HorizontalLineWidget::HorizontalLineWidget() + : QWidget() { setFixedHeight(1); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); diff --git a/application/sources/horizontal_line_widget.h b/application/sources/horizontal_line_widget.h index a2b72dbd..7420ba2e 100644 --- a/application/sources/horizontal_line_widget.h +++ b/application/sources/horizontal_line_widget.h @@ -3,8 +3,7 @@ #include -class HorizontalLineWidget : public QWidget -{ +class HorizontalLineWidget : public QWidget { Q_OBJECT public: HorizontalLineWidget(); diff --git a/application/sources/image_forever.cc b/application/sources/image_forever.cc index d6756c49..115c2259 100644 --- a/application/sources/image_forever.cc +++ b/application/sources/image_forever.cc @@ -1,19 +1,18 @@ -#include +#include "image_forever.h" #include #include #include -#include "image_forever.h" +#include -struct ImageForeverItem -{ - QImage *image; +struct ImageForeverItem { + QImage* image; dust3d::Uuid id; - QByteArray *imageByteArray; + QByteArray* imageByteArray; }; static std::map g_foreverMap; static QMutex g_mapMutex; -const QImage *ImageForever::get(const dust3d::Uuid &id) +const QImage* ImageForever::get(const dust3d::Uuid& id) { QMutexLocker locker(&g_mapMutex); auto findResult = g_foreverMap.find(id); @@ -22,7 +21,7 @@ const QImage *ImageForever::get(const dust3d::Uuid &id) return findResult->second.image; } -void ImageForever::copy(const dust3d::Uuid &id, QImage &image) +void ImageForever::copy(const dust3d::Uuid& id, QImage& image) { QMutexLocker locker(&g_mapMutex); auto findResult = g_foreverMap.find(id); @@ -31,7 +30,7 @@ void ImageForever::copy(const dust3d::Uuid &id, QImage &image) image = *findResult->second.image; } -const QByteArray *ImageForever::getPngByteArray(const dust3d::Uuid &id) +const QByteArray* ImageForever::getPngByteArray(const dust3d::Uuid& id) { QMutexLocker locker(&g_mapMutex); auto findResult = g_foreverMap.find(id); @@ -40,7 +39,7 @@ const QByteArray *ImageForever::getPngByteArray(const dust3d::Uuid &id) return findResult->second.imageByteArray; } -dust3d::Uuid ImageForever::add(const QImage *image, dust3d::Uuid toId) +dust3d::Uuid ImageForever::add(const QImage* image, dust3d::Uuid toId) { QMutexLocker locker(&g_mapMutex); if (nullptr == image) @@ -48,16 +47,16 @@ dust3d::Uuid ImageForever::add(const QImage *image, dust3d::Uuid toId) dust3d::Uuid newId = toId.isNull() ? dust3d::Uuid::createUuid() : toId; if (g_foreverMap.find(newId) != g_foreverMap.end()) return newId; - QImage *newImage = new QImage(*image); - QByteArray *imageByteArray = new QByteArray(); + QImage* newImage = new QImage(*image); + QByteArray* imageByteArray = new QByteArray(); QBuffer pngBuffer(imageByteArray); pngBuffer.open(QIODevice::WriteOnly); newImage->save(&pngBuffer, "PNG"); - g_foreverMap[newId] = {newImage, newId, imageByteArray}; + g_foreverMap[newId] = { newImage, newId, imageByteArray }; return newId; } -void ImageForever::remove(const dust3d::Uuid &id) +void ImageForever::remove(const dust3d::Uuid& id) { QMutexLocker locker(&g_mapMutex); auto findImage = g_foreverMap.find(id); diff --git a/application/sources/image_forever.h b/application/sources/image_forever.h index 52abb02b..307ed24f 100644 --- a/application/sources/image_forever.h +++ b/application/sources/image_forever.h @@ -1,18 +1,17 @@ #ifndef DUST3D_APPLICATION_IMAGE_FOREVER_H_ #define DUST3D_APPLICATION_IMAGE_FOREVER_H_ -#include #include +#include #include -class ImageForever -{ +class ImageForever { public: - static const QImage *get(const dust3d::Uuid &id); - static void copy(const dust3d::Uuid &id, QImage &image); - static const QByteArray *getPngByteArray(const dust3d::Uuid &id); - static dust3d::Uuid add(const QImage *image, dust3d::Uuid toId=dust3d::Uuid()); - static void remove(const dust3d::Uuid &id); + static const QImage* get(const dust3d::Uuid& id); + static void copy(const dust3d::Uuid& id, QImage& image); + static const QByteArray* getPngByteArray(const dust3d::Uuid& id); + static dust3d::Uuid add(const QImage* image, dust3d::Uuid toId = dust3d::Uuid()); + static void remove(const dust3d::Uuid& id); }; #endif diff --git a/application/sources/image_preview_widget.cc b/application/sources/image_preview_widget.cc index fa5a6391..509c9c07 100644 --- a/application/sources/image_preview_widget.cc +++ b/application/sources/image_preview_widget.cc @@ -1,28 +1,28 @@ -#include #include "image_preview_widget.h" +#include -ImagePreviewWidget::ImagePreviewWidget(QWidget *parent) : - QWidget(parent) +ImagePreviewWidget::ImagePreviewWidget(QWidget* parent) + : QWidget(parent) { } -void ImagePreviewWidget::updateImage(const QImage &image) +void ImagePreviewWidget::updateImage(const QImage& image) { m_image = image; update(); } -void ImagePreviewWidget::updateBackgroundColor(const QColor &color) +void ImagePreviewWidget::updateBackgroundColor(const QColor& color) { m_backgroundColor = color; } -void ImagePreviewWidget::mousePressEvent(QMouseEvent *event) +void ImagePreviewWidget::mousePressEvent(QMouseEvent* event) { emit clicked(); } -void ImagePreviewWidget::paintEvent(QPaintEvent *event) +void ImagePreviewWidget::paintEvent(QPaintEvent* event) { QPainter painter(this); if (!m_image.isNull()) @@ -30,4 +30,3 @@ void ImagePreviewWidget::paintEvent(QPaintEvent *event) else painter.fillRect(QRect(0, 0, width(), height()), QBrush(m_backgroundColor)); } - diff --git a/application/sources/image_preview_widget.h b/application/sources/image_preview_widget.h index bb46ee26..cda5f08e 100644 --- a/application/sources/image_preview_widget.h +++ b/application/sources/image_preview_widget.h @@ -1,30 +1,30 @@ #ifndef DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ #define DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ -#include #include -#include #include +#include +#include -class ImagePreviewWidget : public QWidget -{ +class ImagePreviewWidget : public QWidget { Q_OBJECT signals: void clicked(); + public: - ImagePreviewWidget(QWidget *parent=nullptr); - void updateImage(const QImage &image); - void updateBackgroundColor(const QColor &color); - + ImagePreviewWidget(QWidget* parent = nullptr); + void updateImage(const QImage& image); + void updateBackgroundColor(const QColor& color); + protected: - void paintEvent(QPaintEvent *event); - void mousePressEvent(QMouseEvent *event); - + void paintEvent(QPaintEvent* event); + void mousePressEvent(QMouseEvent* event); + private: QImage m_image; QColor m_backgroundColor; - - void resizeImage(QImage *image, const QSize &newSize); + + void resizeImage(QImage* image, const QSize& newSize); }; #endif diff --git a/application/sources/info_label.cc b/application/sources/info_label.cc index 066e8b8a..5bc81e46 100644 --- a/application/sources/info_label.cc +++ b/application/sources/info_label.cc @@ -1,25 +1,25 @@ -#include #include "info_label.h" #include "theme.h" +#include -InfoLabel::InfoLabel(const QString &text, QWidget *parent) : - QWidget(parent) +InfoLabel::InfoLabel(const QString& text, QWidget* parent) + : QWidget(parent) { m_icon = new QLabel(QChar(fa::infocircle)); Theme::initAwesomeLabel(m_icon); - + m_label = new QLabel(text); m_label->setWordWrap(true); - - QHBoxLayout *mainLayout = new QHBoxLayout; + + QHBoxLayout* mainLayout = new QHBoxLayout; mainLayout->addWidget(m_icon); mainLayout->addWidget(m_label); mainLayout->addStretch(); - + setLayout(mainLayout); } -void InfoLabel::setText(const QString &text) +void InfoLabel::setText(const QString& text) { m_label->setText(text); } diff --git a/application/sources/info_label.h b/application/sources/info_label.h index 9308c607..52b1d806 100644 --- a/application/sources/info_label.h +++ b/application/sources/info_label.h @@ -1,18 +1,18 @@ #ifndef DUST3D_APPLICATION_INFO_LABEL_H_ #define DUST3D_APPLICATION_INFO_LABEL_H_ -#include #include +#include #include -class InfoLabel : public QWidget -{ +class InfoLabel : public QWidget { public: - InfoLabel(const QString &text=QString(), QWidget *parent=nullptr); - void setText(const QString &text); + InfoLabel(const QString& text = QString(), QWidget* parent = nullptr); + void setText(const QString& text); + private: - QLabel *m_label = nullptr; - QLabel *m_icon = nullptr; + QLabel* m_label = nullptr; + QLabel* m_icon = nullptr; }; #endif diff --git a/application/sources/int_number_widget.cc b/application/sources/int_number_widget.cc index b067ae79..88df3967 100644 --- a/application/sources/int_number_widget.cc +++ b/application/sources/int_number_widget.cc @@ -1,11 +1,11 @@ -#include +#include "int_number_widget.h" +#include "theme.h" #include #include -#include "theme.h" -#include "int_number_widget.h" +#include -IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) : - QWidget(parent) +IntNumberWidget::IntNumberWidget(QWidget* parent, bool singleLine) + : QWidget(parent) { m_slider = new QSlider(Qt::Horizontal, this); m_slider->setRange(0, 100); @@ -18,8 +18,8 @@ IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) : updateValueLabel(value); emit valueChanged(value); }); - - QBoxLayout *layout = nullptr; + + QBoxLayout* layout = nullptr; if (singleLine) { layout = new QHBoxLayout(this); layout->setMargin(2); @@ -42,7 +42,7 @@ void IntNumberWidget::updateValueLabel(int value) m_label->setText(m_itemName + ": " + valueString); } -void IntNumberWidget::setItemName(const QString &name) +void IntNumberWidget::setItemName(const QString& name) { m_itemName = name; updateValueLabel(value()); diff --git a/application/sources/int_number_widget.h b/application/sources/int_number_widget.h index 50045f09..eb311af0 100644 --- a/application/sources/int_number_widget.h +++ b/application/sources/int_number_widget.h @@ -6,14 +6,13 @@ QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QSlider) -class IntNumberWidget : public QWidget -{ +class IntNumberWidget : public QWidget { Q_OBJECT public: - explicit IntNumberWidget(QWidget *parent = nullptr, bool singleLine=true); + explicit IntNumberWidget(QWidget* parent = nullptr, bool singleLine = true); void setRange(int min, int max); int value() const; - void setItemName(const QString &name); + void setItemName(const QString& name); public slots: void increaseValue(); @@ -22,13 +21,13 @@ public slots: signals: void valueChanged(int value); - + private: void updateValueLabel(int value); private: - QLabel *m_label = nullptr; - QSlider *m_slider = nullptr; + QLabel* m_label = nullptr; + QSlider* m_slider = nullptr; QString m_itemName; }; diff --git a/application/sources/log_browser.cc b/application/sources/log_browser.cc index 6e363142..032cf3fb 100644 --- a/application/sources/log_browser.cc +++ b/application/sources/log_browser.cc @@ -1,17 +1,17 @@ -#include -#include #include "log_browser.h" #include "log_browser_dialog.h" +#include +#include bool LogBrowser::m_enableOutputToFile = true; -LogBrowser::LogBrowser(QObject *parent) : - QObject(parent) +LogBrowser::LogBrowser(QObject* parent) + : QObject(parent) { qRegisterMetaType("QtMsgType"); m_browserDialog = new LogBrowserDialog; connect(this, &LogBrowser::sendMessage, m_browserDialog, &LogBrowserDialog::outputMessage, Qt::QueuedConnection); - + if (m_enableOutputToFile) { QString filePath = "application.log"; m_outputTo = fopen(filePath.toUtf8().constData(), "w"); @@ -42,7 +42,7 @@ bool LogBrowser::isDialogVisible() return m_browserDialog->isVisible(); } -void LogBrowser::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line) +void LogBrowser::outputMessage(QtMsgType type, const QString& msg, const QString& source, int line) { if (m_outputTo) { fprintf(m_outputTo, "[%s:%d]: %s\n", source.toUtf8().constData(), line, msg.toUtf8().constData()); diff --git a/application/sources/log_browser.h b/application/sources/log_browser.h index c3ae8c61..cbbd9f2a 100644 --- a/application/sources/log_browser.h +++ b/application/sources/log_browser.h @@ -6,25 +6,24 @@ class LogBrowserDialog; -class LogBrowser : public QObject -{ +class LogBrowser : public QObject { Q_OBJECT public: - explicit LogBrowser(QObject *parent=0); + explicit LogBrowser(QObject* parent = 0); ~LogBrowser(); public slots: - void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line); + void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line); void showDialog(); void hideDialog(); bool isDialogVisible(); signals: - void sendMessage(QtMsgType type, const QString &msg, const QString &source, int line); + void sendMessage(QtMsgType type, const QString& msg, const QString& source, int line); private: - LogBrowserDialog *m_browserDialog = nullptr; - FILE *m_outputTo = nullptr; + LogBrowserDialog* m_browserDialog = nullptr; + FILE* m_outputTo = nullptr; static bool m_enableOutputToFile; }; diff --git a/application/sources/log_browser_dialog.cc b/application/sources/log_browser_dialog.cc index 522c4bc3..98481de8 100644 --- a/application/sources/log_browser_dialog.cc +++ b/application/sources/log_browser_dialog.cc @@ -1,30 +1,30 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "version.h" #include "log_browser_dialog.h" #include "document_window.h" +#include "version.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -LogBrowserDialog::LogBrowserDialog(QWidget *parent) : - QDialog(parent) +LogBrowserDialog::LogBrowserDialog(QWidget* parent) + : QDialog(parent) { setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); - - QVBoxLayout *layout = new QVBoxLayout; + + QVBoxLayout* layout = new QVBoxLayout; setLayout(layout); m_browser = new QTextBrowser(this); layout->addWidget(m_browser); - QHBoxLayout *buttonLayout = new QHBoxLayout; + QHBoxLayout* buttonLayout = new QHBoxLayout; buttonLayout->setContentsMargins(0, 0, 0, 0); layout->addLayout(buttonLayout); @@ -41,20 +41,17 @@ LogBrowserDialog::LogBrowserDialog(QWidget *parent) : connect(m_saveButton, SIGNAL(clicked()), this, SLOT(save())); resize(600, 300); - + setWindowTitle(applicationTitle(tr("Debug"))); - + hide(); } - LogBrowserDialog::~LogBrowserDialog() { - } - -void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line) +void LogBrowserDialog::outputMessage(QtMsgType type, const QString& msg, const QString& source, int line) { switch (type) { case QtDebugMsg: @@ -79,7 +76,6 @@ void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg, const Q } } - void LogBrowserDialog::save() { QString saveFileName = QFileDialog::getSaveFileName(this, @@ -95,8 +91,8 @@ void LogBrowserDialog::save() QMessageBox::warning(this, tr("Error"), QString(tr("File '%1'
cannot be opened for writing.

" - "The log output could not be saved!
")) - .arg(saveFileName)); + "The log output could not be saved!")) + .arg(saveFileName)); return; } @@ -105,7 +101,7 @@ void LogBrowserDialog::save() file.close(); } -void LogBrowserDialog::closeEvent(QCloseEvent *e) +void LogBrowserDialog::closeEvent(QCloseEvent* e) { if (0 == DocumentWindow::total()) { e->accept(); @@ -115,7 +111,7 @@ void LogBrowserDialog::closeEvent(QCloseEvent *e) hide(); } -void LogBrowserDialog::keyPressEvent(QKeyEvent *e) +void LogBrowserDialog::keyPressEvent(QKeyEvent* e) { e->ignore(); } diff --git a/application/sources/log_browser_dialog.h b/application/sources/log_browser_dialog.h index 09cdf752..50a35d57 100644 --- a/application/sources/log_browser_dialog.h +++ b/application/sources/log_browser_dialog.h @@ -6,26 +6,25 @@ class QTextBrowser; class QPushButton; -class LogBrowserDialog : public QDialog -{ +class LogBrowserDialog : public QDialog { Q_OBJECT public: - LogBrowserDialog(QWidget *parent = 0); + LogBrowserDialog(QWidget* parent = 0); ~LogBrowserDialog(); public slots: - void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line); + void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line); protected slots: void save(); protected: - virtual void keyPressEvent(QKeyEvent *e); - virtual void closeEvent(QCloseEvent *e); + virtual void keyPressEvent(QKeyEvent* e); + virtual void closeEvent(QCloseEvent* e); - QTextBrowser *m_browser; - QPushButton *m_clearButton; - QPushButton *m_saveButton; + QTextBrowser* m_browser; + QPushButton* m_clearButton; + QPushButton* m_saveButton; }; #endif diff --git a/application/sources/main.cc b/application/sources/main.cc index 9f8ddfbd..e6bf25d0 100644 --- a/application/sources/main.cc +++ b/application/sources/main.cc @@ -1,41 +1,40 @@ -#include -#include -#include -#include -#include -#include -#include "document_window.h" #include "document.h" +#include "document_window.h" #include "theme.h" #include "version.h" +#include +#include +#include +#include +#include +#include -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { QApplication app(argc, argv); - + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setVersion(3, 3); QSurfaceFormat::setDefaultFormat(format); - + Theme::initialize(); - + QCoreApplication::setApplicationName(APP_NAME); QCoreApplication::setOrganizationName(APP_COMPANY); QCoreApplication::setOrganizationDomain(APP_HOMEPAGE_URL); - + //freopen("dust3d.log", "w", stdout); //setvbuf(stdout, 0, _IONBF, 0); - - DocumentWindow *firstWindow = DocumentWindow::createDocumentWindow(); + + DocumentWindow* firstWindow = DocumentWindow::createDocumentWindow(); QStringList openFileList; QStringList waitingExportList; bool toggleColor = false; for (int i = 1; i < argc; ++i) { if ('-' == argv[i][0]) { - if (0 == strcmp(argv[i], "-output") || - 0 == strcmp(argv[i], "-o")) { + if (0 == strcmp(argv[i], "-output") || 0 == strcmp(argv[i], "-o")) { ++i; if (i < argc) waitingExportList.append(argv[i]); @@ -55,12 +54,12 @@ int main(int argc, char *argv[]) continue; } } - + int finishedExportFileNum = 0; int totalExportFileNum = 0; int succeedExportNum = 0; int exitCode = -1; - std::vector windowList; + std::vector windowList; auto checkToSafelyExit = [&]() { if (-1 == exitCode) return; @@ -76,17 +75,16 @@ int main(int argc, char *argv[]) windowList.push_back(DocumentWindow::createDocumentWindow()); } if (toggleColor) { - for (auto &it: windowList) + for (auto& it : windowList) it->toggleRenderColor(); } - if (!waitingExportList.empty() && - openFileList.size() == 1) { + if (!waitingExportList.empty() && openFileList.size() == 1) { totalExportFileNum = openFileList.size() * waitingExportList.size(); for (int i = 0; i < openFileList.size(); ++i) { QObject::connect(windowList[i], &DocumentWindow::workingStatusChanged, &app, checkToSafelyExit); } for (int i = 0; i < openFileList.size(); ++i) { - QObject::connect(windowList[i], &DocumentWindow::waitingExportFinished, &app, [&](const QString &filename, bool isSuccessful) { + QObject::connect(windowList[i], &DocumentWindow::waitingExportFinished, &app, [&](const QString& filename, bool isSuccessful) { qDebug() << "Export to" << filename << (isSuccessful ? "isSuccessful" : "failed"); ++finishedExportFileNum; if (isSuccessful) @@ -112,6 +110,6 @@ int main(int argc, char *argv[]) windowList[i]->openPathAs(openFileList[i], openFileList[i]); } } - + return app.exec(); } diff --git a/application/sources/material.cc b/application/sources/material.cc index f7c3b52a..c5c1026c 100644 --- a/application/sources/material.cc +++ b/application/sources/material.cc @@ -1,21 +1,21 @@ #include "material.h" #include "image_forever.h" -void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot &snapshot, - const dust3d::Uuid &materialId, - MaterialTextures &materialTextures, - float &tileScale) +void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot& snapshot, + const dust3d::Uuid& materialId, + MaterialTextures& materialTextures, + float& tileScale) { auto materialIdString = materialId.toString(); - for (const auto &materialItem: snapshot.materials) { + for (const auto& materialItem : snapshot.materials) { if (materialIdString != dust3d::String::valueOrEmpty(materialItem.first, "id")) continue; - for (const auto &layer: materialItem.second) { + for (const auto& layer : materialItem.second) { //FIXME: Only support one layer currently auto findTileScale = layer.first.find("tileScale"); if (findTileScale != layer.first.end()) tileScale = dust3d::String::toFloat(findTileScale->second); - for (const auto &mapItem: layer.second) { + for (const auto& mapItem : layer.second) { auto textureType = dust3d::TextureTypeFromString(dust3d::String::valueOrEmpty(mapItem, "for").c_str()); if (textureType != dust3d::TextureType::None) { int index = (int)textureType - 1; diff --git a/application/sources/material.h b/application/sources/material.h index 2cf7466a..b69357b5 100644 --- a/application/sources/material.h +++ b/application/sources/material.h @@ -2,18 +2,17 @@ #define DUST3D_APPLICATION_MATERIAL_H_ #include -#include -#include #include +#include +#include -struct MaterialTextures -{ - const QImage *textureImages[(int)dust3d::TextureType::Count - 1] = {nullptr}; +struct MaterialTextures { + const QImage* textureImages[(int)dust3d::TextureType::Count - 1] = { nullptr }; }; -void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot &snapshot, - const dust3d::Uuid &materialId, - MaterialTextures &materialTextures, - float &tileScale); +void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot& snapshot, + const dust3d::Uuid& materialId, + MaterialTextures& materialTextures, + float& tileScale); #endif diff --git a/application/sources/material_edit_widget.cc b/application/sources/material_edit_widget.cc index 27870002..bcb7df51 100644 --- a/application/sources/material_edit_widget.cc +++ b/application/sources/material_edit_widget.cc @@ -1,49 +1,49 @@ -#include -#include -#include +#include "material_edit_widget.h" +#include "document.h" +#include "float_number_widget.h" +#include "horizontal_line_widget.h" +#include "image_forever.h" +#include "theme.h" +#include "version.h" +#include #include #include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include #include -#include "theme.h" -#include "material_edit_widget.h" -#include "float_number_widget.h" -#include "version.h" -#include "image_forever.h" -#include "document.h" -#include "horizontal_line_widget.h" +#include +#include -ImagePreviewWidget *MaterialEditWidget::createMapButton() +ImagePreviewWidget* MaterialEditWidget::createMapButton() { - ImagePreviewWidget *mapButton = new ImagePreviewWidget; + ImagePreviewWidget* mapButton = new ImagePreviewWidget; mapButton->setFixedSize(Theme::partPreviewImageSize * 2, Theme::partPreviewImageSize * 2); updateMapButtonBackground(mapButton, nullptr); return mapButton; } -QImage *MaterialEditWidget::pickImage() +QImage* MaterialEditWidget::pickImage() { QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), - tr("Image Files (*.png *.jpg *.bmp)")).trimmed(); + tr("Image Files (*.png *.jpg *.bmp)")) + .trimmed(); if (fileName.isEmpty()) return nullptr; - QImage *image = new QImage(); + QImage* image = new QImage(); if (!image->load(fileName)) return nullptr; return image; } -MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent) : - QDialog(parent), - m_document(document) +MaterialEditWidget::MaterialEditWidget(const Document* document, QWidget* parent) + : QDialog(parent) + , m_document(document) { setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); - + m_layers.resize(1); m_previewWidget = new ModelWidget(this); @@ -51,24 +51,24 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent m_previewWidget->resize(512, 512); m_previewWidget->move(-128, -128); m_previewWidget->setNotGraphics(true); - + QFont nameFont; nameFont.setWeight(QFont::Light); nameFont.setBold(false); - - QGridLayout *mapLayout = new QGridLayout; + + QGridLayout* mapLayout = new QGridLayout; int row = 0; int col = 0; for (int i = 1; i < (int)dust3d::TextureType::Count; i++) { - QVBoxLayout *textureManageLayout = new QVBoxLayout; - + QVBoxLayout* textureManageLayout = new QVBoxLayout; + MaterialMap item; item.forWhat = (dust3d::TextureType)i; m_layers[0].maps.push_back(item); - - ImagePreviewWidget *imageButton = createMapButton(); + + ImagePreviewWidget* imageButton = createMapButton(); connect(imageButton, &ImagePreviewWidget::clicked, [=]() { - QImage *image = pickImage(); + QImage* image = pickImage(); if (nullptr == image) return; m_layers[0].maps[(int)i - 1].imageId = ImageForever::add(image); @@ -76,41 +76,41 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent delete image; emit layersAdjusted(); }); - - QLabel *nameLabel = new QLabel(tr(dust3d::TextureTypeToDispName(item.forWhat).c_str())); + + QLabel* nameLabel = new QLabel(tr(dust3d::TextureTypeToDispName(item.forWhat).c_str())); nameLabel->setFont(nameFont); - - QPushButton *eraser = new QPushButton(QChar(fa::eraser)); + + QPushButton* eraser = new QPushButton(QChar(fa::eraser)); Theme::initAwesomeToolButton(eraser); - + connect(eraser, &QPushButton::clicked, [=]() { m_layers[0].maps[(int)i - 1].imageId = dust3d::Uuid(); updateMapButtonBackground(imageButton, nullptr); emit layersAdjusted(); }); - - QHBoxLayout *textureTitleLayout = new QHBoxLayout; + + QHBoxLayout* textureTitleLayout = new QHBoxLayout; textureTitleLayout->addWidget(eraser); textureTitleLayout->addWidget(nameLabel); textureTitleLayout->addStretch(); - + textureManageLayout->addWidget(imageButton); textureManageLayout->addLayout(textureTitleLayout); m_textureMapButtons[i - 1] = imageButton; - + mapLayout->addLayout(textureManageLayout, row, col++); if (col == 2) { col = 0; row++; } } - - QVBoxLayout *rightLayout = new QVBoxLayout; + + QVBoxLayout* rightLayout = new QVBoxLayout; rightLayout->addStretch(); rightLayout->addLayout(mapLayout); rightLayout->addStretch(); - QHBoxLayout *paramtersLayout = new QHBoxLayout; + QHBoxLayout* paramtersLayout = new QHBoxLayout; paramtersLayout->setContentsMargins(256, 0, 0, 0); paramtersLayout->addStretch(); paramtersLayout->addLayout(rightLayout); @@ -120,41 +120,41 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent m_unsaved = true; updateTitle(); }); - QPushButton *saveButton = new QPushButton(tr("Save")); + QPushButton* saveButton = new QPushButton(tr("Save")); connect(saveButton, &QPushButton::clicked, this, &MaterialEditWidget::save); saveButton->setDefault(true); - - FloatNumberWidget *tileScaleWidget = new FloatNumberWidget; + + FloatNumberWidget* tileScaleWidget = new FloatNumberWidget; tileScaleWidget->setItemName(tr("Tile Scale")); tileScaleWidget->setRange(0.01, 1.0); tileScaleWidget->setValue(m_layers[0].tileScale); - + m_tileScaleSlider = tileScaleWidget; - + connect(tileScaleWidget, &FloatNumberWidget::valueChanged, [=](float value) { m_layers[0].tileScale = value; emit layersAdjusted(); }); - - QPushButton *tileScaleEraser = new QPushButton(QChar(fa::eraser)); + + QPushButton* tileScaleEraser = new QPushButton(QChar(fa::eraser)); Theme::initAwesomeToolButton(tileScaleEraser); - + connect(tileScaleEraser, &QPushButton::clicked, [=]() { tileScaleWidget->setValue(1.0); }); - - QHBoxLayout *tileScaleLayout = new QHBoxLayout; + + QHBoxLayout* tileScaleLayout = new QHBoxLayout; tileScaleLayout->addWidget(tileScaleEraser); tileScaleLayout->addWidget(tileScaleWidget); tileScaleLayout->addStretch(); - QHBoxLayout *baseInfoLayout = new QHBoxLayout; + QHBoxLayout* baseInfoLayout = new QHBoxLayout; baseInfoLayout->addWidget(new QLabel(tr("Name"))); baseInfoLayout->addWidget(m_nameEdit); baseInfoLayout->addStretch(); baseInfoLayout->addWidget(saveButton); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addLayout(paramtersLayout); mainLayout->addStretch(); mainLayout->addWidget(new HorizontalLineWidget()); @@ -176,7 +176,7 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent updateTitle(); } -void MaterialEditWidget::updateMapButtonBackground(ImagePreviewWidget *button, const QImage *image) +void MaterialEditWidget::updateMapButtonBackground(ImagePreviewWidget* button, const QImage* image) { if (nullptr == image) button->updateImage(QImage()); @@ -189,7 +189,7 @@ void MaterialEditWidget::reject() close(); } -void MaterialEditWidget::closeEvent(QCloseEvent *event) +void MaterialEditWidget::closeEvent(QCloseEvent* event) { if (m_unsaved && !m_closed) { QMessageBox::StandardButton answer = QMessageBox::question(this, @@ -235,7 +235,7 @@ void MaterialEditWidget::updatePreview() qDebug() << "Material preview generating.."; - QThread *thread = new QThread; + QThread* thread = new QThread; m_materialPreviewsGenerator = new MaterialPreviewsGenerator(); m_materialPreviewsGenerator->addMaterial(dust3d::Uuid(), m_layers); m_materialPreviewsGenerator->moveToThread(thread); @@ -279,7 +279,7 @@ void MaterialEditWidget::updateTitle() setWindowTitle(applicationTitle(tr("New") + (m_unsaved ? "*" : ""))); return; } - const Material *material = m_document->findMaterial(m_materialId); + const Material* material = m_document->findMaterial(m_materialId); if (nullptr == material) { qDebug() << "Find material failed:" << m_materialId; return; @@ -299,9 +299,9 @@ void MaterialEditWidget::setEditMaterialLayers(std::vector layers m_layers[0].maps[i - 1].imageId = dust3d::Uuid(); } if (!layers.empty()) { - for (const auto &layer: layers) { + for (const auto& layer : layers) { m_layers[0].tileScale = layer.tileScale; - for (const auto &mapItem: layer.maps) { + for (const auto& mapItem : layer.maps) { int index = (int)mapItem.forWhat - 1; if (index >= 0 && index < (int)dust3d::TextureType::Count - 1) { m_layers[0].maps[index].imageId = mapItem.imageId; diff --git a/application/sources/material_edit_widget.h b/application/sources/material_edit_widget.h index d4aca1a1..63359f8a 100644 --- a/application/sources/material_edit_widget.h +++ b/application/sources/material_edit_widget.h @@ -1,26 +1,24 @@ #ifndef DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_ -#include -#include -#include -#include -#include "model_widget.h" -#include "material_previews_generator.h" -#include "image_preview_widget.h" #include "float_number_widget.h" +#include "image_preview_widget.h" #include "material_layer.h" +#include "material_previews_generator.h" +#include "model_widget.h" +#include +#include +#include +#include class Document; -enum class PopupWidgetType -{ +enum class PopupWidgetType { PitchYawRoll, Intersection }; -class MaterialEditWidget : public QDialog -{ +class MaterialEditWidget : public QDialog { Q_OBJECT signals: void addMaterial(dust3d::Uuid materialId, QString name, std::vector layers); @@ -28,8 +26,9 @@ signals: void setMaterialLayers(dust3d::Uuid materialId, std::vector layers); void renameMaterial(dust3d::Uuid materialId, QString name); void layersAdjusted(); + public: - MaterialEditWidget(const Document *document, QWidget *parent=nullptr); + MaterialEditWidget(const Document* document, QWidget* parent = nullptr); ~MaterialEditWidget(); public slots: void updatePreview(); @@ -40,25 +39,27 @@ public slots: void save(); void clearUnsaveState(); void previewReady(); + protected: QSize sizeHint() const override; - void closeEvent(QCloseEvent *event) override; + void closeEvent(QCloseEvent* event) override; void reject() override; + private: - void updateMapButtonBackground(ImagePreviewWidget *button, const QImage *image); - ImagePreviewWidget *createMapButton(); - QImage *pickImage(); - const Document *m_document = nullptr; - MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr; - ModelWidget *m_previewWidget = nullptr; - FloatNumberWidget *m_tileScaleSlider = nullptr; + void updateMapButtonBackground(ImagePreviewWidget* button, const QImage* image); + ImagePreviewWidget* createMapButton(); + QImage* pickImage(); + const Document* m_document = nullptr; + MaterialPreviewsGenerator* m_materialPreviewsGenerator = nullptr; + ModelWidget* m_previewWidget = nullptr; + FloatNumberWidget* m_tileScaleSlider = nullptr; bool m_isPreviewDirty = false; bool m_closed = false; dust3d::Uuid m_materialId; bool m_unsaved = false; - QLineEdit *m_nameEdit = nullptr; + QLineEdit* m_nameEdit = nullptr; std::vector m_layers; - ImagePreviewWidget *m_textureMapButtons[(int)dust3d::TextureType::Count - 1] = {nullptr}; + ImagePreviewWidget* m_textureMapButtons[(int)dust3d::TextureType::Count - 1] = { nullptr }; }; #endif diff --git a/application/sources/material_layer.h b/application/sources/material_layer.h index c24655f8..9d7cacba 100644 --- a/application/sources/material_layer.h +++ b/application/sources/material_layer.h @@ -1,19 +1,17 @@ #ifndef DUST3D_APPLICATION_MATERIAL_LAYER_H_ #define DUST3D_APPLICATION_MATERIAL_LAYER_H_ -#include #include #include +#include -class MaterialMap -{ +class MaterialMap { public: dust3d::TextureType forWhat; dust3d::Uuid imageId; }; -class MaterialLayer -{ +class MaterialLayer { public: std::vector maps; float tileScale = 1.0; diff --git a/application/sources/material_list_widget.cc b/application/sources/material_list_widget.cc index d264b634..52045288 100644 --- a/application/sources/material_list_widget.cc +++ b/application/sources/material_list_widget.cc @@ -1,15 +1,15 @@ +#include "material_list_widget.h" +#include "document.h" +#include +#include #include #include #include -#include -#include #include -#include "material_list_widget.h" -#include "document.h" -MaterialListWidget::MaterialListWidget(const Document *document, QWidget *parent) : - QTreeWidget(parent), - m_document(document) +MaterialListWidget::MaterialListWidget(const Document* document, QWidget* parent) + : QTreeWidget(parent) + , m_document(document) { setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); setFocusPolicy(Qt::NoFocus); @@ -59,7 +59,7 @@ void MaterialListWidget::updateMaterialSelectState(dust3d::Uuid materialId, bool qDebug() << "Find material item failed:" << materialId; return; } - MaterialWidget *materialWidget = (MaterialWidget *)itemWidget(findItemResult->second.first, findItemResult->second.second); + MaterialWidget* materialWidget = (MaterialWidget*)itemWidget(findItemResult->second.first, findItemResult->second.second); materialWidget->updateCheckedState(selected); } @@ -90,7 +90,7 @@ void MaterialListWidget::selectMaterial(dust3d::Uuid materialId, bool multiple) } } if (!m_selectedMaterialIds.empty()) { - for (const auto &id: m_selectedMaterialIds) { + for (const auto& id : m_selectedMaterialIds) { updateMaterialSelectState(id, false); } m_selectedMaterialIds.clear(); @@ -107,20 +107,20 @@ void MaterialListWidget::selectMaterial(dust3d::Uuid materialId, bool multiple) } } -void MaterialListWidget::mousePressEvent(QMouseEvent *event) +void MaterialListWidget::mousePressEvent(QMouseEvent* event) { QModelIndex itemIndex = indexAt(event->pos()); QTreeView::mousePressEvent(event); if (event->button() == Qt::LeftButton) { bool multiple = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier); if (itemIndex.isValid()) { - QTreeWidgetItem *item = itemFromIndex(itemIndex); + QTreeWidgetItem* item = itemFromIndex(itemIndex); auto materialId = dust3d::Uuid(item->data(itemIndex.column(), Qt::UserRole).toString().toUtf8().constData()); if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { bool startAdd = false; bool stopAdd = false; std::vector waitQueue; - for (const auto &childId: m_document->materialIdList) { + for (const auto& childId : m_document->materialIdList) { if (m_shiftStartMaterialId == childId || materialId == childId) { if (startAdd) { stopAdd = true; @@ -135,7 +135,7 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event) } if (stopAdd && !waitQueue.empty()) { if (!m_selectedMaterialIds.empty()) { - for (const auto &id: m_selectedMaterialIds) { + for (const auto& id : m_selectedMaterialIds) { updateMaterialSelectState(id, false); } m_selectedMaterialIds.clear(); @@ -143,7 +143,7 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event) if (!m_currentSelectedMaterialId.isNull()) { m_currentSelectedMaterialId = dust3d::Uuid(); } - for (const auto &waitId: waitQueue) { + for (const auto& waitId : waitQueue) { selectMaterial(waitId, true); } } @@ -161,11 +161,10 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event) bool MaterialListWidget::isMaterialSelected(dust3d::Uuid materialId) { - return (m_currentSelectedMaterialId == materialId || - m_selectedMaterialIds.find(materialId) != m_selectedMaterialIds.end()); + return (m_currentSelectedMaterialId == materialId || m_selectedMaterialIds.find(materialId) != m_selectedMaterialIds.end()); } -void MaterialListWidget::showContextMenu(const QPoint &pos) +void MaterialListWidget::showContextMenu(const QPoint& pos) { if (!m_hasContextMenu) return; @@ -177,7 +176,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos) unorderedMaterialIds.insert(m_currentSelectedMaterialId); std::vector materialIds; - for (const auto &cand: m_document->materialIdList) { + for (const auto& cand : m_document->materialIdList) { if (unorderedMaterialIds.find(cand) != unorderedMaterialIds.end()) materialIds.push_back(cand); } @@ -205,7 +204,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos) QAction deleteAction(tr("Delete"), this); if (!materialIds.empty()) { connect(&deleteAction, &QAction::triggered, [=]() { - for (const auto &materialId: materialIds) + for (const auto& materialId : materialIds) emit removeMaterial(materialId); }); contextMenu.addAction(&deleteAction); @@ -214,7 +213,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos) contextMenu.exec(mapToGlobal(pos)); } -void MaterialListWidget::resizeEvent(QResizeEvent *event) +void MaterialListWidget::resizeEvent(QResizeEvent* event) { QTreeWidget::resizeEvent(event); if (calculateColumnCount() != columnCount()) @@ -247,11 +246,11 @@ void MaterialListWidget::reload() setColumnCount(columns); for (int i = 0; i < columns; i++) setColumnWidth(i, columnWidth); - + std::vector orderedMaterialIdList = m_document->materialIdList; - std::sort(orderedMaterialIdList.begin(), orderedMaterialIdList.end(), [&](const dust3d::Uuid &firstMaterialId, const dust3d::Uuid &secondMaterialId) { - const auto *firstMaterial = m_document->findMaterial(firstMaterialId); - const auto *secondMaterial = m_document->findMaterial(secondMaterialId); + std::sort(orderedMaterialIdList.begin(), orderedMaterialIdList.end(), [&](const dust3d::Uuid& firstMaterialId, const dust3d::Uuid& secondMaterialId) { + const auto* firstMaterial = m_document->findMaterial(firstMaterialId); + const auto* secondMaterial = m_document->findMaterial(secondMaterialId); if (nullptr == firstMaterial || nullptr == secondMaterial) return false; return QString::compare(firstMaterial->name, secondMaterial->name, Qt::CaseInsensitive) < 0; @@ -259,13 +258,13 @@ void MaterialListWidget::reload() decltype(orderedMaterialIdList.size()) materialIndex = 0; while (materialIndex < orderedMaterialIdList.size()) { - QTreeWidgetItem *item = new QTreeWidgetItem(this); + QTreeWidgetItem* item = new QTreeWidgetItem(this); item->setFlags((item->flags() | Qt::ItemIsEnabled) & ~(Qt::ItemIsSelectable) & ~(Qt::ItemIsEditable)); for (int col = 0; col < columns && materialIndex < orderedMaterialIdList.size(); col++, materialIndex++) { - const auto &materialId = orderedMaterialIdList[materialIndex]; + const auto& materialId = orderedMaterialIdList[materialIndex]; item->setSizeHint(col, QSize(columnWidth, MaterialWidget::preferredHeight() + 2)); item->setData(col, Qt::UserRole, QString(materialId.toString().c_str())); - MaterialWidget *widget = new MaterialWidget(m_document, materialId); + MaterialWidget* widget = new MaterialWidget(m_document, materialId); connect(widget, &MaterialWidget::modifyMaterial, this, &MaterialListWidget::modifyMaterial); setItemWidget(item, col, widget); widget->reload(); @@ -301,9 +300,9 @@ void MaterialListWidget::copy() dust3d::Snapshot snapshot; m_document->toSnapshot(&snapshot, emptySet, DocumentToSnapshotFor::Materials, limitMaterialIds); - + std::string snapshotXml; dust3d::saveSnapshotToXmlString(snapshot, snapshotXml); - QClipboard *clipboard = QApplication::clipboard(); + QClipboard* clipboard = QApplication::clipboard(); clipboard->setText(snapshotXml.c_str()); } diff --git a/application/sources/material_list_widget.h b/application/sources/material_list_widget.h index cdaabecf..db8b4ad3 100644 --- a/application/sources/material_list_widget.h +++ b/application/sources/material_list_widget.h @@ -1,41 +1,43 @@ #ifndef DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_ +#include "material_widget.h" +#include #include #include -#include -#include "material_widget.h" class Document; -class MaterialListWidget : public QTreeWidget -{ +class MaterialListWidget : public QTreeWidget { Q_OBJECT signals: void removeMaterial(dust3d::Uuid materialId); void modifyMaterial(dust3d::Uuid materialId); void cornerButtonClicked(dust3d::Uuid materialId); void currentSelectedMaterialChanged(dust3d::Uuid materialId); + public: - MaterialListWidget(const Document *document, QWidget *parent=nullptr); + MaterialListWidget(const Document* document, QWidget* parent = nullptr); bool isMaterialSelected(dust3d::Uuid materialId); void enableMultipleSelection(bool enabled); public slots: void reload(); void removeAllContent(); void materialRemoved(dust3d::Uuid materialId); - void showContextMenu(const QPoint &pos); - void selectMaterial(dust3d::Uuid materialId, bool multiple=false); + void showContextMenu(const QPoint& pos); + void selectMaterial(dust3d::Uuid materialId, bool multiple = false); void copy(); void setHasContextMenu(bool hasContextMenu); + protected: - void resizeEvent(QResizeEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; + void resizeEvent(QResizeEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + private: int calculateColumnCount(); void updateMaterialSelectState(dust3d::Uuid materialId, bool selected); - const Document *m_document = nullptr; - std::map> m_itemMap; + const Document* m_document = nullptr; + std::map> m_itemMap; std::set m_selectedMaterialIds; dust3d::Uuid m_currentSelectedMaterialId; dust3d::Uuid m_shiftStartMaterialId; diff --git a/application/sources/material_manage_widget.cc b/application/sources/material_manage_widget.cc index d82b7005..8905cd8f 100644 --- a/application/sources/material_manage_widget.cc +++ b/application/sources/material_manage_widget.cc @@ -1,34 +1,34 @@ -#include -#include -#include #include "material_manage_widget.h" -#include "theme.h" -#include "material_edit_widget.h" -#include "info_label.h" #include "document.h" +#include "info_label.h" +#include "material_edit_widget.h" +#include "theme.h" +#include +#include +#include -MaterialManageWidget::MaterialManageWidget(const Document *document, QWidget *parent) : - QWidget(parent), - m_document(document) +MaterialManageWidget::MaterialManageWidget(const Document* document, QWidget* parent) + : QWidget(parent) + , m_document(document) { - QPushButton *addMaterialButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Material...")); + QPushButton* addMaterialButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Material...")); connect(addMaterialButton, &QPushButton::clicked, this, &MaterialManageWidget::showAddMaterialDialog); - QHBoxLayout *toolsLayout = new QHBoxLayout; + QHBoxLayout* toolsLayout = new QHBoxLayout; toolsLayout->addWidget(addMaterialButton); m_materialListWidget = new MaterialListWidget(document); connect(m_materialListWidget, &MaterialListWidget::modifyMaterial, this, &MaterialManageWidget::showMaterialDialog); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addLayout(toolsLayout); mainLayout->addWidget(m_materialListWidget); setLayout(mainLayout); } -MaterialListWidget *MaterialManageWidget::materialListWidget() +MaterialListWidget* MaterialManageWidget::materialListWidget() { return m_materialListWidget; } @@ -45,10 +45,10 @@ void MaterialManageWidget::showAddMaterialDialog() void MaterialManageWidget::showMaterialDialog(dust3d::Uuid materialId) { - MaterialEditWidget *materialEditWidget = new MaterialEditWidget(m_document); + MaterialEditWidget* materialEditWidget = new MaterialEditWidget(m_document); materialEditWidget->setAttribute(Qt::WA_DeleteOnClose); if (!materialId.isNull()) { - const Material *material = m_document->findMaterial(materialId); + const Material* material = m_document->findMaterial(materialId); if (nullptr != material) { materialEditWidget->setEditMaterialId(materialId); materialEditWidget->setEditMaterialName(material->name); @@ -58,7 +58,7 @@ void MaterialManageWidget::showMaterialDialog(dust3d::Uuid materialId) } materialEditWidget->show(); connect(materialEditWidget, &QDialog::destroyed, [=]() { - emit unregisterDialog((QWidget *)materialEditWidget); + emit unregisterDialog((QWidget*)materialEditWidget); }); - emit registerDialog((QWidget *)materialEditWidget); + emit registerDialog((QWidget*)materialEditWidget); } diff --git a/application/sources/material_manage_widget.h b/application/sources/material_manage_widget.h index f01de182..9310e609 100644 --- a/application/sources/material_manage_widget.h +++ b/application/sources/material_manage_widget.h @@ -1,28 +1,30 @@ #ifndef DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_ -#include #include "material_list_widget.h" +#include class Document; -class MaterialManageWidget : public QWidget -{ +class MaterialManageWidget : public QWidget { Q_OBJECT signals: - void registerDialog(QWidget *widget); - void unregisterDialog(QWidget *widget); + void registerDialog(QWidget* widget); + void unregisterDialog(QWidget* widget); + public: - MaterialManageWidget(const Document *document, QWidget *parent=nullptr); - MaterialListWidget *materialListWidget(); + MaterialManageWidget(const Document* document, QWidget* parent = nullptr); + MaterialListWidget* materialListWidget(); + protected: virtual QSize sizeHint() const; public slots: void showAddMaterialDialog(); void showMaterialDialog(dust3d::Uuid materialId); + private: - const Document *m_document = nullptr; - MaterialListWidget *m_materialListWidget = nullptr; + const Document* m_document = nullptr; + MaterialListWidget* m_materialListWidget = nullptr; }; #endif diff --git a/application/sources/material_previews_generator.cc b/application/sources/material_previews_generator.cc index 03c523fd..a0857a05 100644 --- a/application/sources/material_previews_generator.cc +++ b/application/sources/material_previews_generator.cc @@ -1,14 +1,14 @@ -#include -#include +#include "material_previews_generator.h" +#include "image_forever.h" +#include "mesh_generator.h" +#include "mesh_result_post_processor.h" +#include "texture_generator.h" #include +#include #include +#include #include #include -#include "material_previews_generator.h" -#include "mesh_generator.h" -#include "texture_generator.h" -#include "image_forever.h" -#include "mesh_result_post_processor.h" MaterialPreviewsGenerator::MaterialPreviewsGenerator() { @@ -16,78 +16,78 @@ MaterialPreviewsGenerator::MaterialPreviewsGenerator() MaterialPreviewsGenerator::~MaterialPreviewsGenerator() { - for (auto &item: m_previews) { + for (auto& item : m_previews) { delete item.second; } } -void MaterialPreviewsGenerator::addMaterial(dust3d::Uuid materialId, const std::vector &layers) +void MaterialPreviewsGenerator::addMaterial(dust3d::Uuid materialId, const std::vector& layers) { - m_materials.push_back({materialId, layers}); + m_materials.push_back({ materialId, layers }); } -const std::set &MaterialPreviewsGenerator::generatedPreviewMaterialIds() +const std::set& MaterialPreviewsGenerator::generatedPreviewMaterialIds() { return m_generatedMaterialIds; } -ModelMesh *MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId) +ModelMesh* MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId) { - ModelMesh *resultMesh = m_previews[materialId]; + ModelMesh* resultMesh = m_previews[materialId]; m_previews[materialId] = nullptr; return resultMesh; } void MaterialPreviewsGenerator::generate() { - dust3d::Snapshot *snapshot = new dust3d::Snapshot; - + dust3d::Snapshot* snapshot = new dust3d::Snapshot; + QFile file(":/resources/material-demo-model.ds3"); file.open(QFile::ReadOnly); QByteArray fileData = file.readAll(); - + std::vector partIds; - dust3d::Ds3FileReader ds3Reader((const std::uint8_t *)fileData.data(), fileData.size()); + dust3d::Ds3FileReader ds3Reader((const std::uint8_t*)fileData.data(), fileData.size()); for (int i = 0; i < (int)ds3Reader.items().size(); ++i) { dust3d::Ds3ReaderItem item = ds3Reader.items().at(i); if (item.type == "model") { std::vector data; ds3Reader.loadItem(item.name, &data); - std::string xmlString((char *)data.data(), data.size()); - dust3d::loadSnapshotFromXmlString(snapshot, (char *)xmlString.c_str()); - for (const auto &item: snapshot->parts) { + std::string xmlString((char*)data.data(), data.size()); + dust3d::loadSnapshotFromXmlString(snapshot, (char*)xmlString.c_str()); + for (const auto& item : snapshot->parts) { partIds.push_back(dust3d::Uuid(item.first)); } } } - - dust3d::MeshGenerator::GeneratedCacheContext *cacheContext = new dust3d::MeshGenerator::GeneratedCacheContext(); - MeshGenerator *meshGenerator = new MeshGenerator(snapshot); + + dust3d::MeshGenerator::GeneratedCacheContext* cacheContext = new dust3d::MeshGenerator::GeneratedCacheContext(); + MeshGenerator* meshGenerator = new MeshGenerator(snapshot); meshGenerator->setGeneratedCacheContext(cacheContext); - + meshGenerator->generate(); - for (const auto &mirror: cacheContext->partMirrorIdMap) { + for (const auto& mirror : cacheContext->partMirrorIdMap) { partIds.push_back(dust3d::Uuid(mirror.first)); } - - dust3d::Object *object = meshGenerator->takeObject(); + + dust3d::Object* object = meshGenerator->takeObject(); if (nullptr != object) { - MeshResultPostProcessor *poseProcessor = new MeshResultPostProcessor(*object); + MeshResultPostProcessor* poseProcessor = new MeshResultPostProcessor(*object); poseProcessor->poseProcess(); delete object; object = poseProcessor->takePostProcessedObject(); delete poseProcessor; } - + if (nullptr != object) { - for (const auto &material: m_materials) { - TextureGenerator *textureGenerator = new TextureGenerator(*object); - for (const auto &layer: material.second) { - for (const auto &mapItem: layer.maps) { - const QImage *image = ImageForever::get(mapItem.imageId); + for (const auto& material : m_materials) { + TextureGenerator* textureGenerator = new TextureGenerator(*object); + for (const auto& layer : material.second) { + for (const auto& mapItem : layer.maps) { + const QImage* image = ImageForever::get(mapItem.imageId); if (nullptr == image) continue; - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { if (dust3d::TextureType::BaseColor == mapItem.forWhat) textureGenerator->addPartColorMap(partId, image, layer.tileScale); else if (dust3d::TextureType::Normal == mapItem.forWhat) @@ -102,7 +102,7 @@ void MaterialPreviewsGenerator::generate() } } textureGenerator->generate(); - ModelMesh *texturedResultMesh = textureGenerator->takeResultMesh(); + ModelMesh* texturedResultMesh = textureGenerator->takeResultMesh(); if (nullptr != texturedResultMesh) { m_previews[material.first] = new ModelMesh(*texturedResultMesh); m_generatedMaterialIds.insert(material.first); @@ -111,9 +111,9 @@ void MaterialPreviewsGenerator::generate() delete textureGenerator; } } - + delete object; - + delete meshGenerator; delete cacheContext; } diff --git a/application/sources/material_previews_generator.h b/application/sources/material_previews_generator.h index b6161694..6f1fa2b6 100644 --- a/application/sources/material_previews_generator.h +++ b/application/sources/material_previews_generator.h @@ -1,29 +1,29 @@ #ifndef DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_ #define DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_ +#include "material_layer.h" +#include "model_mesh.h" #include #include #include -#include "model_mesh.h" -#include "material_layer.h" -class MaterialPreviewsGenerator : public QObject -{ +class MaterialPreviewsGenerator : public QObject { Q_OBJECT public: MaterialPreviewsGenerator(); ~MaterialPreviewsGenerator(); - void addMaterial(dust3d::Uuid materialId, const std::vector &layers); - const std::set &generatedPreviewMaterialIds(); - ModelMesh *takePreview(dust3d::Uuid materialId); + void addMaterial(dust3d::Uuid materialId, const std::vector& layers); + const std::set& generatedPreviewMaterialIds(); + ModelMesh* takePreview(dust3d::Uuid materialId); void generate(); signals: void finished(); public slots: void process(); + private: std::vector>> m_materials; - std::map m_previews; + std::map m_previews; std::set m_generatedMaterialIds; }; diff --git a/application/sources/material_widget.cc b/application/sources/material_widget.cc index d3803875..768e64d1 100644 --- a/application/sources/material_widget.cc +++ b/application/sources/material_widget.cc @@ -1,10 +1,10 @@ -#include #include "material_widget.h" #include "document.h" +#include -MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId) : - m_materialId(materialId), - m_document(document) +MaterialWidget::MaterialWidget(const Document* document, dust3d::Uuid materialId) + : m_materialId(materialId) + , m_document(document) { setObjectName("MaterialFrame"); @@ -23,7 +23,7 @@ MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId nameFont.setBold(false); m_nameLabel->setFont(nameFont); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addStretch(); mainLayout->addWidget(m_nameLabel); @@ -36,7 +36,7 @@ MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId connect(document, &Document::materialPreviewChanged, this, &MaterialWidget::updatePreview); } -void MaterialWidget::resizeEvent(QResizeEvent *event) +void MaterialWidget::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); m_previewWidget->move((width() - Theme::materialPreviewImageSize) / 2, 0); @@ -57,12 +57,12 @@ void MaterialWidget::updatePreview(dust3d::Uuid materialId) { if (materialId != m_materialId) return; - const Material *material = m_document->findMaterial(m_materialId); + const Material* material = m_document->findMaterial(m_materialId); if (!material) { qDebug() << "Material not found:" << m_materialId; return; } - ModelMesh *previewMesh = material->takePreviewMesh(); + ModelMesh* previewMesh = material->takePreviewMesh(); m_previewWidget->updateMesh(previewMesh); } @@ -70,7 +70,7 @@ void MaterialWidget::updateName(dust3d::Uuid materialId) { if (materialId != m_materialId) return; - const Material *material = m_document->findMaterial(m_materialId); + const Material* material = m_document->findMaterial(m_materialId); if (!material) { qDebug() << "Material not found:" << m_materialId; return; @@ -86,12 +86,12 @@ void MaterialWidget::updateCheckedState(bool checked) setStyleSheet("#MaterialFrame {border: 1px solid transparent;}"); } -ModelWidget *MaterialWidget::previewWidget() +ModelWidget* MaterialWidget::previewWidget() { return m_previewWidget; } -void MaterialWidget::mouseDoubleClickEvent(QMouseEvent *event) +void MaterialWidget::mouseDoubleClickEvent(QMouseEvent* event) { QFrame::mouseDoubleClickEvent(event); emit modifyMaterial(m_materialId); diff --git a/application/sources/material_widget.h b/application/sources/material_widget.h index 3b0af2cd..4734ae58 100644 --- a/application/sources/material_widget.h +++ b/application/sources/material_widget.h @@ -1,36 +1,38 @@ #ifndef DUST3D_APPLICATION_MATERIAL_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_WIDGET_H_ -#include -#include -#include -#include #include "model_widget.h" +#include +#include +#include +#include class Document; -class MaterialWidget : public QFrame -{ +class MaterialWidget : public QFrame { Q_OBJECT signals: void modifyMaterial(dust3d::Uuid materialId); + public: - MaterialWidget(const Document *document, dust3d::Uuid materialId); + MaterialWidget(const Document* document, dust3d::Uuid materialId); static int preferredHeight(); - ModelWidget *previewWidget(); + ModelWidget* previewWidget(); + protected: - void mouseDoubleClickEvent(QMouseEvent *event) override; - void resizeEvent(QResizeEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; + void resizeEvent(QResizeEvent* event) override; public slots: void reload(); void updatePreview(dust3d::Uuid materialId); void updateName(dust3d::Uuid materialId); void updateCheckedState(bool checked); + private: dust3d::Uuid m_materialId; - const Document *m_document = nullptr; - ModelWidget *m_previewWidget = nullptr; - QLabel *m_nameLabel = nullptr; + const Document* m_document = nullptr; + ModelWidget* m_previewWidget = nullptr; + QLabel* m_nameLabel = nullptr; }; #endif diff --git a/application/sources/mesh_generator.cc b/application/sources/mesh_generator.cc index cb47b88d..e3dbd0df 100644 --- a/application/sources/mesh_generator.cc +++ b/application/sources/mesh_generator.cc @@ -1,13 +1,13 @@ -#include -#include -#include -#include #include "mesh_generator.h" #include "cut_face_preview.h" +#include +#include +#include +#include -MeshGenerator::MeshGenerator(dust3d::Snapshot *snapshot) : - dust3d::MeshGenerator(snapshot) +MeshGenerator::MeshGenerator(dust3d::Snapshot* snapshot) + : dust3d::MeshGenerator(snapshot) { } @@ -15,12 +15,12 @@ MeshGenerator::~MeshGenerator() { } -std::map> *MeshGenerator::takeComponentPreviewMeshes() +std::map>* MeshGenerator::takeComponentPreviewMeshes() { return m_componentPreviewMeshes.release(); } -MonochromeMesh *MeshGenerator::takeWireframeMesh() +MonochromeMesh* MeshGenerator::takeWireframeMesh() { return m_wireframeMesh.release(); } @@ -29,29 +29,28 @@ void MeshGenerator::process() { QElapsedTimer countTimeConsumed; countTimeConsumed.start(); - + generate(); - + if (nullptr != m_object) m_resultMesh = std::make_unique(*m_object); - + m_componentPreviewMeshes = std::make_unique>>(); - for (const auto &componentId: m_generatedPreviewComponentIds) { + for (const auto& componentId : m_generatedPreviewComponentIds) { auto it = m_generatedComponentPreviews.find(componentId); if (it == m_generatedComponentPreviews.end()) continue; dust3d::trimVertices(&it->second.vertices, true); - for (auto &it: it->second.vertices) { + for (auto& it : it->second.vertices) { it *= 2.0; } std::vector previewTriangleNormals; previewTriangleNormals.reserve(it->second.triangles.size()); - for (const auto &face: it->second.triangles) { + for (const auto& face : it->second.triangles) { previewTriangleNormals.emplace_back(dust3d::Vector3::normal( it->second.vertices[face[0]], it->second.vertices[face[1]], - it->second.vertices[face[2]] - )); + it->second.vertices[face[2]])); } std::vector> previewTriangleVertexNormals; dust3d::smoothNormal(it->second.vertices, @@ -70,14 +69,13 @@ void MeshGenerator::process() if (nullptr != m_object) m_wireframeMesh = std::make_unique(*m_object); - + qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds"; - + emit finished(); } -ModelMesh *MeshGenerator::takeResultMesh() +ModelMesh* MeshGenerator::takeResultMesh() { return m_resultMesh.release(); } - diff --git a/application/sources/mesh_generator.h b/application/sources/mesh_generator.h index 94a96613..b82ee4e3 100644 --- a/application/sources/mesh_generator.h +++ b/application/sources/mesh_generator.h @@ -1,26 +1,26 @@ #ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_ #define DUST3D_APPLICATION_MESH_GENERATOR_H_ -#include -#include -#include -#include #include "model_mesh.h" #include "monochrome_mesh.h" +#include +#include +#include +#include -class MeshGenerator : public QObject, public dust3d::MeshGenerator -{ +class MeshGenerator : public QObject, public dust3d::MeshGenerator { Q_OBJECT public: - MeshGenerator(dust3d::Snapshot *snapshot); + MeshGenerator(dust3d::Snapshot* snapshot); ~MeshGenerator(); - ModelMesh *takeResultMesh(); - std::map> *takeComponentPreviewMeshes(); - MonochromeMesh *takeWireframeMesh(); + ModelMesh* takeResultMesh(); + std::map>* takeComponentPreviewMeshes(); + MonochromeMesh* takeWireframeMesh(); public slots: void process(); signals: void finished(); + private: std::unique_ptr m_resultMesh; std::unique_ptr>> m_componentPreviewMeshes; diff --git a/application/sources/mesh_preview_images_generator.cc b/application/sources/mesh_preview_images_generator.cc index 61ddc0ca..c547edcc 100644 --- a/application/sources/mesh_preview_images_generator.cc +++ b/application/sources/mesh_preview_images_generator.cc @@ -1,20 +1,20 @@ -#include #include "mesh_preview_images_generator.h" #include "theme.h" +#include -void MeshPreviewImagesGenerator::addInput(const dust3d::Uuid &inputId, std::unique_ptr previewMesh, bool useFrontView) +void MeshPreviewImagesGenerator::addInput(const dust3d::Uuid& inputId, std::unique_ptr previewMesh, bool useFrontView) { - m_previewInputMap.insert({inputId, PreviewInput {std::move(previewMesh), useFrontView}}); + m_previewInputMap.insert({ inputId, PreviewInput { std::move(previewMesh), useFrontView } }); } void MeshPreviewImagesGenerator::process() { generate(); - + emit finished(); } -std::map *MeshPreviewImagesGenerator::takeImages() +std::map* MeshPreviewImagesGenerator::takeImages() { return m_partImages.release(); } @@ -22,10 +22,10 @@ std::map *MeshPreviewImagesGenerator::takeImages() void MeshPreviewImagesGenerator::generate() { m_partImages = std::make_unique>(); - + m_offscreenRender->setZRotation(0); m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0)); - for (auto &it: m_previewInputMap) { + for (auto& it : m_previewInputMap) { if (it.second.useFrontView) { m_offscreenRender->setXRotation(0); m_offscreenRender->setYRotation(0); diff --git a/application/sources/mesh_preview_images_generator.h b/application/sources/mesh_preview_images_generator.h index e80855fd..c4fb8b7d 100644 --- a/application/sources/mesh_preview_images_generator.h +++ b/application/sources/mesh_preview_images_generator.h @@ -1,43 +1,42 @@ #ifndef DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ #define DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ -#include -#include -#include -#include -#include #include "model_offscreen_render.h" +#include +#include +#include +#include +#include -class MeshPreviewImagesGenerator : public QObject -{ +class MeshPreviewImagesGenerator : public QObject { Q_OBJECT public: - MeshPreviewImagesGenerator(ModelOffscreenRender *modelOffscreenRender) : - m_offscreenRender(modelOffscreenRender) + MeshPreviewImagesGenerator(ModelOffscreenRender* modelOffscreenRender) + : m_offscreenRender(modelOffscreenRender) { } - - struct PreviewInput - { + + struct PreviewInput { std::unique_ptr mesh; bool useFrontView = false; }; - + ~MeshPreviewImagesGenerator() { delete m_offscreenRender; } - void addInput(const dust3d::Uuid &inputId, std::unique_ptr previewMesh, bool useFrontView=false); + void addInput(const dust3d::Uuid& inputId, std::unique_ptr previewMesh, bool useFrontView = false); void generate(); - std::map *takeImages(); + std::map* takeImages(); signals: void finished(); public slots: void process(); + private: std::map m_previewInputMap; - ModelOffscreenRender *m_offscreenRender = nullptr; + ModelOffscreenRender* m_offscreenRender = nullptr; std::unique_ptr> m_partImages; }; diff --git a/application/sources/mesh_result_post_processor.cc b/application/sources/mesh_result_post_processor.cc index c24f0d46..5774d715 100644 --- a/application/sources/mesh_result_post_processor.cc +++ b/application/sources/mesh_result_post_processor.cc @@ -1,9 +1,9 @@ -#include -#include -#include #include "mesh_result_post_processor.h" +#include +#include +#include -MeshResultPostProcessor::MeshResultPostProcessor(const dust3d::Object &object) +MeshResultPostProcessor::MeshResultPostProcessor(const dust3d::Object& object) { m_object = new dust3d::Object; *m_object = object; @@ -14,9 +14,9 @@ MeshResultPostProcessor::~MeshResultPostProcessor() delete m_object; } -dust3d::Object *MeshResultPostProcessor::takePostProcessedObject() +dust3d::Object* MeshResultPostProcessor::takePostProcessedObject() { - dust3d::Object *object = m_object; + dust3d::Object* object = m_object; m_object = nullptr; return object; } @@ -32,7 +32,7 @@ void MeshResultPostProcessor::poseProcess() m_object->setTriangleVertexUvs(triangleVertexUvs); m_object->setPartUvRects(partUvRects); } - + { std::vector triangleTangents; dust3d::resolveTriangleTangent(*m_object, triangleTangents); diff --git a/application/sources/mesh_result_post_processor.h b/application/sources/mesh_result_post_processor.h index 6c6ae202..cfe041bf 100644 --- a/application/sources/mesh_result_post_processor.h +++ b/application/sources/mesh_result_post_processor.h @@ -4,20 +4,20 @@ #include #include -class MeshResultPostProcessor : public QObject -{ +class MeshResultPostProcessor : public QObject { Q_OBJECT public: - MeshResultPostProcessor(const dust3d::Object &object); + MeshResultPostProcessor(const dust3d::Object& object); ~MeshResultPostProcessor(); - dust3d::Object *takePostProcessedObject(); + dust3d::Object* takePostProcessedObject(); void poseProcess(); signals: void finished(); public slots: void process(); + private: - dust3d::Object *m_object = nullptr; + dust3d::Object* m_object = nullptr; }; #endif diff --git a/application/sources/model_mesh.cc b/application/sources/model_mesh.cc index 545d586b..a286fc22 100644 --- a/application/sources/model_mesh.cc +++ b/application/sources/model_mesh.cc @@ -1,20 +1,19 @@ -#include -#include -#include -#include #include "model_mesh.h" #include "version.h" +#include +#include +#include +#include float ModelMesh::m_defaultMetalness = 0.0; float ModelMesh::m_defaultRoughness = 1.0; -ModelMesh::ModelMesh(const ModelMesh &mesh) : - m_triangleVertices(nullptr), - m_triangleVertexCount(0), - m_textureImage(nullptr) +ModelMesh::ModelMesh(const ModelMesh& mesh) + : m_triangleVertices(nullptr) + , m_triangleVertexCount(0) + , m_textureImage(nullptr) { - if (nullptr != mesh.m_triangleVertices && - mesh.m_triangleVertexCount > 0) { + if (nullptr != mesh.m_triangleVertices && mesh.m_triangleVertexCount > 0) { this->m_triangleVertices = new ModelOpenGLVertex[mesh.m_triangleVertexCount]; this->m_triangleVertexCount = mesh.m_triangleVertexCount; for (int i = 0; i < mesh.m_triangleVertexCount; i++) @@ -42,39 +41,39 @@ void ModelMesh::removeColor() { delete this->m_textureImage; this->m_textureImage = nullptr; - + delete this->m_normalMapImage; this->m_normalMapImage = nullptr; - + delete this->m_metalnessRoughnessAmbientOcclusionMapImage; this->m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; - + this->m_hasMetalnessInImage = false; this->m_hasRoughnessInImage = false; this->m_hasAmbientOcclusionInImage = false; - + for (int i = 0; i < this->m_triangleVertexCount; ++i) { - auto &vertex = this->m_triangleVertices[i]; + auto& vertex = this->m_triangleVertices[i]; vertex.colorR = 1.0; vertex.colorG = 1.0; vertex.colorB = 1.0; } } -ModelMesh::ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum) : - m_triangleVertices(triangleVertices), - m_triangleVertexCount(vertexNum), - m_textureImage(nullptr) +ModelMesh::ModelMesh(ModelOpenGLVertex* triangleVertices, int vertexNum) + : m_triangleVertices(triangleVertices) + , m_triangleVertexCount(vertexNum) + , m_textureImage(nullptr) { } -ModelMesh::ModelMesh(const std::vector &vertices, - const std::vector> &triangles, - const std::vector> &triangleVertexNormals, - const dust3d::Color &color, +ModelMesh::ModelMesh(const std::vector& vertices, + const std::vector>& triangles, + const std::vector>& triangleVertexNormals, + const dust3d::Color& color, float metalness, float roughness, - const std::vector> *vertexProperties) + const std::vector>* vertexProperties) { m_triangleVertexCount = (int)triangles.size() * 3; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount]; @@ -82,9 +81,9 @@ ModelMesh::ModelMesh(const std::vector &vertices, for (size_t i = 0; i < triangles.size(); ++i) { for (auto j = 0; j < 3; j++) { int vertexIndex = (int)triangles[i][j]; - const dust3d::Vector3 *srcVert = &vertices[vertexIndex]; - const dust3d::Vector3 *srcNormal = &(triangleVertexNormals)[i][j]; - ModelOpenGLVertex *dest = &m_triangleVertices[destIndex]; + const dust3d::Vector3* srcVert = &vertices[vertexIndex]; + const dust3d::Vector3* srcNormal = &(triangleVertexNormals)[i][j]; + ModelOpenGLVertex* dest = &m_triangleVertices[destIndex]; dest->posX = srcVert->x(); dest->posY = srcVert->y(); dest->posZ = srcVert->z(); @@ -101,7 +100,7 @@ ModelMesh::ModelMesh(const std::vector &vertices, dest->metalness = metalness; dest->roughness = roughness; } else { - const auto &property = (*vertexProperties)[vertexIndex]; + const auto& property = (*vertexProperties)[vertexIndex]; dest->colorR = std::get<0>(property).r(); dest->colorG = std::get<0>(property).g(); dest->colorB = std::get<0>(property).b(); @@ -117,21 +116,21 @@ ModelMesh::ModelMesh(const std::vector &vertices, } } -ModelMesh::ModelMesh(dust3d::Object &object) : - m_triangleVertices(nullptr), - m_triangleVertexCount(0), - m_textureImage(nullptr) +ModelMesh::ModelMesh(dust3d::Object& object) + : m_triangleVertices(nullptr) + , m_triangleVertexCount(0) + , m_textureImage(nullptr) { m_meshId = object.meshId; m_vertices = object.vertices; m_faces = object.triangleAndQuads; - std::map, const dust3d::ObjectNode *> nodeMap; + std::map, const dust3d::ObjectNode*> nodeMap; for (size_t i = 0; i < object.nodes.size(); ++i) { - const auto &node = object.nodes[i]; - nodeMap.insert({{node.partId, node.nodeId}, &node}); + const auto& node = object.nodes[i]; + nodeMap.insert({ { node.partId, node.nodeId }, &node }); } - + m_triangleVertexCount = (int)object.triangles.size() * 3; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount]; int destIndex = 0; @@ -142,20 +141,20 @@ ModelMesh::ModelMesh(dust3d::Object &object) : const dust3d::Vector2 defaultUv = dust3d::Vector2(0, 0); const dust3d::Vector3 defaultTangent = dust3d::Vector3(0, 0, 0); for (size_t i = 0; i < object.triangles.size(); ++i) { - const auto &triangleColor = &object.triangleColors[i]; + const auto& triangleColor = &object.triangleColors[i]; for (auto j = 0; j < 3; j++) { int vertexIndex = (int)object.triangles[i][j]; - const dust3d::Vector3 *srcVert = &object.vertices[vertexIndex]; - const dust3d::Vector3 *srcNormal = &defaultNormal; + const dust3d::Vector3* srcVert = &object.vertices[vertexIndex]; + const dust3d::Vector3* srcNormal = &defaultNormal; if (triangleVertexNormals) srcNormal = &(*triangleVertexNormals)[i][j]; - const dust3d::Vector2 *srcUv = &defaultUv; + const dust3d::Vector2* srcUv = &defaultUv; if (triangleVertexUvs) srcUv = &(*triangleVertexUvs)[i][j]; - const dust3d::Vector3 *srcTangent = &defaultTangent; + const dust3d::Vector3* srcTangent = &defaultTangent; if (triangleTangents) srcTangent = &(*triangleTangents)[i]; - ModelOpenGLVertex *dest = &m_triangleVertices[destIndex]; + ModelOpenGLVertex* dest = &m_triangleVertices[destIndex]; dest->colorR = triangleColor->r(); dest->colorG = triangleColor->g(); dest->colorB = triangleColor->b(); @@ -184,10 +183,10 @@ ModelMesh::ModelMesh(dust3d::Object &object) : } } -ModelMesh::ModelMesh() : - m_triangleVertices(nullptr), - m_triangleVertexCount(0), - m_textureImage(nullptr) +ModelMesh::ModelMesh() + : m_triangleVertices(nullptr) + , m_triangleVertexCount(0) + , m_textureImage(nullptr) { } @@ -200,22 +199,22 @@ ModelMesh::~ModelMesh() delete m_metalnessRoughnessAmbientOcclusionMapImage; } -const std::vector &ModelMesh::vertices() +const std::vector& ModelMesh::vertices() { return m_vertices; } -const std::vector> &ModelMesh::faces() +const std::vector>& ModelMesh::faces() { return m_faces; } -const std::vector &ModelMesh::triangulatedVertices() +const std::vector& ModelMesh::triangulatedVertices() { return m_triangulatedVertices; } -ModelOpenGLVertex *ModelMesh::triangleVertices() +ModelOpenGLVertex* ModelMesh::triangleVertices() { return m_triangleVertices; } @@ -225,53 +224,53 @@ int ModelMesh::triangleVertexCount() return m_triangleVertexCount; } -void ModelMesh::setTextureImage(QImage *textureImage) +void ModelMesh::setTextureImage(QImage* textureImage) { m_textureImage = textureImage; } -const QImage *ModelMesh::textureImage() +const QImage* ModelMesh::textureImage() { return m_textureImage; } -QImage *ModelMesh::takeTextureImage() +QImage* ModelMesh::takeTextureImage() { auto image = m_textureImage; m_textureImage = nullptr; return image; } -void ModelMesh::setNormalMapImage(QImage *normalMapImage) +void ModelMesh::setNormalMapImage(QImage* normalMapImage) { m_normalMapImage = normalMapImage; } -const QImage *ModelMesh::normalMapImage() +const QImage* ModelMesh::normalMapImage() { return m_normalMapImage; } -QImage *ModelMesh::takeNormalMapImage() +QImage* ModelMesh::takeNormalMapImage() { auto image = m_normalMapImage; m_normalMapImage = nullptr; return image; } -const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionMapImage() +const QImage* ModelMesh::metalnessRoughnessAmbientOcclusionMapImage() { return m_metalnessRoughnessAmbientOcclusionMapImage; } -QImage *ModelMesh::takeMetalnessRoughnessAmbientOcclusionMapImage() +QImage* ModelMesh::takeMetalnessRoughnessAmbientOcclusionMapImage() { auto image = m_metalnessRoughnessAmbientOcclusionMapImage; m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; return image; } -void ModelMesh::setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image) +void ModelMesh::setMetalnessRoughnessAmbientOcclusionMapImage(QImage* image) { m_metalnessRoughnessAmbientOcclusionMapImage = image; } @@ -306,24 +305,24 @@ void ModelMesh::setHasAmbientOcclusionInImage(bool hasInImage) m_hasAmbientOcclusionInImage = hasInImage; } -void ModelMesh::exportAsObj(QTextStream *textStream) +void ModelMesh::exportAsObj(QTextStream* textStream) { - auto &stream = *textStream; + auto& stream = *textStream; stream << "# " << APP_NAME << " " << APP_HUMAN_VER << endl; stream << "# " << APP_HOMEPAGE_URL << endl; - for (std::vector::const_iterator it = vertices().begin() ; it != vertices().end(); ++it) { + for (std::vector::const_iterator it = vertices().begin(); it != vertices().end(); ++it) { stream << "v " << QString::number((*it).x()) << " " << QString::number((*it).y()) << " " << QString::number((*it).z()) << endl; } - for (std::vector>::const_iterator it = faces().begin() ; it != faces().end(); ++it) { + for (std::vector>::const_iterator it = faces().begin(); it != faces().end(); ++it) { stream << "f"; - for (std::vector::const_iterator subIt = (*it).begin() ; subIt != (*it).end(); ++subIt) { + for (std::vector::const_iterator subIt = (*it).begin(); subIt != (*it).end(); ++subIt) { stream << " " << QString::number((1 + *subIt)); } stream << endl; } } -void ModelMesh::exportAsObj(const QString &filename) +void ModelMesh::exportAsObj(const QString& filename) { QFile file(filename); if (file.open(QIODevice::WriteOnly)) { @@ -332,12 +331,12 @@ void ModelMesh::exportAsObj(const QString &filename) } } -void ModelMesh::updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount) +void ModelMesh::updateTriangleVertices(ModelOpenGLVertex* triangleVertices, int triangleVertexCount) { delete[] m_triangleVertices; m_triangleVertices = 0; m_triangleVertexCount = 0; - + m_triangleVertices = triangleVertices; m_triangleVertexCount = triangleVertexCount; } diff --git a/application/sources/model_mesh.h b/application/sources/model_mesh.h index e8962334..97e84e0d 100644 --- a/application/sources/model_mesh.h +++ b/application/sources/model_mesh.h @@ -1,44 +1,43 @@ #ifndef DUST3D_APPLICATION_MODEL_MESH_H_ #define DUST3D_APPLICATION_MODEL_MESH_H_ -#include -#include +#include "model_opengl_vertex.h" #include +#include #include -#include #include #include -#include "model_opengl_vertex.h" +#include +#include -class ModelMesh -{ +class ModelMesh { public: - ModelMesh(const std::vector &vertices, - const std::vector> &triangles, - const std::vector> &triangleVertexNormals, - const dust3d::Color &color=dust3d::Color::createWhite(), - float metalness=0.0, - float roughness=1.0, - const std::vector> *vertexProperties=nullptr); - ModelMesh(dust3d::Object &object); - ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum); - ModelMesh(const ModelMesh &mesh); + ModelMesh(const std::vector& vertices, + const std::vector>& triangles, + const std::vector>& triangleVertexNormals, + const dust3d::Color& color = dust3d::Color::createWhite(), + float metalness = 0.0, + float roughness = 1.0, + const std::vector>* vertexProperties = nullptr); + ModelMesh(dust3d::Object& object); + ModelMesh(ModelOpenGLVertex* triangleVertices, int vertexNum); + ModelMesh(const ModelMesh& mesh); ModelMesh(); ~ModelMesh(); - ModelOpenGLVertex *triangleVertices(); + ModelOpenGLVertex* triangleVertices(); int triangleVertexCount(); - const std::vector &vertices(); - const std::vector> &faces(); - const std::vector &triangulatedVertices(); - void setTextureImage(QImage *textureImage); - const QImage *textureImage(); - QImage *takeTextureImage(); - void setNormalMapImage(QImage *normalMapImage); - const QImage *normalMapImage(); - QImage *takeNormalMapImage(); - const QImage *metalnessRoughnessAmbientOcclusionMapImage(); - QImage *takeMetalnessRoughnessAmbientOcclusionMapImage(); - void setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image); + const std::vector& vertices(); + const std::vector>& faces(); + const std::vector& triangulatedVertices(); + void setTextureImage(QImage* textureImage); + const QImage* textureImage(); + QImage* takeTextureImage(); + void setNormalMapImage(QImage* normalMapImage); + const QImage* normalMapImage(); + QImage* takeNormalMapImage(); + const QImage* metalnessRoughnessAmbientOcclusionMapImage(); + QImage* takeMetalnessRoughnessAmbientOcclusionMapImage(); + void setMetalnessRoughnessAmbientOcclusionMapImage(QImage* image); bool hasMetalnessInImage(); void setHasMetalnessInImage(bool hasInImage); bool hasRoughnessInImage(); @@ -47,21 +46,22 @@ public: void setHasAmbientOcclusionInImage(bool hasInImage); static float m_defaultMetalness; static float m_defaultRoughness; - void exportAsObj(const QString &filename); - void exportAsObj(QTextStream *textStream); - void updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount); + void exportAsObj(const QString& filename); + void exportAsObj(QTextStream* textStream); + void updateTriangleVertices(ModelOpenGLVertex* triangleVertices, int triangleVertexCount); quint64 meshId() const; void setMeshId(quint64 id); void removeColor(); + private: - ModelOpenGLVertex *m_triangleVertices = nullptr; + ModelOpenGLVertex* m_triangleVertices = nullptr; int m_triangleVertexCount = 0; std::vector m_vertices; std::vector> m_faces; std::vector m_triangulatedVertices; - QImage *m_textureImage = nullptr; - QImage *m_normalMapImage = nullptr; - QImage *m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; + QImage* m_textureImage = nullptr; + QImage* m_normalMapImage = nullptr; + QImage* m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; bool m_hasMetalnessInImage = false; bool m_hasRoughnessInImage = false; bool m_hasAmbientOcclusionInImage = false; diff --git a/application/sources/model_offscreen_render.cc b/application/sources/model_offscreen_render.cc index 35c29681..50dd27f2 100644 --- a/application/sources/model_offscreen_render.cc +++ b/application/sources/model_offscreen_render.cc @@ -2,10 +2,10 @@ #include "model_opengl_object.h" #include "model_opengl_program.h" -ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat &format, QScreen *targetScreen): - QOffscreenSurface(targetScreen), - m_context(nullptr), - m_mesh(nullptr) +ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat& format, QScreen* targetScreen) + : QOffscreenSurface(targetScreen) + , m_context(nullptr) + , m_mesh(nullptr) { setFormat(format); create(); @@ -13,11 +13,11 @@ ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat &format, QScreen ModelOffscreenRender::~ModelOffscreenRender() { - // FIXME: If delete m_renderFbo inside toImage, + // FIXME: If delete m_renderFbo inside toImage, // sometimes, the application will freeze, maybe there are dead locks inside the destruction call // move it here can make sure it will be deleted on the main GUI thread to avoid dead locks delete m_renderFbo; - + destroy(); delete m_mesh; } @@ -37,28 +37,28 @@ void ModelOffscreenRender::setZRotation(int angle) m_zRot = angle; } -void ModelOffscreenRender::setEyePosition(const QVector3D &eyePosition) +void ModelOffscreenRender::setEyePosition(const QVector3D& eyePosition) { m_eyePosition = eyePosition; } -void ModelOffscreenRender::setMoveToPosition(const QVector3D &moveToPosition) +void ModelOffscreenRender::setMoveToPosition(const QVector3D& moveToPosition) { m_moveToPosition = moveToPosition; } -void ModelOffscreenRender::setRenderThread(QThread *thread) +void ModelOffscreenRender::setRenderThread(QThread* thread) { moveToThread(thread); } -void ModelOffscreenRender::updateMesh(ModelMesh *mesh) +void ModelOffscreenRender::updateMesh(ModelMesh* mesh) { delete m_mesh; m_mesh = mesh; } -QImage ModelOffscreenRender::toImage(const QSize &size) +QImage ModelOffscreenRender::toImage(const QSize& size) { QImage image; @@ -105,7 +105,7 @@ QImage ModelOffscreenRender::toImage(const QSize &size) m_renderFbo = new QOpenGLFramebufferObject(size, format); m_renderFbo->bind(); - QOpenGLFunctions *f = m_context->functions(); + QOpenGLFunctions* f = m_context->functions(); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/application/sources/model_offscreen_render.h b/application/sources/model_offscreen_render.h index 79047633..4381e6ea 100644 --- a/application/sources/model_offscreen_render.h +++ b/application/sources/model_offscreen_render.h @@ -1,34 +1,34 @@ #ifndef DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ #define DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ +#include "model_mesh.h" #include #include #include #include -#include "model_mesh.h" -class ModelOffscreenRender: public QOffscreenSurface -{ +class ModelOffscreenRender : public QOffscreenSurface { public: - ModelOffscreenRender(const QSurfaceFormat &format, QScreen *targetScreen=Q_NULLPTR); + ModelOffscreenRender(const QSurfaceFormat& format, QScreen* targetScreen = Q_NULLPTR); ~ModelOffscreenRender(); void setXRotation(int angle); void setYRotation(int angle); void setZRotation(int angle); - void setEyePosition(const QVector3D &eyePosition); - void setMoveToPosition(const QVector3D &moveToPosition); - void setRenderThread(QThread *thread); - void updateMesh(ModelMesh *mesh); - QImage toImage(const QSize &size); + void setEyePosition(const QVector3D& eyePosition); + void setMoveToPosition(const QVector3D& moveToPosition); + void setRenderThread(QThread* thread); + void updateMesh(ModelMesh* mesh); + QImage toImage(const QSize& size); + private: int m_xRot = 0; int m_yRot = 0; int m_zRot = 0; QVector3D m_eyePosition; QVector3D m_moveToPosition; - QOpenGLContext *m_context = nullptr; - QOpenGLFramebufferObject *m_renderFbo = nullptr; - ModelMesh *m_mesh = nullptr; + QOpenGLContext* m_context = nullptr; + QOpenGLFramebufferObject* m_renderFbo = nullptr; + ModelMesh* m_mesh = nullptr; }; #endif diff --git a/application/sources/model_opengl_object.cc b/application/sources/model_opengl_object.cc index 3cf116c6..9852a151 100644 --- a/application/sources/model_opengl_object.cc +++ b/application/sources/model_opengl_object.cc @@ -1,7 +1,7 @@ -#include -#include -#include #include "model_opengl_object.h" +#include +#include +#include void ModelOpenGLObject::update(std::unique_ptr mesh) { @@ -15,7 +15,7 @@ void ModelOpenGLObject::draw() copyMeshToOpenGL(); if (0 == m_meshTriangleVertexCount) return; - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); f->glDrawArrays(GL_TRIANGLES, 0, m_meshTriangleVertexCount); } @@ -43,7 +43,7 @@ void ModelOpenGLObject::copyMeshToOpenGL() m_buffer.bind(); m_buffer.allocate(mesh->triangleVertices(), mesh->triangleVertexCount() * sizeof(ModelOpenGLVertex)); m_meshTriangleVertexCount = mesh->triangleVertexCount(); - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glEnableVertexAttribArray(2); @@ -53,13 +53,13 @@ void ModelOpenGLObject::copyMeshToOpenGL() f->glEnableVertexAttribArray(6); f->glEnableVertexAttribArray(7); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), 0); - f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(3 * sizeof(GLfloat))); - f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(6 * sizeof(GLfloat))); - f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(9 * sizeof(GLfloat))); - f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(11 * sizeof(GLfloat))); - f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(12 * sizeof(GLfloat))); - f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(13 * sizeof(GLfloat))); - f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(16 * sizeof(GLfloat))); + f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(3 * sizeof(GLfloat))); + f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(6 * sizeof(GLfloat))); + f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(9 * sizeof(GLfloat))); + f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(11 * sizeof(GLfloat))); + f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(12 * sizeof(GLfloat))); + f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(13 * sizeof(GLfloat))); + f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast(16 * sizeof(GLfloat))); m_buffer.release(); } } \ No newline at end of file diff --git a/application/sources/model_opengl_object.h b/application/sources/model_opengl_object.h index 2a0a2455..83cba77b 100644 --- a/application/sources/model_opengl_object.h +++ b/application/sources/model_opengl_object.h @@ -1,17 +1,17 @@ #ifndef DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ #define DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ -#include -#include -#include -#include #include "model_mesh.h" +#include +#include +#include +#include -class ModelOpenGLObject -{ +class ModelOpenGLObject { public: void update(std::unique_ptr mesh); void draw(); + private: void copyMeshToOpenGL(); QOpenGLVertexArrayObject m_vertexArrayObject; diff --git a/application/sources/model_opengl_program.cc b/application/sources/model_opengl_program.cc index 24561dfe..1e2a3e5d 100644 --- a/application/sources/model_opengl_program.cc +++ b/application/sources/model_opengl_program.cc @@ -1,11 +1,11 @@ -#include -#include -#include -#include #include "model_opengl_program.h" #include "dds_file.h" +#include +#include +#include +#include -static const QString &loadShaderSource(const QString &name) +static const QString& loadShaderSource(const QString& name) { static std::map s_shaderSources; auto findShader = s_shaderSources.find(name); @@ -15,11 +15,11 @@ static const QString &loadShaderSource(const QString &name) QFile file(name); file.open(QFile::ReadOnly | QFile::Text); QTextStream stream(&file); - auto insertResult = s_shaderSources.insert({name, stream.readAll()}); + auto insertResult = s_shaderSources.insert({ name, stream.readAll() }); return insertResult.first->second; } -void ModelOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName) +void ModelOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName) { if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); @@ -57,7 +57,7 @@ void ModelOpenGLProgram::updateMetalnessRoughnessAmbientOcclusionMapImage(std::u m_imageIsDirty = true; } -void ModelOpenGLProgram::activeAndBindTexture(int location, QOpenGLTexture *texture) +void ModelOpenGLProgram::activeAndBindTexture(int location, QOpenGLTexture* texture) { if (0 == texture->textureId()) { dust3dDebug << "Expected texture with a bound id"; @@ -105,7 +105,7 @@ void ModelOpenGLProgram::bindMaps() DdsFileReader irradianceFile(":/resources/cedar_bridge_specular.dds"); m_environmentSpecularMap.reset(irradianceFile.createOpenGLTexture()); } - + bindLocation++; activeAndBindTexture(bindLocation, m_environmentIrradianceMap.get()); setUniformValue(getUniformLocationByName("environmentIrradianceMapId"), bindLocation); @@ -224,12 +224,12 @@ void ModelOpenGLProgram::releaseMaps() } } -int ModelOpenGLProgram::getUniformLocationByName(const std::string &name) +int ModelOpenGLProgram::getUniformLocationByName(const std::string& name) { auto findLocation = m_uniformLocationMap.find(name); if (findLocation != m_uniformLocationMap.end()) return findLocation->second; int location = uniformLocation(name.c_str()); - m_uniformLocationMap.insert({name, location}); + m_uniformLocationMap.insert({ name, location }); return location; } diff --git a/application/sources/model_opengl_program.h b/application/sources/model_opengl_program.h index 803b5647..7cd04869 100644 --- a/application/sources/model_opengl_program.h +++ b/application/sources/model_opengl_program.h @@ -1,30 +1,29 @@ #ifndef DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ #define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ -#include -#include -#include -#include #include +#include +#include +#include +#include -class ModelOpenGLProgram: public QOpenGLShaderProgram -{ +class ModelOpenGLProgram : public QOpenGLShaderProgram { public: - void load(bool isCoreProfile=false); - int getUniformLocationByName(const std::string &name); + void load(bool isCoreProfile = false); + int getUniformLocationByName(const std::string& name); bool isCoreProfile() const; void bindMaps(); void releaseMaps(); void updateTextureImage(std::unique_ptr image); void updateNormalMapImage(std::unique_ptr image); void updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr image, - bool hasMetalnessMap = false, - bool hasRoughnessMap = false, + bool hasMetalnessMap = false, + bool hasRoughnessMap = false, bool hasAmbientOcclusionMap = false); private: - void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName); - void activeAndBindTexture(int location, QOpenGLTexture *texture); + void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName); + void activeAndBindTexture(int location, QOpenGLTexture* texture); bool m_isLoaded = false; bool m_isCoreProfile = false; diff --git a/application/sources/model_widget.cc b/application/sources/model_widget.cc index 5bf4da49..d1aa5ec6 100644 --- a/application/sources/model_widget.cc +++ b/application/sources/model_widget.cc @@ -1,11 +1,11 @@ -#include -#include -#include -#include -#include -#include #include "model_widget.h" #include "dds_file.h" +#include +#include +#include +#include +#include +#include float ModelWidget::m_minZoomRatio = 5.0; float ModelWidget::m_maxZoomRatio = 80.0; @@ -18,36 +18,36 @@ QString ModelWidget::m_openGLVersion = ""; QString ModelWidget::m_openGLShadingLanguageVersion = ""; bool ModelWidget::m_openGLIsCoreProfile = false; -ModelWidget::ModelWidget(QWidget *parent) : - QOpenGLWidget(parent) +ModelWidget::ModelWidget(QWidget* parent) + : QOpenGLWidget(parent) { setAttribute(Qt::WA_AlwaysStackOnTop); setAttribute(Qt::WA_TranslucentBackground); - + QSurfaceFormat fmt = format(); fmt.setAlphaBufferSize(8); fmt.setSamples(4); setFormat(fmt); setContextMenuPolicy(Qt::CustomContextMenu); - + m_widthInPixels = width() * window()->devicePixelRatio(); - m_heightInPixels = height() * window()->devicePixelRatio(); - + m_heightInPixels = height() * window()->devicePixelRatio(); + zoom(200); } -const QVector3D &ModelWidget::eyePosition() +const QVector3D& ModelWidget::eyePosition() { - return m_eyePosition; + return m_eyePosition; } -const QVector3D &ModelWidget::moveToPosition() +const QVector3D& ModelWidget::moveToPosition() { return m_moveToPosition; } -void ModelWidget::setEyePosition(const QVector3D &eyePosition) +void ModelWidget::setEyePosition(const QVector3D& eyePosition) { m_eyePosition = eyePosition; emit eyePositionChanged(m_eyePosition); @@ -130,7 +130,7 @@ void ModelWidget::disableCullFace() m_enableCullFace = false; } -void ModelWidget::setMoveToPosition(const QVector3D &moveToPosition) +void ModelWidget::setMoveToPosition(const QVector3D& moveToPosition) { m_moveToPosition = moveToPosition; } @@ -144,13 +144,13 @@ void ModelWidget::updateProjectionMatrix() void ModelWidget::resizeGL(int w, int h) { - m_widthInPixels = w * window()->devicePixelRatio(); - m_heightInPixels = h * window()->devicePixelRatio(); + m_widthInPixels = w * window()->devicePixelRatio(); + m_heightInPixels = h * window()->devicePixelRatio(); updateProjectionMatrix(); emit renderParametersChanged(); } -std::pair ModelWidget::screenPositionToMouseRay(const QPoint &screenPosition) +std::pair ModelWidget::screenPositionToMouseRay(const QPoint& screenPosition) { auto modelView = m_camera * m_world; float x = qMax(qMin(screenPosition.x(), width() - 1), 0); @@ -190,12 +190,11 @@ void ModelWidget::toggleRotation() } } -bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent *event, bool notGraphics) +bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent* event, bool notGraphics) { bool shouldStartMove = false; if (event->button() == Qt::LeftButton) { - if ((notGraphics || QGuiApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) && - !QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) { + if ((notGraphics || QGuiApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) && !QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) { shouldStartMove = m_moveEnabled; } if (!shouldStartMove && !m_mousePickTargetPositionInModelSpace.isNull()) @@ -216,7 +215,7 @@ bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent *event, bool n return false; } -bool ModelWidget::inputMouseReleaseEventFromOtherWidget(QMouseEvent *event) +bool ModelWidget::inputMouseReleaseEventFromOtherWidget(QMouseEvent* event) { Q_UNUSED(event); if (m_moveStarted) { @@ -235,10 +234,10 @@ void ModelWidget::canvasResized() resize(parentWidget()->size()); } -bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event) +bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent* event) { QPoint pos = convertInputPosFromOtherWidget(event); - + if (m_mousePickingEnabled) { auto segment = screenPositionToMouseRay(pos); emit mouseRayChanged(segment.first, segment.second); @@ -247,12 +246,11 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event) if (!m_moveStarted) { return false; } - + int dx = pos.x() - m_lastPos.x(); int dy = pos.y() - m_lastPos.y(); - if ((event->buttons() & Qt::MidButton) || - (m_moveStarted && (event->buttons() & Qt::LeftButton))) { + if ((event->buttons() & Qt::MidButton) || (m_moveStarted && (event->buttons() & Qt::LeftButton))) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { if (m_moveStarted) { if (m_moveAndZoomByWindow) { @@ -283,27 +281,27 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event) } } m_lastPos = pos; - + return true; } -QPoint ModelWidget::convertInputPosFromOtherWidget(QMouseEvent *event) +QPoint ModelWidget::convertInputPosFromOtherWidget(QMouseEvent* event) { return mapFromGlobal(event->globalPos()); } -bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent *event) +bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent* event) { if (m_moveStarted) return true; - + if (m_mousePickingEnabled) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { emit addMouseRadius((float)event->delta() / 200 / height()); return true; } } - + if (!m_zoomEnabled) return false; @@ -311,7 +309,7 @@ bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent *event) if (event->delta() < 0) delta = -delta; zoom(delta); - + return true; } @@ -359,7 +357,7 @@ void ModelWidget::setMousePickRadius(float radius) update(); } -void ModelWidget::updateMesh(ModelMesh *mesh) +void ModelWidget::updateMesh(ModelMesh* mesh) { if (!m_modelOpenGLProgram) m_modelOpenGLProgram = std::make_unique(); @@ -369,7 +367,7 @@ void ModelWidget::updateMesh(ModelMesh *mesh) mesh && mesh->hasMetalnessInImage(), mesh && mesh->hasRoughnessInImage(), mesh && mesh->hasAmbientOcclusionInImage()); - + if (!m_modelOpenGLObject) m_modelOpenGLObject = std::make_unique(); m_modelOpenGLObject->update(std::unique_ptr(mesh)); @@ -378,7 +376,7 @@ void ModelWidget::updateMesh(ModelMesh *mesh) update(); } -void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh) +void ModelWidget::updateWireframeMesh(MonochromeMesh* mesh) { if (!m_wireframeOpenGLObject) m_wireframeOpenGLObject = std::make_unique(); @@ -389,12 +387,12 @@ void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh) int ModelWidget::widthInPixels() { - return m_widthInPixels; + return m_widthInPixels; } int ModelWidget::heightInPixels() { - return m_heightInPixels; + return m_heightInPixels; } void ModelWidget::enableMove(bool enabled) @@ -417,22 +415,22 @@ void ModelWidget::setMoveAndZoomByWindow(bool byWindow) m_moveAndZoomByWindow = byWindow; } -void ModelWidget::mousePressEvent(QMouseEvent *event) +void ModelWidget::mousePressEvent(QMouseEvent* event) { inputMousePressEventFromOtherWidget(event, m_notGraphics); } -void ModelWidget::mouseMoveEvent(QMouseEvent *event) +void ModelWidget::mouseMoveEvent(QMouseEvent* event) { inputMouseMoveEventFromOtherWidget(event); } -void ModelWidget::wheelEvent(QWheelEvent *event) +void ModelWidget::wheelEvent(QWheelEvent* event) { inputWheelEventFromOtherWidget(event); } -void ModelWidget::mouseReleaseEvent(QMouseEvent *event) +void ModelWidget::mouseReleaseEvent(QMouseEvent* event) { inputMouseReleaseEventFromOtherWidget(event); } @@ -442,7 +440,7 @@ void ModelWidget::setNotGraphics(bool notGraphics) m_notGraphics = notGraphics; } -void ModelWidget::normalizeAngle(int &angle) +void ModelWidget::normalizeAngle(int& angle) { while (angle < 0) angle += 360 * 16; @@ -455,10 +453,10 @@ void ModelWidget::initializeGL() connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup); if (m_openGLVersion.isEmpty()) { - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - const char *openGLVersion = (const char *)f->glGetString(GL_VERSION); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); + const char* openGLVersion = (const char*)f->glGetString(GL_VERSION); m_openGLVersion = nullptr != openGLVersion ? openGLVersion : ""; - const char *shadingLanguageVersion = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + const char* shadingLanguageVersion = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION); m_openGLShadingLanguageVersion = nullptr != shadingLanguageVersion ? shadingLanguageVersion : ""; m_openGLIsCoreProfile = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; } @@ -466,7 +464,7 @@ void ModelWidget::initializeGL() void ModelWidget::paintGL() { - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); f->glEnable(GL_BLEND); @@ -485,13 +483,13 @@ void ModelWidget::paintGL() f->glEnable(GL_POLYGON_OFFSET_FILL); f->glPolygonOffset(1.0, 1.0); - f->glViewport(0, 0, m_widthInPixels, m_heightInPixels); + f->glViewport(0, 0, m_widthInPixels, m_heightInPixels); m_world.setToIdentity(); m_world.rotate(m_xRot / 16.0f, 1, 0, 0); m_world.rotate(m_yRot / 16.0f, 0, 1, 0); m_world.rotate(m_zRot / 16.0f, 0, 0, 1); - + m_camera.setToIdentity(); m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z()); @@ -506,7 +504,7 @@ void ModelWidget::paintGL() m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile); } } - + drawModel(); if (m_isWireframeVisible) { drawWireframe(); diff --git a/application/sources/model_widget.h b/application/sources/model_widget.h index d5612e7b..e118dd71 100644 --- a/application/sources/model_widget.h +++ b/application/sources/model_widget.h @@ -1,27 +1,26 @@ #ifndef DUST3D_APPLICATION_MODEL_WIDGET_H_ #define DUST3D_APPLICATION_MODEL_WIDGET_H_ -#include -#include -#include -#include +#include "model_mesh.h" +#include "model_opengl_object.h" +#include "model_opengl_program.h" +#include "monochrome_mesh.h" +#include "monochrome_opengl_object.h" +#include "monochrome_opengl_program.h" #include #include -#include -#include +#include +#include +#include #include -#include "model_mesh.h" -#include "model_opengl_program.h" -#include "model_opengl_object.h" -#include "monochrome_mesh.h" -#include "monochrome_opengl_program.h" -#include "monochrome_opengl_object.h" +#include +#include +#include -class ModelWidget : public QOpenGLWidget -{ +class ModelWidget : public QOpenGLWidget { Q_OBJECT signals: - void mouseRayChanged(const QVector3D &near, const QVector3D &far); + void mouseRayChanged(const QVector3D& near, const QVector3D& far); void mousePressed(); void mouseReleased(); void addMouseRadius(float radius); @@ -29,13 +28,14 @@ signals: void xRotationChanged(int angle); void yRotationChanged(int angle); void zRotationChanged(int angle); - void eyePositionChanged(const QVector3D &eyePosition); - void moveToPositionChanged(const QVector3D &moveToPosition); + void eyePositionChanged(const QVector3D& eyePosition); + void moveToPositionChanged(const QVector3D& moveToPosition); + public: - ModelWidget(QWidget *parent = 0); + ModelWidget(QWidget* parent = 0); ~ModelWidget(); - void updateMesh(ModelMesh *mesh); - void updateWireframeMesh(MonochromeMesh *mesh); + void updateMesh(ModelMesh* mesh); + void updateWireframeMesh(MonochromeMesh* mesh); void toggleWireframe(); bool isWireframeVisible(); void toggleRotation(); @@ -44,40 +44,42 @@ public: void enableMousePicking(bool enabled); void setMoveAndZoomByWindow(bool byWindow); void disableCullFace(); - void setMoveToPosition(const QVector3D &moveToPosition); - bool inputMousePressEventFromOtherWidget(QMouseEvent *event, bool notGraphics=false); - bool inputMouseMoveEventFromOtherWidget(QMouseEvent *event); - bool inputWheelEventFromOtherWidget(QWheelEvent *event); - bool inputMouseReleaseEventFromOtherWidget(QMouseEvent *event); - QPoint convertInputPosFromOtherWidget(QMouseEvent *event); + void setMoveToPosition(const QVector3D& moveToPosition); + bool inputMousePressEventFromOtherWidget(QMouseEvent* event, bool notGraphics = false); + bool inputMouseMoveEventFromOtherWidget(QMouseEvent* event); + bool inputWheelEventFromOtherWidget(QWheelEvent* event); + bool inputMouseReleaseEventFromOtherWidget(QMouseEvent* event); + QPoint convertInputPosFromOtherWidget(QMouseEvent* event); int widthInPixels(); int heightInPixels(); void setNotGraphics(bool notGraphics); int xRot(); int yRot(); int zRot(); - const QVector3D &eyePosition(); - const QVector3D &moveToPosition(); - const QString &openGLVersion(); + const QVector3D& eyePosition(); + const QVector3D& moveToPosition(); + const QString& openGLVersion(); public slots: void setXRotation(int angle); void setYRotation(int angle); void setZRotation(int angle); - void setEyePosition(const QVector3D &eyePosition); + void setEyePosition(const QVector3D& eyePosition); void cleanup(); void zoom(float delta); void setMousePickTargetPositionInModelSpace(QVector3D position); void setMousePickRadius(float radius); void reRender(); void canvasResized(); + protected: void initializeGL() override; void paintGL() override; void resizeGL(int width, int height) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void wheelEvent(QWheelEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + private: int m_xRot = m_defaultXRotation; int m_yRot = m_defaultYRotation; @@ -103,7 +105,7 @@ private: QPoint m_moveStartPos; QRect m_moveStartGeometry; int m_modelInitialHeight = 0; - QTimer *m_rotationTimer = nullptr; + QTimer* m_rotationTimer = nullptr; int m_widthInPixels = 0; int m_heightInPixels = 0; QVector3D m_moveToPosition; @@ -111,11 +113,12 @@ private: bool m_enableCullFace = true; bool m_notGraphics = false; bool m_isWireframeVisible = false; - std::pair screenPositionToMouseRay(const QPoint &screenPosition); + std::pair screenPositionToMouseRay(const QPoint& screenPosition); void updateProjectionMatrix(); - void normalizeAngle(int &angle); + void normalizeAngle(int& angle); void drawModel(); void drawWireframe(); + public: static int m_defaultXRotation; static int m_defaultYRotation; diff --git a/application/sources/monochrome_mesh.cc b/application/sources/monochrome_mesh.cc index 824f9ead..3bfcf1bb 100644 --- a/application/sources/monochrome_mesh.cc +++ b/application/sources/monochrome_mesh.cc @@ -1,59 +1,57 @@ -#include #include "monochrome_mesh.h" +#include -MonochromeMesh::MonochromeMesh(const MonochromeMesh &mesh) +MonochromeMesh::MonochromeMesh(const MonochromeMesh& mesh) { m_lineVertices = mesh.m_lineVertices; } -MonochromeMesh::MonochromeMesh(MonochromeMesh &&mesh) +MonochromeMesh::MonochromeMesh(MonochromeMesh&& mesh) { m_lineVertices = std::move(mesh.m_lineVertices); } -MonochromeMesh::MonochromeMesh(const dust3d::Object &object) +MonochromeMesh::MonochromeMesh(const dust3d::Object& object) { std::set> halfEdges; - for (const auto &face: object.triangleAndQuads) { + for (const auto& face : object.triangleAndQuads) { if (3 == face.size()) { - halfEdges.insert({face[0], face[1]}); - halfEdges.insert({face[1], face[0]}); - halfEdges.insert({face[1], face[2]}); - halfEdges.insert({face[2], face[1]}); - halfEdges.insert({face[2], face[0]}); - halfEdges.insert({face[0], face[2]}); + halfEdges.insert({ face[0], face[1] }); + halfEdges.insert({ face[1], face[0] }); + halfEdges.insert({ face[1], face[2] }); + halfEdges.insert({ face[2], face[1] }); + halfEdges.insert({ face[2], face[0] }); + halfEdges.insert({ face[0], face[2] }); continue; } - halfEdges.insert({face[0], face[1]}); - halfEdges.insert({face[1], face[0]}); - halfEdges.insert({face[1], face[2]}); - halfEdges.insert({face[2], face[1]}); - halfEdges.insert({face[2], face[3]}); - halfEdges.insert({face[3], face[2]}); - halfEdges.insert({face[3], face[0]}); - halfEdges.insert({face[0], face[3]}); + halfEdges.insert({ face[0], face[1] }); + halfEdges.insert({ face[1], face[0] }); + halfEdges.insert({ face[1], face[2] }); + halfEdges.insert({ face[2], face[1] }); + halfEdges.insert({ face[2], face[3] }); + halfEdges.insert({ face[3], face[2] }); + halfEdges.insert({ face[3], face[0] }); + halfEdges.insert({ face[0], face[3] }); } m_lineVertices.reserve(halfEdges.size() * 2); - for (const auto &halfEdge: halfEdges) { + for (const auto& halfEdge : halfEdges) { // For two halfedges shared one edge, only output one line if (halfEdge.first > halfEdge.second) continue; - const auto &from = object.vertices[halfEdge.first]; - const auto &to = object.vertices[halfEdge.second]; + const auto& from = object.vertices[halfEdge.first]; + const auto& to = object.vertices[halfEdge.second]; m_lineVertices.emplace_back(MonochromeOpenGLVertex { - (GLfloat)from.x(), - (GLfloat)from.y(), - (GLfloat)from.z() - }); + (GLfloat)from.x(), + (GLfloat)from.y(), + (GLfloat)from.z() }); m_lineVertices.emplace_back(MonochromeOpenGLVertex { - (GLfloat)to.x(), - (GLfloat)to.y(), - (GLfloat)to.z() - }); + (GLfloat)to.x(), + (GLfloat)to.y(), + (GLfloat)to.z() }); } } -const MonochromeOpenGLVertex *MonochromeMesh::lineVertices() +const MonochromeOpenGLVertex* MonochromeMesh::lineVertices() { if (m_lineVertices.empty()) return nullptr; diff --git a/application/sources/monochrome_mesh.h b/application/sources/monochrome_mesh.h index bc046bff..ad58f355 100644 --- a/application/sources/monochrome_mesh.h +++ b/application/sources/monochrome_mesh.h @@ -1,21 +1,20 @@ #ifndef DUST3D_APPLICATION_MONOCHROME_MESH_H_ #define DUST3D_APPLICATION_MONOCHROME_MESH_H_ -#include -#include #include "monochrome_opengl_vertex.h" +#include +#include -class MonochromeMesh -{ +class MonochromeMesh { public: - MonochromeMesh(const MonochromeMesh &mesh); - MonochromeMesh(MonochromeMesh &&mesh); - MonochromeMesh(const dust3d::Object &object); - const MonochromeOpenGLVertex *lineVertices(); + MonochromeMesh(const MonochromeMesh& mesh); + MonochromeMesh(MonochromeMesh&& mesh); + MonochromeMesh(const dust3d::Object& object); + const MonochromeOpenGLVertex* lineVertices(); int lineVertexCount(); + private: std::vector m_lineVertices; }; #endif - diff --git a/application/sources/monochrome_opengl_object.cc b/application/sources/monochrome_opengl_object.cc index 2d693e14..78cc84ca 100644 --- a/application/sources/monochrome_opengl_object.cc +++ b/application/sources/monochrome_opengl_object.cc @@ -1,7 +1,7 @@ -#include -#include -#include #include "monochrome_opengl_object.h" +#include +#include +#include void MonochromeOpenGLObject::update(std::unique_ptr mesh) { @@ -15,7 +15,7 @@ void MonochromeOpenGLObject::draw() copyMeshToOpenGL(); if (0 == m_meshLineVertexCount) return; - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); f->glDrawArrays(GL_LINES, 0, m_meshLineVertexCount); } @@ -43,13 +43,13 @@ void MonochromeOpenGLObject::copyMeshToOpenGL() m_buffer.bind(); m_buffer.allocate(mesh->lineVertices(), mesh->lineVertexCount() * sizeof(MonochromeOpenGLVertex)); m_meshLineVertexCount = mesh->lineVertexCount(); - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glEnableVertexAttribArray(2); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), 0); - f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(3 * sizeof(GLfloat))); - f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(6 * sizeof(GLfloat))); + f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(3 * sizeof(GLfloat))); + f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast(6 * sizeof(GLfloat))); m_buffer.release(); } } \ No newline at end of file diff --git a/application/sources/monochrome_opengl_object.h b/application/sources/monochrome_opengl_object.h index 856799e7..5ac7da93 100644 --- a/application/sources/monochrome_opengl_object.h +++ b/application/sources/monochrome_opengl_object.h @@ -1,17 +1,17 @@ #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ #define DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ -#include -#include -#include -#include #include "monochrome_mesh.h" +#include +#include +#include +#include -class MonochromeOpenGLObject -{ +class MonochromeOpenGLObject { public: void update(std::unique_ptr mesh); void draw(); + private: void copyMeshToOpenGL(); QOpenGLVertexArrayObject m_vertexArrayObject; diff --git a/application/sources/monochrome_opengl_program.cc b/application/sources/monochrome_opengl_program.cc index 25417d29..31ad7c11 100644 --- a/application/sources/monochrome_opengl_program.cc +++ b/application/sources/monochrome_opengl_program.cc @@ -1,9 +1,9 @@ -#include -#include -#include #include "monochrome_opengl_program.h" +#include +#include +#include -static const QString &loadShaderSource(const QString &name) +static const QString& loadShaderSource(const QString& name) { static std::map s_shaderSources; auto findShader = s_shaderSources.find(name); @@ -13,11 +13,11 @@ static const QString &loadShaderSource(const QString &name) QFile file(name); file.open(QFile::ReadOnly | QFile::Text); QTextStream stream(&file); - auto insertResult = s_shaderSources.insert({name, stream.readAll()}); + auto insertResult = s_shaderSources.insert({ name, stream.readAll() }); return insertResult.first->second; } -void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName) +void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName) { if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); @@ -49,12 +49,12 @@ void MonochromeOpenGLProgram::load(bool isCoreProfile) m_isLoaded = true; } -int MonochromeOpenGLProgram::getUniformLocationByName(const std::string &name) +int MonochromeOpenGLProgram::getUniformLocationByName(const std::string& name) { auto findLocation = m_uniformLocationMap.find(name); if (findLocation != m_uniformLocationMap.end()) return findLocation->second; int location = uniformLocation(name.c_str()); - m_uniformLocationMap.insert({name, location}); + m_uniformLocationMap.insert({ name, location }); return location; } diff --git a/application/sources/monochrome_opengl_program.h b/application/sources/monochrome_opengl_program.h index aac445f0..229d6524 100644 --- a/application/sources/monochrome_opengl_program.h +++ b/application/sources/monochrome_opengl_program.h @@ -1,19 +1,18 @@ #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ #define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ -#include -#include #include +#include +#include -class MonochromeOpenGLProgram: public QOpenGLShaderProgram -{ +class MonochromeOpenGLProgram : public QOpenGLShaderProgram { public: - void load(bool isCoreProfile=false); - int getUniformLocationByName(const std::string &name); + void load(bool isCoreProfile = false); + int getUniformLocationByName(const std::string& name); bool isCoreProfile() const; private: - void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName); + void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName); bool m_isLoaded = false; bool m_isCoreProfile = false; diff --git a/application/sources/part_manage_widget.cc b/application/sources/part_manage_widget.cc index 0a28c7dd..6d8e27d9 100644 --- a/application/sources/part_manage_widget.cc +++ b/application/sources/part_manage_widget.cc @@ -1,27 +1,27 @@ -#include -#include -#include #include "part_manage_widget.h" +#include "component_list_model.h" #include "component_preview_grid_widget.h" #include "component_property_widget.h" -#include "component_list_model.h" -#include "theme.h" #include "document.h" +#include "theme.h" +#include +#include +#include -PartManageWidget::PartManageWidget(Document *document, QWidget *parent): - QWidget(parent), - m_document(document) +PartManageWidget::PartManageWidget(Document* document, QWidget* parent) + : QWidget(parent) + , m_document(document) { setContextMenuPolicy(Qt::CustomContextMenu); - QHBoxLayout *toolsLayout = new QHBoxLayout; + QHBoxLayout* toolsLayout = new QHBoxLayout; toolsLayout->setSpacing(0); toolsLayout->setMargin(0); setStyleSheet("QPushButton:disabled {border: 0; color: " + Theme::gray.name() + "}"); - auto createButton = [](QChar icon, const QString &title) { - QPushButton *button = new QPushButton(icon); + auto createButton = [](QChar icon, const QString& title) { + QPushButton* button = new QPushButton(icon); Theme::initIconButton(button); button->setToolTip(title); return button; @@ -58,50 +58,50 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent): //connect(m_componentPreviewGridWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PartManageWidget::showSelectedComponentProperties); connect(m_levelUpButton, &QPushButton::clicked, [this]() { - const auto &parent = m_document->findComponentParent(this->m_componentPreviewGridWidget->componentListModel()->listingComponentId()); + const auto& parent = m_document->findComponentParent(this->m_componentPreviewGridWidget->componentListModel()->listingComponentId()); if (nullptr == parent) return; this->m_componentPreviewGridWidget->componentListModel()->setListingComponentId(parent->id); }); connect(m_hideButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartVisibleState(partId, false); this->m_document->saveSnapshot(); }); connect(m_showButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartVisibleState(partId, true); this->m_document->saveSnapshot(); }); connect(m_unlockButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartLockState(partId, false); this->m_document->saveSnapshot(); }); connect(m_lockButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartLockState(partId, true); this->m_document->saveSnapshot(); }); connect(m_unlinkButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartDisableState(partId, true); this->m_document->saveSnapshot(); }); connect(m_linkButton, &QPushButton::clicked, [this]() { - for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) + for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds()) this->m_document->setPartDisableState(partId, false); this->m_document->saveSnapshot(); }); connect(m_selectButton, &QPushButton::clicked, [this]() { - for (const auto &componentId: this->m_componentPreviewGridWidget->getSelectedComponentIds()) { + for (const auto& componentId : this->m_componentPreviewGridWidget->getSelectedComponentIds()) { std::vector partIds; this->m_document->collectComponentDescendantParts(componentId, partIds); - for (const auto &partId: partIds) + for (const auto& partId : partIds) emit this->selectPartOnCanvas(partId); } }); @@ -119,7 +119,7 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent): connect(this, &PartManageWidget::customContextMenuRequested, this, &PartManageWidget::showContextMenu); - QVBoxLayout *mainLayout = new QVBoxLayout; + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addLayout(toolsLayout); mainLayout->addWidget(m_componentPreviewGridWidget); @@ -135,10 +135,10 @@ void PartManageWidget::showSelectedComponentProperties() if (componentIds.empty()) return; - auto *propertyWidget = new ComponentPropertyWidget(m_document, componentIds); + auto* propertyWidget = new ComponentPropertyWidget(m_document, componentIds); auto menu = std::make_unique(this->parentWidget()); - QWidgetAction *widgetAction = new QWidgetAction(menu.get()); + QWidgetAction* widgetAction = new QWidgetAction(menu.get()); widgetAction->setDefaultWidget(propertyWidget); menu->addAction(widgetAction); @@ -146,14 +146,13 @@ void PartManageWidget::showSelectedComponentProperties() if (x <= 0) x = QCursor::pos().x(); menu->exec(QPoint( - x - propertyWidget->width(), - QCursor::pos().y() - )); + x - propertyWidget->width(), + QCursor::pos().y())); } -void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId) +void PartManageWidget::selectComponentByPartId(const dust3d::Uuid& partId) { - const auto &part = m_document->findPart(partId); + const auto& part = m_document->findPart(partId); if (nullptr == part) return; auto componentId = part->componentId; @@ -163,7 +162,7 @@ void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId) m_componentPreviewGridWidget->scrollTo(index); return; } - const auto &component = m_document->findComponent(componentId); + const auto& component = m_document->findComponent(componentId); if (nullptr == component) return; m_componentPreviewGridWidget->componentListModel()->setListingComponentId(component->parentId); @@ -178,7 +177,7 @@ void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId) void PartManageWidget::updateLevelUpButton() { - const auto &parent = m_document->findComponentParent(m_componentPreviewGridWidget->componentListModel()->listingComponentId()); + const auto& parent = m_document->findComponentParent(m_componentPreviewGridWidget->componentListModel()->listingComponentId()); m_levelUpButton->setEnabled(nullptr != parent); } @@ -193,13 +192,13 @@ void PartManageWidget::updateToolButtons() bool enableUnlinkButton = false; bool enableLinkButton = false; bool enablePropertyButton = false; - for (const auto &component: selectedComponents) { + for (const auto& component : selectedComponents) { enablePropertyButton = true; enableSelectButton = true; if (component->linkToPartId.isNull()) { continue; } - const auto &part = m_document->findPart(component->linkToPartId); + const auto& part = m_document->findPart(component->linkToPartId); if (part->visible) { enableHideButton = true; } else { @@ -229,14 +228,14 @@ void PartManageWidget::updateToolButtons() bool PartManageWidget::hasSelectedGroupedComponent() { auto selectedComponents = m_componentPreviewGridWidget->getSelectedComponents(); - for (auto &component: selectedComponents) { + for (auto& component : selectedComponents) { if (!component->childrenIds.empty()) return true; } return false; } -void PartManageWidget::showContextMenu(const QPoint &pos) +void PartManageWidget::showContextMenu(const QPoint& pos) { auto selectedComponentIds = m_componentPreviewGridWidget->getSelectedComponentIds(); if (selectedComponentIds.empty()) @@ -255,7 +254,7 @@ void PartManageWidget::showContextMenu(const QPoint &pos) QAction ungroupAction(tr("Ungroup"), this); if (hasSelectedGroupedComponent()) { connect(&ungroupAction, &QAction::triggered, this, [=]() { - for (const auto &it: selectedComponentIds) + for (const auto& it : selectedComponentIds) emit this->ungroupComponent(it); emit this->groupOperationAdded(); }); diff --git a/application/sources/part_manage_widget.h b/application/sources/part_manage_widget.h index 0e611a3c..07ae5b4b 100644 --- a/application/sources/part_manage_widget.h +++ b/application/sources/part_manage_widget.h @@ -1,41 +1,42 @@ #ifndef DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ #define DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ -#include #include +#include class Document; class ComponentPreviewGridWidget; class ComponentPropertyWidget; class QPushButton; -class PartManageWidget: public QWidget -{ +class PartManageWidget : public QWidget { Q_OBJECT signals: void unselectAllOnCanvas(); - void selectPartOnCanvas(const dust3d::Uuid &partId); - void groupComponents(const std::vector &componentIds); - void ungroupComponent(const dust3d::Uuid &componentId); + void selectPartOnCanvas(const dust3d::Uuid& partId); + void groupComponents(const std::vector& componentIds); + void ungroupComponent(const dust3d::Uuid& componentId); void groupOperationAdded(); public slots: - void selectComponentByPartId(const dust3d::Uuid &partId); + void selectComponentByPartId(const dust3d::Uuid& partId); void showSelectedComponentProperties(); - void showContextMenu(const QPoint &pos); + void showContextMenu(const QPoint& pos); + public: - PartManageWidget(Document *document, QWidget *parent=nullptr); + PartManageWidget(Document* document, QWidget* parent = nullptr); + private: - Document *m_document = nullptr; - ComponentPreviewGridWidget *m_componentPreviewGridWidget = nullptr; - QPushButton *m_levelUpButton = nullptr; - QPushButton *m_selectButton = nullptr; - QPushButton *m_lockButton = nullptr; - QPushButton *m_unlockButton = nullptr; - QPushButton *m_showButton = nullptr; - QPushButton *m_hideButton = nullptr; - QPushButton *m_unlinkButton = nullptr; - QPushButton *m_linkButton = nullptr; - QPushButton *m_propertyButton = nullptr; + Document* m_document = nullptr; + ComponentPreviewGridWidget* m_componentPreviewGridWidget = nullptr; + QPushButton* m_levelUpButton = nullptr; + QPushButton* m_selectButton = nullptr; + QPushButton* m_lockButton = nullptr; + QPushButton* m_unlockButton = nullptr; + QPushButton* m_showButton = nullptr; + QPushButton* m_hideButton = nullptr; + QPushButton* m_unlinkButton = nullptr; + QPushButton* m_linkButton = nullptr; + QPushButton* m_propertyButton = nullptr; void updateToolButtons(); void updateLevelUpButton(); bool hasSelectedGroupedComponent(); diff --git a/application/sources/preferences.cc b/application/sources/preferences.cc index ba81ddda..c5388d0b 100644 --- a/application/sources/preferences.cc +++ b/application/sources/preferences.cc @@ -1,10 +1,10 @@ #include "preferences.h" -#define MAX_RECENT_FILES 7 +#define MAX_RECENT_FILES 7 -Preferences &Preferences::instance() +Preferences& Preferences::instance() { - static Preferences *s_preferences = nullptr; + static Preferences* s_preferences = nullptr; if (nullptr == s_preferences) { s_preferences = new Preferences; } @@ -40,15 +40,15 @@ int Preferences::maxRecentFiles() const return MAX_RECENT_FILES; } -void Preferences::setCurrentFile(const QString &fileName) +void Preferences::setCurrentFile(const QString& fileName) { QStringList files = m_settings.value("recentFileList").toStringList(); - + files.removeAll(fileName); files.prepend(fileName); while (files.size() > MAX_RECENT_FILES) files.removeLast(); - + m_settings.setValue("recentFileList", files); } @@ -57,6 +57,6 @@ void Preferences::reset() auto files = m_settings.value("recentFileList").toStringList(); m_settings.clear(); m_settings.setValue("recentFileList", files); - + loadDefault(); } diff --git a/application/sources/preferences.h b/application/sources/preferences.h index 058c06fd..81a26e5e 100644 --- a/application/sources/preferences.h +++ b/application/sources/preferences.h @@ -5,19 +5,19 @@ #include #include -class Preferences : public QObject -{ +class Preferences : public QObject { Q_OBJECT public: - static Preferences &instance(); + static Preferences& instance(); Preferences(); QSize documentWindowSize() const; void setDocumentWindowSize(const QSize&); QStringList recentFileList() const; int maxRecentFiles() const; public slots: - void setCurrentFile(const QString &fileName); + void setCurrentFile(const QString& fileName); void reset(); + private: QSettings m_settings; void loadDefault(); diff --git a/application/sources/preview_grid_view.cc b/application/sources/preview_grid_view.cc index b27cc09d..32320cde 100644 --- a/application/sources/preview_grid_view.cc +++ b/application/sources/preview_grid_view.cc @@ -1,8 +1,8 @@ #include "preview_grid_view.h" #include "theme.h" -PreviewGridView::PreviewGridView(QWidget *parent): - QListView(parent) +PreviewGridView::PreviewGridView(QWidget* parent) + : QListView(parent) { QPalette viewPalette = palette(); viewPalette.setColor(QPalette::Window, Qt::transparent); @@ -13,9 +13,7 @@ PreviewGridView::PreviewGridView(QWidget *parent): auto margin = Theme::previewIconMargin; auto borderRadius = Theme::previewIconBorderRadius; setStyleSheet( - "QListView::item {border:" + QString::number(borderSize) + "px solid transparent; margin:" + QString::number(margin) + "px; background-color: " + Theme::gray.name() +"; border-radius: " + QString::number(borderRadius) + ";}" + - "QListView::item:selected {border-color: " + Theme::red.name() + ";}" - ); + "QListView::item {border:" + QString::number(borderSize) + "px solid transparent; margin:" + QString::number(margin) + "px; background-color: " + Theme::gray.name() + "; border-radius: " + QString::number(borderRadius) + ";}" + "QListView::item:selected {border-color: " + Theme::red.name() + ";}"); setViewMode(QListView::IconMode); setGridSize(QSize(Theme::partPreviewImageSize, Theme::partPreviewImageSize)); diff --git a/application/sources/preview_grid_view.h b/application/sources/preview_grid_view.h index ee97d6ca..f00c5d7d 100644 --- a/application/sources/preview_grid_view.h +++ b/application/sources/preview_grid_view.h @@ -3,11 +3,10 @@ #include -class PreviewGridView: public QListView -{ +class PreviewGridView : public QListView { Q_OBJECT public: - PreviewGridView(QWidget *parent=nullptr); + PreviewGridView(QWidget* parent = nullptr); }; #endif diff --git a/application/sources/skeleton_document.cc b/application/sources/skeleton_document.cc index b9f6e5a7..829327b8 100644 --- a/application/sources/skeleton_document.cc +++ b/application/sources/skeleton_document.cc @@ -1,7 +1,7 @@ -#include #include "skeleton_document.h" +#include -const SkeletonNode *SkeletonDocument::findNode(dust3d::Uuid nodeId) const +const SkeletonNode* SkeletonDocument::findNode(dust3d::Uuid nodeId) const { auto it = nodeMap.find(nodeId); if (it == nodeMap.end()) @@ -9,7 +9,7 @@ const SkeletonNode *SkeletonDocument::findNode(dust3d::Uuid nodeId) const return &it->second; } -const SkeletonEdge *SkeletonDocument::findEdge(dust3d::Uuid edgeId) const +const SkeletonEdge* SkeletonDocument::findEdge(dust3d::Uuid edgeId) const { auto it = edgeMap.find(edgeId); if (it == edgeMap.end()) @@ -17,7 +17,7 @@ const SkeletonEdge *SkeletonDocument::findEdge(dust3d::Uuid edgeId) const return &it->second; } -const SkeletonPart *SkeletonDocument::findPart(dust3d::Uuid partId) const +const SkeletonPart* SkeletonDocument::findPart(dust3d::Uuid partId) const { auto it = partMap.find(partId); if (it == partMap.end()) @@ -25,9 +25,9 @@ const SkeletonPart *SkeletonDocument::findPart(dust3d::Uuid partId) const return &it->second; } -const SkeletonEdge *SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const +const SkeletonEdge* SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const { - const SkeletonNode *firstNode = nullptr; + const SkeletonNode* firstNode = nullptr; firstNode = findNode(firstNodeId); if (nullptr == firstNode) { return nullptr; @@ -43,18 +43,18 @@ const SkeletonEdge *SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId, return nullptr; } -void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::set &neighbors) const +void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::set& neighbors) const { - const auto &node = findNode(nodeId); + const auto& node = findNode(nodeId); if (nullptr == node) { return; } - for (const auto &edgeId: node->edgeIds) { - const auto &edge = findEdge(edgeId); + for (const auto& edgeId : node->edgeIds) { + const auto& edge = findEdge(edgeId); if (nullptr == edge) { continue; } - const auto &neighborNodeId = edge->neighborOf(nodeId); + const auto& neighborNodeId = edge->neighborOf(nodeId); if (neighborNodeId.isNull()) { continue; } @@ -68,7 +68,7 @@ void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::setedgeIds.size() < 2) @@ -78,7 +78,7 @@ bool SkeletonDocument::isNodeConnectable(dust3d::Uuid nodeId) const void SkeletonDocument::reduceNode(dust3d::Uuid nodeId) { - const SkeletonNode *node = findNode(nodeId); + const SkeletonNode* node = findNode(nodeId); if (nullptr == node) { return; } @@ -87,11 +87,11 @@ void SkeletonDocument::reduceNode(dust3d::Uuid nodeId) } dust3d::Uuid firstEdgeId = node->edgeIds[0]; dust3d::Uuid secondEdgeId = node->edgeIds[1]; - const SkeletonEdge *firstEdge = findEdge(firstEdgeId); + const SkeletonEdge* firstEdge = findEdge(firstEdgeId); if (nullptr == firstEdge) { return; } - const SkeletonEdge *secondEdge = findEdge(secondEdgeId); + const SkeletonEdge* secondEdge = findEdge(secondEdgeId); if (nullptr == secondEdge) { return; } @@ -103,7 +103,7 @@ void SkeletonDocument::reduceNode(dust3d::Uuid nodeId) void SkeletonDocument::breakEdge(dust3d::Uuid edgeId) { - const SkeletonEdge *edge = findEdge(edgeId); + const SkeletonEdge* edge = findEdge(edgeId); if (nullptr == edge) { return; } @@ -112,11 +112,11 @@ void SkeletonDocument::breakEdge(dust3d::Uuid edgeId) } dust3d::Uuid firstNodeId = edge->nodeIds[0]; dust3d::Uuid secondNodeId = edge->nodeIds[1]; - const SkeletonNode *firstNode = findNode(firstNodeId); + const SkeletonNode* firstNode = findNode(firstNodeId); if (nullptr == firstNode) { return; } - const SkeletonNode *secondNode = findNode(secondNodeId); + const SkeletonNode* secondNode = findNode(secondNodeId); if (nullptr == secondNode) { return; } @@ -134,7 +134,7 @@ void SkeletonDocument::breakEdge(dust3d::Uuid edgeId) void SkeletonDocument::reverseEdge(dust3d::Uuid edgeId) { - SkeletonEdge *edge = (SkeletonEdge *)findEdge(edgeId); + SkeletonEdge* edge = (SkeletonEdge*)findEdge(edgeId); if (nullptr == edge) { return; } @@ -151,13 +151,13 @@ void SkeletonDocument::reverseEdge(dust3d::Uuid edgeId) void SkeletonDocument::removeEdge(dust3d::Uuid edgeId) { - const SkeletonEdge *edge = findEdge(edgeId); + const SkeletonEdge* edge = findEdge(edgeId); if (nullptr == edge) { return; } if (isPartReadonly(edge->partId)) return; - const SkeletonPart *oldPart = findPart(edge->partId); + const SkeletonPart* oldPart = findPart(edge->partId); if (nullptr == oldPart) { return; } @@ -169,7 +169,7 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId) std::vector newPartIds; for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) { const auto newUuid = dust3d::Uuid::createUuid(); - SkeletonPart &part = partMap[newUuid]; + SkeletonPart& part = partMap[newUuid]; part.id = newUuid; part.copyAttributes(*oldPart); part.name = nextPartName; @@ -189,7 +189,7 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId) } } addPartToComponent(part.id, findComponentParentId(part.componentId)); - newPartNodeNumMap.push_back({part.id, part.nodeIds.size()}); + newPartNodeNumMap.push_back({ part.id, part.nodeIds.size() }); newPartIds.push_back(part.id); emit partAdded(part.id); } @@ -204,27 +204,26 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId) edgeMap.erase(edgeId); emit edgeRemoved(edgeId); removePart(oldPartId); - + if (!newPartNodeNumMap.empty()) { - std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&]( - const std::pair &first, const std::pair &second) { + std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&](const std::pair& first, const std::pair& second) { return first.second > second.second; }); updateLinkedPart(oldPartId, newPartNodeNumMap[0].first); } - + emit skeletonChanged(); } void SkeletonDocument::removeNode(dust3d::Uuid nodeId) { - const SkeletonNode *node = findNode(nodeId); + const SkeletonNode* node = findNode(nodeId); if (nullptr == node) { return; } if (isPartReadonly(node->partId)) return; - const SkeletonPart *oldPart = findPart(node->partId); + const SkeletonPart* oldPart = findPart(node->partId); if (nullptr == oldPart) { return; } @@ -236,7 +235,7 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId) std::vector newPartIds; for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) { const auto newUuid = dust3d::Uuid::createUuid(); - SkeletonPart &part = partMap[newUuid]; + SkeletonPart& part = partMap[newUuid]; part.id = newUuid; part.copyAttributes(*oldPart); part.name = nextPartName; @@ -256,7 +255,7 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId) } } addPartToComponent(part.id, findComponentParentId(part.componentId)); - newPartNodeNumMap.push_back({part.id, part.nodeIds.size()}); + newPartNodeNumMap.push_back({ part.id, part.nodeIds.size() }); newPartIds.push_back(part.id); emit partAdded(part.id); } @@ -277,15 +276,14 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId) nodeMap.erase(nodeId); emit nodeRemoved(nodeId); removePart(oldPartId); - + if (!newPartNodeNumMap.empty()) { - std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&]( - const std::pair &first, const std::pair &second) { + std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&](const std::pair& first, const std::pair& second) { return first.second > second.second; }); updateLinkedPart(oldPartId, newPartNodeNumMap[0].first); } - + emit skeletonChanged(); } @@ -302,11 +300,11 @@ void SkeletonDocument::addNodeWithId(dust3d::Uuid nodeId, float x, float y, floa dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId) { dust3d::Uuid partId; - const SkeletonNode *fromNode = nullptr; + const SkeletonNode* fromNode = nullptr; bool newPartAdded = false; if (fromNodeId.isNull()) { const auto newUuid = dust3d::Uuid::createUuid(); - SkeletonPart &part = partMap[newUuid]; + SkeletonPart& part = partMap[newUuid]; part.id = newUuid; partId = part.id; emit partAdded(partId); @@ -331,35 +329,35 @@ dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y, node.setZ(z); nodeMap[node.id] = node; partMap[partId].nodeIds.push_back(node.id); - + emit nodeAdded(node.id); - + if (nullptr != fromNode) { SkeletonEdge edge; edge.partId = partId; edge.nodeIds.push_back(fromNode->id); edge.nodeIds.push_back(node.id); edgeMap[edge.id] = edge; - + nodeMap[node.id].edgeIds.push_back(edge.id); nodeMap[fromNode->id].edgeIds.push_back(edge.id); - + emit edgeAdded(edge.id); } - + if (newPartAdded) addPartToComponent(partId, m_currentCanvasComponentId); - + emit skeletonChanged(); - + return node.id; } -void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector *group, dust3d::Uuid nodeId, std::set *visitMap, dust3d::Uuid noUseEdgeId) +void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector* group, dust3d::Uuid nodeId, std::set* visitMap, dust3d::Uuid noUseEdgeId) { if (nodeId.isNull() || visitMap->find(nodeId) != visitMap->end()) return; - const SkeletonNode *node = findNode(nodeId); + const SkeletonNode* node = findNode(nodeId); if (nullptr == node) { return; } @@ -368,7 +366,7 @@ void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector *grou for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { if (noUseEdgeId == *edgeIt) continue; - const SkeletonEdge *edge = findEdge(*edgeIt); + const SkeletonEdge* edge = findEdge(*edgeIt); if (nullptr == edge) { continue; } @@ -378,14 +376,14 @@ void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector *grou } } -void SkeletonDocument::splitPartByNode(std::vector> *groups, dust3d::Uuid nodeId) +void SkeletonDocument::splitPartByNode(std::vector>* groups, dust3d::Uuid nodeId) { - const SkeletonNode *node = findNode(nodeId); + const SkeletonNode* node = findNode(nodeId); std::set visitMap; visitMap.insert(nodeId); for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { std::vector group; - const SkeletonEdge *edge = findEdge(*edgeIt); + const SkeletonEdge* edge = findEdge(*edgeIt); if (nullptr == edge) { continue; } @@ -395,9 +393,9 @@ void SkeletonDocument::splitPartByNode(std::vector> *g } } -void SkeletonDocument::splitPartByEdge(std::vector> *groups, dust3d::Uuid edgeId) +void SkeletonDocument::splitPartByEdge(std::vector>* groups, dust3d::Uuid edgeId) { - const SkeletonEdge *edge = findEdge(edgeId); + const SkeletonEdge* edge = findEdge(edgeId); if (nullptr == edge) { return; } @@ -410,17 +408,17 @@ void SkeletonDocument::splitPartByEdge(std::vector> *g } } -const SkeletonComponent *SkeletonDocument::findComponentParent(dust3d::Uuid componentId) const +const SkeletonComponent* SkeletonDocument::findComponentParent(dust3d::Uuid componentId) const { auto component = componentMap.find(componentId); if (component == componentMap.end()) { return nullptr; } - + if (component->second.parentId.isNull()) return &rootComponent; - - return (SkeletonComponent *)findComponent(component->second.parentId); + + return (SkeletonComponent*)findComponent(component->second.parentId); } dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) const @@ -429,18 +427,18 @@ dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) c if (component == componentMap.end()) { return dust3d::Uuid(); } - + return component->second.parentId; } void SkeletonDocument::moveComponentUp(dust3d::Uuid componentId) { - SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); + SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId); if (nullptr == parent) return; - + dust3d::Uuid parentId = findComponentParentId(componentId); - + parent->moveChildUp(componentId); parent->dirty = true; emit componentChildrenChanged(parentId); @@ -449,12 +447,12 @@ void SkeletonDocument::moveComponentUp(dust3d::Uuid componentId) void SkeletonDocument::moveComponentDown(dust3d::Uuid componentId) { - SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); + SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId); if (nullptr == parent) return; - + dust3d::Uuid parentId = findComponentParentId(componentId); - + parent->moveChildDown(componentId); parent->dirty = true; emit componentChildrenChanged(parentId); @@ -463,12 +461,12 @@ void SkeletonDocument::moveComponentDown(dust3d::Uuid componentId) void SkeletonDocument::moveComponentToTop(dust3d::Uuid componentId) { - SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); + SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId); if (nullptr == parent) return; - + dust3d::Uuid parentId = findComponentParentId(componentId); - + parent->moveChildToTop(componentId); parent->dirty = true; emit componentChildrenChanged(parentId); @@ -477,12 +475,12 @@ void SkeletonDocument::moveComponentToTop(dust3d::Uuid componentId) void SkeletonDocument::moveComponentToBottom(dust3d::Uuid componentId) { - SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); + SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId); if (nullptr == parent) return; - + dust3d::Uuid parentId = findComponentParentId(componentId); - + parent->moveChildToBottom(componentId); parent->dirty = true; emit componentChildrenChanged(parentId); @@ -495,10 +493,10 @@ void SkeletonDocument::renameComponent(dust3d::Uuid componentId, QString name) if (component == componentMap.end()) { return; } - + if (component->second.name == name) return; - + if (!name.trimmed().isEmpty()) component->second.name = name; emit componentNameChanged(componentId); @@ -511,20 +509,20 @@ void SkeletonDocument::setComponentExpandState(dust3d::Uuid componentId, bool ex if (component == componentMap.end()) { return; } - + if (component->second.expanded == expanded) return; - + component->second.expanded = expanded; emit componentExpandStateChanged(componentId); emit optionsChanged(); } -void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId) +void SkeletonDocument::ungroupComponent(const dust3d::Uuid& componentId) { if (componentId.isNull()) return; - SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); + SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId); if (nullptr == component) { dust3dDebug << "Component not found:" << componentId.toString(); return; @@ -532,15 +530,15 @@ void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId) if (component->childrenIds.empty()) return; auto childrenIds = component->childrenIds; - SkeletonComponent *newParent = (SkeletonComponent *)findComponentParent(componentId); + SkeletonComponent* newParent = (SkeletonComponent*)findComponentParent(componentId); if (nullptr == newParent) { dust3dDebug << "Expected parent component to be found, component:" << componentId.toString(); return; } auto newParentId = newParent->id; newParent->replaceChildWithOthers(componentId, childrenIds); - for (const auto &childId: childrenIds) { - SkeletonComponent *child = (SkeletonComponent *)findComponent(childId); + for (const auto& childId : childrenIds) { + SkeletonComponent* child = (SkeletonComponent*)findComponent(childId); if (nullptr == child) continue; child->parentId = newParentId; @@ -551,7 +549,7 @@ void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId) emit skeletonChanged(); } -void SkeletonDocument::groupComponents(const std::vector &componentIds) +void SkeletonDocument::groupComponents(const std::vector& componentIds) { if (componentIds.empty()) return; @@ -563,7 +561,7 @@ void SkeletonDocument::groupComponents(const std::vector &componen auto it = componentIds.begin(); - SkeletonComponent *oldParent = (SkeletonComponent *)findComponentParent(*it); + SkeletonComponent* oldParent = (SkeletonComponent*)findComponentParent(*it); if (nullptr == oldParent) { dust3dDebug << "Expected parent component to be found, component:" << it->toString(); return; @@ -574,7 +572,7 @@ void SkeletonDocument::groupComponents(const std::vector &componen oldParent->removeChild(*it); } - for (const auto &componentId: componentIds) { + for (const auto& componentId : componentIds) { auto component = componentMap.find(componentId); if (component == componentMap.end()) { continue; @@ -594,21 +592,21 @@ void SkeletonDocument::groupComponents(const std::vector &componen void SkeletonDocument::createNewChildComponent(dust3d::Uuid parentComponentId) { - SkeletonComponent *parentComponent = (SkeletonComponent *)findComponent(parentComponentId); + SkeletonComponent* parentComponent = (SkeletonComponent*)findComponent(parentComponentId); if (!parentComponent->linkToPartId.isNull()) { parentComponentId = parentComponent->parentId; - parentComponent = (SkeletonComponent *)findComponent(parentComponentId); + parentComponent = (SkeletonComponent*)findComponent(parentComponentId); } - + SkeletonComponent newComponent(dust3d::Uuid::createUuid()); newComponent.name = tr("Group") + " " + QString::number(componentMap.size() - partMap.size() + 1); - + parentComponent->addChild(newComponent.id); newComponent.parentId = parentComponentId; - + auto newComponentId = newComponent.id; componentMap.emplace(newComponentId, std::move(newComponent)); - + emit componentChildrenChanged(parentComponentId); emit componentAdded(newComponentId); emit optionsChanged(); @@ -620,12 +618,12 @@ void SkeletonDocument::removePart(dust3d::Uuid partId) if (part == partMap.end()) { return; } - + if (!part->second.componentId.isNull()) { removeComponent(part->second.componentId); return; } - + removePartDontCareComponent(partId); } @@ -635,10 +633,10 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId) if (part == partMap.end()) { return; } - + std::vector removedNodeIds; std::vector removedEdgeIds; - + for (auto nodeIt = nodeMap.begin(); nodeIt != nodeMap.end();) { if (nodeIt->second.partId != partId) { nodeIt++; @@ -647,7 +645,7 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId) removedNodeIds.push_back(nodeIt->second.id); nodeIt = nodeMap.erase(nodeIt); } - + for (auto edgeIt = edgeMap.begin(); edgeIt != edgeMap.end();) { if (edgeIt->second.partId != partId) { edgeIt++; @@ -656,13 +654,13 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId) removedEdgeIds.push_back(edgeIt->second.id); edgeIt = edgeMap.erase(edgeIt); } - + partMap.erase(part); - - for (const auto &nodeId: removedNodeIds) { + + for (const auto& nodeId : removedNodeIds) { emit nodeRemoved(nodeId); } - for (const auto &edgeId: removedEdgeIds) { + for (const auto& edgeId : removedEdgeIds) { emit edgeRemoved(edgeId); } emit partRemoved(partId); @@ -671,7 +669,7 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId) void SkeletonDocument::addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId) { SkeletonComponent child(dust3d::Uuid::createUuid()); - + if (!componentId.isNull()) { auto parentComponent = componentMap.find(componentId); if (parentComponent == componentMap.end()) { @@ -683,13 +681,13 @@ void SkeletonDocument::addPartToComponent(dust3d::Uuid partId, dust3d::Uuid comp } else { rootComponent.addChild(child.id); } - + partMap[partId].componentId = child.id; child.linkToPartId = partId; child.parentId = componentId; auto childId = child.id; componentMap.emplace(childId, std::move(child)); - + emit componentChildrenChanged(componentId); emit componentAdded(childId); } @@ -706,16 +704,16 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId) if (component == componentMap.end()) { return; } - + if (!component->second.linkToPartId.isNull()) { removePartDontCareComponent(component->second.linkToPartId); } - + auto childrenIds = component->second.childrenIds; - for (const auto &childId: childrenIds) { + for (const auto& childId : childrenIds) { removeComponentRecursively(childId); } - + dust3d::Uuid parentId = component->second.parentId; if (!parentId.isNull()) { auto parentComponent = componentMap.find(parentId); @@ -726,7 +724,7 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId) } else { rootComponent.removeChild(componentId); } - + componentMap.erase(component); emit componentRemoved(componentId); emit componentChildrenChanged(parentId); @@ -735,7 +733,7 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId) void SkeletonDocument::setCurrentCanvasComponentId(dust3d::Uuid componentId) { m_currentCanvasComponentId = componentId; - const SkeletonComponent *component = findComponent(m_currentCanvasComponentId); + const SkeletonComponent* component = findComponent(m_currentCanvasComponentId); if (nullptr == component) { m_currentCanvasComponentId = dust3d::Uuid(); } else { @@ -749,7 +747,7 @@ void SkeletonDocument::setCurrentCanvasComponentId(dust3d::Uuid componentId) void SkeletonDocument::addComponent(dust3d::Uuid parentId) { SkeletonComponent component(dust3d::Uuid::createUuid()); - + if (!parentId.isNull()) { auto parentComponent = componentMap.find(parentId); if (parentComponent == componentMap.end()) { @@ -759,18 +757,18 @@ void SkeletonDocument::addComponent(dust3d::Uuid parentId) } else { rootComponent.addChild(component.id); } - + component.parentId = parentId; auto componentId = component.id; componentMap.emplace(componentId, std::move(component)); - + emit componentChildrenChanged(parentId); emit componentAdded(componentId); } bool SkeletonDocument::isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId) { - const SkeletonComponent *loopComponent = findComponentParent(suspiciousId); + const SkeletonComponent* loopComponent = findComponentParent(suspiciousId); while (nullptr != loopComponent) { if (loopComponent->id == componentId) return true; @@ -788,13 +786,13 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa if (component == componentMap.end()) { return; } - + if (component->second.parentId == toParentId) return; - + if (isDescendantComponent(componentId, toParentId)) return; - + if (component->second.parentId.isNull()) { rootComponent.removeChild(componentId); emit componentChildrenChanged(rootComponent.id); @@ -806,9 +804,9 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa emit componentChildrenChanged(oldParent->second.id); } } - + component->second.parentId = toParentId; - + if (toParentId.isNull()) { rootComponent.addChild(componentId); emit componentChildrenChanged(rootComponent.id); @@ -820,7 +818,7 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa emit componentChildrenChanged(newParent->second.id); } } - + emit skeletonChanged(); } @@ -864,25 +862,25 @@ void SkeletonDocument::setPartDisableState(dust3d::Uuid partId, bool disabled) emit skeletonChanged(); } -void SkeletonDocument::collectComponentDescendantParts(dust3d::Uuid componentId, std::vector &partIds) const +void SkeletonDocument::collectComponentDescendantParts(dust3d::Uuid componentId, std::vector& partIds) const { - const SkeletonComponent *component = findComponent(componentId); + const SkeletonComponent* component = findComponent(componentId); if (nullptr == component) return; - + if (!component->linkToPartId.isNull()) { partIds.push_back(component->linkToPartId); return; } - - for (const auto &childId: component->childrenIds) { + + for (const auto& childId : component->childrenIds) { collectComponentDescendantParts(childId, partIds); } } -void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector &componentIds) const +void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector& componentIds) const { - const SkeletonComponent *component = findComponent(componentId); + const SkeletonComponent* component = findComponent(componentId); if (nullptr == component) return; @@ -890,7 +888,7 @@ void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid compone return; } - for (const auto &childId: component->childrenIds) { + for (const auto& childId : component->childrenIds) { componentIds.push_back(childId); collectComponentDescendantComponents(childId, componentIds); } @@ -901,10 +899,10 @@ void SkeletonDocument::hideOtherComponents(dust3d::Uuid componentId) std::vector partIds; collectComponentDescendantParts(componentId, partIds); std::set partIdSet; - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { partIdSet.insert(partId); } - for (const auto &part: partMap) { + for (const auto& part : partMap) { if (partIdSet.find(part.first) != partIdSet.end()) continue; setPartVisibleState(part.first, false); @@ -916,10 +914,10 @@ void SkeletonDocument::lockOtherComponents(dust3d::Uuid componentId) std::vector partIds; collectComponentDescendantParts(componentId, partIds); std::set partIdSet; - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { partIdSet.insert(partId); } - for (const auto &part: partMap) { + for (const auto& part : partMap) { if (partIdSet.find(part.first) != partIdSet.end()) continue; setPartLockState(part.first, true); @@ -928,14 +926,14 @@ void SkeletonDocument::lockOtherComponents(dust3d::Uuid componentId) void SkeletonDocument::hideAllComponents() { - for (const auto &part: partMap) { + for (const auto& part : partMap) { setPartVisibleState(part.first, false); } } void SkeletonDocument::showAllComponents() { - for (const auto &part: partMap) { + for (const auto& part : partMap) { setPartVisibleState(part.first, true); } } @@ -943,7 +941,7 @@ void SkeletonDocument::showAllComponents() void SkeletonDocument::showOrHideAllComponents() { bool foundVisiblePart = false; - for (const auto &part: partMap) { + for (const auto& part : partMap) { if (part.second.visible) { foundVisiblePart = true; } @@ -956,7 +954,7 @@ void SkeletonDocument::showOrHideAllComponents() void SkeletonDocument::collapseAllComponents() { - for (const auto &component: componentMap) { + for (const auto& component : componentMap) { if (!component.second.linkToPartId.isNull()) continue; setComponentExpandState(component.first, false); @@ -965,7 +963,7 @@ void SkeletonDocument::collapseAllComponents() void SkeletonDocument::expandAllComponents() { - for (const auto &component: componentMap) { + for (const auto& component : componentMap) { if (!component.second.linkToPartId.isNull()) continue; setComponentExpandState(component.first, true); @@ -974,14 +972,14 @@ void SkeletonDocument::expandAllComponents() void SkeletonDocument::lockAllComponents() { - for (const auto &part: partMap) { + for (const auto& part : partMap) { setPartLockState(part.first, true); } } void SkeletonDocument::unlockAllComponents() { - for (const auto &part: partMap) { + for (const auto& part : partMap) { setPartLockState(part.first, false); } } @@ -990,7 +988,7 @@ void SkeletonDocument::hideDescendantComponents(dust3d::Uuid componentId) { std::vector partIds; collectComponentDescendantParts(componentId, partIds); - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { setPartVisibleState(partId, false); } } @@ -999,7 +997,7 @@ void SkeletonDocument::showDescendantComponents(dust3d::Uuid componentId) { std::vector partIds; collectComponentDescendantParts(componentId, partIds); - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { setPartVisibleState(partId, true); } } @@ -1008,7 +1006,7 @@ void SkeletonDocument::lockDescendantComponents(dust3d::Uuid componentId) { std::vector partIds; collectComponentDescendantParts(componentId, partIds); - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { setPartLockState(partId, true); } } @@ -1017,7 +1015,7 @@ void SkeletonDocument::unlockDescendantComponents(dust3d::Uuid componentId) { std::vector partIds; collectComponentDescendantParts(componentId, partIds); - for (const auto &partId: partIds) { + for (const auto& partId : partIds) { setPartLockState(partId, false); } } @@ -1042,7 +1040,7 @@ void SkeletonDocument::scaleNodeByAddRadius(dust3d::Uuid nodeId, float amount) bool SkeletonDocument::isPartReadonly(dust3d::Uuid partId) const { - const SkeletonPart *part = findPart(partId); + const SkeletonPart* part = findPart(partId); if (nullptr == part) { return true; } @@ -1151,7 +1149,7 @@ void SkeletonDocument::switchNodeXZ(dust3d::Uuid nodeId) emit skeletonChanged(); } -const SkeletonComponent *SkeletonDocument::findComponent(dust3d::Uuid componentId) const +const SkeletonComponent* SkeletonDocument::findComponent(dust3d::Uuid componentId) const { if (componentId.isNull()) return &rootComponent; @@ -1166,36 +1164,36 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId) if (findEdgeByNodes(fromNodeId, toNodeId)) { return; } - - const SkeletonNode *fromNode = nullptr; - const SkeletonNode *toNode = nullptr; + + const SkeletonNode* fromNode = nullptr; + const SkeletonNode* toNode = nullptr; bool toPartRemoved = false; - + fromNode = findNode(fromNodeId); if (nullptr == fromNode) { return; } - + if (isPartReadonly(fromNode->partId)) return; - + toNode = findNode(toNodeId); if (nullptr == toNode) { return; } - + if (isPartReadonly(toNode->partId)) return; - + dust3d::Uuid toPartId = toNode->partId; - + auto fromPart = partMap.find(fromNode->partId); if (fromPart == partMap.end()) { return; } - + fromPart->second.dirty = true; - + if (fromNode->partId != toNode->partId) { toPartRemoved = true; std::vector toGroup; @@ -1217,7 +1215,7 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId) } } } - + SkeletonEdge edge; edge.partId = fromNode->partId; edge.nodeIds.push_back(fromNode->id); @@ -1226,34 +1224,34 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId) nodeMap[toNodeId].edgeIds.push_back(edge.id); nodeMap[fromNode->id].edgeIds.push_back(edge.id); - + emit edgeAdded(edge.id); - + if (toPartRemoved) { updateLinkedPart(toPartId, fromNode->partId); removePart(toPartId); } - + emit skeletonChanged(); } void SkeletonDocument::updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId) { - for (auto &partIt: partMap) { + for (auto& partIt : partMap) { if (partIt.second.cutFaceLinkedId == oldPartId) { partIt.second.dirty = true; partIt.second.setCutFaceLinkedId(newPartId); } } std::set dirtyPartIds; - for (auto &nodeIt: nodeMap) { + for (auto& nodeIt : nodeMap) { if (nodeIt.second.cutFaceLinkedId == oldPartId) { dirtyPartIds.insert(nodeIt.second.partId); nodeIt.second.setCutFaceLinkedId(newPartId); } } - for (const auto &partId: dirtyPartIds) { - SkeletonPart *part = (SkeletonPart *)findPart(partId); + for (const auto& partId : dirtyPartIds) { + SkeletonPart* part = (SkeletonPart*)findPart(partId); if (nullptr == part) continue; part->dirty = true; @@ -1272,17 +1270,17 @@ void SkeletonDocument::disableAllPositionRelatedLocks() void SkeletonDocument::resetDirtyFlags() { - for (auto &part: partMap) { + for (auto& part : partMap) { part.second.dirty = false; } - for (auto &component: componentMap) { + for (auto& component : componentMap) { component.second.dirty = false; } } void SkeletonDocument::markAllDirty() { - for (auto &part: partMap) { + for (auto& part : partMap) { part.second.dirty = true; } } @@ -1319,27 +1317,27 @@ void SkeletonDocument::setRadiusLockState(bool locked) emit radiusLockStateChanged(); } -void SkeletonDocument::setComponentPreviewImage(const dust3d::Uuid &componentId, std::unique_ptr image) +void SkeletonDocument::setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr image) { - SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); + SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId); if (nullptr == component) return; component->isPreviewImageDecorationObsolete = true; component->previewImage = std::move(image); } -void SkeletonDocument::setComponentPreviewPixmap(const dust3d::Uuid &componentId, const QPixmap &pixmap) +void SkeletonDocument::setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap) { - SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); + SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId); if (nullptr == component) return; component->previewPixmap = pixmap; emit componentPreviewPixmapChanged(componentId); } -void SkeletonDocument::setComponentPreviewMesh(const dust3d::Uuid &componentId, std::unique_ptr mesh) +void SkeletonDocument::setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr mesh) { - SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); + SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId); if (nullptr == component) return; component->updatePreviewMesh(std::move(mesh)); diff --git a/application/sources/skeleton_document.h b/application/sources/skeleton_document.h index c886f77e..9c794710 100644 --- a/application/sources/skeleton_document.h +++ b/application/sources/skeleton_document.h @@ -1,35 +1,34 @@ #ifndef DUST3D_APPLICATION_SKELETON_DOCUMENT_H_ #define DUST3D_APPLICATION_SKELETON_DOCUMENT_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "theme.h" -#include "model_mesh.h" #include "debug.h" #include "mesh_generator.h" +#include "model_mesh.h" +#include "theme.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -class SkeletonNode -{ +class SkeletonNode { public: - SkeletonNode(const dust3d::Uuid &withId=dust3d::Uuid()) : - radius(0), - cutRotation(0.0), - cutFace(dust3d::CutFace::Quad), - hasCutFaceSettings(false), - m_x(0), - m_y(0), - m_z(0) + SkeletonNode(const dust3d::Uuid& withId = dust3d::Uuid()) + : radius(0) + , cutRotation(0.0) + , cutFace(dust3d::CutFace::Quad) + , hasCutFaceSettings(false) + , m_x(0) + , m_y(0) + , m_z(0) { id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; } @@ -56,7 +55,7 @@ public: cutFaceLinkedId = dust3d::Uuid(); hasCutFaceSettings = true; } - void setCutFaceLinkedId(const dust3d::Uuid &linkedId) + void setCutFaceLinkedId(const dust3d::Uuid& linkedId) { if (linkedId.isNull()) { clearCutFaceSettings(); @@ -73,21 +72,21 @@ public: cutRotation = 0; hasCutFaceSettings = false; } - float getX(bool rotated=false) const + float getX(bool rotated = false) const { if (rotated) return m_y; return m_x; } - float getY(bool rotated=false) const + float getY(bool rotated = false) const { if (rotated) return m_x; return m_y; } - float getZ(bool rotated=false) const + float getZ(bool rotated = false) const { - (void) rotated; + (void)rotated; return m_z; } void setX(float x) @@ -123,16 +122,16 @@ public: dust3d::Uuid cutFaceLinkedId; bool hasCutFaceSettings; std::vector edgeIds; + private: float m_x; float m_y; float m_z; }; -class SkeletonEdge -{ +class SkeletonEdge { public: - SkeletonEdge(const dust3d::Uuid &withId=dust3d::Uuid()) + SkeletonEdge(const dust3d::Uuid& withId = dust3d::Uuid()) { id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; } @@ -148,8 +147,7 @@ public: } }; -class SkeletonPart -{ +class SkeletonPart { public: dust3d::Uuid id; QString name; @@ -180,30 +178,30 @@ public: float hollowThickness; bool countershaded; bool smooth; - SkeletonPart(const dust3d::Uuid &withId=dust3d::Uuid()) : - visible(true), - locked(false), - subdived(false), - disabled(false), - xMirrored(false), - base(dust3d::PartBase::Average), - deformThickness(1.0), - deformWidth(1.0), - deformUnified(false), - rounded(false), - chamfered(false), - color(Qt::white), - hasColor(false), - dirty(true), - cutRotation(0.0), - cutFace(dust3d::CutFace::Quad), - target(dust3d::PartTarget::Model), - colorSolubility(0.0), - metalness(0.0), - roughness(1.0), - hollowThickness(0.0), - countershaded(false), - smooth(false) + SkeletonPart(const dust3d::Uuid& withId = dust3d::Uuid()) + : visible(true) + , locked(false) + , subdived(false) + , disabled(false) + , xMirrored(false) + , base(dust3d::PartBase::Average) + , deformThickness(1.0) + , deformWidth(1.0) + , deformUnified(false) + , rounded(false) + , chamfered(false) + , color(Qt::white) + , hasColor(false) + , dirty(true) + , cutRotation(0.0) + , cutFace(dust3d::CutFace::Quad) + , target(dust3d::PartTarget::Model) + , colorSolubility(0.0) + , metalness(0.0) + , roughness(1.0) + , hollowThickness(0.0) + , countershaded(false) + , smooth(false) { id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; } @@ -296,7 +294,7 @@ public: cutFace = face; cutFaceLinkedId = dust3d::Uuid(); } - void setCutFaceLinkedId(const dust3d::Uuid &linkedId) + void setCutFaceLinkedId(const dust3d::Uuid& linkedId) { if (linkedId.isNull()) { setCutFace(dust3d::CutFace::Quad); @@ -353,7 +351,7 @@ public: { return visible && !disabled; } - void copyAttributes(const SkeletonPart &other) + void copyAttributes(const SkeletonPart& other) { visible = other.visible; locked = other.locked; @@ -382,12 +380,12 @@ public: smooth = other.smooth; hollowThickness = other.hollowThickness; } + private: Q_DISABLE_COPY(SkeletonPart); }; -enum class SkeletonDocumentEditMode -{ +enum class SkeletonDocumentEditMode { Add = 0, Select, Paint, @@ -396,20 +394,18 @@ enum class SkeletonDocumentEditMode ZoomOut }; -enum class SkeletonProfile -{ +enum class SkeletonProfile { Unknown = 0, Main, Side }; -class SkeletonComponent -{ +class SkeletonComponent { public: SkeletonComponent() { } - SkeletonComponent(const dust3d::Uuid &withId, const QString &linkData=QString(), const QString &linkDataType=QString()) + SkeletonComponent(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString()) { id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; if (!linkData.isEmpty()) { @@ -445,13 +441,13 @@ public: m_childrenIdSet.insert(childId); childrenIds.push_back(childId); } - void replaceChildWithOthers(const dust3d::Uuid &childId, const std::vector &others) + void replaceChildWithOthers(const dust3d::Uuid& childId, const std::vector& others) { if (m_childrenIdSet.find(childId) == m_childrenIdSet.end()) return; m_childrenIdSet.erase(childId); std::vector candidates; - for (const auto &it: others) { + for (const auto& it : others) { if (m_childrenIdSet.find(it) == m_childrenIdSet.end()) { m_childrenIdSet.insert(it); candidates.emplace_back(it); @@ -500,7 +496,7 @@ public: if (it == childrenIds.end()) { return; } - + auto index = std::distance(childrenIds.begin(), it); if (index == 0) return; @@ -512,7 +508,7 @@ public: if (it == childrenIds.end()) { return; } - + auto index = std::distance(childrenIds.begin(), it); if (index == (int)childrenIds.size() - 1) return; @@ -524,7 +520,7 @@ public: if (it == childrenIds.end()) { return; } - + auto index = std::distance(childrenIds.begin(), it); if (index == 0) return; @@ -537,7 +533,7 @@ public: if (it == childrenIds.end()) { return; } - + auto index = std::distance(childrenIds.begin(), it); if (index == (int)childrenIds.size() - 1) return; @@ -549,19 +545,19 @@ public: m_previewMesh = std::move(mesh); isPreviewMeshObsolete = true; } - ModelMesh *takePreviewMesh() const + ModelMesh* takePreviewMesh() const { if (nullptr == m_previewMesh) return nullptr; return new ModelMesh(*m_previewMesh); } + private: std::unique_ptr m_previewMesh; std::set m_childrenIdSet; }; -class SkeletonDocument : public QObject -{ +class SkeletonDocument : public QObject { Q_OBJECT signals: void partAdded(dust3d::Uuid partId); @@ -576,8 +572,8 @@ signals: void componentRemoved(dust3d::Uuid componentId); void componentAdded(dust3d::Uuid componentId); void componentExpandStateChanged(dust3d::Uuid componentId); - void componentPreviewMeshChanged(const dust3d::Uuid &componentId); - void componentPreviewPixmapChanged(const dust3d::Uuid &componentId); + void componentPreviewMeshChanged(const dust3d::Uuid& componentId); + void componentPreviewPixmapChanged(const dust3d::Uuid& componentId); void nodeRemoved(dust3d::Uuid nodeId); void edgeRemoved(dust3d::Uuid edgeId); void nodeRadiusChanged(dust3d::Uuid nodeId); @@ -590,6 +586,7 @@ signals: void ylockStateChanged(); void zlockStateChanged(); void radiusLockStateChanged(); + public: SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select; bool xlocked = false; @@ -604,22 +601,22 @@ public: std::map componentMap; SkeletonComponent rootComponent; - const SkeletonNode *findNode(dust3d::Uuid nodeId) const; - const SkeletonEdge *findEdge(dust3d::Uuid edgeId) const; - const SkeletonPart *findPart(dust3d::Uuid partId) const; - const SkeletonEdge *findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const; - void findAllNeighbors(dust3d::Uuid nodeId, std::set &neighbors) const; + const SkeletonNode* findNode(dust3d::Uuid nodeId) const; + const SkeletonEdge* findEdge(dust3d::Uuid edgeId) const; + const SkeletonPart* findPart(dust3d::Uuid partId) const; + const SkeletonEdge* findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const; + void findAllNeighbors(dust3d::Uuid nodeId, std::set& neighbors) const; bool isNodeConnectable(dust3d::Uuid nodeId) const; - const SkeletonComponent *findComponent(dust3d::Uuid componentId) const; - const SkeletonComponent *findComponentParent(dust3d::Uuid componentId) const; + const SkeletonComponent* findComponent(dust3d::Uuid componentId) const; + const SkeletonComponent* findComponentParent(dust3d::Uuid componentId) const; dust3d::Uuid findComponentParentId(dust3d::Uuid componentId) const; - void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector &partIds) const; - void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector &componentIds) const; - void setComponentPreviewMesh(const dust3d::Uuid &componentId, std::unique_ptr mesh); - void setComponentPreviewImage(const dust3d::Uuid &componentId, std::unique_ptr image); + void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector& partIds) const; + void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector& componentIds) const; + void setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr mesh); + void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr image); void resetDirtyFlags(); void markAllDirty(); - + virtual bool undoable() const = 0; virtual bool redoable() const = 0; virtual bool hasPastableNodesInClipboard() const = 0; @@ -628,31 +625,31 @@ public: virtual bool isEdgeEditable(dust3d::Uuid edgeId) const = 0; virtual bool isNodeDeactivated(dust3d::Uuid nodeId) const { - (void) nodeId; + (void)nodeId; return false; }; virtual bool isEdgeDeactivated(dust3d::Uuid edgeId) const { - (void) edgeId; + (void)edgeId; return false; }; virtual void copyNodes(std::set nodeIdSet) const = 0; - - float getOriginX(bool rotated=false) const + + float getOriginX(bool rotated = false) const { if (rotated) return m_originY; return m_originX; } - float getOriginY(bool rotated=false) const + float getOriginY(bool rotated = false) const { if (rotated) return m_originX; return m_originY; } - float getOriginZ(bool rotated=false) const + float getOriginZ(bool rotated = false) const { - (void) rotated; + (void)rotated; return m_originZ; } void setOriginX(float originX) @@ -679,7 +676,7 @@ public: { m_originZ += originZ; } - + public slots: virtual void undo() = 0; virtual void redo() = 0; @@ -706,8 +703,8 @@ public slots: void addComponent(dust3d::Uuid parentId); void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId); void setCurrentCanvasComponentId(dust3d::Uuid componentId); - void groupComponents(const std::vector &componentIds); - void ungroupComponent(const dust3d::Uuid &componentId); + void groupComponents(const std::vector& componentIds); + void ungroupComponent(const dust3d::Uuid& componentId); void createNewChildComponent(dust3d::Uuid parentComponentId); void setComponentExpandState(dust3d::Uuid componentId, bool expanded); void hideOtherComponents(dust3d::Uuid componentId); @@ -723,7 +720,7 @@ public slots: void showDescendantComponents(dust3d::Uuid componentId); void lockDescendantComponents(dust3d::Uuid componentId); void unlockDescendantComponents(dust3d::Uuid componentId); - void setComponentPreviewPixmap(const dust3d::Uuid &componentId, const QPixmap &pixmap); + void setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap); void setPartLockState(dust3d::Uuid partId, bool locked); void setPartVisibleState(dust3d::Uuid partId, bool visible); void setPartDisableState(dust3d::Uuid partId, bool disabled); @@ -737,18 +734,18 @@ public slots: void setYlockState(bool locked); void setZlockState(bool locked); void setRadiusLockState(bool locked); - + private: float m_originX = 0; float m_originY = 0; float m_originZ = 0; - + dust3d::Uuid m_currentCanvasComponentId; bool m_allPositionRelatedLocksEnabled = true; - - void splitPartByNode(std::vector> *groups, dust3d::Uuid nodeId); - void joinNodeAndNeiborsToGroup(std::vector *group, dust3d::Uuid nodeId, std::set *visitMap, dust3d::Uuid noUseEdgeId=dust3d::Uuid()); - void splitPartByEdge(std::vector> *groups, dust3d::Uuid edgeId); + + void splitPartByNode(std::vector>* groups, dust3d::Uuid nodeId); + void joinNodeAndNeiborsToGroup(std::vector* group, dust3d::Uuid nodeId, std::set* visitMap, dust3d::Uuid noUseEdgeId = dust3d::Uuid()); + void splitPartByEdge(std::vector>* groups, dust3d::Uuid edgeId); void removePartDontCareComponent(dust3d::Uuid partId); void addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId); bool isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId); diff --git a/application/sources/skeleton_graphics_widget.cc b/application/sources/skeleton_graphics_widget.cc index 7dcf590f..e241936c 100644 --- a/application/sources/skeleton_graphics_widget.cc +++ b/application/sources/skeleton_graphics_widget.cc @@ -1,61 +1,61 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "skeleton_graphics_widget.h" #include "theme.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument *document) : - m_document(document) +SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument* document) + : m_document(document) { setRenderHint(QPainter::Antialiasing, false); setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern)); setContentsMargins(0, 0, 0, 0); setFrameStyle(QFrame::NoFrame); - + setAlignment(Qt::AlignCenter); - + setScene(new QGraphicsScene()); - + m_backgroundItem = new QGraphicsPixmapItem(); enableBackgroundBlur(); scene()->addItem(m_backgroundItem); - + m_cursorNodeItem = new SkeletonGraphicsNodeItem(); m_cursorNodeItem->hide(); m_cursorNodeItem->setData(0, "cursorNode"); scene()->addItem(m_cursorNodeItem); - + m_cursorEdgeItem = new SkeletonGraphicsEdgeItem(); m_cursorEdgeItem->hide(); m_cursorEdgeItem->setData(0, "cursorEdge"); scene()->addItem(m_cursorEdgeItem); - + m_selectionItem = new SkeletonGraphicsSelectionItem(); m_selectionItem->hide(); scene()->addItem(m_selectionItem); - + m_mainOriginItem = new SkeletonGraphicsOriginItem(SkeletonProfile::Main); m_mainOriginItem->setRotated(m_rotated); m_mainOriginItem->hide(); scene()->addItem(m_mainOriginItem); - + m_sideOriginItem = new SkeletonGraphicsOriginItem(SkeletonProfile::Side); m_sideOriginItem->hide(); scene()->addItem(m_sideOriginItem); - + scene()->setSceneRect(rect()); - + setMouseTracking(true); - + setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &SkeletonGraphicsWidget::customContextMenuRequested, this, &SkeletonGraphicsWidget::showContextMenu); } @@ -75,7 +75,7 @@ void SkeletonGraphicsWidget::setRotated(bool rotated) updateItems(); } -void SkeletonGraphicsWidget::setModelWidget(ModelWidget *modelWidget) +void SkeletonGraphicsWidget::setModelWidget(ModelWidget* modelWidget) { m_modelWidget = modelWidget; } @@ -100,123 +100,122 @@ void SkeletonGraphicsWidget::shortcutEscape() { if (!isVisible()) return; - - if (SkeletonDocumentEditMode::Add == m_document->editMode || - SkeletonDocumentEditMode::Paint == m_document->editMode) { + + if (SkeletonDocumentEditMode::Add == m_document->editMode || SkeletonDocumentEditMode::Paint == m_document->editMode) { emit setEditMode(SkeletonDocumentEditMode::Select); return; } } -void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos) +void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos) { if (SkeletonDocumentEditMode::Add == m_document->editMode) { emit setEditMode(SkeletonDocumentEditMode::Select); return; } - + if (SkeletonDocumentEditMode::Select != m_document->editMode) { return; } - + QMenu contextMenu(this); - + QAction addAction(tr("Add..."), this); connect(&addAction, &QAction::triggered, [=]() { emit setEditMode(SkeletonDocumentEditMode::Add); }); contextMenu.addAction(&addAction); - + QAction undoAction(tr("Undo"), this); if (m_document->undoable()) { connect(&undoAction, &QAction::triggered, m_document, &SkeletonDocument::undo); contextMenu.addAction(&undoAction); } - + QAction redoAction(tr("Redo"), this); if (m_document->redoable()) { connect(&redoAction, &QAction::triggered, m_document, &SkeletonDocument::redo); contextMenu.addAction(&redoAction); } - + QAction deleteAction(tr("Delete"), this); if (hasSelection()) { connect(&deleteAction, &QAction::triggered, this, &SkeletonGraphicsWidget::deleteSelected); contextMenu.addAction(&deleteAction); } - + QAction breakAction(tr("Break"), this); if (hasEdgeSelection()) { connect(&breakAction, &QAction::triggered, this, &SkeletonGraphicsWidget::breakSelected); contextMenu.addAction(&breakAction); } - + QAction reduceAction(tr("Reduce"), this); if (hasSelection()) { connect(&reduceAction, &QAction::triggered, this, &SkeletonGraphicsWidget::reduceSelected); contextMenu.addAction(&reduceAction); } - + QAction reverseAction(tr("Reverse"), this); if (hasEdgeSelection()) { connect(&reverseAction, &QAction::triggered, this, &SkeletonGraphicsWidget::reverseSelectedEdges); contextMenu.addAction(&reverseAction); } - + QAction connectAction(tr("Connect"), this); if (hasTwoDisconnectedNodesSelection()) { connect(&connectAction, &QAction::triggered, this, &SkeletonGraphicsWidget::connectSelected); contextMenu.addAction(&connectAction); } - + QAction cutAction(tr("Cut"), this); if (hasSelection()) { connect(&cutAction, &QAction::triggered, this, &SkeletonGraphicsWidget::cut); contextMenu.addAction(&cutAction); } - + QAction copyAction(tr("Copy"), this); if (hasNodeSelection()) { connect(©Action, &QAction::triggered, this, &SkeletonGraphicsWidget::copy); contextMenu.addAction(©Action); } - + QAction pasteAction(tr("Paste"), this); if (m_document->hasPastableNodesInClipboard()) { connect(&pasteAction, &QAction::triggered, m_document, &SkeletonDocument::paste); contextMenu.addAction(&pasteAction); } - + QAction flipHorizontallyAction(tr("H Flip"), this); if (hasMultipleSelection()) { connect(&flipHorizontallyAction, &QAction::triggered, this, &SkeletonGraphicsWidget::flipHorizontally); contextMenu.addAction(&flipHorizontallyAction); } - + QAction flipVerticallyAction(tr("V Flip"), this); if (hasMultipleSelection()) { connect(&flipVerticallyAction, &QAction::triggered, this, &SkeletonGraphicsWidget::flipVertically); contextMenu.addAction(&flipVerticallyAction); } - + QAction rotateClockwiseAction(tr("Rotate 90D CW"), this); if (hasMultipleSelection()) { connect(&rotateClockwiseAction, &QAction::triggered, this, &SkeletonGraphicsWidget::rotateClockwise90Degree); contextMenu.addAction(&rotateClockwiseAction); } - + QAction rotateCounterclockwiseAction(tr("Rotate 90D CCW"), this); if (hasMultipleSelection()) { connect(&rotateCounterclockwiseAction, &QAction::triggered, this, &SkeletonGraphicsWidget::rotateCounterclockwise90Degree); contextMenu.addAction(&rotateCounterclockwiseAction); } - + QAction switchXzAction(tr("Switch XZ"), this); if (hasSelection()) { connect(&switchXzAction, &QAction::triggered, this, &SkeletonGraphicsWidget::switchSelectedXZ); contextMenu.addAction(&switchXzAction); } - + QAction alignToLocalCenterAction(tr("Local Center"), this); QAction alignToLocalVerticalCenterAction(tr("Local Vertical Center"), this); QAction alignToLocalHorizontalCenterAction(tr("Local Horizontal Center"), this); @@ -224,55 +223,55 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos) QAction alignToGlobalVerticalCenterAction(tr("Global Vertical Center"), this); QAction alignToGlobalHorizontalCenterAction(tr("Global Horizontal Center"), this); if (((hasSelection() && m_document->originSettled()) || hasMultipleSelection())) { - QMenu *subMenu = contextMenu.addMenu(tr("Align To")); - + QMenu* subMenu = contextMenu.addMenu(tr("Align To")); + if (hasMultipleSelection()) { connect(&alignToLocalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalCenter); subMenu->addAction(&alignToLocalCenterAction); - + connect(&alignToLocalVerticalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalVerticalCenter); subMenu->addAction(&alignToLocalVerticalCenterAction); - + connect(&alignToLocalHorizontalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToLocalHorizontalCenter); subMenu->addAction(&alignToLocalHorizontalCenterAction); } - + if (hasSelection() && m_document->originSettled()) { connect(&alignToGlobalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalCenter); subMenu->addAction(&alignToGlobalCenterAction); - + connect(&alignToGlobalVerticalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalVerticalCenter); subMenu->addAction(&alignToGlobalVerticalCenterAction); - + connect(&alignToGlobalHorizontalCenterAction, &QAction::triggered, this, &SkeletonGraphicsWidget::alignSelectedToGlobalHorizontalCenter); subMenu->addAction(&alignToGlobalHorizontalCenterAction); } } - + QAction colorizeAsBlankAction(tr("Blank"), this); QAction colorizeAsAutoColorAction(tr("Auto Color"), this); if (hasNodeSelection()) { - QMenu *subMenu = contextMenu.addMenu(tr("Colorize")); - + QMenu* subMenu = contextMenu.addMenu(tr("Colorize")); + connect(&colorizeAsBlankAction, &QAction::triggered, this, &SkeletonGraphicsWidget::fadeSelected); subMenu->addAction(&colorizeAsBlankAction); - + connect(&colorizeAsAutoColorAction, &QAction::triggered, this, &SkeletonGraphicsWidget::colorizeSelected); subMenu->addAction(&colorizeAsAutoColorAction); } - + QAction selectAllAction(tr("Select All"), this); if (hasItems()) { connect(&selectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectAll); contextMenu.addAction(&selectAllAction); } - + QAction selectPartAllAction(tr("Select Part"), this); if (hasItems()) { connect(&selectPartAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectPartAll); contextMenu.addAction(&selectPartAllAction); } - + QAction unselectAllAction(tr("Unselect All"), this); if (hasSelection()) { connect(&unselectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::unselectAll); @@ -299,7 +298,7 @@ bool SkeletonGraphicsWidget::hasMultipleSelection() bool SkeletonGraphicsWidget::hasEdgeSelection() { - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "edge") return true; } @@ -308,7 +307,7 @@ bool SkeletonGraphicsWidget::hasEdgeSelection() bool SkeletonGraphicsWidget::hasNodeSelection() { - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") return true; } @@ -318,9 +317,9 @@ bool SkeletonGraphicsWidget::hasNodeSelection() bool SkeletonGraphicsWidget::hasTwoDisconnectedNodesSelection() { std::vector nodeIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") { - nodeIds.push_back(((SkeletonGraphicsNodeItem *)it)->id()); + nodeIds.push_back(((SkeletonGraphicsNodeItem*)it)->id()); } } if (nodeIds.size() != 2) @@ -337,10 +336,10 @@ bool SkeletonGraphicsWidget::hasTwoDisconnectedNodesSelection() void SkeletonGraphicsWidget::fadeSelected() { std::set partIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)it; - const SkeletonNode *node = m_document->findNode(nodeItem->id()); + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)it; + const SkeletonNode* node = m_document->findNode(nodeItem->id()); if (nullptr == node) continue; if (partIds.find(node->partId) != partIds.end()) @@ -351,7 +350,7 @@ void SkeletonGraphicsWidget::fadeSelected() if (partIds.empty()) return; emit batchChangeBegin(); - for (const auto &it: partIds) { + for (const auto& it : partIds) { emit setPartColorState(it, false, Qt::white); } emit batchChangeEnd(); @@ -363,17 +362,17 @@ void SkeletonGraphicsWidget::colorizeSelected() if (nullptr == m_backgroundImage) return; std::map> sumOfColor; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)it; - const SkeletonNode *node = m_document->findNode(nodeItem->id()); + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)it; + const SkeletonNode* node = m_document->findNode(nodeItem->id()); if (nullptr == node) continue; - const auto &position = nodeItem->origin(); + const auto& position = nodeItem->origin(); sumOfColor[node->partId][m_backgroundImage->pixelColor(position.x(), position.y()).name()]++; } else if (it->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)it; - const SkeletonEdge *edge = m_document->findEdge(edgeItem->id()); + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)it; + const SkeletonEdge* edge = m_document->findEdge(edgeItem->id()); if (nullptr == edge) continue; const auto position = (edgeItem->firstItem()->origin() + edgeItem->secondItem()->origin()) / 2; @@ -383,11 +382,11 @@ void SkeletonGraphicsWidget::colorizeSelected() if (sumOfColor.empty()) return; emit batchChangeBegin(); - for (const auto &it: sumOfColor) { + for (const auto& it : sumOfColor) { int r = 0; int g = 0; int b = 0; - for (const auto &freq: it.second) { + for (const auto& freq : it.second) { QColor color(freq.first); r += color.red(); g += color.green(); @@ -403,14 +402,14 @@ void SkeletonGraphicsWidget::colorizeSelected() void SkeletonGraphicsWidget::breakSelected() { std::set edgeIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "edge") - edgeIds.insert(((SkeletonGraphicsEdgeItem *)it)->id()); + edgeIds.insert(((SkeletonGraphicsEdgeItem*)it)->id()); } if (edgeIds.empty()) return; emit batchChangeBegin(); - for (const auto &it: edgeIds) { + for (const auto& it : edgeIds) { emit breakEdge(it); } emit batchChangeEnd(); @@ -420,14 +419,14 @@ void SkeletonGraphicsWidget::breakSelected() void SkeletonGraphicsWidget::reduceSelected() { std::set nodeIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") - nodeIds.insert(((SkeletonGraphicsNodeItem *)it)->id()); + nodeIds.insert(((SkeletonGraphicsNodeItem*)it)->id()); } if (nodeIds.empty()) return; emit batchChangeBegin(); - for (const auto &it: nodeIds) { + for (const auto& it : nodeIds) { emit reduceNode(it); } emit batchChangeEnd(); @@ -437,14 +436,14 @@ void SkeletonGraphicsWidget::reduceSelected() void SkeletonGraphicsWidget::reverseSelectedEdges() { std::set edgeIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "edge") - edgeIds.insert(((SkeletonGraphicsEdgeItem *)it)->id()); + edgeIds.insert(((SkeletonGraphicsEdgeItem*)it)->id()); } if (edgeIds.empty()) return; emit batchChangeBegin(); - for (const auto &it: edgeIds) { + for (const auto& it : edgeIds) { emit reverseEdge(it); } emit batchChangeEnd(); @@ -454,9 +453,9 @@ void SkeletonGraphicsWidget::reverseSelectedEdges() void SkeletonGraphicsWidget::connectSelected() { std::vector nodeIds; - for (const auto &it: m_rangeSelectionSet) { + for (const auto& it : m_rangeSelectionSet) { if (it->data(0) == "node") { - nodeIds.push_back(((SkeletonGraphicsNodeItem *)it)->id()); + nodeIds.push_back(((SkeletonGraphicsNodeItem*)it)->id()); } } if (nodeIds.size() != 2) @@ -475,7 +474,7 @@ void SkeletonGraphicsWidget::alignSelectedToLocal(bool alignToVerticalCenter, bo { if (!hasMultipleSelection()) return; - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); if (nodeItems.empty()) return; @@ -483,8 +482,8 @@ void SkeletonGraphicsWidget::alignSelectedToLocal(bool alignToVerticalCenter, bo return; emit batchChangeBegin(); QVector2D center = centerOfNodeItemSet(nodeItems); - for (const auto &it: nodeItems) { - SkeletonGraphicsNodeItem *nodeItem = it; + for (const auto& it : nodeItems) { + SkeletonGraphicsNodeItem* nodeItem = it; QPointF nodeOrigin = nodeItem->origin(); float byX = alignToHorizontalCenter ? sceneRadiusToUnified(center.x() - nodeOrigin.x()) : 0; float byY = alignToVerticalCenter ? sceneRadiusToUnified(center.y() - nodeOrigin.y()) : 0; @@ -510,13 +509,13 @@ void SkeletonGraphicsWidget::alignSelectedToGlobal(bool alignToVerticalCenter, b return; if (!hasSelection()) return; - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); if (nodeItems.empty()) return; emit batchChangeBegin(); - for (const auto &nodeItem: nodeItems) { - const SkeletonNode *node = m_document->findNode(nodeItem->id()); + for (const auto& nodeItem : nodeItems) { + const SkeletonNode* node = m_document->findNode(nodeItem->id()); if (!node) { qDebug() << "Find node id failed:" << nodeItem->id(); continue; @@ -604,20 +603,20 @@ void SkeletonGraphicsWidget::turnaroundChanged() void SkeletonGraphicsWidget::updateTurnaround() { - const QImage *turnaroundImage = &m_document->turnaround; + const QImage* turnaroundImage = &m_document->turnaround; QImage onePixel(2, 1, QImage::Format_ARGB32); if (turnaroundImage->isNull()) { onePixel.fill(Qt::white); turnaroundImage = &onePixel; } - + m_turnaroundChanged = true; if (m_turnaroundLoader) return; - + m_turnaroundChanged = false; - QThread *thread = new QThread; + QThread* thread = new QThread; m_turnaroundLoader = new TurnaroundLoader(*turnaroundImage, parentWidget()->rect().size()); m_turnaroundLoader->moveToThread(thread); @@ -643,7 +642,7 @@ void SkeletonGraphicsWidget::turnaroundImageReady() } delete m_turnaroundLoader; m_turnaroundLoader = nullptr; - + emit loadedTurnaroundImageChanged(); if (m_turnaroundChanged) { @@ -651,7 +650,7 @@ void SkeletonGraphicsWidget::turnaroundImageReady() } } -const QImage *SkeletonGraphicsWidget::loadedTurnaroundImage() const +const QImage* SkeletonGraphicsWidget::loadedTurnaroundImage() const { return m_backgroundImage; } @@ -662,9 +661,9 @@ void SkeletonGraphicsWidget::updateCursor() m_cursorEdgeItem->hide(); m_cursorNodeItem->hide(); } - + // Set cursor here if needed - + emit cursorChanged(); } @@ -672,9 +671,9 @@ void SkeletonGraphicsWidget::editModeChanged() { updateCursor(); if (SkeletonDocumentEditMode::Add == m_document->editMode) { - SkeletonGraphicsNodeItem *choosenNodeItem = nullptr; + SkeletonGraphicsNodeItem* choosenNodeItem = nullptr; if (!m_rangeSelectionSet.empty()) { - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); if (nodeItems.size() == 1) { choosenNodeItem = *nodeItems.begin(); @@ -686,11 +685,11 @@ void SkeletonGraphicsWidget::editModeChanged() } } -void SkeletonGraphicsWidget::mouseMoveEvent(QMouseEvent *event) +void SkeletonGraphicsWidget::mouseMoveEvent(QMouseEvent* event) { if (m_modelWidget && m_modelWidget->inputMouseMoveEventFromOtherWidget(event)) return; - + QGraphicsView::mouseMoveEvent(event); mouseMove(event); } @@ -700,7 +699,7 @@ bool SkeletonGraphicsWidget::rotated() return m_rotated; } -bool SkeletonGraphicsWidget::inputWheelEventFromOtherWidget(QWheelEvent *event) +bool SkeletonGraphicsWidget::inputWheelEventFromOtherWidget(QWheelEvent* event) { if (!wheel(event)) { if (m_modelWidget && m_modelWidget->inputWheelEventFromOtherWidget(event)) @@ -709,7 +708,7 @@ bool SkeletonGraphicsWidget::inputWheelEventFromOtherWidget(QWheelEvent *event) return true; } -void SkeletonGraphicsWidget::wheelEvent(QWheelEvent *event) +void SkeletonGraphicsWidget::wheelEvent(QWheelEvent* event) { if (!wheel(event)) { if (m_modelWidget && m_modelWidget->inputWheelEventFromOtherWidget(event)) @@ -717,20 +716,20 @@ void SkeletonGraphicsWidget::wheelEvent(QWheelEvent *event) } } -void SkeletonGraphicsWidget::mouseReleaseEvent(QMouseEvent *event) +void SkeletonGraphicsWidget::mouseReleaseEvent(QMouseEvent* event) { if (m_modelWidget && m_modelWidget->inputMouseReleaseEventFromOtherWidget(event)) return; - + QGraphicsView::mouseReleaseEvent(event); mouseRelease(event); } -void SkeletonGraphicsWidget::mousePressEvent(QMouseEvent *event) +void SkeletonGraphicsWidget::mousePressEvent(QMouseEvent* event) { if (m_modelWidget && m_modelWidget->inputMousePressEventFromOtherWidget(event)) return; - + QGraphicsView::mousePressEvent(event); m_mouseEventFromSelf = true; if (mousePress(event)) { @@ -740,27 +739,27 @@ void SkeletonGraphicsWidget::mousePressEvent(QMouseEvent *event) m_mouseEventFromSelf = false; } -void SkeletonGraphicsWidget::mouseDoubleClickEvent(QMouseEvent *event) +void SkeletonGraphicsWidget::mouseDoubleClickEvent(QMouseEvent* event) { QGraphicsView::mouseDoubleClickEvent(event); mouseDoubleClick(event); } -void SkeletonGraphicsWidget::keyPressEvent(QKeyEvent *event) +void SkeletonGraphicsWidget::keyPressEvent(QKeyEvent* event) { if (keyPress(event)) return; QGraphicsView::keyPressEvent(event); } -void SkeletonGraphicsWidget::keyReleaseEvent(QKeyEvent *event) +void SkeletonGraphicsWidget::keyReleaseEvent(QKeyEvent* event) { if (keyRelease(event)) return; QGraphicsView::keyReleaseEvent(event); } -bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) +bool SkeletonGraphicsWidget::mouseMove(QMouseEvent* event) { if (m_dragStarted) { QPoint currentGlobalPos = event->globalPos(); @@ -771,7 +770,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) m_lastGlobalPos = currentGlobalPos; return true; } - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_rangeSelectionStarted) { QPointF mouseScenePos = mouseEventScenePos(event); @@ -782,32 +781,31 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) return true; } } - - if (SkeletonDocumentEditMode::Select == m_document->editMode || - SkeletonDocumentEditMode::Add == m_document->editMode) { - + + if (SkeletonDocumentEditMode::Select == m_document->editMode || SkeletonDocumentEditMode::Add == m_document->editMode) { + // // > For overlapping nodes, you can make it a bit better by selecting the node center nearest the mouse, rather than simply checking against the wider circle. // > https://www.reddit.com/user/hdu // - - SkeletonGraphicsNodeItem *newHoverNodeItem = nullptr; - SkeletonGraphicsEdgeItem *newHoverEdgeItem = nullptr; - SkeletonGraphicsOriginItem *newHoverOriginItem = nullptr; + + SkeletonGraphicsNodeItem* newHoverNodeItem = nullptr; + SkeletonGraphicsEdgeItem* newHoverEdgeItem = nullptr; + SkeletonGraphicsOriginItem* newHoverOriginItem = nullptr; QPointF scenePos = mouseEventScenePos(event); - QList items = scene()->items(scenePos); - std::vector> itemDistance2MapWithMouse; + QList items = scene()->items(scenePos); + std::vector> itemDistance2MapWithMouse; for (auto it = items.begin(); it != items.end(); it++) { - QGraphicsItem *item = *it; + QGraphicsItem* item = *it; if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; if (nodeItem->deactivated()) continue; QPointF origin = nodeItem->origin(); float distance2 = pow(origin.x() - scenePos.x(), 2) + pow(origin.y() - scenePos.y(), 2); itemDistance2MapWithMouse.push_back(std::make_pair(item, distance2)); } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; if (edgeItem->deactivated()) continue; if (edgeItem->firstItem() && edgeItem->secondItem()) { @@ -818,19 +816,19 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) itemDistance2MapWithMouse.push_back(std::make_pair(item, distance2)); } } else if (item->data(0) == "origin") { - newHoverOriginItem = (SkeletonGraphicsOriginItem *)item; + newHoverOriginItem = (SkeletonGraphicsOriginItem*)item; } } if (!itemDistance2MapWithMouse.empty()) { std::sort(itemDistance2MapWithMouse.begin(), itemDistance2MapWithMouse.end(), - [](const std::pair &a, const std::pair &b) { - return a.second < b.second; - }); - QGraphicsItem *pickedNearestItem = itemDistance2MapWithMouse[0].first; + [](const std::pair& a, const std::pair& b) { + return a.second < b.second; + }); + QGraphicsItem* pickedNearestItem = itemDistance2MapWithMouse[0].first; if (pickedNearestItem->data(0) == "node") { - newHoverNodeItem = (SkeletonGraphicsNodeItem *)pickedNearestItem; + newHoverNodeItem = (SkeletonGraphicsNodeItem*)pickedNearestItem; } else if (pickedNearestItem->data(0) == "edge") { - newHoverEdgeItem = (SkeletonGraphicsEdgeItem *)pickedNearestItem; + newHoverEdgeItem = (SkeletonGraphicsEdgeItem*)pickedNearestItem; } } if (newHoverNodeItem) { @@ -873,7 +871,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) } hoverPart(hoveredPartId); } - + if (SkeletonDocumentEditMode::Add == m_document->editMode) { QPointF mouseScenePos = mouseEventScenePos(event); m_cursorNodeItem->setOrigin(mouseScenePos); @@ -890,7 +888,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) } return true; } - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_moveStarted) { if (m_checkedOriginItem) { @@ -906,12 +904,12 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) float byX = mouseScenePos.x() - m_lastScenePos.x(); float byY = mouseScenePos.y() - m_lastScenePos.y(); if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); bool ikMoved = false; if (nodeItems.size() == 1) { - auto &nodeItem = *nodeItems.begin(); - const SkeletonNode *node = m_document->findNode(nodeItem->id()); + auto& nodeItem = *nodeItems.begin(); + const SkeletonNode* node = m_document->findNode(nodeItem->id()); if (node->edgeIds.size() == 1) { const auto origin = nodeItem->origin(); byX = mouseScenePos.x() - origin.x(); @@ -941,7 +939,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) } } } - + return false; } @@ -949,10 +947,10 @@ void SkeletonGraphicsWidget::rotateSelected(int degree) { if (m_rangeSelectionSet.empty()) return; - - std::set nodeItems; + + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); - + QVector2D center; if (1 == nodeItems.size() && m_document->originSettled()) { @@ -960,21 +958,21 @@ void SkeletonGraphicsWidget::rotateSelected(int degree) // 1. Pick who is the parent from neighbors // 2. Rotate all the remaining neighbor nodes and their children exlucde the picked parent QVector3D worldOrigin = QVector3D(m_document->getOriginX(m_rotated), m_document->getOriginY(m_rotated), m_document->getOriginZ(m_rotated)); - SkeletonGraphicsNodeItem *centerNodeItem = *nodeItems.begin(); - const auto ¢erNode = m_document->findNode(centerNodeItem->id()); + SkeletonGraphicsNodeItem* centerNodeItem = *nodeItems.begin(); + const auto& centerNode = m_document->findNode(centerNodeItem->id()); if (nullptr == centerNode) { qDebug() << "findNode:" << centerNodeItem->id() << " failed while rotate"; return; } std::vector> directNeighborDists; - for (const auto &neighborId: centerNode->edgeIds) { - const auto &neighborEdge = m_document->findEdge(neighborId); + for (const auto& neighborId : centerNode->edgeIds) { + const auto& neighborEdge = m_document->findEdge(neighborId); if (nullptr == neighborEdge) { qDebug() << "findEdge:" << neighborId << " failed while rotate"; continue; } - const auto &neighborNodeId = neighborEdge->neighborOf(centerNodeItem->id()); - const auto &neighborNode = m_document->findNode(neighborNodeId); + const auto& neighborNodeId = neighborEdge->neighborOf(centerNodeItem->id()); + const auto& neighborNode = m_document->findNode(neighborNodeId); if (nullptr == centerNode) { qDebug() << "findNode:" << neighborNodeId << " failed while rotate"; continue; @@ -982,7 +980,7 @@ void SkeletonGraphicsWidget::rotateSelected(int degree) QVector3D nodeOrigin(neighborNode->getX(m_rotated), neighborNode->getY(m_rotated), neighborNode->getZ(m_rotated)); directNeighborDists.push_back(std::make_pair(neighborNodeId, (nodeOrigin - worldOrigin).lengthSquared())); } - std::sort(directNeighborDists.begin(), directNeighborDists.end(), [](const std::pair &a, const std::pair &b) { + std::sort(directNeighborDists.begin(), directNeighborDists.end(), [](const std::pair& a, const std::pair& b) { return a.second < b.second; }); int skippedNum = 1; @@ -998,8 +996,8 @@ void SkeletonGraphicsWidget::rotateSelected(int degree) } center = QVector2D(centerNodeItem->origin().x(), centerNodeItem->origin().y()); nodeItems.clear(); - for (const auto &neighborId: neighborIds) { - const auto &findItemResult = nodeItemMap.find(neighborId); + for (const auto& neighborId : neighborIds) { + const auto& findItemResult = nodeItemMap.find(neighborId); if (findItemResult == nodeItemMap.end()) { qDebug() << "find node item:" << neighborId << "failed"; continue; @@ -1017,12 +1015,12 @@ void SkeletonGraphicsWidget::rotateSelected(int degree) rotateItems(nodeItems, degree, center); } -void SkeletonGraphicsWidget::rotateItems(const std::set &nodeItems, int degree, QVector2D center) +void SkeletonGraphicsWidget::rotateItems(const std::set& nodeItems, int degree, QVector2D center) { emit disableAllPositionRelatedLocks(); QVector3D centerPoint(center.x(), center.y(), 0); - for (const auto &it: nodeItems) { - SkeletonGraphicsNodeItem *nodeItem = it; + for (const auto& it : nodeItems) { + SkeletonGraphicsNodeItem* nodeItem = it; QMatrix4x4 mat; QPointF nodeOrigin = nodeItem->origin(); QVector3D nodeOriginPoint(nodeOrigin.x(), nodeOrigin.y(), 0); @@ -1049,8 +1047,8 @@ void SkeletonGraphicsWidget::rotateItems(const std::set items; - for (const auto &item: nodeItemMap) { + std::set items; + for (const auto& item : nodeItemMap) { items.insert(item.second.second); } QVector2D center(scenePosFromUnified(QPointF(m_document->getOriginZ(m_rotated), m_document->getOriginY(m_rotated)))); @@ -1080,16 +1078,16 @@ void SkeletonGraphicsWidget::moveSelected(float byX, float byY) { if (m_rangeSelectionSet.empty()) return; - + m_ikMoveEndEffectorId = dust3d::Uuid(); - + byX = sceneRadiusToUnified(byX); byY = sceneRadiusToUnified(byY); - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); - - for (const auto &it: nodeItems) { - SkeletonGraphicsNodeItem *nodeItem = it; + + for (const auto& it : nodeItems) { + SkeletonGraphicsNodeItem* nodeItem = it; if (SkeletonProfile::Main == nodeItem->profile()) { if (m_rotated) emit moveNodeBy(nodeItem->id(), byY, byX, 0); @@ -1108,14 +1106,14 @@ void SkeletonGraphicsWidget::switchSelectedXZ() { if (m_rangeSelectionSet.empty()) return; - + std::set nodeIdSet; readSkeletonNodeAndEdgeIdSetFromRangeSelection(&nodeIdSet); if (nodeIdSet.empty()) return; - + emit batchChangeBegin(); - for (const auto nodeId: nodeIdSet) { + for (const auto nodeId : nodeIdSet) { emit switchNodeXZ(nodeId); } emit batchChangeEnd(); @@ -1126,21 +1124,21 @@ void SkeletonGraphicsWidget::zoomSelected(float delta) { if (m_rangeSelectionSet.empty()) return; - - std::set nodeItems; + + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); - + float unifiedDelta = sceneRadiusToUnified(delta); - for (const auto &it: nodeItems) { - SkeletonGraphicsNodeItem *nodeItem = it; + for (const auto& it : nodeItems) { + SkeletonGraphicsNodeItem* nodeItem = it; emit scaleNodeByAddRadius(nodeItem->id(), unifiedDelta); } } -void SkeletonGraphicsWidget::getOtherProfileNodeItems(const std::set &nodeItemSet, - std::set *otherProfileNodeItemSet) +void SkeletonGraphicsWidget::getOtherProfileNodeItems(const std::set& nodeItemSet, + std::set* otherProfileNodeItemSet) { - for (const auto &nodeItem: nodeItemSet) { + for (const auto& nodeItem : nodeItemSet) { auto findNodeItem = nodeItemMap.find(nodeItem->id()); if (findNodeItem == nodeItemMap.end()) continue; @@ -1155,18 +1153,18 @@ void SkeletonGraphicsWidget::scaleSelected(float delta) { if (m_rangeSelectionSet.empty()) return; - - std::set nodeItems; + + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); - - std::set otherProfileNodeItems; + + std::set otherProfileNodeItems; getOtherProfileNodeItems(nodeItems, &otherProfileNodeItems); - + QVector2D center = centerOfNodeItemSet(nodeItems); QVector2D otherCenter = centerOfNodeItemSet(otherProfileNodeItems); std::map> moveByMap; float scale = sceneRadiusToUnified(delta); - for (const auto &nodeItem: nodeItems) { + for (const auto& nodeItem : nodeItems) { QVector2D origin = QVector2D(nodeItem->origin()); QVector2D ray = (center - origin) * scale; float byX = -sceneRadiusToUnified(ray.x()); @@ -1177,7 +1175,7 @@ void SkeletonGraphicsWidget::scaleSelected(float delta) moveByMap[nodeItem->id()] = std::make_tuple(0.0, byY, byX); } } - for (const auto &nodeItem: otherProfileNodeItems) { + for (const auto& nodeItem : otherProfileNodeItems) { QVector2D origin = QVector2D(nodeItem->origin()); QVector2D ray = (otherCenter - origin) * scale; float byX = -sceneRadiusToUnified(ray.x()); @@ -1187,7 +1185,7 @@ void SkeletonGraphicsWidget::scaleSelected(float delta) std::get<2>(moveByMap[nodeItem->id()]) = byX; } } - for (const auto &it: moveByMap) { + for (const auto& it : moveByMap) { if (m_rotated) emit moveNodeBy(it.first, std::get<1>(it.second), std::get<0>(it.second), std::get<2>(it.second)); else @@ -1195,7 +1193,7 @@ void SkeletonGraphicsWidget::scaleSelected(float delta) } } -bool SkeletonGraphicsWidget::wheel(QWheelEvent *event) +bool SkeletonGraphicsWidget::wheel(QWheelEvent* event) { float delta = 0; if (event->delta() > 0) @@ -1226,10 +1224,10 @@ bool SkeletonGraphicsWidget::wheel(QWheelEvent *event) return false; } -QVector2D SkeletonGraphicsWidget::centerOfNodeItemSet(const std::set &set) +QVector2D SkeletonGraphicsWidget::centerOfNodeItemSet(const std::set& set) { QVector2D center; - for (const auto &nodeItem: set) { + for (const auto& nodeItem : set) { center += QVector2D(nodeItem->origin()); } center /= set.size(); @@ -1238,13 +1236,13 @@ QVector2D SkeletonGraphicsWidget::centerOfNodeItemSet(const std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); if (nodeItems.empty()) return; QVector2D center = centerOfNodeItemSet(nodeItems); emit batchChangeBegin(); - for (const auto &nodeItem: nodeItems) { + for (const auto& nodeItem : nodeItems) { QPointF origin = nodeItem->origin(); float offset = origin.x() - center.x(); float unifiedOffset = -sceneRadiusToUnified(offset * 2); @@ -1263,13 +1261,13 @@ void SkeletonGraphicsWidget::flipHorizontally() void SkeletonGraphicsWidget::flipVertically() { - std::set nodeItems; + std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); if (nodeItems.empty()) return; QVector2D center = centerOfNodeItemSet(nodeItems); emit batchChangeBegin(); - for (const auto &nodeItem: nodeItems) { + for (const auto& nodeItem : nodeItems) { QPointF origin = nodeItem->origin(); float offset = origin.y() - center.y(); float unifiedOffset = -sceneRadiusToUnified(offset * 2); @@ -1318,7 +1316,7 @@ void SkeletonGraphicsWidget::rotateAllMainProfileCounterclockwise90DegreeAlongOr emit groupOperationAdded(); } -bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event) +bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { bool processed = m_dragStarted || m_moveStarted || m_rangeSelectionStarted; @@ -1341,12 +1339,12 @@ bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event) return false; } -QPointF SkeletonGraphicsWidget::mouseEventScenePos(QMouseEvent *event) +QPointF SkeletonGraphicsWidget::mouseEventScenePos(QMouseEvent* event) { return mapToScene(mapFromGlobal(event->globalPos())); } -bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) +bool SkeletonGraphicsWidget::mousePress(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode) { @@ -1374,11 +1372,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) } else if (SkeletonDocumentEditMode::Add == m_document->editMode) { if (m_cursorNodeItem->isVisible()) { if (m_addFromNodeItem) { - if (m_hoveredNodeItem && m_addFromNodeItem && - m_hoveredNodeItem != m_addFromNodeItem && - m_hoveredNodeItem->profile() == m_addFromNodeItem->profile() && - !m_document->findEdgeByNodes(m_addFromNodeItem->id(), m_hoveredNodeItem->id()) && - m_document->isNodeEditable(m_hoveredNodeItem->id())) { + if (m_hoveredNodeItem && m_addFromNodeItem && m_hoveredNodeItem != m_addFromNodeItem && m_hoveredNodeItem->profile() == m_addFromNodeItem->profile() && !m_document->findEdgeByNodes(m_addFromNodeItem->id(), m_hoveredNodeItem->id()) && m_document->isNodeEditable(m_hoveredNodeItem->id())) { if (m_document->isNodeConnectable(m_hoveredNodeItem->id())) { emit addEdge(m_addFromNodeItem->id(), m_hoveredNodeItem->id()); emit groupOperationAdded(); @@ -1399,7 +1393,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) if (mainProfile.x() >= scene()->width() / 2) { sideProfile.setX(mainProfile.x() - scene()->width() / 4); } else { - sideProfile.setX(mainProfile.x() +scene()->width() / 4); + sideProfile.setX(mainProfile.x() + scene()->width() / 4); } } QPointF unifiedMainPos = scenePosToUnified(mainProfile); @@ -1436,8 +1430,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) processed = true; } } else { - if ((nullptr == m_hoveredNodeItem || m_rangeSelectionSet.find(m_hoveredNodeItem) == m_rangeSelectionSet.end()) && - (nullptr == m_hoveredEdgeItem || m_rangeSelectionSet.find(m_hoveredEdgeItem) == m_rangeSelectionSet.end())) { + if ((nullptr == m_hoveredNodeItem || m_rangeSelectionSet.find(m_hoveredNodeItem) == m_rangeSelectionSet.end()) && (nullptr == m_hoveredEdgeItem || m_rangeSelectionSet.find(m_hoveredEdgeItem) == m_rangeSelectionSet.end())) { if (!QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) { clearRangeSelection(); } @@ -1472,7 +1465,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) } } } - + if (event->button() == Qt::LeftButton) { if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (!m_rangeSelectionStarted) { @@ -1513,7 +1506,7 @@ QPointF SkeletonGraphicsWidget::scenePosFromUnified(QPointF pos) return QPointF(pos.x() * scene()->height(), pos.y() * scene()->height()); } -bool SkeletonGraphicsWidget::mouseDoubleClick(QMouseEvent *event) +bool SkeletonGraphicsWidget::mouseDoubleClick(QMouseEvent* event) { if (m_hoveredNodeItem || m_hoveredEdgeItem) { selectPartAll(); @@ -1530,25 +1523,25 @@ void SkeletonGraphicsWidget::timeToRemoveDeferredNodesAndEdges() { delete m_deferredRemoveTimer; m_deferredRemoveTimer = nullptr; - + bool committed = false; - + if (!committed && !m_deferredRemoveEdgeIds.empty()) { - const auto &it = m_deferredRemoveEdgeIds.begin(); + const auto& it = m_deferredRemoveEdgeIds.begin(); const auto edgeId = *it; m_deferredRemoveEdgeIds.erase(it); emit removeEdge(edgeId); committed = true; } - + if (!committed && !m_deferredRemoveNodeIds.empty()) { - const auto &it = m_deferredRemoveNodeIds.begin(); + const auto& it = m_deferredRemoveNodeIds.begin(); const auto nodeId = *it; m_deferredRemoveNodeIds.erase(it); emit removeNode(nodeId); committed = true; } - + if (committed) { m_deferredRemoveTimer = new QTimer(this); connect(m_deferredRemoveTimer, &QTimer::timeout, this, &SkeletonGraphicsWidget::timeToRemoveDeferredNodesAndEdges); @@ -1562,30 +1555,30 @@ void SkeletonGraphicsWidget::deleteSelected() { if (m_rangeSelectionSet.empty()) return; - + std::set nodeIdSet; std::set edgeIdSet; readSkeletonNodeAndEdgeIdSetFromRangeSelection(&nodeIdSet, &edgeIdSet); - + std::set partIds; - for (const auto &it: nodeIdSet) { - const SkeletonNode *node = m_document->findNode(it); + for (const auto& it : nodeIdSet) { + const SkeletonNode* node = m_document->findNode(it); if (nullptr == node) continue; partIds.insert(node->partId); } - for (const auto &it: edgeIdSet) { - const SkeletonEdge *edge = m_document->findEdge(it); + for (const auto& it : edgeIdSet) { + const SkeletonEdge* edge = m_document->findEdge(it); if (nullptr == edge) continue; partIds.insert(edge->partId); } std::set cleanupPartIds; - for (const auto &partId: partIds) { - const SkeletonPart *part = m_document->findPart(partId); + for (const auto& partId : partIds) { + const SkeletonPart* part = m_document->findPart(partId); if (nullptr != part) { bool allNodesSelected = true; - for (const auto &it: part->nodeIds) { + for (const auto& it : part->nodeIds) { if (nodeIdSet.find(it) == nodeIdSet.end()) { allNodesSelected = false; break; @@ -1596,17 +1589,17 @@ void SkeletonGraphicsWidget::deleteSelected() } } } - for (const auto &partId: cleanupPartIds) { - for (auto it = nodeIdSet.begin(); it != nodeIdSet.end(); ) { - const SkeletonNode *node = m_document->findNode(*it); + for (const auto& partId : cleanupPartIds) { + for (auto it = nodeIdSet.begin(); it != nodeIdSet.end();) { + const SkeletonNode* node = m_document->findNode(*it); if (nullptr != node && node->partId == partId) { it = nodeIdSet.erase(it); continue; } ++it; } - for (auto it = edgeIdSet.begin(); it != edgeIdSet.end(); ) { - const SkeletonEdge *edge = m_document->findEdge(*it); + for (auto it = edgeIdSet.begin(); it != edgeIdSet.end();) { + const SkeletonEdge* edge = m_document->findEdge(*it); if (nullptr != edge && edge->partId == partId) { it = edgeIdSet.erase(it); continue; @@ -1614,18 +1607,18 @@ void SkeletonGraphicsWidget::deleteSelected() ++it; } } - - for (const auto &partId: cleanupPartIds) { + + for (const auto& partId : cleanupPartIds) { emit removePart(partId); } - - for (const auto &it: nodeIdSet) { + + for (const auto& it : nodeIdSet) { m_deferredRemoveNodeIds.insert(it); } - for (const auto &it: edgeIdSet) { + for (const auto& it : edgeIdSet) { m_deferredRemoveEdgeIds.insert(it); } - + if (!nodeIdSet.empty() || !edgeIdSet.empty()) { if (nullptr == m_deferredRemoveTimer) { timeToRemoveDeferredNodesAndEdges(); @@ -1637,7 +1630,7 @@ void SkeletonGraphicsWidget::shortcutDelete() { if (!isVisible()) return; - + bool processed = false; if (!m_rangeSelectionSet.empty()) { deleteSelected(); @@ -1662,7 +1655,7 @@ void SkeletonGraphicsWidget::shortcutUndo() { if (!isVisible()) return; - + emit undo(); } @@ -1670,7 +1663,7 @@ void SkeletonGraphicsWidget::shortcutRedo() { if (!isVisible()) return; - + emit redo(); } @@ -1693,7 +1686,7 @@ void SkeletonGraphicsWidget::shortcutCut() { if (!isVisible()) return; - + cut(); } @@ -1701,7 +1694,7 @@ void SkeletonGraphicsWidget::shortcutCopy() { if (!isVisible()) return; - + copy(); } @@ -1709,7 +1702,7 @@ void SkeletonGraphicsWidget::shortcutPaste() { if (!isVisible()) return; - + emit paste(); } @@ -1727,7 +1720,7 @@ void SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10() { if (!isVisible()) return; - + emit zoomRenderedModelBy(-10); } @@ -1735,7 +1728,7 @@ void SkeletonGraphicsWidget::shortcutZoomSelectedByMinus1() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) { zoomSelected(-1); emit groupOperationAdded(); @@ -1750,7 +1743,7 @@ void SkeletonGraphicsWidget::shortcutZoomRenderedModelBy10() { if (!isVisible()) return; - + emit zoomRenderedModelBy(10); } @@ -1758,7 +1751,7 @@ void SkeletonGraphicsWidget::shortcutZoomSelectedBy1() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) { zoomSelected(1); emit groupOperationAdded(); @@ -1773,9 +1766,8 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedByMinus1() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - hasSelection()) { + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { rotateSelected(-1); emit groupOperationAdded(); } @@ -1785,9 +1777,8 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedBy1() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - hasSelection()) { + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { rotateSelected(1); emit groupOperationAdded(); } @@ -1797,7 +1788,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToLeft() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_checkedOriginItem) { moveCheckedOrigin(-1, 0); @@ -1813,7 +1804,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToRight() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_checkedOriginItem) { moveCheckedOrigin(1, 0); @@ -1829,7 +1820,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToUp() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_checkedOriginItem) { moveCheckedOrigin(0, -1); @@ -1845,7 +1836,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToDown() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (m_checkedOriginItem) { moveCheckedOrigin(0, 1); @@ -1861,9 +1852,8 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedByMinus1() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - hasSelection()) { + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { scaleSelected(-1); emit groupOperationAdded(); } @@ -1873,9 +1863,8 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedBy1() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - hasSelection()) { + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { scaleSelected(1); emit groupOperationAdded(); } @@ -1885,9 +1874,8 @@ void SkeletonGraphicsWidget::shortcutSwitchProfileOnSelected() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - hasSelection()) { + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && hasSelection()) { switchProfileOnRangeSelection(); } } @@ -1896,10 +1884,10 @@ void SkeletonGraphicsWidget::shortcutShowOrHideSelectedPart() { if (!isVisible()) return; - + if (SkeletonDocumentEditMode::Select == m_document->editMode) { if (!m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partVisible = part && part->visible; emit setPartVisibleState(m_lastCheckedPart, !partVisible); emit groupOperationAdded(); @@ -1913,10 +1901,9 @@ void SkeletonGraphicsWidget::shortcutEnableOrDisableSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partDisabled = part && part->disabled; emit setPartDisableState(m_lastCheckedPart, !partDisabled); emit groupOperationAdded(); @@ -1927,10 +1914,9 @@ void SkeletonGraphicsWidget::shortcutLockOrUnlockSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partLocked = part && part->locked; emit setPartLockState(m_lastCheckedPart, !partLocked); emit groupOperationAdded(); @@ -1941,10 +1927,9 @@ void SkeletonGraphicsWidget::shortcutXmirrorOnOrOffSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partXmirrored = part && part->xMirrored; emit setPartXmirrorState(m_lastCheckedPart, !partXmirrored); emit groupOperationAdded(); @@ -1955,10 +1940,9 @@ void SkeletonGraphicsWidget::shortcutSubdivedOrNotSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partSubdived = part && part->subdived; emit setPartSubdivState(m_lastCheckedPart, !partSubdived); emit groupOperationAdded(); @@ -1969,10 +1953,9 @@ void SkeletonGraphicsWidget::shortcutChamferedOrNotSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partChamfered = part && part->chamfered; emit setPartChamferState(m_lastCheckedPart, !partChamfered); emit groupOperationAdded(); @@ -1983,7 +1966,7 @@ void SkeletonGraphicsWidget::shortcutSelectAll() { if (!isVisible()) return; - + selectAll(); } @@ -1991,34 +1974,30 @@ void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart() { if (!isVisible()) return; - - if ((SkeletonDocumentEditMode::Select == m_document->editMode) && - !m_lastCheckedPart.isNull()) { - const SkeletonPart *part = m_document->findPart(m_lastCheckedPart); + + if ((SkeletonDocumentEditMode::Select == m_document->editMode) && !m_lastCheckedPart.isNull()) { + const SkeletonPart* part = m_document->findPart(m_lastCheckedPart); bool partRounded = part && part->rounded; emit setPartRoundState(m_lastCheckedPart, !partRounded); emit groupOperationAdded(); } } -bool SkeletonGraphicsWidget::keyPress(QKeyEvent *event) +bool SkeletonGraphicsWidget::keyPress(QKeyEvent* event) { if (event->key() == Qt::Key_Space) { - if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode || - SkeletonDocumentEditMode::ZoomOut == m_document->editMode || - SkeletonDocumentEditMode::Select == m_document->editMode || - SkeletonDocumentEditMode::Add == m_document->editMode) { + if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode || SkeletonDocumentEditMode::ZoomOut == m_document->editMode || SkeletonDocumentEditMode::Select == m_document->editMode || SkeletonDocumentEditMode::Add == m_document->editMode) { m_inTempDragMode = true; m_modeBeforeEnterTempDragMode = m_document->editMode; emit setEditMode(SkeletonDocumentEditMode::Drag); return true; } } - + return false; } -bool SkeletonGraphicsWidget::keyRelease(QKeyEvent *event) +bool SkeletonGraphicsWidget::keyRelease(QKeyEvent* event) { if (event->key() == Qt::Key_Space) { if (m_inTempDragMode) { @@ -2027,7 +2006,7 @@ bool SkeletonGraphicsWidget::keyRelease(QKeyEvent *event) return true; } } - + return false; } @@ -2046,7 +2025,7 @@ void SkeletonGraphicsWidget::originChanged() void SkeletonGraphicsWidget::nodeAdded(dust3d::Uuid nodeId) { - const SkeletonNode *node = m_document->findNode(nodeId); + const SkeletonNode* node = m_document->findNode(nodeId); if (nullptr == node) { qDebug() << "New node added but node id not exist:" << nodeId; return; @@ -2055,9 +2034,9 @@ void SkeletonGraphicsWidget::nodeAdded(dust3d::Uuid nodeId) qDebug() << "New node added but node item already exist:" << nodeId; return; } - SkeletonGraphicsNodeItem *mainProfileItem = new SkeletonGraphicsNodeItem(SkeletonProfile::Main); + SkeletonGraphicsNodeItem* mainProfileItem = new SkeletonGraphicsNodeItem(SkeletonProfile::Main); mainProfileItem->setRotated(m_rotated); - SkeletonGraphicsNodeItem *sideProfileItem = new SkeletonGraphicsNodeItem(SkeletonProfile::Side); + SkeletonGraphicsNodeItem* sideProfileItem = new SkeletonGraphicsNodeItem(SkeletonProfile::Side); sideProfileItem->setRotated(m_rotated); mainProfileItem->setOrigin(scenePosFromUnified(QPointF(node->getX(m_rotated), node->getY(m_rotated)))); sideProfileItem->setOrigin(scenePosFromUnified(QPointF(node->getZ(m_rotated), node->getY(m_rotated)))); @@ -2072,7 +2051,7 @@ void SkeletonGraphicsWidget::nodeAdded(dust3d::Uuid nodeId) scene()->addItem(mainProfileItem); scene()->addItem(sideProfileItem); nodeItemMap[nodeId] = std::make_pair(mainProfileItem, sideProfileItem); - + if (nullptr == m_addFromNodeItem) { m_addFromNodeItem = mainProfileItem; } else { @@ -2087,7 +2066,7 @@ void SkeletonGraphicsWidget::nodeAdded(dust3d::Uuid nodeId) void SkeletonGraphicsWidget::edgeReversed(dust3d::Uuid edgeId) { - const SkeletonEdge *edge = m_document->findEdge(edgeId); + const SkeletonEdge* edge = m_document->findEdge(edgeId); if (nullptr == edge) { qDebug() << "Edge changed but edge id not exist:" << edgeId; return; @@ -2103,7 +2082,7 @@ void SkeletonGraphicsWidget::edgeReversed(dust3d::Uuid edgeId) void SkeletonGraphicsWidget::edgeAdded(dust3d::Uuid edgeId) { - const SkeletonEdge *edge = m_document->findEdge(edgeId); + const SkeletonEdge* edge = m_document->findEdge(edgeId); if (nullptr == edge) { qDebug() << "New edge added but edge id not exist:" << edgeId; return; @@ -2128,9 +2107,9 @@ void SkeletonGraphicsWidget::edgeAdded(dust3d::Uuid edgeId) qDebug() << "New edge added but edge item already exist:" << edgeId; return; } - SkeletonGraphicsEdgeItem *mainProfileEdgeItem = new SkeletonGraphicsEdgeItem(); + SkeletonGraphicsEdgeItem* mainProfileEdgeItem = new SkeletonGraphicsEdgeItem(); mainProfileEdgeItem->setRotated(m_rotated); - SkeletonGraphicsEdgeItem *sideProfileEdgeItem = new SkeletonGraphicsEdgeItem(); + SkeletonGraphicsEdgeItem* sideProfileEdgeItem = new SkeletonGraphicsEdgeItem(); sideProfileEdgeItem->setRotated(m_rotated); mainProfileEdgeItem->setId(edgeId); sideProfileEdgeItem->setId(edgeId); @@ -2145,7 +2124,7 @@ void SkeletonGraphicsWidget::edgeAdded(dust3d::Uuid edgeId) edgeItemMap[edgeId] = std::make_pair(mainProfileEdgeItem, sideProfileEdgeItem); } -void SkeletonGraphicsWidget::removeItem(QGraphicsItem *item) +void SkeletonGraphicsWidget::removeItem(QGraphicsItem* item) { if (m_hoveredNodeItem == item) m_hoveredNodeItem = nullptr; @@ -2189,7 +2168,7 @@ void SkeletonGraphicsWidget::edgeRemoved(dust3d::Uuid edgeId) void SkeletonGraphicsWidget::nodeRadiusChanged(dust3d::Uuid nodeId) { - const SkeletonNode *node = m_document->findNode(nodeId); + const SkeletonNode* node = m_document->findNode(nodeId); if (nullptr == node) { qDebug() << "Node changed but node id not exist:" << nodeId; return; @@ -2206,7 +2185,7 @@ void SkeletonGraphicsWidget::nodeRadiusChanged(dust3d::Uuid nodeId) void SkeletonGraphicsWidget::nodeOriginChanged(dust3d::Uuid nodeId) { - const SkeletonNode *node = m_document->findNode(nodeId); + const SkeletonNode* node = m_document->findNode(nodeId); if (nullptr == node) { qDebug() << "Node changed but node id not exist:" << nodeId; return; @@ -2239,9 +2218,9 @@ void SkeletonGraphicsWidget::nodeOriginChanged(dust3d::Uuid nodeId) void SkeletonGraphicsWidget::partVisibleStateChanged(dust3d::Uuid partId) { - const SkeletonPart *part = m_document->findPart(partId); - for (const auto &nodeId: part->nodeIds) { - const SkeletonNode *node = m_document->findNode(nodeId); + const SkeletonPart* part = m_document->findPart(partId); + for (const auto& nodeId : part->nodeIds) { + const SkeletonNode* node = m_document->findNode(nodeId); for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { auto edgeItemIt = edgeItemMap.find(*edgeIt); if (edgeItemIt == edgeItemMap.end()) { @@ -2261,14 +2240,14 @@ void SkeletonGraphicsWidget::partVisibleStateChanged(dust3d::Uuid partId) } } -bool SkeletonGraphicsWidget::checkSkeletonItem(QGraphicsItem *item, bool checked) +bool SkeletonGraphicsWidget::checkSkeletonItem(QGraphicsItem* item, bool checked) { if (checked) { if (!item->isVisible()) return false; } if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; if (checked) { if (!m_document->isNodeEditable(nodeItem->id())) { return false; @@ -2278,7 +2257,7 @@ bool SkeletonGraphicsWidget::checkSkeletonItem(QGraphicsItem *item, bool checked nodeItem->setChecked(checked); return true; } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; if (checked) { if (!m_document->isEdgeEditable(edgeItem->id())) { return false; @@ -2291,19 +2270,19 @@ bool SkeletonGraphicsWidget::checkSkeletonItem(QGraphicsItem *item, bool checked return false; } -dust3d::Uuid SkeletonGraphicsWidget::querySkeletonItemPartId(QGraphicsItem *item) +dust3d::Uuid SkeletonGraphicsWidget::querySkeletonItemPartId(QGraphicsItem* item) { if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; - const SkeletonNode *node = m_document->findNode(nodeItem->id()); + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; + const SkeletonNode* node = m_document->findNode(nodeItem->id()); if (!node) { qDebug() << "Find node id failed:" << nodeItem->id(); return dust3d::Uuid(); } return node->partId; } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; - const SkeletonEdge *edge = m_document->findEdge(edgeItem->id()); + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; + const SkeletonEdge* edge = m_document->findEdge(edgeItem->id()); if (!edge) { qDebug() << "Find edge id failed:" << edgeItem->id(); return dust3d::Uuid(); @@ -2313,13 +2292,13 @@ dust3d::Uuid SkeletonGraphicsWidget::querySkeletonItemPartId(QGraphicsItem *item return dust3d::Uuid(); } -SkeletonProfile SkeletonGraphicsWidget::readSkeletonItemProfile(QGraphicsItem *item) +SkeletonProfile SkeletonGraphicsWidget::readSkeletonItemProfile(QGraphicsItem* item) { if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; return nodeItem->profile(); } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; return edgeItem->profile(); } return SkeletonProfile::Unknown; @@ -2327,18 +2306,18 @@ SkeletonProfile SkeletonGraphicsWidget::readSkeletonItemProfile(QGraphicsItem *i void SkeletonGraphicsWidget::checkRangeSelection() { - std::set newSet; - std::set deleteSet; - std::set forceDeleteSet; + std::set newSet; + std::set deleteSet; + std::set forceDeleteSet; SkeletonProfile choosenProfile = SkeletonProfile::Unknown; if (!m_rangeSelectionSet.empty()) { auto it = m_rangeSelectionSet.begin(); choosenProfile = readSkeletonItemProfile(*it); } if (m_selectionItem->isVisible()) { - QList items = scene()->items(m_selectionItem->sceneBoundingRect()); + QList items = scene()->items(m_selectionItem->sceneBoundingRect()); for (auto it = items.begin(); it != items.end(); it++) { - QGraphicsItem *item = *it; + QGraphicsItem* item = *it; if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) { checkSkeletonItem(item, false); forceDeleteSet.insert(item); @@ -2356,40 +2335,40 @@ void SkeletonGraphicsWidget::checkRangeSelection() } } if (!QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) { - for (const auto &item: m_rangeSelectionSet) { + for (const auto& item : m_rangeSelectionSet) { if (newSet.find(item) == newSet.end()) { checkSkeletonItem(item, false); deleteSet.insert(item); } } } - for (const auto &item: newSet) { + for (const auto& item : newSet) { m_rangeSelectionSet.insert(item); } - for (const auto &item: deleteSet) { + for (const auto& item : deleteSet) { m_rangeSelectionSet.erase(item); } - for (const auto &item: forceDeleteSet) { + for (const auto& item : forceDeleteSet) { m_rangeSelectionSet.erase(item); } } void SkeletonGraphicsWidget::clearRangeSelection() { - for (const auto &item: m_rangeSelectionSet) { + for (const auto& item : m_rangeSelectionSet) { checkSkeletonItem(item, false); } m_rangeSelectionSet.clear(); } -void SkeletonGraphicsWidget::readMergedSkeletonNodeSetFromRangeSelection(std::set *nodeItemSet) +void SkeletonGraphicsWidget::readMergedSkeletonNodeSetFromRangeSelection(std::set* nodeItemSet) { - for (const auto &it: m_rangeSelectionSet) { - QGraphicsItem *item = it; + for (const auto& it : m_rangeSelectionSet) { + QGraphicsItem* item = it; if (item->data(0) == "node") { - nodeItemSet->insert((SkeletonGraphicsNodeItem *)item); + nodeItemSet->insert((SkeletonGraphicsNodeItem*)item); } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; if (edgeItem->firstItem() && edgeItem->secondItem()) { nodeItemSet->insert(edgeItem->firstItem()); nodeItemSet->insert(edgeItem->secondItem()); @@ -2398,29 +2377,29 @@ void SkeletonGraphicsWidget::readMergedSkeletonNodeSetFromRangeSelection(std::se } } -void SkeletonGraphicsWidget::readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set *nodeIdSet, std::set *edgeIdSet) +void SkeletonGraphicsWidget::readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set* nodeIdSet, std::set* edgeIdSet) { - for (const auto &it: m_rangeSelectionSet) { - QGraphicsItem *item = it; + for (const auto& it : m_rangeSelectionSet) { + QGraphicsItem* item = it; if (item->data(0) == "node") { - nodeIdSet->insert(((SkeletonGraphicsNodeItem *)item)->id()); + nodeIdSet->insert(((SkeletonGraphicsNodeItem*)item)->id()); } else if (item->data(0) == "edge") { if (nullptr != edgeIdSet) - edgeIdSet->insert(((SkeletonGraphicsEdgeItem *)item)->id()); + edgeIdSet->insert(((SkeletonGraphicsEdgeItem*)item)->id()); } } } -bool SkeletonGraphicsWidget::readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem **nodeItem, SkeletonGraphicsEdgeItem **edgeItem) +bool SkeletonGraphicsWidget::readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem** nodeItem, SkeletonGraphicsEdgeItem** edgeItem) { - SkeletonGraphicsNodeItem *choosenNodeItem = nullptr; - SkeletonGraphicsEdgeItem *choosenEdgeItem = nullptr; - for (const auto &it: m_rangeSelectionSet) { - QGraphicsItem *item = it; + SkeletonGraphicsNodeItem* choosenNodeItem = nullptr; + SkeletonGraphicsEdgeItem* choosenEdgeItem = nullptr; + for (const auto& it : m_rangeSelectionSet) { + QGraphicsItem* item = it; if (item->data(0) == "node") { - choosenNodeItem = (SkeletonGraphicsNodeItem *)item; + choosenNodeItem = (SkeletonGraphicsNodeItem*)item; } else if (item->data(0) == "edge") { - choosenEdgeItem = (SkeletonGraphicsEdgeItem *)item; + choosenEdgeItem = (SkeletonGraphicsEdgeItem*)item; } if (choosenNodeItem && choosenEdgeItem) break; @@ -2443,18 +2422,18 @@ bool SkeletonGraphicsWidget::readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection( void SkeletonGraphicsWidget::selectPartAllById(dust3d::Uuid partId) { unselectAll(); - for (const auto &it: nodeItemMap) { - SkeletonGraphicsNodeItem *item = it.second.first; - const SkeletonNode *node = m_document->findNode(item->id()); + for (const auto& it : nodeItemMap) { + SkeletonGraphicsNodeItem* item = it.second.first; + const SkeletonNode* node = m_document->findNode(item->id()); if (!node) continue; if (node->partId != partId) continue; addItemToRangeSelection(item); } - for (const auto &it: edgeItemMap) { - SkeletonGraphicsEdgeItem *item = it.second.first; - const SkeletonEdge *edge = m_document->findEdge(item->id()); + for (const auto& it : edgeItemMap) { + SkeletonGraphicsEdgeItem* item = it.second.first; + const SkeletonEdge* edge = m_document->findEdge(item->id()); if (!edge) continue; if (edge->partId != partId) @@ -2466,7 +2445,7 @@ void SkeletonGraphicsWidget::selectPartAllById(dust3d::Uuid partId) void SkeletonGraphicsWidget::addSelectNode(dust3d::Uuid nodeId) { - const auto &findResult = nodeItemMap.find(nodeId); + const auto& findResult = nodeItemMap.find(nodeId); if (findResult == nodeItemMap.end()) { qDebug() << "addSelectNode failed because of node id not exists:<<" << nodeId; return; @@ -2477,7 +2456,7 @@ void SkeletonGraphicsWidget::addSelectNode(dust3d::Uuid nodeId) void SkeletonGraphicsWidget::addSelectEdge(dust3d::Uuid edgeId) { - const auto &findResult = edgeItemMap.find(edgeId); + const auto& findResult = edgeItemMap.find(edgeId); if (findResult == edgeItemMap.end()) { qDebug() << "addSelectEdge failed because of edge id not exists:<<" << edgeId; return; @@ -2495,9 +2474,9 @@ void SkeletonGraphicsWidget::addPartToSelection(dust3d::Uuid partId) choosenProfile = m_hoveredEdgeItem->profile(); } dust3d::Uuid choosenPartId = partId; - for (const auto &it: nodeItemMap) { - SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; - const SkeletonNode *node = m_document->findNode(item->id()); + for (const auto& it : nodeItemMap) { + SkeletonGraphicsNodeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + const SkeletonNode* node = m_document->findNode(item->id()); if (!node) continue; if (choosenPartId.isNull()) { @@ -2507,9 +2486,9 @@ void SkeletonGraphicsWidget::addPartToSelection(dust3d::Uuid partId) continue; addItemToRangeSelection(item); } - for (const auto &it: edgeItemMap) { - SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; - const SkeletonEdge *edge = m_document->findEdge(item->id()); + for (const auto& it : edgeItemMap) { + SkeletonGraphicsEdgeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + const SkeletonEdge* edge = m_document->findEdge(item->id()); if (!edge) continue; if (choosenPartId.isNull()) { @@ -2528,12 +2507,12 @@ void SkeletonGraphicsWidget::selectConnectedAll() dust3d::Uuid startNodeId; if (m_hoveredNodeItem) { choosenProfile = m_hoveredNodeItem->profile(); - const SkeletonNode *node = m_document->findNode(m_hoveredNodeItem->id()); + const SkeletonNode* node = m_document->findNode(m_hoveredNodeItem->id()); if (node) startNodeId = node->id; } else if (m_hoveredEdgeItem) { choosenProfile = m_hoveredEdgeItem->profile(); - const SkeletonEdge *edge = m_document->findEdge(m_hoveredEdgeItem->id()); + const SkeletonEdge* edge = m_document->findEdge(m_hoveredEdgeItem->id()); if (edge && !edge->nodeIds.empty()) startNodeId = *edge->nodeIds.begin(); } @@ -2548,30 +2527,30 @@ void SkeletonGraphicsWidget::selectConnectedAll() nodeIds.pop(); if (visitedNodes.find(nodeId) != visitedNodes.end()) continue; - const SkeletonNode *node = m_document->findNode(nodeId); + const SkeletonNode* node = m_document->findNode(nodeId); if (nullptr == node) continue; visitedNodes.insert(nodeId); - for (const auto &edgeId: node->edgeIds) { - const SkeletonEdge *edge = m_document->findEdge(edgeId); + for (const auto& edgeId : node->edgeIds) { + const SkeletonEdge* edge = m_document->findEdge(edgeId); if (nullptr == edge) continue; visitedEdges.insert(edgeId); - for (const auto &nodeIdOfEdge: edge->nodeIds) { + for (const auto& nodeIdOfEdge : edge->nodeIds) { if (visitedNodes.find(nodeIdOfEdge) != visitedNodes.end()) continue; nodeIds.push(nodeIdOfEdge); } } } - for (const auto &it: nodeItemMap) { - SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + for (const auto& it : nodeItemMap) { + SkeletonGraphicsNodeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; if (visitedNodes.find(item->id()) == visitedNodes.end()) continue; addItemToRangeSelection(item); } - for (const auto &it: edgeItemMap) { - SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + for (const auto& it : edgeItemMap) { + SkeletonGraphicsEdgeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; if (visitedEdges.find(item->id()) == visitedEdges.end()) continue; addItemToRangeSelection(item); @@ -2585,18 +2564,18 @@ void SkeletonGraphicsWidget::selectPartAll() dust3d::Uuid choosenPartId; if (m_hoveredNodeItem) { choosenProfile = m_hoveredNodeItem->profile(); - const SkeletonNode *node = m_document->findNode(m_hoveredNodeItem->id()); + const SkeletonNode* node = m_document->findNode(m_hoveredNodeItem->id()); if (node) choosenPartId = node->partId; } else if (m_hoveredEdgeItem) { choosenProfile = m_hoveredEdgeItem->profile(); - const SkeletonEdge *edge = m_document->findEdge(m_hoveredEdgeItem->id()); + const SkeletonEdge* edge = m_document->findEdge(m_hoveredEdgeItem->id()); if (edge) choosenPartId = edge->partId; } - for (const auto &it: nodeItemMap) { - SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; - const SkeletonNode *node = m_document->findNode(item->id()); + for (const auto& it : nodeItemMap) { + SkeletonGraphicsNodeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + const SkeletonNode* node = m_document->findNode(item->id()); if (!node) continue; if (choosenPartId.isNull()) { @@ -2606,9 +2585,9 @@ void SkeletonGraphicsWidget::selectPartAll() continue; addItemToRangeSelection(item); } - for (const auto &it: edgeItemMap) { - SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; - const SkeletonEdge *edge = m_document->findEdge(item->id()); + for (const auto& it : edgeItemMap) { + SkeletonGraphicsEdgeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + const SkeletonEdge* edge = m_document->findEdge(item->id()); if (!edge) continue; if (choosenPartId.isNull()) { @@ -2627,14 +2606,14 @@ void SkeletonGraphicsWidget::shortcutCheckPartComponent() { if (!isVisible()) return; - + dust3d::Uuid choosenPartId; if (m_hoveredNodeItem) { - const SkeletonNode *node = m_document->findNode(m_hoveredNodeItem->id()); + const SkeletonNode* node = m_document->findNode(m_hoveredNodeItem->id()); if (node) choosenPartId = node->partId; } else if (m_hoveredEdgeItem) { - const SkeletonEdge *edge = m_document->findEdge(m_hoveredEdgeItem->id()); + const SkeletonEdge* edge = m_document->findEdge(m_hoveredEdgeItem->id()); if (edge) choosenPartId = edge->partId; } @@ -2652,17 +2631,17 @@ void SkeletonGraphicsWidget::selectAll() } else if (m_hoveredEdgeItem) { choosenProfile = m_hoveredEdgeItem->profile(); } - for (const auto &it: nodeItemMap) { - SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + for (const auto& it : nodeItemMap) { + SkeletonGraphicsNodeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; addItemToRangeSelection(item); } - for (const auto &it: edgeItemMap) { - SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; + for (const auto& it : edgeItemMap) { + SkeletonGraphicsEdgeItem* item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second; addItemToRangeSelection(item); } } -void SkeletonGraphicsWidget::addItemToRangeSelection(QGraphicsItem *item) +void SkeletonGraphicsWidget::addItemToRangeSelection(QGraphicsItem* item) { if (!item->isVisible()) return; @@ -2670,7 +2649,7 @@ void SkeletonGraphicsWidget::addItemToRangeSelection(QGraphicsItem *item) m_rangeSelectionSet.insert(item); } -void SkeletonGraphicsWidget::removeItemFromRangeSelection(QGraphicsItem *item) +void SkeletonGraphicsWidget::removeItemFromRangeSelection(QGraphicsItem* item) { checkSkeletonItem(item, false); m_rangeSelectionSet.erase(item); @@ -2678,7 +2657,7 @@ void SkeletonGraphicsWidget::removeItemFromRangeSelection(QGraphicsItem *item) void SkeletonGraphicsWidget::unselectAll() { - for (const auto &item: m_rangeSelectionSet) { + for (const auto& item : m_rangeSelectionSet) { checkSkeletonItem(item, false); } m_rangeSelectionSet.clear(); @@ -2710,9 +2689,9 @@ void SkeletonGraphicsWidget::removeAllContent() m_addFromNodeItem = nullptr; m_cursorEdgeItem->hide(); m_cursorNodeItem->hide(); - std::vector contentItems; - for (const auto &it: items()) { - QGraphicsItem *item = it; + std::vector contentItems; + for (const auto& it : items()) { + QGraphicsItem* item = it; if (item->data(0) == "node") { contentItems.push_back(item); } else if (item->data(0) == "edge") { @@ -2720,7 +2699,7 @@ void SkeletonGraphicsWidget::removeAllContent() } } for (size_t i = 0; i < contentItems.size(); i++) { - QGraphicsItem *item = contentItems[i]; + QGraphicsItem* item = contentItems[i]; Q_ASSERT(item != m_cursorEdgeItem); Q_ASSERT(item != m_cursorNodeItem); delete item; @@ -2731,8 +2710,8 @@ bool SkeletonGraphicsWidget::isSingleNodeSelected() { if (m_rangeSelectionSet.size() != 1) return false; - const auto &it = m_rangeSelectionSet.begin(); - QGraphicsItem *item = *it; + const auto& it = m_rangeSelectionSet.begin(); + QGraphicsItem* item = *it; return item->data(0) == "node"; } @@ -2740,14 +2719,14 @@ void SkeletonGraphicsWidget::hoverPart(dust3d::Uuid partId) { if (partId.isNull()) { if (!m_rangeSelectionSet.empty()) { - const auto &it = m_rangeSelectionSet.begin(); + const auto& it = m_rangeSelectionSet.begin(); partId = querySkeletonItemPartId(*it); } } - + if (m_lastCheckedPart == partId) return; - + if (!m_lastCheckedPart.isNull()) emit partUnchecked(m_lastCheckedPart); m_lastCheckedPart = partId; @@ -2758,40 +2737,40 @@ void SkeletonGraphicsWidget::hoverPart(dust3d::Uuid partId) void SkeletonGraphicsWidget::switchProfileOnRangeSelection() { auto copiedSet = m_rangeSelectionSet; - for (const auto &item: copiedSet) { + for (const auto& item : copiedSet) { if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; - const auto &find = nodeItemMap.find(nodeItem->id()); + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; + const auto& find = nodeItemMap.find(nodeItem->id()); if (find == nodeItemMap.end()) { qDebug() << "Node item map key not found:" << nodeItem->id(); return; } checkSkeletonItem(nodeItem, false); m_rangeSelectionSet.erase(nodeItem); - SkeletonGraphicsNodeItem *altNodeItem = nodeItem == find->second.first ? find->second.second : find->second.first; + SkeletonGraphicsNodeItem* altNodeItem = nodeItem == find->second.first ? find->second.second : find->second.first; if (checkSkeletonItem(altNodeItem, true)) m_rangeSelectionSet.insert(altNodeItem); } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; - const auto &find = edgeItemMap.find(edgeItem->id()); + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; + const auto& find = edgeItemMap.find(edgeItem->id()); if (find == edgeItemMap.end()) { qDebug() << "Edge item map key not found:" << edgeItem->id(); return; } checkSkeletonItem(edgeItem, false); m_rangeSelectionSet.erase(edgeItem); - SkeletonGraphicsEdgeItem *altEdgeItem = edgeItem == find->second.first ? find->second.second : find->second.first; + SkeletonGraphicsEdgeItem* altEdgeItem = edgeItem == find->second.first ? find->second.second : find->second.first; if (checkSkeletonItem(altEdgeItem, true)) m_rangeSelectionSet.insert(altEdgeItem); } } } -void SkeletonGraphicsWidget::setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered) +void SkeletonGraphicsWidget::setItemHoveredOnAllProfiles(QGraphicsItem* item, bool hovered) { if (item->data(0) == "node") { - SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item; - const auto &find = nodeItemMap.find(nodeItem->id()); + SkeletonGraphicsNodeItem* nodeItem = (SkeletonGraphicsNodeItem*)item; + const auto& find = nodeItemMap.find(nodeItem->id()); if (find == nodeItemMap.end()) { qDebug() << "Node item map key not found:" << nodeItem->id(); return; @@ -2799,8 +2778,8 @@ void SkeletonGraphicsWidget::setItemHoveredOnAllProfiles(QGraphicsItem *item, bo find->second.first->setHovered(hovered); find->second.second->setHovered(hovered); } else if (item->data(0) == "edge") { - SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item; - const auto &find = edgeItemMap.find(edgeItem->id()); + SkeletonGraphicsEdgeItem* edgeItem = (SkeletonGraphicsEdgeItem*)item; + const auto& find = edgeItemMap.find(edgeItem->id()); if (find == edgeItemMap.end()) { qDebug() << "Edge item map key not found:" << edgeItem->id(); return; @@ -2813,11 +2792,10 @@ void SkeletonGraphicsWidget::setItemHoveredOnAllProfiles(QGraphicsItem *item, bo void SkeletonGraphicsWidget::ikMoveReady() { unsigned long long movedUpdateVersion = m_ikMover->getUpdateVersion(); - - if (movedUpdateVersion == m_ikMoveUpdateVersion && - !m_ikMoveEndEffectorId.isNull()) { + + if (movedUpdateVersion == m_ikMoveUpdateVersion && !m_ikMoveEndEffectorId.isNull()) { emit batchChangeBegin(); - for (const auto &it: m_ikMover->ikNodes()) { + for (const auto& it : m_ikMover->ikNodes()) { if (m_rotated) emit setNodeOrigin(it.id, it.newPosition.y(), it.newPosition.x(), it.newPosition.z()); else @@ -2826,12 +2804,11 @@ void SkeletonGraphicsWidget::ikMoveReady() emit batchChangeEnd(); emit groupOperationAdded(); } - + delete m_ikMover; m_ikMover = nullptr; - - if (movedUpdateVersion != m_ikMoveUpdateVersion && - !m_ikMoveEndEffectorId.isNull()) { + + if (movedUpdateVersion != m_ikMoveUpdateVersion && !m_ikMoveEndEffectorId.isNull()) { ikMove(m_ikMoveEndEffectorId, m_ikMoveTarget); } } @@ -2844,9 +2821,9 @@ void SkeletonGraphicsWidget::ikMove(dust3d::Uuid endEffectorId, QVector3D target if (nullptr != m_ikMover) { return; } - - QThread *thread = new QThread; - + + QThread* thread = new QThread; + m_ikMover = new SkeletonIkMover(); m_ikMover->setUpdateVersion(m_ikMoveUpdateVersion); m_ikMover->setTarget(m_ikMoveTarget); @@ -2862,7 +2839,7 @@ void SkeletonGraphicsWidget::ikMove(dust3d::Uuid endEffectorId, QVector3D target if (node->edgeIds.size() < 1 || node->edgeIds.size() > 2) break; dust3d::Uuid choosenNodeId; - for (const auto &edgeId: node->edgeIds) { + for (const auto& edgeId : node->edgeIds) { const auto edge = m_document->findEdge(edgeId); if (nullptr == edge) break; diff --git a/application/sources/skeleton_graphics_widget.h b/application/sources/skeleton_graphics_widget.h index 07ed380b..5d8f3d5e 100644 --- a/application/sources/skeleton_graphics_widget.h +++ b/application/sources/skeleton_graphics_widget.h @@ -1,32 +1,31 @@ #ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ #define DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ -#include -#include -#include +#include "model_widget.h" +#include "skeleton_document.h" +#include "skeleton_ik_mover.h" +#include "theme.h" +#include "turnaround_loader.h" #include #include -#include #include #include +#include +#include +#include #include -#include -#include #include -#include "skeleton_document.h" -#include "turnaround_loader.h" -#include "theme.h" -#include "skeleton_ik_mover.h" -#include "model_widget.h" +#include +#include +#include -class SkeletonGraphicsOriginItem : public QGraphicsPolygonItem -{ +class SkeletonGraphicsOriginItem : public QGraphicsPolygonItem { public: - SkeletonGraphicsOriginItem(SkeletonProfile profile=SkeletonProfile::Unknown) : - m_profile(profile), - m_hovered(false), - m_checked(false), - m_rotated(false) + SkeletonGraphicsOriginItem(SkeletonProfile profile = SkeletonProfile::Unknown) + : m_profile(profile) + , m_hovered(false) + , m_checked(false) + , m_rotated(false) { setData(0, "origin"); } @@ -37,9 +36,8 @@ public: void updateAppearance() { QColor color = Theme::white; - - switch (m_profile) - { + + switch (m_profile) { case SkeletonProfile::Unknown: break; case SkeletonProfile::Main: @@ -49,13 +47,13 @@ public: color = Theme::green; break; } - + QColor penColor = color; penColor.setAlphaF(m_checked ? Theme::checkedAlpha : Theme::normalAlpha); QPen pen(penColor); pen.setWidth(0); setPen(pen); - + QColor brushColor = color; brushColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); QBrush brush(brushColor); @@ -99,6 +97,7 @@ public: { return m_hovered; } + private: SkeletonProfile m_profile; bool m_hovered; @@ -107,8 +106,7 @@ private: bool m_rotated; }; -class SkeletonGraphicsSelectionItem : public QGraphicsRectItem -{ +class SkeletonGraphicsSelectionItem : public QGraphicsRectItem { public: SkeletonGraphicsSelectionItem() { @@ -124,16 +122,15 @@ public: } }; -class SkeletonGraphicsNodeItem : public QGraphicsEllipseItem -{ +class SkeletonGraphicsNodeItem : public QGraphicsEllipseItem { public: - SkeletonGraphicsNodeItem(SkeletonProfile profile=SkeletonProfile::Unknown) : - m_profile(profile), - m_hovered(false), - m_checked(false), - m_markColor(Qt::transparent), - m_deactivated(false), - m_rotated(false) + SkeletonGraphicsNodeItem(SkeletonProfile profile = SkeletonProfile::Unknown) + : m_profile(profile) + , m_hovered(false) + , m_checked(false) + , m_markColor(Qt::transparent) + , m_deactivated(false) + , m_rotated(false) { setData(0, "node"); setRadius(32); @@ -145,10 +142,9 @@ public: void updateAppearance() { QColor color = Qt::gray; - + if (!m_deactivated) { - switch (m_profile) - { + switch (m_profile) { case SkeletonProfile::Unknown: break; case SkeletonProfile::Main: @@ -159,13 +155,13 @@ public: break; } } - + QColor penColor = color; penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); QPen pen(penColor); pen.setWidth(0); setPen(pen); - + QColor brushColor; Qt::BrushStyle style; if (m_markColor == Qt::transparent) { @@ -253,6 +249,7 @@ public: { return m_hovered; } + private: dust3d::Uuid m_uuid; SkeletonProfile m_profile; @@ -263,17 +260,16 @@ private: bool m_rotated; }; -class SkeletonGraphicsEdgeItem : public QGraphicsPolygonItem -{ +class SkeletonGraphicsEdgeItem : public QGraphicsPolygonItem { public: - SkeletonGraphicsEdgeItem() : - m_firstItem(nullptr), - m_secondItem(nullptr), - m_hovered(false), - m_checked(false), - m_profile(SkeletonProfile::Unknown), - m_deactivated(false), - m_rotated(false) + SkeletonGraphicsEdgeItem() + : m_firstItem(nullptr) + , m_secondItem(nullptr) + , m_hovered(false) + , m_checked(false) + , m_profile(SkeletonProfile::Unknown) + , m_deactivated(false) + , m_rotated(false) { setData(0, "edge"); } @@ -281,17 +277,17 @@ public: { m_rotated = rotated; } - void setEndpoints(SkeletonGraphicsNodeItem *first, SkeletonGraphicsNodeItem *second) + void setEndpoints(SkeletonGraphicsNodeItem* first, SkeletonGraphicsNodeItem* second) { m_firstItem = first; m_secondItem = second; updateAppearance(); } - SkeletonGraphicsNodeItem *firstItem() + SkeletonGraphicsNodeItem* firstItem() { return m_firstItem; } - SkeletonGraphicsNodeItem *secondItem() + SkeletonGraphicsNodeItem* secondItem() { return m_secondItem; } @@ -299,11 +295,11 @@ public: { if (nullptr == m_firstItem || nullptr == m_secondItem) return; - + m_profile = m_firstItem->profile(); - + QLineF line(m_firstItem->origin(), m_secondItem->origin()); - + QPolygonF polygon; float radAngle = line.angle() * M_PI / 180; float dx = 2 * sin(radAngle); @@ -313,12 +309,11 @@ public: //polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2() + offset2 << line.p2() + offset1; polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2(); setPolygon(polygon); - + QColor color = Qt::gray; - + if (!m_deactivated) { - switch (m_firstItem->profile()) - { + switch (m_firstItem->profile()) { case SkeletonProfile::Unknown: break; case SkeletonProfile::Main: @@ -329,7 +324,7 @@ public: break; } } - + QColor penColor = color; penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); QPen pen(penColor); @@ -380,10 +375,11 @@ public: { return m_hovered; } + private: dust3d::Uuid m_uuid; - SkeletonGraphicsNodeItem *m_firstItem; - SkeletonGraphicsNodeItem *m_secondItem; + SkeletonGraphicsNodeItem* m_firstItem; + SkeletonGraphicsNodeItem* m_secondItem; QPolygonF m_selectionPolygon; bool m_hovered; bool m_checked; @@ -392,8 +388,7 @@ private: bool m_rotated; }; -class SkeletonGraphicsWidget : public QGraphicsView -{ +class SkeletonGraphicsWidget : public QGraphicsView { Q_OBJECT public: ~SkeletonGraphicsWidget(); @@ -445,43 +440,45 @@ signals: void shortcutToggleFlatShading(); void shortcutToggleRotation(); void loadedTurnaroundImageChanged(); + public: - SkeletonGraphicsWidget(const SkeletonDocument *document); - std::map> nodeItemMap; - std::map> edgeItemMap; - bool mouseMove(QMouseEvent *event); - bool wheel(QWheelEvent *event); - bool mouseRelease(QMouseEvent *event); - bool mousePress(QMouseEvent *event); - bool mouseDoubleClick(QMouseEvent *event); - bool keyPress(QKeyEvent *event); - bool keyRelease(QKeyEvent *event); - bool checkSkeletonItem(QGraphicsItem *item, bool checked); - dust3d::Uuid querySkeletonItemPartId(QGraphicsItem *item); - static SkeletonProfile readSkeletonItemProfile(QGraphicsItem *item); - void getOtherProfileNodeItems(const std::set &nodeItemSet, - std::set *otherProfileNodeItemSet); - void readMergedSkeletonNodeSetFromRangeSelection(std::set *nodeItemSet); - void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set *nodeIdSet, std::set *edgeIdSet=nullptr); - bool readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem **nodeItem, SkeletonGraphicsEdgeItem **edgeItem); + SkeletonGraphicsWidget(const SkeletonDocument* document); + std::map> nodeItemMap; + std::map> edgeItemMap; + bool mouseMove(QMouseEvent* event); + bool wheel(QWheelEvent* event); + bool mouseRelease(QMouseEvent* event); + bool mousePress(QMouseEvent* event); + bool mouseDoubleClick(QMouseEvent* event); + bool keyPress(QKeyEvent* event); + bool keyRelease(QKeyEvent* event); + bool checkSkeletonItem(QGraphicsItem* item, bool checked); + dust3d::Uuid querySkeletonItemPartId(QGraphicsItem* item); + static SkeletonProfile readSkeletonItemProfile(QGraphicsItem* item); + void getOtherProfileNodeItems(const std::set& nodeItemSet, + std::set* otherProfileNodeItemSet); + void readMergedSkeletonNodeSetFromRangeSelection(std::set* nodeItemSet); + void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set* nodeIdSet, std::set* edgeIdSet = nullptr); + bool readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem** nodeItem, SkeletonGraphicsEdgeItem** edgeItem); bool hasSelection(); bool hasItems(); bool hasMultipleSelection(); bool hasEdgeSelection(); bool hasNodeSelection(); bool hasTwoDisconnectedNodesSelection(); - void setModelWidget(ModelWidget *modelWidget); - bool inputWheelEventFromOtherWidget(QWheelEvent *event); + void setModelWidget(ModelWidget* modelWidget); + bool inputWheelEventFromOtherWidget(QWheelEvent* event); bool rotated(); - const QImage *loadedTurnaroundImage() const; + const QImage* loadedTurnaroundImage() const; + protected: - void mouseMoveEvent(QMouseEvent *event) override; - void wheelEvent(QWheelEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void keyReleaseEvent(QKeyEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; + void keyPressEvent(QKeyEvent* event) override; + void keyReleaseEvent(QKeyEvent* event) override; public slots: void nodeAdded(dust3d::Uuid nodeId); void edgeAdded(dust3d::Uuid edgeId); @@ -495,7 +492,7 @@ public slots: void editModeChanged(); void updateCursor(); void partVisibleStateChanged(dust3d::Uuid partId); - void showContextMenu(const QPoint &pos); + void showContextMenu(const QPoint& pos); void deleteSelected(); void selectAll(); void unselectAll(); @@ -577,8 +574,9 @@ public slots: void shortcutEscape(); private slots: void turnaroundImageReady(); + private: - QPointF mouseEventScenePos(QMouseEvent *event); + QPointF mouseEventScenePos(QMouseEvent* event); QPointF scenePosToUnified(QPointF pos); QPointF scenePosFromUnified(QPointF pos); float sceneRadiusToUnified(float radius); @@ -587,56 +585,57 @@ private: void updateItems(); void checkRangeSelection(); void clearRangeSelection(); - void removeItem(QGraphicsItem *item); - QVector2D centerOfNodeItemSet(const std::set &set); + void removeItem(QGraphicsItem* item); + QVector2D centerOfNodeItemSet(const std::set& set); bool isSingleNodeSelected(); - void addItemToRangeSelection(QGraphicsItem *item); - void removeItemFromRangeSelection(QGraphicsItem *item); + void addItemToRangeSelection(QGraphicsItem* item); + void removeItemFromRangeSelection(QGraphicsItem* item); void hoverPart(dust3d::Uuid partId); void switchProfileOnRangeSelection(); - void setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered); + void setItemHoveredOnAllProfiles(QGraphicsItem* item, bool hovered); void alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter); void alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter); - void rotateItems(const std::set &nodeItems, int degree, QVector2D center); + void rotateItems(const std::set& nodeItems, int degree, QVector2D center); void rotateAllSideProfile(int degree); bool isFloatEqual(float a, float b); + private: - const SkeletonDocument *m_document = nullptr; - QGraphicsPixmapItem *m_backgroundItem = nullptr; + const SkeletonDocument* m_document = nullptr; + QGraphicsPixmapItem* m_backgroundItem = nullptr; bool m_turnaroundChanged = false; - TurnaroundLoader *m_turnaroundLoader = nullptr; + TurnaroundLoader* m_turnaroundLoader = nullptr; bool m_dragStarted = false; bool m_moveStarted = false; - SkeletonGraphicsNodeItem *m_cursorNodeItem = nullptr; - SkeletonGraphicsEdgeItem *m_cursorEdgeItem = nullptr; - SkeletonGraphicsNodeItem *m_addFromNodeItem = nullptr; - SkeletonGraphicsNodeItem *m_hoveredNodeItem = nullptr; - SkeletonGraphicsEdgeItem *m_hoveredEdgeItem = nullptr; + SkeletonGraphicsNodeItem* m_cursorNodeItem = nullptr; + SkeletonGraphicsEdgeItem* m_cursorEdgeItem = nullptr; + SkeletonGraphicsNodeItem* m_addFromNodeItem = nullptr; + SkeletonGraphicsNodeItem* m_hoveredNodeItem = nullptr; + SkeletonGraphicsEdgeItem* m_hoveredEdgeItem = nullptr; float m_lastAddedX = false; float m_lastAddedY = false; float m_lastAddedZ = false; - SkeletonGraphicsSelectionItem *m_selectionItem = nullptr; + SkeletonGraphicsSelectionItem* m_selectionItem = nullptr; bool m_rangeSelectionStarted = false; bool m_mouseEventFromSelf = false; bool m_moveHappened = false; int m_lastRot = 0; - SkeletonGraphicsOriginItem *m_mainOriginItem = nullptr; - SkeletonGraphicsOriginItem *m_sideOriginItem = nullptr; - SkeletonGraphicsOriginItem *m_hoveredOriginItem = nullptr; - SkeletonGraphicsOriginItem *m_checkedOriginItem = nullptr; + SkeletonGraphicsOriginItem* m_mainOriginItem = nullptr; + SkeletonGraphicsOriginItem* m_sideOriginItem = nullptr; + SkeletonGraphicsOriginItem* m_hoveredOriginItem = nullptr; + SkeletonGraphicsOriginItem* m_checkedOriginItem = nullptr; unsigned long long m_ikMoveUpdateVersion = 0; - SkeletonIkMover *m_ikMover = nullptr; - QTimer *m_deferredRemoveTimer = nullptr; + SkeletonIkMover* m_ikMover = nullptr; + QTimer* m_deferredRemoveTimer = nullptr; bool m_eventForwardingToModelWidget = false; - ModelWidget *m_modelWidget = nullptr; + ModelWidget* m_modelWidget = nullptr; bool m_inTempDragMode = false; SkeletonDocumentEditMode m_modeBeforeEnterTempDragMode = SkeletonDocumentEditMode::Select; float m_turnaroundOpacity = 0.25f; bool m_rotated = false; - QImage *m_backgroundImage = nullptr; + QImage* m_backgroundImage = nullptr; QVector3D m_ikMoveTarget; dust3d::Uuid m_ikMoveEndEffectorId; - std::set m_rangeSelectionSet; + std::set m_rangeSelectionSet; QPoint m_lastGlobalPos; QPointF m_lastScenePos; QPointF m_rangeSelectionStartPos; @@ -645,27 +644,28 @@ private: std::set m_deferredRemoveEdgeIds; }; -class SkeletonGraphicsContainerWidget : public QWidget -{ +class SkeletonGraphicsContainerWidget : public QWidget { Q_OBJECT signals: void containerSizeChanged(QSize size); + public: - SkeletonGraphicsContainerWidget() : - m_graphicsWidget(nullptr) + SkeletonGraphicsContainerWidget() + : m_graphicsWidget(nullptr) { } - void resizeEvent(QResizeEvent *event) override + void resizeEvent(QResizeEvent* event) override { if (m_graphicsWidget && m_graphicsWidget->size() != event->size()) emit containerSizeChanged(event->size()); } - void setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget) + void setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget) { m_graphicsWidget = graphicsWidget; } + private: - SkeletonGraphicsWidget *m_graphicsWidget; + SkeletonGraphicsWidget* m_graphicsWidget; }; #endif diff --git a/application/sources/skeleton_ik_mover.cc b/application/sources/skeleton_ik_mover.cc index b64e100d..be7edb99 100644 --- a/application/sources/skeleton_ik_mover.cc +++ b/application/sources/skeleton_ik_mover.cc @@ -1,6 +1,6 @@ -#include #include "skeleton_ik_mover.h" #include "ccd_ik_resolver.h" +#include SkeletonIkMover::SkeletonIkMover() { @@ -10,7 +10,7 @@ SkeletonIkMover::~SkeletonIkMover() { } -void SkeletonIkMover::setTarget(const QVector3D &target) +void SkeletonIkMover::setTarget(const QVector3D& target) { m_target = target; } @@ -33,7 +33,7 @@ void SkeletonIkMover::addNode(dust3d::Uuid id, QVector3D position) m_ikNodes.push_back(ikNode); } -const std::vector &SkeletonIkMover::ikNodes() +const std::vector& SkeletonIkMover::ikNodes() { return m_ikNodes; } @@ -41,7 +41,7 @@ const std::vector &SkeletonIkMover::ikNodes() void SkeletonIkMover::process() { resolve(); - + emit finished(); } diff --git a/application/sources/skeleton_ik_mover.h b/application/sources/skeleton_ik_mover.h index 9d49b11c..aaffcc00 100644 --- a/application/sources/skeleton_ik_mover.h +++ b/application/sources/skeleton_ik_mover.h @@ -2,34 +2,34 @@ #define DUST3D_APPLICATION_SKELETON_IK_MOVER_H_ #include -#include #include #include +#include -struct SkeletonIkNode -{ +struct SkeletonIkNode { dust3d::Uuid id; QVector3D position; QVector3D newPosition; }; -class SkeletonIkMover : public QObject -{ +class SkeletonIkMover : public QObject { Q_OBJECT public: SkeletonIkMover(); ~SkeletonIkMover(); - void setTarget(const QVector3D &target); + void setTarget(const QVector3D& target); void setUpdateVersion(unsigned long long version); unsigned long long getUpdateVersion(); void addNode(dust3d::Uuid id, QVector3D position); - const std::vector &ikNodes(); + const std::vector& ikNodes(); signals: void finished(); public slots: void process(); + private: void resolve(); + private: unsigned long long m_updateVersion = 0; std::vector m_ikNodes; diff --git a/application/sources/spinnable_toolbar_icon.cc b/application/sources/spinnable_toolbar_icon.cc index 0c31358e..dbf535b9 100644 --- a/application/sources/spinnable_toolbar_icon.cc +++ b/application/sources/spinnable_toolbar_icon.cc @@ -1,8 +1,8 @@ #include "spinnable_toolbar_icon.h" #include "theme.h" -SpinnableToolbarIcon::SpinnableToolbarIcon(QWidget *parent) : - QWidget(parent) +SpinnableToolbarIcon::SpinnableToolbarIcon(QWidget* parent) + : QWidget(parent) { setFixedSize(Theme::toolIconSize, Theme::toolIconSize); diff --git a/application/sources/spinnable_toolbar_icon.h b/application/sources/spinnable_toolbar_icon.h index a8f9bc75..3644f65b 100644 --- a/application/sources/spinnable_toolbar_icon.h +++ b/application/sources/spinnable_toolbar_icon.h @@ -1,18 +1,18 @@ #ifndef DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ #define DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ -#include -#include "waitingspinnerwidget.h" #include "toolbar_button.h" +#include "waitingspinnerwidget.h" +#include -class SpinnableToolbarIcon : public QWidget -{ +class SpinnableToolbarIcon : public QWidget { public: - SpinnableToolbarIcon(QWidget *parent=nullptr); - void showSpinner(bool showSpinner=true); + SpinnableToolbarIcon(QWidget* parent = nullptr); + void showSpinner(bool showSpinner = true); bool isSpinning(); + private: - WaitingSpinnerWidget *m_spinner = nullptr; + WaitingSpinnerWidget* m_spinner = nullptr; }; #endif diff --git a/application/sources/texture_generator.cc b/application/sources/texture_generator.cc index 653c87c8..6790fa5f 100644 --- a/application/sources/texture_generator.cc +++ b/application/sources/texture_generator.cc @@ -1,19 +1,19 @@ -#include -#include -#include -#include -#include -#include -#include #include "texture_generator.h" -#include "theme.h" -#include "material.h" #include "debug.h" +#include "material.h" +#include "theme.h" +#include +#include +#include +#include +#include +#include +#include QColor TextureGenerator::m_defaultTextureColor = Qt::transparent; -TextureGenerator::TextureGenerator(const dust3d::Object &object, dust3d::Snapshot *snapshot) : - m_snapshot(snapshot) +TextureGenerator::TextureGenerator(const dust3d::Object& object, dust3d::Snapshot* snapshot) + : m_snapshot(snapshot) { m_object = new dust3d::Object(); *m_object = object; @@ -31,84 +31,84 @@ TextureGenerator::~TextureGenerator() delete m_snapshot; } -QImage *TextureGenerator::takeResultTextureColorImage() +QImage* TextureGenerator::takeResultTextureColorImage() { - QImage *resultTextureColorImage = m_resultTextureColorImage; + QImage* resultTextureColorImage = m_resultTextureColorImage; m_resultTextureColorImage = nullptr; return resultTextureColorImage; } -QImage *TextureGenerator::takeResultTextureNormalImage() +QImage* TextureGenerator::takeResultTextureNormalImage() { - QImage *resultTextureNormalImage = m_resultTextureNormalImage; + QImage* resultTextureNormalImage = m_resultTextureNormalImage; m_resultTextureNormalImage = nullptr; return resultTextureNormalImage; } -QImage *TextureGenerator::takeResultTextureRoughnessImage() +QImage* TextureGenerator::takeResultTextureRoughnessImage() { - QImage *resultTextureRoughnessImage = m_resultTextureRoughnessImage; + QImage* resultTextureRoughnessImage = m_resultTextureRoughnessImage; m_resultTextureRoughnessImage = nullptr; return resultTextureRoughnessImage; } -QImage *TextureGenerator::takeResultTextureMetalnessImage() +QImage* TextureGenerator::takeResultTextureMetalnessImage() { - QImage *resultTextureMetalnessImage = m_resultTextureMetalnessImage; + QImage* resultTextureMetalnessImage = m_resultTextureMetalnessImage; m_resultTextureMetalnessImage = nullptr; return resultTextureMetalnessImage; } -QImage *TextureGenerator::takeResultTextureAmbientOcclusionImage() +QImage* TextureGenerator::takeResultTextureAmbientOcclusionImage() { - QImage *resultTextureAmbientOcclusionImage = m_resultTextureAmbientOcclusionImage; + QImage* resultTextureAmbientOcclusionImage = m_resultTextureAmbientOcclusionImage; m_resultTextureAmbientOcclusionImage = nullptr; return resultTextureAmbientOcclusionImage; } -dust3d::Object *TextureGenerator::takeObject() +dust3d::Object* TextureGenerator::takeObject() { - dust3d::Object *object = m_object; + dust3d::Object* object = m_object; m_object = nullptr; return object; } -ModelMesh *TextureGenerator::takeResultMesh() +ModelMesh* TextureGenerator::takeResultMesh() { - ModelMesh *resultMesh = m_resultMesh; + ModelMesh* resultMesh = m_resultMesh; m_resultMesh = nullptr; return resultMesh; } -void TextureGenerator::addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale) +void TextureGenerator::addPartColorMap(dust3d::Uuid partId, const QImage* image, float tileScale) { if (nullptr == image) return; m_partColorTextureMap[partId] = std::make_pair(*image, tileScale); } -void TextureGenerator::addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale) +void TextureGenerator::addPartNormalMap(dust3d::Uuid partId, const QImage* image, float tileScale) { if (nullptr == image) return; m_partNormalTextureMap[partId] = std::make_pair(*image, tileScale); } -void TextureGenerator::addPartMetalnessMap(dust3d::Uuid partId, const QImage *image, float tileScale) +void TextureGenerator::addPartMetalnessMap(dust3d::Uuid partId, const QImage* image, float tileScale) { if (nullptr == image) return; m_partMetalnessTextureMap[partId] = std::make_pair(*image, tileScale); } -void TextureGenerator::addPartRoughnessMap(dust3d::Uuid partId, const QImage *image, float tileScale) +void TextureGenerator::addPartRoughnessMap(dust3d::Uuid partId, const QImage* image, float tileScale) { if (nullptr == image) return; m_partRoughnessTextureMap[partId] = std::make_pair(*image, tileScale); } -void TextureGenerator::addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage *image, float tileScale) +void TextureGenerator::addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage* image, float tileScale) { if (nullptr == image) return; @@ -119,28 +119,28 @@ void TextureGenerator::prepare() { if (nullptr == m_snapshot) return; - + std::map updatedMaterialIdMap; std::map updatedCountershadedMap; - for (const auto &partIt: m_snapshot->parts) { + for (const auto& partIt : m_snapshot->parts) { dust3d::Uuid materialId; auto materialIdIt = partIt.second.find("materialId"); if (materialIdIt != partIt.second.end()) materialId = dust3d::Uuid(materialIdIt->second); dust3d::Uuid partId = dust3d::Uuid(partIt.first); - updatedMaterialIdMap.insert({partId, materialId}); - updatedCountershadedMap.insert({partId, - dust3d::String::isTrue(dust3d::String::valueOrEmpty(partIt.second, "countershaded"))}); + updatedMaterialIdMap.insert({ partId, materialId }); + updatedCountershadedMap.insert({ partId, + dust3d::String::isTrue(dust3d::String::valueOrEmpty(partIt.second, "countershaded")) }); } - for (const auto &bmeshNode: m_object->nodes) { - + for (const auto& bmeshNode : m_object->nodes) { + bool countershaded = bmeshNode.countershaded; auto findUpdatedCountershadedMap = updatedCountershadedMap.find(bmeshNode.mirrorFromPartId.isNull() ? bmeshNode.partId : bmeshNode.mirrorFromPartId); if (findUpdatedCountershadedMap != updatedCountershadedMap.end()) countershaded = findUpdatedCountershadedMap->second; if (countershaded) m_countershadedPartIds.insert(bmeshNode.partId); - + for (size_t i = 0; i < (int)dust3d::TextureType::Count - 1; ++i) { dust3d::TextureType forWhat = (dust3d::TextureType)(i + 1); MaterialTextures materialTextures; @@ -150,7 +150,7 @@ void TextureGenerator::prepare() materialId = findUpdatedMaterialIdResult->second; float tileScale = 1.0; initializeMaterialTexturesFromSnapshot(*m_snapshot, materialId, materialTextures, tileScale); - const QImage *image = materialTextures.textureImages[i]; + const QImage* image = materialTextures.textureImages[i]; if (nullptr != image) { if (dust3d::TextureType::BaseColor == forWhat) addPartColorMap(bmeshNode.partId, image, tileScale); @@ -175,100 +175,100 @@ bool TextureGenerator::hasTransparencySettings() void TextureGenerator::generate() { m_resultMesh = new ModelMesh(*m_object); - + if (nullptr == m_object->triangleVertexUvs()) return; if (nullptr == m_object->triangleSourceNodes()) return; if (nullptr == m_object->partUvRects()) return; - + QElapsedTimer countTimeConsumed; countTimeConsumed.start(); - + prepare(); - + bool hasNormalMap = false; bool hasMetalnessMap = false; bool hasRoughnessMap = false; bool hasAmbientOcclusionMap = false; - - const auto &triangleVertexUvs = *m_object->triangleVertexUvs(); - const auto &triangleSourceNodes = *m_object->triangleSourceNodes(); - const auto &partUvRects = *m_object->partUvRects(); - const auto &triangleNormals = m_object->triangleNormals; - + + const auto& triangleVertexUvs = *m_object->triangleVertexUvs(); + const auto& triangleSourceNodes = *m_object->triangleSourceNodes(); + const auto& partUvRects = *m_object->partUvRects(); + const auto& triangleNormals = m_object->triangleNormals; + std::map partColorMap; - std::map, const dust3d::ObjectNode *> nodeMap; + std::map, const dust3d::ObjectNode*> nodeMap; std::map partColorSolubilityMap; std::map partMetalnessMap; std::map partRoughnessMap; - for (const auto &item: m_object->nodes) { + for (const auto& item : m_object->nodes) { if (!m_hasTransparencySettings) { if (!qFuzzyCompare(1.0, item.color.alpha())) m_hasTransparencySettings = true; } - nodeMap.insert({{item.partId, item.nodeId}, &item}); - partColorMap.insert({item.partId, QColor(item.color.toString().c_str())}); - partColorSolubilityMap.insert({item.partId, item.colorSolubility}); - partMetalnessMap.insert({item.partId, item.metalness}); - partRoughnessMap.insert({item.partId, item.roughness}); + nodeMap.insert({ { item.partId, item.nodeId }, &item }); + partColorMap.insert({ item.partId, QColor(item.color.toString().c_str()) }); + partColorSolubilityMap.insert({ item.partId, item.colorSolubility }); + partMetalnessMap.insert({ item.partId, item.metalness }); + partRoughnessMap.insert({ item.partId, item.roughness }); } - + m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureColorImage->fill(m_hasTransparencySettings ? m_defaultTextureColor : Qt::white); - + m_resultTextureNormalImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureNormalImage->fill(QColor(128, 128, 255)); - + m_resultTextureMetalnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureMetalnessImage->fill(Qt::black); - + m_resultTextureRoughnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureRoughnessImage->fill(Qt::white); - + m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureAmbientOcclusionImage->fill(Qt::white); QColor borderColor = Qt::darkGray; QPen pen(borderColor); - + QPainter texturePainter; texturePainter.begin(m_resultTextureColorImage); texturePainter.setRenderHint(QPainter::Antialiasing); texturePainter.setRenderHint(QPainter::HighQualityAntialiasing); - + QPainter textureNormalPainter; textureNormalPainter.begin(m_resultTextureNormalImage); textureNormalPainter.setRenderHint(QPainter::Antialiasing); textureNormalPainter.setRenderHint(QPainter::HighQualityAntialiasing); - + QPainter textureMetalnessPainter; textureMetalnessPainter.begin(m_resultTextureMetalnessImage); textureMetalnessPainter.setRenderHint(QPainter::Antialiasing); textureMetalnessPainter.setRenderHint(QPainter::HighQualityAntialiasing); - + QPainter textureRoughnessPainter; textureRoughnessPainter.begin(m_resultTextureRoughnessImage); textureRoughnessPainter.setRenderHint(QPainter::Antialiasing); textureRoughnessPainter.setRenderHint(QPainter::HighQualityAntialiasing); - + QPainter textureAmbientOcclusionPainter; textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage); textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing); textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing); - + texturePainter.setPen(Qt::NoPen); - - for (const auto &it: partUvRects) { - const auto &partId = it.first; - const auto &rects = it.second; + + for (const auto& it : partUvRects) { + const auto& partId = it.first; + const auto& rects = it.second; auto findSourceColorResult = partColorMap.find(partId); if (findSourceColorResult != partColorMap.end()) { - const auto &color = findSourceColorResult->second; + const auto& color = findSourceColorResult->second; QBrush brush(color); float fillExpandSize = 2; - for (const auto &rect: rects) { + for (const auto& rect : rects) { QRectF translatedRect = { rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize, @@ -279,20 +279,20 @@ void TextureGenerator::generate() } } } - - for (const auto &it: partUvRects) { - const auto &partId = it.first; - const auto &rects = it.second; + + for (const auto& it : partUvRects) { + const auto& partId = it.first; + const auto& rects = it.second; auto findMetalnessResult = partMetalnessMap.find(partId); if (findMetalnessResult != partMetalnessMap.end()) { if (qFuzzyCompare(findMetalnessResult->second, (float)0.0)) continue; - const auto &color = QColor(findMetalnessResult->second * 255, + const auto& color = QColor(findMetalnessResult->second * 255, findMetalnessResult->second * 255, findMetalnessResult->second * 255); QBrush brush(color); float fillExpandSize = 2; - for (const auto &rect: rects) { + for (const auto& rect : rects) { QRectF translatedRect = { rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize, @@ -304,20 +304,20 @@ void TextureGenerator::generate() } } } - - for (const auto &it: partUvRects) { - const auto &partId = it.first; - const auto &rects = it.second; + + for (const auto& it : partUvRects) { + const auto& partId = it.first; + const auto& rects = it.second; auto findRoughnessResult = partRoughnessMap.find(partId); if (findRoughnessResult != partRoughnessMap.end()) { if (qFuzzyCompare(findRoughnessResult->second, (float)1.0)) continue; - const auto &color = QColor(findRoughnessResult->second * 255, + const auto& color = QColor(findRoughnessResult->second * 255, findRoughnessResult->second * 255, findRoughnessResult->second * 255); QBrush brush(color); float fillExpandSize = 2; - for (const auto &rect: rects) { + for (const auto& rect : rects) { QRectF translatedRect = { rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize, @@ -329,25 +329,25 @@ void TextureGenerator::generate() } } } - - auto drawTexture = [&](const std::map> &map, QPainter &painter, bool useAlpha) { - for (const auto &it: partUvRects) { - const auto &partId = it.first; - const auto &rects = it.second; + + auto drawTexture = [&](const std::map>& map, QPainter& painter, bool useAlpha) { + for (const auto& it : partUvRects) { + const auto& partId = it.first; + const auto& rects = it.second; float alpha = 1.0; if (useAlpha) { auto findSourceColorResult = partColorMap.find(partId); if (findSourceColorResult != partColorMap.end()) { - const auto &color = findSourceColorResult->second; + const auto& color = findSourceColorResult->second; alpha = color.alphaF(); } } auto findTextureResult = map.find(partId); if (findTextureResult != map.end()) { - const auto &pixmap = findTextureResult->second.first; - const auto &rotatedPixmap = findTextureResult->second.second; + const auto& pixmap = findTextureResult->second.first; + const auto& rotatedPixmap = findTextureResult->second.second; painter.setOpacity(alpha); - for (const auto &rect: rects) { + for (const auto& rect : rects) { QRectF translatedRect = { rect.left() * TextureGenerator::m_textureSize, rect.top() * TextureGenerator::m_textureSize, @@ -364,12 +364,12 @@ void TextureGenerator::generate() } } }; - - auto convertTextureImageToPixmap = [&](const std::map> &sourceMap, - std::map> &targetMap) { - for (const auto &it: sourceMap) { + + auto convertTextureImageToPixmap = [&](const std::map>& sourceMap, + std::map>& targetMap) { + for (const auto& it : sourceMap) { float tileScale = it.second.second; - const auto &image = it.second.first; + const auto& image = it.second.first; auto newSize = image.size() * tileScale; QImage scaledImage = image.scaled(newSize); QPoint center = scaledImage.rect().center(); @@ -381,53 +381,52 @@ void TextureGenerator::generate() QPixmap::fromImage(rotatedImage)); } }; - + std::map> partColorTexturePixmaps; std::map> partNormalTexturePixmaps; std::map> partMetalnessTexturePixmaps; std::map> partRoughnessTexturePixmaps; std::map> partAmbientOcclusionTexturePixmaps; - + convertTextureImageToPixmap(m_partColorTextureMap, partColorTexturePixmaps); convertTextureImageToPixmap(m_partNormalTextureMap, partNormalTexturePixmaps); convertTextureImageToPixmap(m_partMetalnessTextureMap, partMetalnessTexturePixmaps); convertTextureImageToPixmap(m_partRoughnessTextureMap, partRoughnessTexturePixmaps); convertTextureImageToPixmap(m_partAmbientOcclusionTextureMap, partAmbientOcclusionTexturePixmaps); - + drawTexture(partColorTexturePixmaps, texturePainter, true); drawTexture(partNormalTexturePixmaps, textureNormalPainter, false); drawTexture(partMetalnessTexturePixmaps, textureMetalnessPainter, false); drawTexture(partRoughnessTexturePixmaps, textureRoughnessPainter, false); drawTexture(partAmbientOcclusionTexturePixmaps, textureAmbientOcclusionPainter, false); - - auto drawBySolubility = [&](const dust3d::Uuid &partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex, - const dust3d::Uuid &neighborPartId) { - const std::vector &uv = triangleVertexUvs[triangleIndex]; - const auto &allRects = partUvRects.find(partId); + + auto drawBySolubility = [&](const dust3d::Uuid& partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex, + const dust3d::Uuid& neighborPartId) { + const std::vector& uv = triangleVertexUvs[triangleIndex]; + const auto& allRects = partUvRects.find(partId); if (allRects == partUvRects.end()) { qDebug() << "Found part uv rects failed"; return; } - const auto &firstPoint = uv[firstVertexIndex]; - const auto &secondPoint = uv[secondVertexIndex]; + const auto& firstPoint = uv[firstVertexIndex]; + const auto& secondPoint = uv[secondVertexIndex]; auto edgeLength = (firstPoint - secondPoint).length(); auto middlePoint = (firstPoint + secondPoint) / 2.0; float alpha = 1.0; - const auto &findColor = partColorMap.find(partId); + const auto& findColor = partColorMap.find(partId); if (findColor == partColorMap.end()) return; alpha = findColor->second.alphaF(); - const auto &findNeighborColorSolubility = partColorSolubilityMap.find(neighborPartId); + const auto& findNeighborColorSolubility = partColorSolubilityMap.find(neighborPartId); if (findNeighborColorSolubility == partColorSolubilityMap.end()) return; if (qFuzzyIsNull(findNeighborColorSolubility->second)) return; - const auto &findNeighborColor = partColorMap.find(neighborPartId); + const auto& findNeighborColor = partColorMap.find(neighborPartId); if (findNeighborColor == partColorMap.end()) return; - for (const auto &it: allRects->second) { - if (it.contains(firstPoint.x(), firstPoint.y()) || - it.contains(secondPoint.x(), secondPoint.y())) { + for (const auto& it : allRects->second) { + if (it.contains(firstPoint.x(), firstPoint.y()) || it.contains(secondPoint.x(), secondPoint.y())) { float finalRadius = (it.width() + it.height()) * 0.5 * findNeighborColorSolubility->second; if (finalRadius < edgeLength) finalRadius = edgeLength; @@ -445,14 +444,14 @@ void TextureGenerator::generate() texturePainter.setOpacity(alpha); auto findTextureResult = partColorTexturePixmaps.find(neighborPartId); if (findTextureResult != partColorTexturePixmaps.end()) { - const auto &pixmap = findTextureResult->second.first; - const auto &rotatedPixmap = findTextureResult->second.second; - + const auto& pixmap = findTextureResult->second.first; + const auto& rotatedPixmap = findTextureResult->second.second; + QImage tmpImage(translatedRect.width(), translatedRect.height(), QImage::Format_ARGB32); QPixmap tmpPixmap = QPixmap::fromImage(tmpImage); QPainter tmpPainter; QRectF tmpImageFrame = QRectF(0, 0, translatedRect.width(), translatedRect.height()); - + // Fill tiled texture tmpPainter.begin(&tmpPixmap); tmpPainter.setOpacity(alpha); @@ -463,23 +462,23 @@ void TextureGenerator::generate() } tmpPainter.setOpacity(1.0); tmpPainter.end(); - + // Apply gradient QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize - translatedRect.left(), - middlePoint.y() * TextureGenerator::m_textureSize - translatedRect.top()), + middlePoint.y() * TextureGenerator::m_textureSize - translatedRect.top()), finalRadius * TextureGenerator::m_textureSize); gradient.setColorAt(0.0, findNeighborColor->second); gradient.setColorAt(1.0, Qt::transparent); - + tmpPainter.begin(&tmpPixmap); tmpPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); tmpPainter.fillRect(tmpImageFrame, gradient); tmpPainter.end(); - + texturePainter.drawPixmap(translatedRect, tmpPixmap, tmpImageFrame); } else { QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize, - middlePoint.y() * TextureGenerator::m_textureSize), + middlePoint.y() * TextureGenerator::m_textureSize), finalRadius * TextureGenerator::m_textureSize); gradient.setColorAt(0.0, findNeighborColor->second); gradient.setColorAt(1.0, Qt::transparent); @@ -490,10 +489,10 @@ void TextureGenerator::generate() } } }; - + std::map, std::tuple> halfEdgeToTriangleMap; for (size_t i = 0; i < m_object->triangles.size(); ++i) { - const auto &triangleIndices = m_object->triangles[i]; + const auto& triangleIndices = m_object->triangles[i]; if (triangleIndices.size() != 3) { qDebug() << "Found invalid triangle indices"; continue; @@ -504,38 +503,38 @@ void TextureGenerator::generate() std::make_tuple(i, j, k))); } } - for (const auto &it: halfEdgeToTriangleMap) { + for (const auto& it : halfEdgeToTriangleMap) { auto oppositeHalfEdge = std::make_pair(it.first.second, it.first.first); - const auto &opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); + const auto& opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); if (opposite == halfEdgeToTriangleMap.end()) continue; - const std::pair &source = triangleSourceNodes[std::get<0>(it.second)]; - const std::pair &oppositeSource = triangleSourceNodes[std::get<0>(opposite->second)]; + const std::pair& source = triangleSourceNodes[std::get<0>(it.second)]; + const std::pair& oppositeSource = triangleSourceNodes[std::get<0>(opposite->second)]; if (source.first == oppositeSource.first) continue; drawBySolubility(source.first, std::get<0>(it.second), std::get<1>(it.second), std::get<2>(it.second), oppositeSource.first); drawBySolubility(oppositeSource.first, std::get<0>(opposite->second), std::get<1>(opposite->second), std::get<2>(opposite->second), source.first); } - + // Draw belly white texturePainter.setCompositionMode(QPainter::CompositionMode_SoftLight); for (size_t triangleIndex = 0; triangleIndex < m_object->triangles.size(); ++triangleIndex) { - const auto &normal = triangleNormals[triangleIndex]; - const std::pair &source = triangleSourceNodes[triangleIndex]; - const auto &partId = source.first; + const auto& normal = triangleNormals[triangleIndex]; + const std::pair& source = triangleSourceNodes[triangleIndex]; + const auto& partId = source.first; if (m_countershadedPartIds.find(partId) == m_countershadedPartIds.end()) continue; - - const auto &allRects = partUvRects.find(partId); + + const auto& allRects = partUvRects.find(partId); if (allRects == partUvRects.end()) { qDebug() << "Found part uv rects failed"; continue; } - - const auto &findObjectNode = nodeMap.find(source); + + const auto& findObjectNode = nodeMap.find(source); if (findObjectNode == nodeMap.end()) continue; - const dust3d::ObjectNode *objectNode = findObjectNode->second; + const dust3d::ObjectNode* objectNode = findObjectNode->second; if (qAbs(dust3d::Vector3::dotProduct(objectNode->direction, dust3d::Vector3(0, 1, 0))) >= 0.707) { if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, 0, 1)) <= 0.0) continue; @@ -543,24 +542,22 @@ void TextureGenerator::generate() if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, -1, 0)) <= 0.0) continue; } - - const auto &triangleIndices = m_object->triangles[triangleIndex]; + + const auto& triangleIndices = m_object->triangles[triangleIndex]; if (triangleIndices.size() != 3) { qDebug() << "Found invalid triangle indices"; continue; } - - const std::vector &uv = triangleVertexUvs[triangleIndex]; + + const std::vector& uv = triangleVertexUvs[triangleIndex]; dust3d::Vector2 middlePoint = (uv[0] + uv[1] + uv[2]) / 3.0; - float finalRadius = ((uv[0] - uv[1]).length() + - (uv[1] - uv[2]).length() + - (uv[2] - uv[0]).length()) / 3.0; + float finalRadius = ((uv[0] - uv[1]).length() + (uv[1] - uv[2]).length() + (uv[2] - uv[0]).length()) / 3.0; QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize, - middlePoint.y() * TextureGenerator::m_textureSize), + middlePoint.y() * TextureGenerator::m_textureSize), finalRadius * TextureGenerator::m_textureSize); gradient.setColorAt(0.0, Qt::white); gradient.setColorAt(1.0, Qt::transparent); - for (const auto &it: allRects->second) { + for (const auto& it : allRects->second) { if (it.contains(middlePoint.x(), middlePoint.y())) { dust3d::Rectangle fillTarget((middlePoint.x() - finalRadius), (middlePoint.y() - finalRadius), @@ -576,31 +573,31 @@ void TextureGenerator::generate() texturePainter.fillRect(translatedRect, gradient); } } - + // Fill the neighbor halfedges for (int i = 0; i < 3; ++i) { int j = (i + 1) % 3; auto oppositeHalfEdge = std::make_pair(triangleIndices[j], triangleIndices[i]); - const auto &opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); + const auto& opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); if (opposite == halfEdgeToTriangleMap.end()) continue; auto oppositeTriangleIndex = std::get<0>(opposite->second); - const std::pair &oppositeSource = triangleSourceNodes[oppositeTriangleIndex]; + const std::pair& oppositeSource = triangleSourceNodes[oppositeTriangleIndex]; if (partId == oppositeSource.first) continue; - const auto &oppositeAllRects = partUvRects.find(oppositeSource.first); + const auto& oppositeAllRects = partUvRects.find(oppositeSource.first); if (oppositeAllRects == partUvRects.end()) { qDebug() << "Found part uv rects failed"; continue; } - const std::vector &oppositeUv = triangleVertexUvs[oppositeTriangleIndex]; + const std::vector& oppositeUv = triangleVertexUvs[oppositeTriangleIndex]; dust3d::Vector2 oppositeMiddlePoint = (oppositeUv[std::get<1>(opposite->second)] + oppositeUv[std::get<2>(opposite->second)]) * 0.5; QRadialGradient oppositeGradient(QPointF(oppositeMiddlePoint.x() * TextureGenerator::m_textureSize, - oppositeMiddlePoint.y() * TextureGenerator::m_textureSize), + oppositeMiddlePoint.y() * TextureGenerator::m_textureSize), finalRadius * TextureGenerator::m_textureSize); oppositeGradient.setColorAt(0.0, Qt::white); oppositeGradient.setColorAt(1.0, Qt::transparent); - for (const auto &it: oppositeAllRects->second) { + for (const auto& it : oppositeAllRects->second) { if (it.contains(oppositeMiddlePoint.x(), oppositeMiddlePoint.y())) { dust3d::Rectangle fillTarget((oppositeMiddlePoint.x() - finalRadius), (oppositeMiddlePoint.y() - finalRadius), @@ -618,7 +615,7 @@ void TextureGenerator::generate() } } } - + hasNormalMap = !m_partNormalTextureMap.empty(); if (!m_partMetalnessTextureMap.empty()) hasMetalnessMap = true; @@ -631,12 +628,12 @@ void TextureGenerator::generate() textureMetalnessPainter.end(); textureRoughnessPainter.end(); textureAmbientOcclusionPainter.end(); - + if (!hasNormalMap) { delete m_resultTextureNormalImage; m_resultTextureNormalImage = nullptr; } - + if (!hasMetalnessMap && !hasRoughnessMap && !hasAmbientOcclusionMap) { delete m_resultTextureMetalnessImage; m_resultTextureMetalnessImage = nullptr; @@ -647,7 +644,7 @@ void TextureGenerator::generate() delete m_resultTextureAmbientOcclusionImage; m_resultTextureAmbientOcclusionImage = nullptr; } - + m_resultMesh->setTextureImage(new QImage(*m_resultTextureColorImage)); if (nullptr != m_resultTextureNormalImage) m_resultMesh->setNormalMapImage(new QImage(*m_resultTextureNormalImage)); @@ -660,18 +657,16 @@ void TextureGenerator::generate() m_resultMesh->setHasRoughnessInImage(hasRoughnessMap); m_resultMesh->setHasAmbientOcclusionInImage(hasAmbientOcclusionMap); } - + qDebug() << "The texture[" << TextureGenerator::m_textureSize << "x" << TextureGenerator::m_textureSize << "] generation took" << countTimeConsumed.elapsed() << "milliseconds"; } -QImage *TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(QImage *metalnessImage, - QImage *roughnessImage, - QImage *ambientOcclusionImage) +QImage* TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(QImage* metalnessImage, + QImage* roughnessImage, + QImage* ambientOcclusionImage) { - QImage *textureMetalnessRoughnessAmbientOcclusionImage = nullptr; - if (nullptr != metalnessImage || - nullptr != roughnessImage || - nullptr != ambientOcclusionImage) { + QImage* textureMetalnessRoughnessAmbientOcclusionImage = nullptr; + if (nullptr != metalnessImage || nullptr != roughnessImage || nullptr != ambientOcclusionImage) { int textureSize = 0; if (nullptr != metalnessImage) textureSize = metalnessImage->height(); diff --git a/application/sources/texture_generator.h b/application/sources/texture_generator.h index 1c6b1145..30984ad1 100644 --- a/application/sources/texture_generator.h +++ b/application/sources/texture_generator.h @@ -1,61 +1,63 @@ #ifndef DUST3D_APPLICATION_TEXTURE_GENERATOR_H_ #define DUST3D_APPLICATION_TEXTURE_GENERATOR_H_ -#include -#include -#include +#include "model_mesh.h" #include +#include +#include #include #include #include -#include "model_mesh.h" +#include -class TextureGenerator : public QObject -{ +class TextureGenerator : public QObject { Q_OBJECT public: - TextureGenerator(const dust3d::Object &object, dust3d::Snapshot *snapshot=nullptr); + TextureGenerator(const dust3d::Object& object, dust3d::Snapshot* snapshot = nullptr); ~TextureGenerator(); - QImage *takeResultTextureColorImage(); - QImage *takeResultTextureNormalImage(); - QImage *takeResultTextureRoughnessImage(); - QImage *takeResultTextureMetalnessImage(); - QImage *takeResultTextureAmbientOcclusionImage(); - dust3d::Object *takeObject(); - ModelMesh *takeResultMesh(); + QImage* takeResultTextureColorImage(); + QImage* takeResultTextureNormalImage(); + QImage* takeResultTextureRoughnessImage(); + QImage* takeResultTextureMetalnessImage(); + QImage* takeResultTextureAmbientOcclusionImage(); + dust3d::Object* takeObject(); + ModelMesh* takeResultMesh(); bool hasTransparencySettings(); - void addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale); - void addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale); - void addPartMetalnessMap(dust3d::Uuid partId, const QImage *image, float tileScale); - void addPartRoughnessMap(dust3d::Uuid partId, const QImage *image, float tileScale); - void addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage *image, float tileScale); + void addPartColorMap(dust3d::Uuid partId, const QImage* image, float tileScale); + void addPartNormalMap(dust3d::Uuid partId, const QImage* image, float tileScale); + void addPartMetalnessMap(dust3d::Uuid partId, const QImage* image, float tileScale); + void addPartRoughnessMap(dust3d::Uuid partId, const QImage* image, float tileScale); + void addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage* image, float tileScale); void generate(); - static QImage *combineMetalnessRoughnessAmbientOcclusionImages(QImage *metalnessImage, - QImage *roughnessImage, - QImage *ambientOcclusionImage); + static QImage* combineMetalnessRoughnessAmbientOcclusionImages(QImage* metalnessImage, + QImage* roughnessImage, + QImage* ambientOcclusionImage); signals: void finished(); public slots: void process(); + public: static QColor m_defaultTextureColor; + private: void prepare(); + private: - dust3d::Object *m_object = nullptr; - QImage *m_resultTextureColorImage = nullptr; - QImage *m_resultTextureNormalImage = nullptr; - QImage *m_resultTextureRoughnessImage = nullptr; - QImage *m_resultTextureMetalnessImage = nullptr; - QImage *m_resultTextureAmbientOcclusionImage = nullptr; - ModelMesh *m_resultMesh = nullptr; + dust3d::Object* m_object = nullptr; + QImage* m_resultTextureColorImage = nullptr; + QImage* m_resultTextureNormalImage = nullptr; + QImage* m_resultTextureRoughnessImage = nullptr; + QImage* m_resultTextureMetalnessImage = nullptr; + QImage* m_resultTextureAmbientOcclusionImage = nullptr; + ModelMesh* m_resultMesh = nullptr; std::map> m_partColorTextureMap; std::map> m_partNormalTextureMap; std::map> m_partMetalnessTextureMap; std::map> m_partRoughnessTextureMap; std::map> m_partAmbientOcclusionTextureMap; std::set m_countershadedPartIds; - dust3d::Snapshot *m_snapshot = nullptr; + dust3d::Snapshot* m_snapshot = nullptr; bool m_hasTransparencySettings = false; int m_textureSize = 1024; }; diff --git a/application/sources/theme.cc b/application/sources/theme.cc index afb0c677..22304c1f 100644 --- a/application/sources/theme.cc +++ b/application/sources/theme.cc @@ -1,9 +1,9 @@ +#include "theme.h" #include -#include -#include #include #include -#include "theme.h" +#include +#include QColor Theme::white = QColor(0xf7, 0xd9, 0xc8); QColor Theme::red = QColor(0xfc, 0x66, 0x21); @@ -42,14 +42,14 @@ void Theme::initialize() darkPalette.setColor(QPalette::BrightText, QColor(0xfc, 0x66, 0x21)); darkPalette.setColor(QPalette::Link, QColor(42, 130, 218)); darkPalette.setColor(QPalette::Highlight, QColor(0xfc, 0x66, 0x21)); - darkPalette.setColor(QPalette::HighlightedText, QColor(0x25, 0x25, 0x25)); + darkPalette.setColor(QPalette::HighlightedText, QColor(0x25, 0x25, 0x25)); QApplication::setPalette(darkPalette); - + QFont font; font.setWeight(QFont::Light); font.setBold(false); QApplication::setFont(font); - + QFontMetrics fontMetrics(QApplication::font()); Theme::toolIconFontSize = fontMetrics.height(); Theme::toolIconSize = (int)(Theme::toolIconFontSize * 1.5); @@ -63,9 +63,9 @@ void Theme::initialize() Theme::previewIconBorderRadius = std::max(3, Theme::partPreviewImageSize / 10); } -QtAwesome *Theme::awesome() +QtAwesome* Theme::awesome() { - static QtAwesome *s_awesome = nullptr; + static QtAwesome* s_awesome = nullptr; if (nullptr == s_awesome) { s_awesome = new QtAwesome(); s_awesome->initFontAwesome(); @@ -77,7 +77,7 @@ QtAwesome *Theme::awesome() return s_awesome; } -void Theme::initAwesomeButton(QPushButton *button) +void Theme::initAwesomeButton(QPushButton* button) { button->setFont(Theme::awesome()->font(Theme::toolIconFontSize)); button->setFixedSize(Theme::toolIconSize, Theme::toolIconSize); @@ -85,25 +85,25 @@ void Theme::initAwesomeButton(QPushButton *button) button->setFocusPolicy(Qt::NoFocus); } -void Theme::initAwesomeLabel(QLabel *label) +void Theme::initAwesomeLabel(QLabel* label) { label->setFont(Theme::awesome()->font(Theme::toolIconFontSize)); label->setStyleSheet("QLabel {color: " + Theme::white.name() + "}"); } -void Theme::initAwesomeMiniButton(QPushButton *button) +void Theme::initAwesomeMiniButton(QPushButton* button) { button->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); button->setFixedSize(Theme::miniIconSize, Theme::miniIconSize); button->setFocusPolicy(Qt::NoFocus); } -void Theme::updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool enabled, bool unnormal) +void Theme::updateAwesomeMiniButton(QPushButton* button, QChar icon, bool highlighted, bool enabled, bool unnormal) { button->setText(icon); QColor color; bool needDesaturation = true; - + if (highlighted) { if (unnormal) { color = Theme::blue; @@ -114,13 +114,13 @@ void Theme::updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highli } else { color = QColor("#525252"); } - + if (needDesaturation) { color = color.toHsv(); color.setHsv(color.hue(), color.saturation() / 5, color.value() * 2 / 3); color = color.toRgb(); } - + if (!enabled) { color = QColor(42, 42, 42); } @@ -128,20 +128,20 @@ void Theme::updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highli button->setStyleSheet("QPushButton {border: none; background: none; color: " + color.name() + ";}"); } -void Theme::initAwesomeToolButtonWithoutFont(QPushButton *button) +void Theme::initAwesomeToolButtonWithoutFont(QPushButton* button) { button->setFixedSize(Theme::toolIconSize * 0.75, Theme::toolIconSize * 0.75); button->setStyleSheet("QPushButton {color: " + Theme::white.name() + "}"); button->setFocusPolicy(Qt::NoFocus); } -void Theme::initAwesomeToolButton(QPushButton *button) +void Theme::initAwesomeToolButton(QPushButton* button) { button->setFont(Theme::awesome()->font(Theme::toolIconFontSize * 0.75)); Theme::initAwesomeToolButtonWithoutFont(button); } -void Theme::initToolButton(QPushButton *button) +void Theme::initToolButton(QPushButton* button) { QFont font = button->font(); font.setWeight(QFont::Light); @@ -152,14 +152,14 @@ void Theme::initToolButton(QPushButton *button) button->setFocusPolicy(Qt::NoFocus); } -void Theme::initCheckbox(QCheckBox *checkbox) +void Theme::initCheckbox(QCheckBox* checkbox) { QPalette palette = checkbox->palette(); palette.setColor(QPalette::Background, Theme::white); checkbox->setPalette(palette); } -void Theme::initIconButton(QPushButton *button) +void Theme::initIconButton(QPushButton* button) { button->setFixedSize(Theme::toolIconSize, Theme::toolIconSize); } diff --git a/application/sources/theme.h b/application/sources/theme.h index 2964d15d..ca21d8c0 100644 --- a/application/sources/theme.h +++ b/application/sources/theme.h @@ -1,15 +1,14 @@ #ifndef DUST3D_APPLICATION_THEME_H_ #define DUST3D_APPLICATION_THEME_H_ -#include -#include -#include -#include -#include #include "QtAwesome.h" +#include +#include +#include +#include +#include -class Theme -{ +class Theme { public: static QColor white; static QColor red; @@ -31,19 +30,19 @@ public: static int previewIconBorderSize; static int previewIconMargin; static int previewIconBorderRadius; - + static void initialize(); - static QtAwesome *awesome(); - static void initAwesomeButton(QPushButton *button); - static void initAwesomeLabel(QLabel *label); - static void initAwesomeMiniButton(QPushButton *button); - static void updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool enabled, bool unnormal=false); - static void initAwesomeToolButton(QPushButton *button); - static void initAwesomeToolButtonWithoutFont(QPushButton *button); + static QtAwesome* awesome(); + static void initAwesomeButton(QPushButton* button); + static void initAwesomeLabel(QLabel* label); + static void initAwesomeMiniButton(QPushButton* button); + static void updateAwesomeMiniButton(QPushButton* button, QChar icon, bool highlighted, bool enabled, bool unnormal = false); + static void initAwesomeToolButton(QPushButton* button); + static void initAwesomeToolButtonWithoutFont(QPushButton* button); static void initAwsome(); - static void initToolButton(QPushButton *button); - static void initCheckbox(QCheckBox *checkbox); - static void initIconButton(QPushButton *button); + static void initToolButton(QPushButton* button); + static void initCheckbox(QCheckBox* checkbox); + static void initIconButton(QPushButton* button); }; #endif diff --git a/application/sources/toolbar_button.cc b/application/sources/toolbar_button.cc index dfb438cc..541151c6 100644 --- a/application/sources/toolbar_button.cc +++ b/application/sources/toolbar_button.cc @@ -1,28 +1,28 @@ -#include -#include #include "toolbar_button.h" #include "theme.h" +#include +#include -ToolbarButton::ToolbarButton(const QString &filename, QWidget *parent) : - QPushButton(parent) +ToolbarButton::ToolbarButton(const QString& filename, QWidget* parent) + : QPushButton(parent) { auto margin = Theme::toolIconSize / 5; - + setFixedSize(Theme::toolIconSize, Theme::toolIconSize); setFocusPolicy(Qt::NoFocus); - - QSvgWidget *svgWidget = new QSvgWidget(filename); + + QSvgWidget* svgWidget = new QSvgWidget(filename); m_iconWidget = svgWidget; - - QGridLayout *containerLayout = new QGridLayout; + + QGridLayout* containerLayout = new QGridLayout; containerLayout->setSpacing(0); containerLayout->setContentsMargins(margin, margin, margin, margin); containerLayout->addWidget(svgWidget); - + setLayout(containerLayout); } -void ToolbarButton::setIcon(const QString &filename) +void ToolbarButton::setIcon(const QString& filename) { m_iconWidget->load(filename); } diff --git a/application/sources/toolbar_button.h b/application/sources/toolbar_button.h index 8eccd52b..5399c07c 100644 --- a/application/sources/toolbar_button.h +++ b/application/sources/toolbar_button.h @@ -6,14 +6,14 @@ class QSvgWidget; -class ToolbarButton : public QPushButton -{ +class ToolbarButton : public QPushButton { Q_OBJECT public: - ToolbarButton(const QString &filename=QString(), QWidget *parent=nullptr); - void setIcon(const QString &filename); + ToolbarButton(const QString& filename = QString(), QWidget* parent = nullptr); + void setIcon(const QString& filename); + private: - QSvgWidget *m_iconWidget = nullptr; + QSvgWidget* m_iconWidget = nullptr; }; #endif diff --git a/application/sources/turnaround_loader.cc b/application/sources/turnaround_loader.cc index 7761712d..f11c74eb 100644 --- a/application/sources/turnaround_loader.cc +++ b/application/sources/turnaround_loader.cc @@ -1,13 +1,13 @@ -#include #include "turnaround_loader.h" +#include -TurnaroundLoader::TurnaroundLoader(const QString &filename, QSize viewSize) +TurnaroundLoader::TurnaroundLoader(const QString& filename, QSize viewSize) { m_filename = filename; m_viewSize = viewSize; } -TurnaroundLoader::TurnaroundLoader(const QImage &image, QSize viewSize) +TurnaroundLoader::TurnaroundLoader(const QImage& image, QSize viewSize) { m_inputImage = image; m_viewSize = viewSize; @@ -18,9 +18,9 @@ TurnaroundLoader::~TurnaroundLoader() delete m_resultImage; } -QImage *TurnaroundLoader::takeResultImage() +QImage* TurnaroundLoader::takeResultImage() { - QImage *returnImage = m_resultImage; + QImage* returnImage = m_resultImage; m_resultImage = nullptr; return returnImage; } diff --git a/application/sources/turnaround_loader.h b/application/sources/turnaround_loader.h index ad450caf..2d741c64 100644 --- a/application/sources/turnaround_loader.h +++ b/application/sources/turnaround_loader.h @@ -1,25 +1,25 @@ #ifndef DUST3D_APPLICATION_TURNAROUND_LOADER_H_ #define DUST3D_APPLICATION_TURNAROUND_LOADER_H_ -#include -#include -#include #include +#include +#include +#include -class TurnaroundLoader : public QObject -{ +class TurnaroundLoader : public QObject { Q_OBJECT public: - TurnaroundLoader(const QString &filename, QSize viewSize); - TurnaroundLoader(const QImage &image, QSize viewSize); + TurnaroundLoader(const QString& filename, QSize viewSize); + TurnaroundLoader(const QImage& image, QSize viewSize); ~TurnaroundLoader(); - QImage *takeResultImage(); + QImage* takeResultImage(); signals: void finished(); public slots: void process(); + private: - QImage *m_resultImage = nullptr; + QImage* m_resultImage = nullptr; QImage m_inputImage; QString m_filename; QSize m_viewSize; diff --git a/application/sources/updates_check_widget.cc b/application/sources/updates_check_widget.cc index 88a0e536..d3237e9f 100644 --- a/application/sources/updates_check_widget.cc +++ b/application/sources/updates_check_widget.cc @@ -1,62 +1,62 @@ -#include -#include -#include #include "updates_check_widget.h" #include "updates_checker.h" #include "version.h" +#include +#include +#include -#define CHECKING_WIDGET_INDEX 0 -#define SHOWING_RESULT_WIDGET_INDEX 1 +#define CHECKING_WIDGET_INDEX 0 +#define SHOWING_RESULT_WIDGET_INDEX 1 UpdatesCheckWidget::UpdatesCheckWidget() { setWindowTitle(applicationTitle(tr("Check for Updates"))); - + m_stackedWidget = new QStackedWidget; - - QVBoxLayout *mainLayout = new QVBoxLayout; + + QVBoxLayout* mainLayout = new QVBoxLayout; mainLayout->addWidget(m_stackedWidget); - - QWidget *checkingWidget = new QWidget; - QWidget *showingResultWidget = new QWidget; - + + QWidget* checkingWidget = new QWidget; + QWidget* showingResultWidget = new QWidget; + ////////// checking /////////////////// - - QLabel *busyLabel = new QLabel; + + QLabel* busyLabel = new QLabel; busyLabel->setText(tr("Checking for updates...")); - - QProgressBar *busyBar = new QProgressBar; + + QProgressBar* busyBar = new QProgressBar; busyBar->setMaximum(0); busyBar->setMinimum(0); busyBar->setValue(0); - - QVBoxLayout *checkingLayout = new QVBoxLayout; + + QVBoxLayout* checkingLayout = new QVBoxLayout; checkingLayout->addWidget(busyLabel); checkingLayout->addWidget(busyBar); - + checkingWidget->setLayout(checkingLayout); - + ////////// showing result ///////////// - + m_infoLabel = new QLabel; - + m_viewButton = new QPushButton(tr("View")); m_viewButton->hide(); - + connect(m_viewButton, &QPushButton::clicked, this, &UpdatesCheckWidget::viewUpdates); - - QVBoxLayout *showingResultLayout = new QVBoxLayout; + + QVBoxLayout* showingResultLayout = new QVBoxLayout; showingResultLayout->addWidget(m_infoLabel); showingResultLayout->addStretch(); showingResultLayout->addWidget(m_viewButton); - + showingResultWidget->setLayout(showingResultLayout); - + m_stackedWidget->addWidget(checkingWidget); m_stackedWidget->addWidget(showingResultWidget); - + m_stackedWidget->setCurrentIndex(CHECKING_WIDGET_INDEX); - + setLayout(mainLayout); } @@ -69,7 +69,7 @@ void UpdatesCheckWidget::viewUpdates() { if (m_viewUrl.isEmpty()) return; - + QDesktopServices::openUrl(QUrl(m_viewUrl)); } @@ -77,11 +77,11 @@ void UpdatesCheckWidget::check() { if (nullptr != m_updatesChecker) return; - + m_stackedWidget->setCurrentIndex(CHECKING_WIDGET_INDEX); - + m_viewUrl.clear(); - + m_updatesChecker = new UpdatesChecker; connect(m_updatesChecker, &UpdatesChecker::finished, this, &UpdatesCheckWidget::checkFinished); m_updatesChecker->start(); @@ -101,7 +101,7 @@ void UpdatesCheckWidget::checkFinished() } } m_stackedWidget->setCurrentIndex(SHOWING_RESULT_WIDGET_INDEX); - + m_updatesChecker->deleteLater(); m_updatesChecker = nullptr; } diff --git a/application/sources/updates_check_widget.h b/application/sources/updates_check_widget.h index 718c50ec..c511c012 100644 --- a/application/sources/updates_check_widget.h +++ b/application/sources/updates_check_widget.h @@ -2,14 +2,13 @@ #define DUST3D_APPLICATION_UPDATES_CHECK_WIDGET_H_ #include -#include #include #include +#include class UpdatesChecker; -class UpdatesCheckWidget : public QDialog -{ +class UpdatesCheckWidget : public QDialog { Q_OBJECT public: UpdatesCheckWidget(); @@ -18,11 +17,12 @@ public slots: void check(); void checkFinished(); void viewUpdates(); + private: - UpdatesChecker *m_updatesChecker = nullptr; - QStackedWidget *m_stackedWidget = nullptr; - QLabel *m_infoLabel = nullptr; - QPushButton *m_viewButton = nullptr; + UpdatesChecker* m_updatesChecker = nullptr; + QStackedWidget* m_stackedWidget = nullptr; + QLabel* m_infoLabel = nullptr; + QPushButton* m_viewButton = nullptr; QString m_viewUrl; }; diff --git a/application/sources/updates_checker.cc b/application/sources/updates_checker.cc index c2564af4..5195f5cc 100644 --- a/application/sources/updates_checker.cc +++ b/application/sources/updates_checker.cc @@ -1,7 +1,7 @@ -#include -#include #include "updates_checker.h" #include "version.h" +#include +#include UpdatesChecker::UpdatesChecker() { @@ -15,7 +15,7 @@ void UpdatesChecker::start() m_networkAccessManager.get(request); } -const QString &UpdatesChecker::message() const +const QString& UpdatesChecker::message() const { return m_message; } @@ -30,7 +30,7 @@ bool UpdatesChecker::hasError() const return m_hasError; } -bool UpdatesChecker::parseUpdateInfoXml(const QByteArray &updateInfoXml, std::vector *updateItems) +bool UpdatesChecker::parseUpdateInfoXml(const QByteArray& updateInfoXml, std::vector* updateItems) { std::vector elementNameStack; QXmlStreamReader reader(updateInfoXml); @@ -50,7 +50,7 @@ bool UpdatesChecker::parseUpdateInfoXml(const QByteArray &updateInfoXml, std::ve } } QStringList nameItems; - for (const auto &nameItem: elementNameStack) { + for (const auto& nameItem : elementNameStack) { nameItems.append(nameItem); } QString fullName = nameItems.join("."); @@ -63,10 +63,7 @@ bool UpdatesChecker::parseUpdateInfoXml(const QByteArray &updateInfoXml, std::ve updateItem.version = reader.attributes().value("version").toString(); updateItem.humanVersion = reader.attributes().value("humanVersion").toString(); updateItem.descriptionUrl = reader.attributes().value("descriptionUrl").toString(); - if (!updateItem.forTags.isEmpty() && - !updateItem.version.isEmpty() && - !updateItem.humanVersion.isEmpty() && - !updateItem.descriptionUrl.isEmpty()) { + if (!updateItem.forTags.isEmpty() && !updateItem.version.isEmpty() && !updateItem.humanVersion.isEmpty() && !updateItem.descriptionUrl.isEmpty()) { if (updateItems->size() >= 100) return false; updateItem.forTags = "," + updateItem.forTags + ","; @@ -78,7 +75,7 @@ bool UpdatesChecker::parseUpdateInfoXml(const QByteArray &updateInfoXml, std::ve return true; } -bool UpdatesChecker::isVersionLessThan(const QString &version, const QString &compareWith) +bool UpdatesChecker::isVersionLessThan(const QString& version, const QString& compareWith) { auto versionTokens = version.split("."); auto compareWithTokens = compareWith.split("."); @@ -103,12 +100,12 @@ bool UpdatesChecker::isVersionLessThan(const QString &version, const QString &co return false; } -const UpdatesChecker::UpdateItem &UpdatesChecker::matchedUpdateItem() const +const UpdatesChecker::UpdateItem& UpdatesChecker::matchedUpdateItem() const { return m_matchedUpdateItem; } -void UpdatesChecker::downloadFinished(QNetworkReply *reply) +void UpdatesChecker::downloadFinished(QNetworkReply* reply) { if (reply->error()) { qDebug() << "Download update info failed:" << qPrintable(reply->errorString()); @@ -129,7 +126,7 @@ void UpdatesChecker::downloadFinished(QNetworkReply *reply) QString platform = QString(APP_PLATFORM).toLower(); if (!platform.isEmpty()) { platform = "," + platform + ","; - for (const auto &it: updateItems) { + for (const auto& it : updateItems) { if (-1 == it.forTags.indexOf(platform)) continue; if (isVersionLessThan(APP_VER, it.version)) { diff --git a/application/sources/updates_checker.h b/application/sources/updates_checker.h index 32f61139..da669797 100644 --- a/application/sources/updates_checker.h +++ b/application/sources/updates_checker.h @@ -4,28 +4,28 @@ #include #include -class UpdatesChecker : public QObject -{ +class UpdatesChecker : public QObject { Q_OBJECT signals: void finished(); + public: - struct UpdateItem - { + struct UpdateItem { QString forTags; QString version; QString humanVersion; QString descriptionUrl; }; - + UpdatesChecker(); void start(); bool isLatest() const; bool hasError() const; - const QString &message() const; - const UpdateItem &matchedUpdateItem() const; + const QString& message() const; + const UpdateItem& matchedUpdateItem() const; private slots: - void downloadFinished(QNetworkReply *reply); + void downloadFinished(QNetworkReply* reply); + private: QNetworkAccessManager m_networkAccessManager; bool m_isLatest = false; @@ -33,9 +33,9 @@ private: QString m_latestUrl; bool m_hasError = true; UpdateItem m_matchedUpdateItem; - - bool parseUpdateInfoXml(const QByteArray &updateInfoXml, std::vector *updateItems); - static bool isVersionLessThan(const QString &version, const QString &compareWith); + + bool parseUpdateInfoXml(const QByteArray& updateInfoXml, std::vector* updateItems); + static bool isVersionLessThan(const QString& version, const QString& compareWith); }; #endif diff --git a/application/sources/version.h b/application/sources/version.h index bbcaad9c..481877aa 100644 --- a/application/sources/version.h +++ b/application/sources/version.h @@ -3,18 +3,18 @@ #include -#define APP_COMPANY PROJECT_DEFINED_APP_COMPANY -#define APP_NAME PROJECT_DEFINED_APP_NAME -#define APP_VER PROJECT_DEFINED_APP_VER -#define APP_HUMAN_VER PROJECT_DEFINED_APP_HUMAN_VER -#define APP_HOMEPAGE_URL PROJECT_DEFINED_APP_HOMEPAGE_URL -#define APP_REPOSITORY_URL PROJECT_DEFINED_APP_REPOSITORY_URL -#define APP_ISSUES_URL PROJECT_DEFINED_APP_ISSUES_URL -#define APP_REFERENCE_GUIDE_URL PROJECT_DEFINED_APP_REFERENCE_GUIDE_URL -#define APP_UPDATES_CHECKER_URL PROJECT_DEFINED_APP_UPDATES_CHECKER_URL -#define APP_PLATFORM PROJECT_DEFINED_APP_PLATFORM +#define APP_COMPANY PROJECT_DEFINED_APP_COMPANY +#define APP_NAME PROJECT_DEFINED_APP_NAME +#define APP_VER PROJECT_DEFINED_APP_VER +#define APP_HUMAN_VER PROJECT_DEFINED_APP_HUMAN_VER +#define APP_HOMEPAGE_URL PROJECT_DEFINED_APP_HOMEPAGE_URL +#define APP_REPOSITORY_URL PROJECT_DEFINED_APP_REPOSITORY_URL +#define APP_ISSUES_URL PROJECT_DEFINED_APP_ISSUES_URL +#define APP_REFERENCE_GUIDE_URL PROJECT_DEFINED_APP_REFERENCE_GUIDE_URL +#define APP_UPDATES_CHECKER_URL PROJECT_DEFINED_APP_UPDATES_CHECKER_URL +#define APP_PLATFORM PROJECT_DEFINED_APP_PLATFORM -inline QString applicationTitle(const QString &text) +inline QString applicationTitle(const QString& text) { return text + QObject::tr(" - ") + APP_NAME; } diff --git a/ci/lint.sh b/ci/lint.sh new file mode 100644 index 00000000..7831b0df --- /dev/null +++ b/ci/lint.sh @@ -0,0 +1,2 @@ +# sudo apt install clang-format +find ../application/sources/ ../dust3d/ -iname *.h -o -iname *.cc | xargs clang-format -style=webkit -i \ No newline at end of file diff --git a/dust3d/base/axis_aligned_bounding_box.h b/dust3d/base/axis_aligned_bounding_box.h index cec02c85..e00f2c93 100644 --- a/dust3d/base/axis_aligned_bounding_box.h +++ b/dust3d/base/axis_aligned_bounding_box.h @@ -19,21 +19,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_AXIS_ALIGNED_BOUNDING_BOX_H_ #define DUST3D_BASE_AXIS_ALIGNED_BOUNDING_BOX_H_ -#include #include +#include #include -namespace dust3d -{ +namespace dust3d { -class AxisAlignedBoudingBox -{ +class AxisAlignedBoudingBox { public: - void update(const Vector3 &vertex) + void update(const Vector3& vertex) { for (size_t i = 0; i < 3; ++i) { if (vertex[i] > m_max[i]) @@ -45,7 +43,7 @@ public: ++m_num; } - const Vector3 ¢er() const + const Vector3& center() const { return m_center; } @@ -57,30 +55,30 @@ public: m_center = m_sum /= (float)m_num; } - const Vector3 &lowerBound() const + const Vector3& lowerBound() const { return m_min; } - const Vector3 &upperBound() const + const Vector3& upperBound() const { return m_max; } - Vector3 &lowerBound() + Vector3& lowerBound() { return m_min; } - Vector3 &upperBound() + Vector3& upperBound() { return m_max; } - bool intersectWithAt(const AxisAlignedBoudingBox &other, AxisAlignedBoudingBox *result) const + bool intersectWithAt(const AxisAlignedBoudingBox& other, AxisAlignedBoudingBox* result) const { - const Vector3 &otherMin = other.lowerBound(); - const Vector3 &otherMax = other.upperBound(); + const Vector3& otherMin = other.lowerBound(); + const Vector3& otherMax = other.upperBound(); for (size_t i = 0; i < 3; ++i) { if (m_min[i] <= otherMax[i] && m_max[i] >= otherMin[i]) continue; @@ -97,10 +95,10 @@ public: return true; } - bool intersectWith(const AxisAlignedBoudingBox &other) const + bool intersectWith(const AxisAlignedBoudingBox& other) const { - const Vector3 &otherMin = other.lowerBound(); - const Vector3 &otherMax = other.upperBound(); + const Vector3& otherMin = other.lowerBound(); + const Vector3& otherMax = other.upperBound(); for (size_t i = 0; i < 3; ++i) { if (m_min[i] <= otherMax[i] && m_max[i] >= otherMin[i]) continue; @@ -108,7 +106,7 @@ public: } return true; } - + private: Vector3 m_min = { std::numeric_limits::max(), diff --git a/dust3d/base/axis_aligned_bounding_box_tree.cc b/dust3d/base/axis_aligned_bounding_box_tree.cc index 2fb662c8..05a3ec0d 100644 --- a/dust3d/base/axis_aligned_bounding_box_tree.cc +++ b/dust3d/base/axis_aligned_bounding_box_tree.cc @@ -19,40 +19,39 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #include -namespace dust3d -{ +namespace dust3d { const size_t AxisAlignedBoudingBoxTree::m_leafMaxNodeSize = 20; -AxisAlignedBoudingBoxTree::AxisAlignedBoudingBoxTree(const std::vector *boxes, - const std::vector &boxIndices, - const AxisAlignedBoudingBox &outterBox) +AxisAlignedBoudingBoxTree::AxisAlignedBoudingBoxTree(const std::vector* boxes, + const std::vector& boxIndices, + const AxisAlignedBoudingBox& outterBox) { m_boxes = boxes; - + m_root = new Node; m_root->boundingBox = outterBox; m_root->boxIndices = boxIndices; - + if (!boxIndices.empty()) { - for (const auto &boxIndex: boxIndices) { + for (const auto& boxIndex : boxIndices) { m_root->center += (*boxes)[boxIndex].center(); } m_root->center /= (float)boxIndices.size(); } - + splitNode(m_root); } -const AxisAlignedBoudingBoxTree::Node *AxisAlignedBoudingBoxTree::root() const +const AxisAlignedBoudingBoxTree::Node* AxisAlignedBoudingBoxTree::root() const { return m_root; } -const std::vector *AxisAlignedBoudingBoxTree::boxes() const +const std::vector* AxisAlignedBoudingBoxTree::boxes() const { return m_boxes; } @@ -62,7 +61,7 @@ AxisAlignedBoudingBoxTree::~AxisAlignedBoudingBoxTree() deleteNode(m_root); } -void AxisAlignedBoudingBoxTree::deleteNode(Node *node) +void AxisAlignedBoudingBoxTree::deleteNode(Node* node) { if (nullptr == node) return; @@ -71,18 +70,17 @@ void AxisAlignedBoudingBoxTree::deleteNode(Node *node) delete node; } -void AxisAlignedBoudingBoxTree::splitNode(Node *node) +void AxisAlignedBoudingBoxTree::splitNode(Node* node) { - const auto &boxIndices = node->boxIndices; + const auto& boxIndices = node->boxIndices; if (boxIndices.size() <= m_leafMaxNodeSize) return; - const auto &splitBox = node->boundingBox; - const Vector3 &lower = splitBox.lowerBound(); - const Vector3 &upper = splitBox.upperBound(); + const auto& splitBox = node->boundingBox; + const Vector3& lower = splitBox.lowerBound(); + const Vector3& upper = splitBox.upperBound(); for (size_t i = 0; i < 3; ++i) - m_spans[i] = {i, upper[i] - lower[i]}; - size_t longestAxis = std::max_element(m_spans.begin(), m_spans.end(), [](const std::pair &first, - const std::pair &second) { + m_spans[i] = { i, upper[i] - lower[i] }; + size_t longestAxis = std::max_element(m_spans.begin(), m_spans.end(), [](const std::pair& first, const std::pair& second) { return first.second < second.second; })->first; auto splitPoint = node->center[longestAxis]; @@ -94,9 +92,9 @@ void AxisAlignedBoudingBoxTree::splitNode(Node *node) size_t leftCount = 0; size_t rightCount = 0; for (size_t i = 0; i < boxIndices.size(); ++i) { - const auto &boxIndex = boxIndices[i]; - const AxisAlignedBoudingBox &box = (*m_boxes)[boxIndex]; - const auto ¢er = box.center()[longestAxis]; + const auto& boxIndex = boxIndices[i]; + const AxisAlignedBoudingBox& box = (*m_boxes)[boxIndex]; + const auto& center = box.center()[longestAxis]; if (center < splitPoint) { m_boxIndicesOrderList[--leftOffset] = boxIndex; ++leftCount; @@ -105,7 +103,7 @@ void AxisAlignedBoudingBoxTree::splitNode(Node *node) ++rightCount; } } - + if (0 == leftCount) { leftCount = rightCount / 2; rightCount -= leftCount; @@ -115,21 +113,21 @@ void AxisAlignedBoudingBoxTree::splitNode(Node *node) leftCount -= rightCount; rightOffset = leftOffset + boxIndices.size() - 1; } - + size_t middle = leftOffset + leftCount - 1; - + for (size_t i = leftOffset; i <= middle; ++i) { - const auto &boxIndex = m_boxIndicesOrderList[i]; - const AxisAlignedBoudingBox &box = (*m_boxes)[boxIndex]; + const auto& boxIndex = m_boxIndicesOrderList[i]; + const AxisAlignedBoudingBox& box = (*m_boxes)[boxIndex]; node->left->boundingBox.update(box.lowerBound()); node->left->boundingBox.update(box.upperBound()); node->left->boxIndices.push_back(boxIndex); node->left->center += box.center(); } - + for (size_t i = middle + 1; i <= rightOffset; ++i) { - const auto &boxIndex = m_boxIndicesOrderList[i]; - const AxisAlignedBoudingBox &box = (*m_boxes)[boxIndex]; + const auto& boxIndex = m_boxIndicesOrderList[i]; + const AxisAlignedBoudingBox& box = (*m_boxes)[boxIndex]; node->right->boundingBox.update(box.lowerBound()); node->right->boundingBox.update(box.upperBound()); node->right->boxIndices.push_back(boxIndex); diff --git a/dust3d/base/axis_aligned_bounding_box_tree.h b/dust3d/base/axis_aligned_bounding_box_tree.h index 3d29589e..8d1e2264 100644 --- a/dust3d/base/axis_aligned_bounding_box_tree.h +++ b/dust3d/base/axis_aligned_bounding_box_tree.h @@ -19,52 +19,49 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_AXIS_ALIGNED_BOUNDING_BOX_TREE_H_ #define DUST3D_BASE_AXIS_ALIGNED_BOUNDING_BOX_TREE_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -class AxisAlignedBoudingBoxTree -{ +class AxisAlignedBoudingBoxTree { public: - struct Node - { + struct Node { AxisAlignedBoudingBox boundingBox; Vector3 center; std::vector boxIndices; - Node *left = nullptr; - Node *right = nullptr; - + Node* left = nullptr; + Node* right = nullptr; + bool isLeaf() const { return nullptr == left && nullptr == right; }; }; - - AxisAlignedBoudingBoxTree(const std::vector *boxes, - const std::vector &boxIndices, - const AxisAlignedBoudingBox &outterBox); - const Node *root() const; - const std::vector *boxes() const; + + AxisAlignedBoudingBoxTree(const std::vector* boxes, + const std::vector& boxIndices, + const AxisAlignedBoudingBox& outterBox); + const Node* root() const; + const std::vector* boxes() const; ~AxisAlignedBoudingBoxTree(); - void splitNode(Node *node); - void deleteNode(Node *node); - - void testNodes(const Node *first, - const Node *second, - const std::vector *secondBoxes, - std::vector> *pairs) const + void splitNode(Node* node); + void deleteNode(Node* node); + + void testNodes(const Node* first, + const Node* second, + const std::vector* secondBoxes, + std::vector>* pairs) const { if (first->boundingBox.intersectWith(second->boundingBox)) { if (first->isLeaf()) { if (second->isLeaf()) { - for (const auto &a: first->boxIndices) { - for (const auto &b: second->boxIndices) { + for (const auto& a : first->boxIndices) { + for (const auto& b : second->boxIndices) { if ((*m_boxes)[a].intersectWith((*secondBoxes)[b])) { pairs->push_back(std::make_pair(a, b)); } @@ -90,20 +87,20 @@ public: } } } - - void test(const Node *first, const Node *second, - const std::vector *secondBoxes, - std::vector> *pairs) const + + void test(const Node* first, const Node* second, + const std::vector* secondBoxes, + std::vector>* pairs) const { testNodes(first, second, secondBoxes, pairs); } - + private: - const std::vector *m_boxes = nullptr; - Node *m_root = nullptr; + const std::vector* m_boxes = nullptr; + Node* m_root = nullptr; std::vector m_boxIndicesOrderList; std::vector> m_spans = std::vector>(3); - + static const size_t m_leafMaxNodeSize; }; diff --git a/dust3d/base/color.h b/dust3d/base/color.h index e46f5c1c..61735800 100644 --- a/dust3d/base/color.h +++ b/dust3d/base/color.h @@ -23,36 +23,34 @@ #ifndef DUST3D_BASE_COLOR_H_ #define DUST3D_BASE_COLOR_H_ -#include -#include #include +#include +#include + +namespace dust3d { -namespace dust3d -{ - class Color; -inline std::string to_string(const Color &color); - -class Color -{ +inline std::string to_string(const Color& color); + +class Color { public: - inline Color() : - m_data {0.0, 0.0, 0.0, 1.0} + inline Color() + : m_data { 0.0, 0.0, 0.0, 1.0 } { } - - inline Color(double r, double g, double b) : - m_data {r, g, b, 1.0} + + inline Color(double r, double g, double b) + : m_data { r, g, b, 1.0 } { } - - inline Color(double r, double g, double b, double alpha) : - m_data {r, g, b, alpha} + + inline Color(double r, double g, double b, double alpha) + : m_data { r, g, b, alpha } { } - - inline Color(const std::string &name) + + inline Color(const std::string& name) { if (7 == name.size() && '#' == name[0]) { m_data[0] = strtoul(name.substr(1, 2).c_str(), nullptr, 16) / 255.0; @@ -65,106 +63,106 @@ public: m_data[2] = strtoul(name.substr(7, 2).c_str(), nullptr, 16) / 255.0; } } - - inline double &operator[](size_t index) - { - return m_data[index]; - } - - inline const double &operator[](size_t index) const + + inline double& operator[](size_t index) { return m_data[index]; } - inline const double &alpha() const + inline const double& operator[](size_t index) const + { + return m_data[index]; + } + + inline const double& alpha() const { return m_data[3]; } - inline const double &r() const + inline const double& r() const { return m_data[0]; } - - inline const double &g() const + + inline const double& g() const { return m_data[1]; } - - inline const double &b() const + + inline const double& b() const { return m_data[2]; } - inline const double &red() const + inline const double& red() const { return m_data[0]; } - - inline const double &green() const + + inline const double& green() const { return m_data[1]; } - - inline const double &blue() const + + inline const double& blue() const { return m_data[2]; } - + inline void setRed(double r) { m_data[0] = r; } - + inline void setGreen(double g) { m_data[1] = g; } - + inline void setBlue(double b) { m_data[2] = b; } - + inline static Color createRed() { return Color(1.0, 0.0, 0.0); } - + inline static Color createWhite() { return Color(1.0, 1.0, 1.0); } - + inline static Color createBlack() { return Color(0.0, 0.0, 0.0); } - + inline static Color createTransparent() { return Color(0.0, 0.0, 0.0, 0.0); } - + inline std::string toString() const { return to_string(*this); } - + private: - double m_data[4] = {0.0, 0.0, 0.0, 1.0}; + double m_data[4] = { 0.0, 0.0, 0.0, 1.0 }; }; -inline std::string to_string(const Color &color) +inline std::string to_string(const Color& color) { - static const char *digits = "0123456789ABCDEF"; + static const char* digits = "0123456789ABCDEF"; std::string name = "#00000000"; - + int alpha = static_cast(color.alpha() * 255); int r = static_cast(color.r() * 255); int g = static_cast(color.g() * 255); int b = static_cast(color.b() * 255); - + name[1] = digits[(alpha & 0xf0) >> 4]; name[2] = digits[alpha & 0x0f]; name[3] = digits[(r & 0xf0) >> 4]; @@ -177,12 +175,12 @@ inline std::string to_string(const Color &color) return name; } -inline Color operator*(const Color &color, double number) +inline Color operator*(const Color& color, double number) { return Color(number * color[0], number * color[1], number * color[2], number * color[3]); } -inline Color operator+(const Color &a, const Color &b) +inline Color operator+(const Color& a, const Color& b) { return Color(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]); } diff --git a/dust3d/base/combine_mode.cc b/dust3d/base/combine_mode.cc index 822e8970..7cb1ee4f 100644 --- a/dust3d/base/combine_mode.cc +++ b/dust3d/base/combine_mode.cc @@ -22,11 +22,10 @@ #include -namespace dust3d -{ - +namespace dust3d { + IMPL_CombineModeToString -IMPL_CombineModeFromString -IMPL_CombineModeToDispName + IMPL_CombineModeFromString + IMPL_CombineModeToDispName } diff --git a/dust3d/base/combine_mode.h b/dust3d/base/combine_mode.h index 97ece01a..41342cac 100644 --- a/dust3d/base/combine_mode.h +++ b/dust3d/base/combine_mode.h @@ -25,59 +25,57 @@ #include -namespace dust3d -{ - -enum class CombineMode -{ +namespace dust3d { + +enum class CombineMode { Normal = 0, Inversion, Uncombined, Count }; -CombineMode CombineModeFromString(const char *modeString); -#define IMPL_CombineModeFromString \ -CombineMode CombineModeFromString(const char *modeString) \ -{ \ - std::string mode = modeString; \ - if (mode == "Normal") \ - return CombineMode::Normal; \ - if (mode == "Inversion") \ - return CombineMode::Inversion; \ - if (mode == "Uncombined") \ - return CombineMode::Uncombined; \ - return CombineMode::Normal; \ -} -const char *CombineModeToString(CombineMode mode); -#define IMPL_CombineModeToString \ -const char *CombineModeToString(CombineMode mode) \ -{ \ - switch (mode) { \ - case CombineMode::Normal: \ - return "Normal"; \ - case CombineMode::Inversion: \ - return "Inversion"; \ - case CombineMode::Uncombined: \ - return "Uncombined"; \ - default: \ - return "Normal"; \ - } \ -} +CombineMode CombineModeFromString(const char* modeString); +#define IMPL_CombineModeFromString \ + CombineMode CombineModeFromString(const char* modeString) \ + { \ + std::string mode = modeString; \ + if (mode == "Normal") \ + return CombineMode::Normal; \ + if (mode == "Inversion") \ + return CombineMode::Inversion; \ + if (mode == "Uncombined") \ + return CombineMode::Uncombined; \ + return CombineMode::Normal; \ + } +const char* CombineModeToString(CombineMode mode); +#define IMPL_CombineModeToString \ + const char* CombineModeToString(CombineMode mode) \ + { \ + switch (mode) { \ + case CombineMode::Normal: \ + return "Normal"; \ + case CombineMode::Inversion: \ + return "Inversion"; \ + case CombineMode::Uncombined: \ + return "Uncombined"; \ + default: \ + return "Normal"; \ + } \ + } std::string CombineModeToDispName(CombineMode mode); -#define IMPL_CombineModeToDispName \ -std::string CombineModeToDispName(CombineMode mode) \ -{ \ - switch (mode) { \ - case CombineMode::Normal: \ - return std::string("Normal"); \ - case CombineMode::Inversion: \ - return std::string("Inversion"); \ - case CombineMode::Uncombined: \ - return std::string("Uncombined"); \ - default: \ - return std::string("Normal"); \ - } \ -} +#define IMPL_CombineModeToDispName \ + std::string CombineModeToDispName(CombineMode mode) \ + { \ + switch (mode) { \ + case CombineMode::Normal: \ + return std::string("Normal"); \ + case CombineMode::Inversion: \ + return std::string("Inversion"); \ + case CombineMode::Uncombined: \ + return std::string("Uncombined"); \ + default: \ + return std::string("Normal"); \ + } \ + } } diff --git a/dust3d/base/cut_face.cc b/dust3d/base/cut_face.cc index db5c5787..50d24838 100644 --- a/dust3d/base/cut_face.cc +++ b/dust3d/base/cut_face.cc @@ -20,26 +20,26 @@ * SOFTWARE. */ -#include // std::reverse +#include // std::reverse +#include #include #include -#include -namespace dust3d -{ - +namespace dust3d { + IMPL_CutFaceFromString -IMPL_CutFaceToString -TMPL_CutFaceToPoints + IMPL_CutFaceToString + TMPL_CutFaceToPoints -static void correctFlippedNormal(std::vector *points) + static void + correctFlippedNormal(std::vector* points) { if (points->size() < 3) return; std::vector referenceFacePoints = { Vector3((float)-1.0, (float)-1.0, (float)0.0), Vector3((float)1.0, (float)-1.0, (float)0.0), - Vector3((float)1.0, (float)1.0, (float)0.0) + Vector3((float)1.0, (float)1.0, (float)0.0) }; Vector3 referenceNormal = Vector3::normal(referenceFacePoints[0], referenceFacePoints[1], referenceFacePoints[2]); @@ -61,7 +61,7 @@ static void correctFlippedNormal(std::vector *points) std::reverse(points->begin() + 1, points->end()); } -void normalizeCutFacePoints(std::vector *points) +void normalizeCutFacePoints(std::vector* points) { Vector2 center; if (nullptr == points || points->empty()) @@ -70,7 +70,7 @@ void normalizeCutFacePoints(std::vector *points) float xHigh = std::numeric_limits::lowest(); float yLow = std::numeric_limits::max(); float yHigh = std::numeric_limits::lowest(); - for (const auto &position: *points) { + for (const auto& position : *points) { if (position.x() < xLow) xLow = position.x(); else if (position.x() > xHigh) @@ -89,24 +89,24 @@ void normalizeCutFacePoints(std::vector *points) longSize = xSize; if (Math::isZero(longSize)) longSize = 0.000001; - for (auto &position: *points) { + for (auto& position : *points) { position.setX((position.x() - xMiddle) * 2 / longSize); position.setY((position.y() - yMiddle) * 2 / longSize); } correctFlippedNormal(points); } -void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing, - std::vector *pointsIds) +void cutFacePointsFromNodes(std::vector& points, const std::vector>& nodes, bool isRing, + std::vector* pointsIds) { if (isRing) { if (nodes.size() < 3) return; - for (const auto &it: nodes) { + for (const auto& it : nodes) { points.push_back(Vector2(std::get<1>(it), std::get<2>(it))); } if (nullptr != pointsIds) { - for (const auto &it: nodes) { + for (const auto& it : nodes) { pointsIds->push_back(std::get<3>(it)); } } @@ -117,38 +117,37 @@ void cutFacePointsFromNodes(std::vector &points, const std::vector edges; for (size_t i = 1; i < nodes.size(); ++i) { - const auto &previous = nodes[i - 1]; - const auto ¤t = nodes[i]; - edges.push_back((Vector2(std::get<1>(current), std::get<2>(current)) - - Vector2(std::get<1>(previous), std::get<2>(previous))).normalized()); + const auto& previous = nodes[i - 1]; + const auto& current = nodes[i]; + edges.push_back((Vector2(std::get<1>(current), std::get<2>(current)) - Vector2(std::get<1>(previous), std::get<2>(previous))).normalized()); } std::vector nodeDirections; nodeDirections.push_back(edges[0]); for (size_t i = 1; i < nodes.size() - 1; ++i) { - const auto &previousEdge = edges[i - 1]; - const auto &nextEdge = edges[i]; + const auto& previousEdge = edges[i - 1]; + const auto& nextEdge = edges[i]; nodeDirections.push_back((previousEdge + nextEdge).normalized()); } nodeDirections.push_back(edges[edges.size() - 1]); std::vector> cutPoints; for (size_t i = 0; i < nodes.size(); ++i) { - const auto ¤t = nodes[i]; - const auto &direction = nodeDirections[i]; - const auto &radius = std::get<0>(current); + const auto& current = nodes[i]; + const auto& direction = nodeDirections[i]; + const auto& radius = std::get<0>(current); Vector3 origin = Vector3(std::get<1>(current), std::get<2>(current), 0); Vector3 pointer = Vector3(direction.x(), direction.y(), 0); Vector3 rotateAxis = Vector3(0, 0, 1); Vector3 u = Vector3::crossProduct(pointer, rotateAxis).normalized(); Vector3 upPoint = origin + u * radius; Vector3 downPoint = origin - u * radius; - cutPoints.push_back({Vector2(upPoint.x(), upPoint.y()), - Vector2(downPoint.x(), downPoint.y())}); + cutPoints.push_back({ Vector2(upPoint.x(), upPoint.y()), + Vector2(downPoint.x(), downPoint.y()) }); } - for (const auto &it: cutPoints) { + for (const auto& it : cutPoints) { points.push_back(it.first); } if (nullptr != pointsIds) { - for (const auto &it: nodes) { + for (const auto& it : nodes) { pointsIds->push_back(std::get<3>(it) + std::string("/1")); } } diff --git a/dust3d/base/cut_face.h b/dust3d/base/cut_face.h index da987d33..9ef2ebe5 100644 --- a/dust3d/base/cut_face.h +++ b/dust3d/base/cut_face.h @@ -23,16 +23,14 @@ #ifndef DUST3D_BASE_CUT_FACE_H_ #define DUST3D_BASE_CUT_FACE_H_ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ - -enum class CutFace -{ +namespace dust3d { + +enum class CutFace { Quad = 0, Pentagon, Hexagon, @@ -41,90 +39,90 @@ enum class CutFace Count }; -CutFace CutFaceFromString(const char *faceString); -#define IMPL_CutFaceFromString \ -CutFace CutFaceFromString(const char *faceString) \ -{ \ - std::string face = faceString; \ - if (face == "Quad") \ - return CutFace::Quad; \ - if (face == "Pentagon") \ - return CutFace::Pentagon; \ - if (face == "Hexagon") \ - return CutFace::Hexagon; \ - if (face == "Triangle") \ - return CutFace::Triangle; \ - if (face == "UserDefined") \ - return CutFace::UserDefined; \ - return CutFace::Quad; \ -} +CutFace CutFaceFromString(const char* faceString); +#define IMPL_CutFaceFromString \ + CutFace CutFaceFromString(const char* faceString) \ + { \ + std::string face = faceString; \ + if (face == "Quad") \ + return CutFace::Quad; \ + if (face == "Pentagon") \ + return CutFace::Pentagon; \ + if (face == "Hexagon") \ + return CutFace::Hexagon; \ + if (face == "Triangle") \ + return CutFace::Triangle; \ + if (face == "UserDefined") \ + return CutFace::UserDefined; \ + return CutFace::Quad; \ + } std::string CutFaceToString(CutFace cutFace); -#define IMPL_CutFaceToString \ -std::string CutFaceToString(CutFace cutFace) \ -{ \ - switch (cutFace) { \ - case CutFace::Quad: \ - return "Quad"; \ - case CutFace::Pentagon: \ - return "Pentagon"; \ - case CutFace::Hexagon: \ - return "Hexagon"; \ - case CutFace::Triangle: \ - return "Triangle"; \ - case CutFace::UserDefined: \ - return "UserDefined"; \ - default: \ - return ""; \ - } \ -} +#define IMPL_CutFaceToString \ + std::string CutFaceToString(CutFace cutFace) \ + { \ + switch (cutFace) { \ + case CutFace::Quad: \ + return "Quad"; \ + case CutFace::Pentagon: \ + return "Pentagon"; \ + case CutFace::Hexagon: \ + return "Hexagon"; \ + case CutFace::Triangle: \ + return "Triangle"; \ + case CutFace::UserDefined: \ + return "UserDefined"; \ + default: \ + return ""; \ + } \ + } std::vector CutFaceToPoints(CutFace cutFace); -#define TMPL_CutFaceToPoints \ -std::vector CutFaceToPoints(CutFace cutFace) \ -{ \ - switch (cutFace) { \ - case CutFace::Quad: \ - return { \ - {(float)-1.0, (float)-1.0}, \ - { (float)1.0, (float)-1.0}, \ - { (float)1.0, (float)1.0}, \ - {(float)-1.0, (float)1.0}, \ - }; \ - case CutFace::Triangle: \ - return { \ - {(float)-1.1527, (float)-0.6655}, \ - { (float)1.1527, (float)-0.6655}, \ - { (float)0.0, (float)1.33447}, \ - }; \ - case CutFace::Pentagon: \ - return { \ - { (float)-0.6498, (float)-0.8944}, \ - { (float)0.6498, (float)-0.8944}, \ - { (float)1.05146, (float)0.34164}, \ - { (float)0.0, (float)1.10557}, \ - {(float)-1.05146, (float)0.34164}, \ - }; \ - case CutFace::Hexagon: \ - return { \ - { (float)-0.577, (float)-1.0}, \ - { (float)0.577, (float)-1.0}, \ - { (float)1.1547, (float)0.0}, \ - { (float)0.577, (float)1.0}, \ - { (float)-0.577, (float)1.0}, \ - {(float)-1.1547, (float)0.0}, \ - }; \ - default: \ - return { \ - {(float)-1.0, (float)-1.0}, \ - { (float)1.0, (float)-1.0}, \ - { (float)1.0, (float)1.0}, \ - {(float)-1.0, (float)1.0}, \ - }; \ - } \ -} +#define TMPL_CutFaceToPoints \ + std::vector CutFaceToPoints(CutFace cutFace) \ + { \ + switch (cutFace) { \ + case CutFace::Quad: \ + return { \ + { (float)-1.0, (float)-1.0 }, \ + { (float)1.0, (float)-1.0 }, \ + { (float)1.0, (float)1.0 }, \ + { (float)-1.0, (float)1.0 }, \ + }; \ + case CutFace::Triangle: \ + return { \ + { (float)-1.1527, (float)-0.6655 }, \ + { (float)1.1527, (float)-0.6655 }, \ + { (float)0.0, (float)1.33447 }, \ + }; \ + case CutFace::Pentagon: \ + return { \ + { (float)-0.6498, (float)-0.8944 }, \ + { (float)0.6498, (float)-0.8944 }, \ + { (float)1.05146, (float)0.34164 }, \ + { (float)0.0, (float)1.10557 }, \ + { (float)-1.05146, (float)0.34164 }, \ + }; \ + case CutFace::Hexagon: \ + return { \ + { (float)-0.577, (float)-1.0 }, \ + { (float)0.577, (float)-1.0 }, \ + { (float)1.1547, (float)0.0 }, \ + { (float)0.577, (float)1.0 }, \ + { (float)-0.577, (float)1.0 }, \ + { (float)-1.1547, (float)0.0 }, \ + }; \ + default: \ + return { \ + { (float)-1.0, (float)-1.0 }, \ + { (float)1.0, (float)-1.0 }, \ + { (float)1.0, (float)1.0 }, \ + { (float)-1.0, (float)1.0 }, \ + }; \ + } \ + } -void normalizeCutFacePoints(std::vector *points); -void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing=false, - std::vector *pointsIds=nullptr); +void normalizeCutFacePoints(std::vector* points); +void cutFacePointsFromNodes(std::vector& points, const std::vector>& nodes, bool isRing = false, + std::vector* pointsIds = nullptr); } diff --git a/dust3d/base/debug.h b/dust3d/base/debug.h index e53a4d32..357e32d7 100644 --- a/dust3d/base/debug.h +++ b/dust3d/base/debug.h @@ -25,34 +25,32 @@ #include -namespace dust3d -{ +namespace dust3d { -class Debug -{ +class Debug { public: Debug() = default; - - Debug(Debug const &) = delete; - - Debug &operator=(Debug const &) = delete; - - Debug &operator=(Debug &&) = delete; - - Debug(Debug &&instance) noexcept + + Debug(Debug const&) = delete; + + Debug& operator=(Debug const&) = delete; + + Debug& operator=(Debug&&) = delete; + + Debug(Debug&& instance) noexcept : m_firstItem(false) { instance.m_lastItem = false; } - ~Debug() + ~Debug() { if (m_lastItem) std::cout << '\n'; } - + template - friend Debug operator<<(Debug instance, const T &value) + friend Debug operator<<(Debug instance, const T& value) { if (instance.m_firstItem) instance.m_firstItem = false; @@ -62,7 +60,7 @@ public: std::cout << value; return instance; } - + private: bool m_firstItem = true; bool m_lastItem = true; diff --git a/dust3d/base/ds3_file.cc b/dust3d/base/ds3_file.cc index eec89e80..11f592cd 100644 --- a/dust3d/base/ds3_file.cc +++ b/dust3d/base/ds3_file.cc @@ -21,21 +21,20 @@ */ #include -#include -#include -#include #include #include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { std::string Ds3FileReader::m_applicationName = std::string("DUST3D"); std::string Ds3FileReader::m_fileFormatVersion = std::string("1.0"); std::string Ds3FileReader::m_headFormat = std::string("xml"); -std::string Ds3FileReader::readFirstLine(const std::uint8_t *data, size_t size) +std::string Ds3FileReader::readFirstLine(const std::uint8_t* data, size_t size) { std::string firstLine; for (size_t i = 0; i < size; ++i) { @@ -47,7 +46,7 @@ std::string Ds3FileReader::readFirstLine(const std::uint8_t *data, size_t size) return std::string(); } -Ds3FileReader::Ds3FileReader(const std::uint8_t *fileData, size_t fileSize) +Ds3FileReader::Ds3FileReader(const std::uint8_t* fileData, size_t fileSize) { m_headerIsGood = false; std::string firstLine = readFirstLine(fileData, fileSize); @@ -76,25 +75,25 @@ Ds3FileReader::Ds3FileReader(const std::uint8_t *fileData, size_t fileSize) std::vector header(m_binaryOffset - firstLine.size() + 1); std::memcpy(header.data(), fileData + firstLine.size(), header.size() - 1); header[header.size() - 1] = '\0'; - + try { rapidxml::xml_document<> xml; xml.parse<0>(header.data()); - rapidxml::xml_node<> *rootNode = xml.first_node("ds3"); + rapidxml::xml_node<>* rootNode = xml.first_node("ds3"); if (nullptr == rootNode) return; m_headerIsGood = true; m_fileContent = std::vector(fileSize); std::memcpy(m_fileContent.data(), fileData, fileSize); - for (rapidxml::xml_node<> *node = rootNode->first_node(); nullptr != node; node = node->next_sibling()) { + for (rapidxml::xml_node<>* node = rootNode->first_node(); nullptr != node; node = node->next_sibling()) { Ds3ReaderItem readerItem; - rapidxml::xml_attribute<> *attribute; + rapidxml::xml_attribute<>* attribute; readerItem.type = node->name(); - if (nullptr != (attribute=node->first_attribute("name"))) + if (nullptr != (attribute = node->first_attribute("name"))) readerItem.name = String::trimmed(attribute->value()); - if (nullptr != (attribute=node->first_attribute("offset"))) + if (nullptr != (attribute = node->first_attribute("offset"))) readerItem.offset = std::stoull(attribute->value()); - if (nullptr != (attribute=node->first_attribute("size"))) + if (nullptr != (attribute = node->first_attribute("size"))) readerItem.size = std::stoull(attribute->value()); if (readerItem.offset > (long long)fileSize) continue; @@ -103,18 +102,18 @@ Ds3FileReader::Ds3FileReader(const std::uint8_t *fileData, size_t fileSize) m_items.push_back(readerItem); m_itemsMap[readerItem.name] = readerItem; } - } catch (const std::runtime_error &e) { + } catch (const std::runtime_error& e) { dust3dDebug << "Runtime error was: " << e.what(); - } catch (const rapidxml::parse_error &e) { + } catch (const rapidxml::parse_error& e) { dust3dDebug << "Parse error was: " << e.what(); - } catch (const std::exception &e) { + } catch (const std::exception& e) { dust3dDebug << "Error was: " << e.what(); } catch (...) { dust3dDebug << "An unknown error occurred."; } } -void Ds3FileReader::loadItem(const std::string &name, std::vector *byteArray) +void Ds3FileReader::loadItem(const std::string& name, std::vector* byteArray) { byteArray->clear(); if (!m_headerIsGood) @@ -124,17 +123,17 @@ void Ds3FileReader::loadItem(const std::string &name, std::vector } Ds3ReaderItem readerItem = m_itemsMap[name]; byteArray->resize(readerItem.size, 0); - std::memcpy((char *)byteArray->data(), - m_fileContent.data() + m_binaryOffset + readerItem.offset, + std::memcpy((char*)byteArray->data(), + m_fileContent.data() + m_binaryOffset + readerItem.offset, byteArray->size()); } -const std::vector &Ds3FileReader::items() const +const std::vector& Ds3FileReader::items() const { return m_items; } -bool Ds3FileWriter::add(const std::string &name, const std::string &type, const void *buffer, size_t bufferSize) +bool Ds3FileWriter::add(const std::string& name, const std::string& type, const void* buffer, size_t bufferSize) { if (m_itemsMap.find(name) != m_itemsMap.end()) { return false; @@ -144,30 +143,30 @@ bool Ds3FileWriter::add(const std::string &name, const std::string &type, const writerItem.name = name; writerItem.byteArray.resize(bufferSize); for (size_t i = 0; i < bufferSize; ++i) - writerItem.byteArray[i] = ((const std::uint8_t *)buffer)[i]; + writerItem.byteArray[i] = ((const std::uint8_t*)buffer)[i]; m_itemsMap[name] = writerItem; m_items.push_back(writerItem); return true; } -bool Ds3FileWriter::save(const std::string &filename) +bool Ds3FileWriter::save(const std::string& filename) { std::ofstream file(filename, std::ios::out | std::ios::trunc | std::ios::binary); if (!file.is_open()) return false; - + std::ostringstream headerXmlStream; headerXmlStream << "" << std::endl; headerXmlStream << "" << std::endl; { long long offset = 0; for (int i = 0; i < m_items.size(); i++) { - Ds3WriterItem *writerItem = &m_items[i]; + Ds3WriterItem* writerItem = &m_items[i]; headerXmlStream << " <" << writerItem->type; - headerXmlStream << " name=\"" << String::doubleQuoteEscapedForXml(writerItem->name) << "\""; - headerXmlStream << " offset=\"" << std::to_string(offset) << "\""; - headerXmlStream << " size=\"" << std::to_string(writerItem->byteArray.size()) << "\""; - offset += writerItem->byteArray.size(); + headerXmlStream << " name=\"" << String::doubleQuoteEscapedForXml(writerItem->name) << "\""; + headerXmlStream << " offset=\"" << std::to_string(offset) << "\""; + headerXmlStream << " size=\"" << std::to_string(writerItem->byteArray.size()) << "\""; + offset += writerItem->byteArray.size(); headerXmlStream << "/>" << std::endl; } } @@ -179,16 +178,16 @@ bool Ds3FileWriter::save(const std::string &filename) Ds3FileReader::m_fileFormatVersion.c_str(), Ds3FileReader::m_headFormat.c_str()); unsigned int headerSize = (unsigned int)(firstLineSizeExcludeSizeSelf + 12 + headerXml.size()); - char headerSizeString[100] = {0}; + char headerSizeString[100] = { 0 }; sprintf(headerSizeString, "%010u\r\n", headerSize); file.write(firstLine, firstLineSizeExcludeSizeSelf); file.write(headerSizeString, strlen(headerSizeString)); file << headerXml; for (int i = 0; i < m_items.size(); i++) { - Ds3WriterItem *writerItem = &m_items[i]; - file.write((char *)writerItem->byteArray.data(), writerItem->byteArray.size()); + Ds3WriterItem* writerItem = &m_items[i]; + file.write((char*)writerItem->byteArray.data(), writerItem->byteArray.size()); } - + return true; } diff --git a/dust3d/base/ds3_file.h b/dust3d/base/ds3_file.h index c282c796..9492ba0f 100644 --- a/dust3d/base/ds3_file.h +++ b/dust3d/base/ds3_file.h @@ -19,19 +19,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_DS3_FILE_H_ #define DUST3D_BASE_DS3_FILE_H_ -#include #include +#include #include -namespace dust3d -{ +namespace dust3d { -class Ds3ReaderItem -{ +class Ds3ReaderItem { public: std::string type; std::string name; @@ -39,38 +37,38 @@ public: long long size; }; -class Ds3FileReader -{ +class Ds3FileReader { public: - Ds3FileReader(const std::uint8_t *fileData, size_t fileSize); - void loadItem(const std::string &name, std::vector *byteArray); - const std::vector &items() const; + Ds3FileReader(const std::uint8_t* fileData, size_t fileSize); + void loadItem(const std::string& name, std::vector* byteArray); + const std::vector& items() const; static std::string m_applicationName; static std::string m_fileFormatVersion; static std::string m_headFormat; + private: std::map m_itemsMap; std::vector m_items; std::vector m_fileContent; + private: - static std::string readFirstLine(const std::uint8_t *data, size_t size); + static std::string readFirstLine(const std::uint8_t* data, size_t size); bool m_headerIsGood = false; long long m_binaryOffset = 0; }; -class Ds3WriterItem -{ +class Ds3WriterItem { public: std::string type; std::string name; std::vector byteArray; }; -class Ds3FileWriter -{ +class Ds3FileWriter { public: - bool add(const std::string &name, const std::string &type, const void *buffer, size_t bufferSize); - bool save(const std::string &filename); + bool add(const std::string& name, const std::string& type, const void* buffer, size_t bufferSize); + bool save(const std::string& filename); + private: std::map m_itemsMap; std::vector m_items; diff --git a/dust3d/base/math.h b/dust3d/base/math.h index d95a7cf5..14b94c29 100644 --- a/dust3d/base/math.h +++ b/dust3d/base/math.h @@ -19,39 +19,37 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_MATH_H_ #define DUST3D_BASE_MATH_H_ #include #include -namespace dust3d -{ -namespace Math -{ - -constexpr double Pi = 3.14159265358979323846; - -inline bool isZero(double number) -{ - return std::abs(number) <= std::numeric_limits::epsilon(); -} +namespace dust3d { +namespace Math { -inline bool isEqual(double a, double b) -{ - return isZero(a - b); -} + constexpr double Pi = 3.14159265358979323846; -inline double radiansFromDegrees(double degrees) -{ - return degrees * (Pi / 180.0); -} + inline bool isZero(double number) + { + return std::abs(number) <= std::numeric_limits::epsilon(); + } -inline double radiansToDegrees(double radians) -{ - return radians * (180.0 / Pi); -} + inline bool isEqual(double a, double b) + { + return isZero(a - b); + } + + inline double radiansFromDegrees(double degrees) + { + return degrees * (Pi / 180.0); + } + + inline double radiansToDegrees(double radians) + { + return radians * (180.0 / Pi); + } } } diff --git a/dust3d/base/matrix4x4.h b/dust3d/base/matrix4x4.h index 1029de06..e24e1e80 100644 --- a/dust3d/base/matrix4x4.h +++ b/dust3d/base/matrix4x4.h @@ -24,30 +24,28 @@ #define DUST3D_BASE_MATRIX4X4_H_ #include -#include -#include #include +#include +#include + +namespace dust3d { -namespace dust3d -{ - class Matrix4x4; - -inline Vector3 operator*(const Matrix4x4 &m, const Vector3 &v); -class Matrix4x4 -{ +inline Vector3 operator*(const Matrix4x4& m, const Vector3& v); + +class Matrix4x4 { public: // | M00 M10 M20 M30 | // | M01 M11 M21 M31 | // | M02 M12 M22 M32 | // | M03 M13 M23 M33 | - + // | 0 4 8 12 | // | 1 5 9 13 | // | 2 6 10 14 | // | 3 7 11 15 | - + const int M00 = 0; const int M01 = 1; const int M02 = 2; @@ -66,15 +64,15 @@ public: const int M33 = 15; inline Matrix4x4() = default; - + // https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle - inline void rotate(const Vector3 &axis, double angle) + inline void rotate(const Vector3& axis, double angle) { double cosine = std::cos(angle); double sine = std::sin(angle); double oneMinusCosine = 1.0 - cosine; Matrix4x4 by; - double *byData = by.data(); + double* byData = by.data(); byData[M00] = cosine + axis.x() * axis.x() * oneMinusCosine; byData[M10] = axis.x() * axis.y() * oneMinusCosine - axis.z() * sine; byData[M20] = axis.x() * axis.z() * oneMinusCosine + axis.y() * sine; @@ -91,23 +89,23 @@ public: byData[M13] = 0.0; byData[M23] = 0.0; byData[M33] = 1.0; - *this *= by; + *this *= by; } - - inline const double *constData() const + + inline const double* constData() const { return &m_data[0]; } - - inline double *data() + + inline double* data() { return &m_data[0]; } - - inline void rotate(const Quaternion &q) + + inline void rotate(const Quaternion& q) { Matrix4x4 tmp; - double *tmpData = tmp.data(); + double* tmpData = tmp.data(); double xx = q.x() + q.x(); double yy = q.y() + q.y(); double zz = q.z() + q.z(); @@ -121,15 +119,15 @@ public: double yyz = yy * q.z(); double zzz = zz * q.z(); tmpData[M00] = 1.0f - (yyy + zzz); - tmpData[M10] = xxy - zzw; - tmpData[M20] = xxz + yyw; + tmpData[M10] = xxy - zzw; + tmpData[M20] = xxz + yyw; tmpData[M30] = 0.0f; - tmpData[M01] = xxy + zzw; + tmpData[M01] = xxy + zzw; tmpData[M11] = 1.0f - (xxx + zzz); - tmpData[M21] = yyz - xxw; + tmpData[M21] = yyz - xxw; tmpData[M31] = 0.0f; - tmpData[M02] = xxz - yyw; - tmpData[M12] = yyz + xxw; + tmpData[M02] = xxz - yyw; + tmpData[M12] = yyz + xxw; tmpData[M22] = 1.0f - (xxx + yyy); tmpData[M32] = 0.0f; tmpData[M03] = 0.0f; @@ -138,120 +136,37 @@ public: tmpData[M33] = 1.0f; *this *= tmp; } - - inline Matrix4x4 &translate(const Vector3 &v) + + inline Matrix4x4& translate(const Vector3& v) { m_data[M30] += v.x(); m_data[M31] += v.y(); m_data[M32] += v.z(); return *this; } - + inline Matrix4x4 inverted() const { Matrix4x4 m; - double *dest = m.data(); - dest[0] = m_data[5] * m_data[10] * m_data[15] - - m_data[5] * m_data[11] * m_data[14] - - m_data[9] * m_data[6] * m_data[15] + - m_data[9] * m_data[7] * m_data[14] + - m_data[13] * m_data[6] * m_data[11] - - m_data[13] * m_data[7] * m_data[10]; - dest[4] = -m_data[4] * m_data[10] * m_data[15] + - m_data[4] * m_data[11] * m_data[14] + - m_data[8] * m_data[6] * m_data[15] - - m_data[8] * m_data[7] * m_data[14] - - m_data[12] * m_data[6] * m_data[11] + - m_data[12] * m_data[7] * m_data[10]; - dest[8] = m_data[4] * m_data[9] * m_data[15] - - m_data[4] * m_data[11] * m_data[13] - - m_data[8] * m_data[5] * m_data[15] + - m_data[8] * m_data[7] * m_data[13] + - m_data[12] * m_data[5] * m_data[11] - - m_data[12] * m_data[7] * m_data[9]; - dest[12] = -m_data[4] * m_data[9] * m_data[14] + - m_data[4] * m_data[10] * m_data[13] + - m_data[8] * m_data[5] * m_data[14] - - m_data[8] * m_data[6] * m_data[13] - - m_data[12] * m_data[5] * m_data[10] + - m_data[12] * m_data[6] * m_data[9]; - dest[1] = -m_data[1] * m_data[10] * m_data[15] + - m_data[1] * m_data[11] * m_data[14] + - m_data[9] * m_data[2] * m_data[15] - - m_data[9] * m_data[3] * m_data[14] - - m_data[13] * m_data[2] * m_data[11] + - m_data[13] * m_data[3] * m_data[10]; - dest[5] = m_data[0] * m_data[10] * m_data[15] - - m_data[0] * m_data[11] * m_data[14] - - m_data[8] * m_data[2] * m_data[15] + - m_data[8] * m_data[3] * m_data[14] + - m_data[12] * m_data[2] * m_data[11] - - m_data[12] * m_data[3] * m_data[10]; - dest[9] = -m_data[0] * m_data[9] * m_data[15] + - m_data[0] * m_data[11] * m_data[13] + - m_data[8] * m_data[1] * m_data[15] - - m_data[8] * m_data[3] * m_data[13] - - m_data[12] * m_data[1] * m_data[11] + - m_data[12] * m_data[3] * m_data[9]; - dest[13] = m_data[0] * m_data[9] * m_data[14] - - m_data[0] * m_data[10] * m_data[13] - - m_data[8] * m_data[1] * m_data[14] + - m_data[8] * m_data[2] * m_data[13] + - m_data[12] * m_data[1] * m_data[10] - - m_data[12] * m_data[2] * m_data[9]; - dest[2] = m_data[1] * m_data[6] * m_data[15] - - m_data[1] * m_data[7] * m_data[14] - - m_data[5] * m_data[2] * m_data[15] + - m_data[5] * m_data[3] * m_data[14] + - m_data[13] * m_data[2] * m_data[7] - - m_data[13] * m_data[3] * m_data[6]; - dest[6] = -m_data[0] * m_data[6] * m_data[15] + - m_data[0] * m_data[7] * m_data[14] + - m_data[4] * m_data[2] * m_data[15] - - m_data[4] * m_data[3] * m_data[14] - - m_data[12] * m_data[2] * m_data[7] + - m_data[12] * m_data[3] * m_data[6]; - dest[10] = m_data[0] * m_data[5] * m_data[15] - - m_data[0] * m_data[7] * m_data[13] - - m_data[4] * m_data[1] * m_data[15] + - m_data[4] * m_data[3] * m_data[13] + - m_data[12] * m_data[1] * m_data[7] - - m_data[12] * m_data[3] * m_data[5]; - dest[14] = -m_data[0] * m_data[5] * m_data[14] + - m_data[0] * m_data[6] * m_data[13] + - m_data[4] * m_data[1] * m_data[14] - - m_data[4] * m_data[2] * m_data[13] - - m_data[12] * m_data[1] * m_data[6] + - m_data[12] * m_data[2] * m_data[5]; - dest[3] = -m_data[1] * m_data[6] * m_data[11] + - m_data[1] * m_data[7] * m_data[10] + - m_data[5] * m_data[2] * m_data[11] - - m_data[5] * m_data[3] * m_data[10] - - m_data[9] * m_data[2] * m_data[7] + - m_data[9] * m_data[3] * m_data[6]; - dest[7] = m_data[0] * m_data[6] * m_data[11] - - m_data[0] * m_data[7] * m_data[10] - - m_data[4] * m_data[2] * m_data[11] + - m_data[4] * m_data[3] * m_data[10] + - m_data[8] * m_data[2] * m_data[7] - - m_data[8] * m_data[3] * m_data[6]; - dest[11] = -m_data[0] * m_data[5] * m_data[11] + - m_data[0] * m_data[7] * m_data[9] + - m_data[4] * m_data[1] * m_data[11] - - m_data[4] * m_data[3] * m_data[9] - - m_data[8] * m_data[1] * m_data[7] + - m_data[8] * m_data[3] * m_data[5]; - dest[15] = m_data[0] * m_data[5] * m_data[10] - - m_data[0] * m_data[6] * m_data[9] - - m_data[4] * m_data[1] * m_data[10] + - m_data[4] * m_data[2] * m_data[9] + - m_data[8] * m_data[1] * m_data[6] - - m_data[8] * m_data[2] * m_data[5]; + double* dest = m.data(); + dest[0] = m_data[5] * m_data[10] * m_data[15] - m_data[5] * m_data[11] * m_data[14] - m_data[9] * m_data[6] * m_data[15] + m_data[9] * m_data[7] * m_data[14] + m_data[13] * m_data[6] * m_data[11] - m_data[13] * m_data[7] * m_data[10]; + dest[4] = -m_data[4] * m_data[10] * m_data[15] + m_data[4] * m_data[11] * m_data[14] + m_data[8] * m_data[6] * m_data[15] - m_data[8] * m_data[7] * m_data[14] - m_data[12] * m_data[6] * m_data[11] + m_data[12] * m_data[7] * m_data[10]; + dest[8] = m_data[4] * m_data[9] * m_data[15] - m_data[4] * m_data[11] * m_data[13] - m_data[8] * m_data[5] * m_data[15] + m_data[8] * m_data[7] * m_data[13] + m_data[12] * m_data[5] * m_data[11] - m_data[12] * m_data[7] * m_data[9]; + dest[12] = -m_data[4] * m_data[9] * m_data[14] + m_data[4] * m_data[10] * m_data[13] + m_data[8] * m_data[5] * m_data[14] - m_data[8] * m_data[6] * m_data[13] - m_data[12] * m_data[5] * m_data[10] + m_data[12] * m_data[6] * m_data[9]; + dest[1] = -m_data[1] * m_data[10] * m_data[15] + m_data[1] * m_data[11] * m_data[14] + m_data[9] * m_data[2] * m_data[15] - m_data[9] * m_data[3] * m_data[14] - m_data[13] * m_data[2] * m_data[11] + m_data[13] * m_data[3] * m_data[10]; + dest[5] = m_data[0] * m_data[10] * m_data[15] - m_data[0] * m_data[11] * m_data[14] - m_data[8] * m_data[2] * m_data[15] + m_data[8] * m_data[3] * m_data[14] + m_data[12] * m_data[2] * m_data[11] - m_data[12] * m_data[3] * m_data[10]; + dest[9] = -m_data[0] * m_data[9] * m_data[15] + m_data[0] * m_data[11] * m_data[13] + m_data[8] * m_data[1] * m_data[15] - m_data[8] * m_data[3] * m_data[13] - m_data[12] * m_data[1] * m_data[11] + m_data[12] * m_data[3] * m_data[9]; + dest[13] = m_data[0] * m_data[9] * m_data[14] - m_data[0] * m_data[10] * m_data[13] - m_data[8] * m_data[1] * m_data[14] + m_data[8] * m_data[2] * m_data[13] + m_data[12] * m_data[1] * m_data[10] - m_data[12] * m_data[2] * m_data[9]; + dest[2] = m_data[1] * m_data[6] * m_data[15] - m_data[1] * m_data[7] * m_data[14] - m_data[5] * m_data[2] * m_data[15] + m_data[5] * m_data[3] * m_data[14] + m_data[13] * m_data[2] * m_data[7] - m_data[13] * m_data[3] * m_data[6]; + dest[6] = -m_data[0] * m_data[6] * m_data[15] + m_data[0] * m_data[7] * m_data[14] + m_data[4] * m_data[2] * m_data[15] - m_data[4] * m_data[3] * m_data[14] - m_data[12] * m_data[2] * m_data[7] + m_data[12] * m_data[3] * m_data[6]; + dest[10] = m_data[0] * m_data[5] * m_data[15] - m_data[0] * m_data[7] * m_data[13] - m_data[4] * m_data[1] * m_data[15] + m_data[4] * m_data[3] * m_data[13] + m_data[12] * m_data[1] * m_data[7] - m_data[12] * m_data[3] * m_data[5]; + dest[14] = -m_data[0] * m_data[5] * m_data[14] + m_data[0] * m_data[6] * m_data[13] + m_data[4] * m_data[1] * m_data[14] - m_data[4] * m_data[2] * m_data[13] - m_data[12] * m_data[1] * m_data[6] + m_data[12] * m_data[2] * m_data[5]; + dest[3] = -m_data[1] * m_data[6] * m_data[11] + m_data[1] * m_data[7] * m_data[10] + m_data[5] * m_data[2] * m_data[11] - m_data[5] * m_data[3] * m_data[10] - m_data[9] * m_data[2] * m_data[7] + m_data[9] * m_data[3] * m_data[6]; + dest[7] = m_data[0] * m_data[6] * m_data[11] - m_data[0] * m_data[7] * m_data[10] - m_data[4] * m_data[2] * m_data[11] + m_data[4] * m_data[3] * m_data[10] + m_data[8] * m_data[2] * m_data[7] - m_data[8] * m_data[3] * m_data[6]; + dest[11] = -m_data[0] * m_data[5] * m_data[11] + m_data[0] * m_data[7] * m_data[9] + m_data[4] * m_data[1] * m_data[11] - m_data[4] * m_data[3] * m_data[9] - m_data[8] * m_data[1] * m_data[7] + m_data[8] * m_data[3] * m_data[5]; + dest[15] = m_data[0] * m_data[5] * m_data[10] - m_data[0] * m_data[6] * m_data[9] - m_data[4] * m_data[1] * m_data[10] + m_data[4] * m_data[2] * m_data[9] + m_data[8] * m_data[1] * m_data[6] - m_data[8] * m_data[2] * m_data[5]; - double det = m_data[0] * dest[0] + - m_data[1] * dest[4] + - m_data[2] * dest[8] + - m_data[3] * dest[12]; + double det = m_data[0] * dest[0] + m_data[1] * dest[4] + m_data[2] * dest[8] + m_data[3] * dest[12]; if (Math::isZero(det)) return Matrix4x4(); @@ -261,79 +176,31 @@ public: for (size_t i = 0; i < 16; ++i) dest[i] *= det; } - - inline Matrix4x4 &operator*=(const Matrix4x4 &by) + + inline Matrix4x4& operator*=(const Matrix4x4& by) { double tmpData[16]; memcpy(tmpData, m_data, sizeof(tmpData)); - const double *byData = by.constData(); - m_data[0] = tmpData[0] * byData[0] + - tmpData[4] * byData[1] + - tmpData[8] * byData[2] + - tmpData[12] * byData[3]; - m_data[4] = tmpData[0] * byData[4] + - tmpData[4] * byData[5] + - tmpData[8] * byData[6] + - tmpData[12] * byData[7]; - m_data[8] = tmpData[0] * byData[8] + - tmpData[4] * byData[9] + - tmpData[8] * byData[10] + - tmpData[12] * byData[11]; - m_data[12] = tmpData[0] * byData[12] + - tmpData[4] * byData[13] + - tmpData[8] * byData[14] + - tmpData[12] * byData[15]; + const double* byData = by.constData(); + m_data[0] = tmpData[0] * byData[0] + tmpData[4] * byData[1] + tmpData[8] * byData[2] + tmpData[12] * byData[3]; + m_data[4] = tmpData[0] * byData[4] + tmpData[4] * byData[5] + tmpData[8] * byData[6] + tmpData[12] * byData[7]; + m_data[8] = tmpData[0] * byData[8] + tmpData[4] * byData[9] + tmpData[8] * byData[10] + tmpData[12] * byData[11]; + m_data[12] = tmpData[0] * byData[12] + tmpData[4] * byData[13] + tmpData[8] * byData[14] + tmpData[12] * byData[15]; - m_data[1] = tmpData[1] * byData[0] + - tmpData[5] * byData[1] + - tmpData[9] * byData[2] + - tmpData[13] * byData[3]; - m_data[5] = tmpData[1] * byData[4] + - tmpData[5] * byData[5] + - tmpData[9] * byData[6] + - tmpData[13] * byData[7]; - m_data[9] = tmpData[1] * byData[8] + - tmpData[5] * byData[9] + - tmpData[9] * byData[10] + - tmpData[13] * byData[11]; - m_data[13] = tmpData[1] * byData[12] + - tmpData[5] * byData[13] + - tmpData[9] * byData[14] + - tmpData[13] * byData[15]; + m_data[1] = tmpData[1] * byData[0] + tmpData[5] * byData[1] + tmpData[9] * byData[2] + tmpData[13] * byData[3]; + m_data[5] = tmpData[1] * byData[4] + tmpData[5] * byData[5] + tmpData[9] * byData[6] + tmpData[13] * byData[7]; + m_data[9] = tmpData[1] * byData[8] + tmpData[5] * byData[9] + tmpData[9] * byData[10] + tmpData[13] * byData[11]; + m_data[13] = tmpData[1] * byData[12] + tmpData[5] * byData[13] + tmpData[9] * byData[14] + tmpData[13] * byData[15]; - m_data[2] = tmpData[2] * byData[0] + - tmpData[6] * byData[1] + - tmpData[10] * byData[2] + - tmpData[14] * byData[3]; - m_data[6] = tmpData[2] * byData[4] + - tmpData[6] * byData[5] + - tmpData[10] * byData[6] + - tmpData[14] * byData[7]; - m_data[10] = tmpData[2] * byData[8] + - tmpData[6] * byData[9] + - tmpData[10] * byData[10] + - tmpData[14] * byData[11]; - m_data[14] = tmpData[2] * byData[12] + - tmpData[6] * byData[13] + - tmpData[10] * byData[14] + - tmpData[14] * byData[15]; + m_data[2] = tmpData[2] * byData[0] + tmpData[6] * byData[1] + tmpData[10] * byData[2] + tmpData[14] * byData[3]; + m_data[6] = tmpData[2] * byData[4] + tmpData[6] * byData[5] + tmpData[10] * byData[6] + tmpData[14] * byData[7]; + m_data[10] = tmpData[2] * byData[8] + tmpData[6] * byData[9] + tmpData[10] * byData[10] + tmpData[14] * byData[11]; + m_data[14] = tmpData[2] * byData[12] + tmpData[6] * byData[13] + tmpData[10] * byData[14] + tmpData[14] * byData[15]; - m_data[3] = tmpData[3] * byData[0] + - tmpData[7] * byData[1] + - tmpData[11] * byData[2] + - tmpData[15] * byData[3]; - m_data[7] = tmpData[3] * byData[4] + - tmpData[7] * byData[5] + - tmpData[11] * byData[6] + - tmpData[15] * byData[7]; - m_data[11] = tmpData[3] * byData[8] + - tmpData[7] * byData[9] + - tmpData[11] * byData[10] + - tmpData[15] * byData[11]; - m_data[15] = tmpData[3] * byData[12] + - tmpData[7] * byData[13] + - tmpData[11] * byData[14] + - tmpData[15] * byData[15]; + m_data[3] = tmpData[3] * byData[0] + tmpData[7] * byData[1] + tmpData[11] * byData[2] + tmpData[15] * byData[3]; + m_data[7] = tmpData[3] * byData[4] + tmpData[7] * byData[5] + tmpData[11] * byData[6] + tmpData[15] * byData[7]; + m_data[11] = tmpData[3] * byData[8] + tmpData[7] * byData[9] + tmpData[11] * byData[10] + tmpData[15] * byData[11]; + m_data[15] = tmpData[3] * byData[12] + tmpData[7] * byData[13] + tmpData[11] * byData[14] + tmpData[15] * byData[15]; return *this; } @@ -346,9 +213,9 @@ private: }; }; -inline Vector3 operator*(const Matrix4x4 &m, const Vector3 &v) +inline Vector3 operator*(const Matrix4x4& m, const Vector3& v) { - const double *data = m.constData(); + const double* data = m.constData(); return Vector3((v.x() * data[0]) + (v.y() * data[4]) + (v.z() * data[8]), (v.x() * data[1]) + (v.y() * data[5]) + (v.z() * data[9]), (v.x() * data[2]) + (v.y() * data[6]) + (v.z() * data[10])); diff --git a/dust3d/base/object.h b/dust3d/base/object.h index 0b0e4292..bbaca995 100644 --- a/dust3d/base/object.h +++ b/dust3d/base/object.h @@ -23,20 +23,18 @@ #ifndef DUST3D_BASE_OBJECT_H_ #define DUST3D_BASE_OBJECT_H_ -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include -namespace dust3d -{ - -struct ObjectNode -{ +namespace dust3d { + +struct ObjectNode { Uuid partId; Uuid nodeId; Vector3 origin; @@ -53,8 +51,7 @@ struct ObjectNode bool joined = true; }; -class Object -{ +class Object { public: std::vector nodes; std::vector, std::pair>> edges; @@ -66,74 +63,74 @@ public: std::vector triangleColors; bool alphaEnabled = false; uint64_t meshId = 0; - - const std::vector> *triangleSourceNodes() const + + const std::vector>* triangleSourceNodes() const { if (!m_hasTriangleSourceNodes) return nullptr; return &m_triangleSourceNodes; } - void setTriangleSourceNodes(const std::vector> &sourceNodes) + void setTriangleSourceNodes(const std::vector>& sourceNodes) { m_triangleSourceNodes = sourceNodes; m_hasTriangleSourceNodes = true; } - - const std::vector> *triangleVertexUvs() const + + const std::vector>* triangleVertexUvs() const { if (!m_hasTriangleVertexUvs) return nullptr; return &m_triangleVertexUvs; } - void setTriangleVertexUvs(const std::vector> &uvs) + void setTriangleVertexUvs(const std::vector>& uvs) { m_triangleVertexUvs = uvs; m_hasTriangleVertexUvs = true; } - - const std::vector> *triangleVertexNormals() const + + const std::vector>* triangleVertexNormals() const { if (!m_hasTriangleVertexNormals) return nullptr; return &m_triangleVertexNormals; } - void setTriangleVertexNormals(const std::vector> &normals) + void setTriangleVertexNormals(const std::vector>& normals) { m_triangleVertexNormals = normals; m_hasTriangleVertexNormals = true; } - - const std::vector *triangleTangents() const + + const std::vector* triangleTangents() const { if (!m_hasTriangleTangents) return nullptr; return &m_triangleTangents; } - void setTriangleTangents(const std::vector &tangents) + void setTriangleTangents(const std::vector& tangents) { m_triangleTangents = tangents; m_hasTriangleTangents = true; } - - const std::map> *partUvRects() const + + const std::map>* partUvRects() const { if (!m_hasPartUvRects) return nullptr; return &m_partUvRects; } - void setPartUvRects(const std::map> &uvRects) + void setPartUvRects(const std::map>& uvRects) { m_partUvRects = uvRects; m_hasPartUvRects = true; } - - const std::vector, std::pair>> *triangleLinks() const + + const std::vector, std::pair>>* triangleLinks() const { if (!m_hasTriangleLinks) return nullptr; return &m_triangleLinks; } - void setTriangleLinks(const std::vector, std::pair>> &triangleLinks) + void setTriangleLinks(const std::vector, std::pair>>& triangleLinks) { m_triangleLinks = triangleLinks; m_hasTriangleLinks = true; @@ -142,19 +139,19 @@ public: private: bool m_hasTriangleSourceNodes = false; std::vector> m_triangleSourceNodes; - + bool m_hasTriangleVertexUvs = false; std::vector> m_triangleVertexUvs; - + bool m_hasTriangleVertexNormals = false; std::vector> m_triangleVertexNormals; - + bool m_hasTriangleTangents = false; std::vector m_triangleTangents; - + bool m_hasPartUvRects = false; std::map> m_partUvRects; - + bool m_hasTriangleLinks = false; std::vector, std::pair>> m_triangleLinks; }; diff --git a/dust3d/base/part_base.cc b/dust3d/base/part_base.cc index 24b707ef..e5318685 100644 --- a/dust3d/base/part_base.cc +++ b/dust3d/base/part_base.cc @@ -22,11 +22,10 @@ #include -namespace dust3d -{ - +namespace dust3d { + IMPL_PartBaseFromString -IMPL_PartBaseToString -IMPL_PartBaseToDispName + IMPL_PartBaseToString + IMPL_PartBaseToDispName } diff --git a/dust3d/base/part_base.h b/dust3d/base/part_base.h index 78eb7b05..d6b7626d 100644 --- a/dust3d/base/part_base.h +++ b/dust3d/base/part_base.h @@ -25,11 +25,9 @@ #include -namespace dust3d -{ +namespace dust3d { -enum class PartBase -{ +enum class PartBase { XYZ = 0, Average, YZ, @@ -37,61 +35,61 @@ enum class PartBase ZX, Count }; -PartBase PartBaseFromString(const char *baseString); -#define IMPL_PartBaseFromString \ -PartBase PartBaseFromString(const char *baseString) \ -{ \ - std::string base = baseString; \ - if (base == "XYZ") \ - return PartBase::XYZ; \ - if (base == "Average") \ - return PartBase::Average; \ - if (base == "YZ") \ - return PartBase::YZ; \ - if (base == "XY") \ - return PartBase::XY; \ - if (base == "ZX") \ - return PartBase::ZX; \ - return PartBase::XYZ; \ -} -const char *PartBaseToString(PartBase base); -#define IMPL_PartBaseToString \ -const char *PartBaseToString(PartBase base) \ -{ \ - switch (base) { \ - case PartBase::XYZ: \ - return "XYZ"; \ - case PartBase::Average: \ - return "Average"; \ - case PartBase::YZ: \ - return "YZ"; \ - case PartBase::XY: \ - return "XY"; \ - case PartBase::ZX: \ - return "ZX"; \ - default: \ - return "XYZ"; \ - } \ -} +PartBase PartBaseFromString(const char* baseString); +#define IMPL_PartBaseFromString \ + PartBase PartBaseFromString(const char* baseString) \ + { \ + std::string base = baseString; \ + if (base == "XYZ") \ + return PartBase::XYZ; \ + if (base == "Average") \ + return PartBase::Average; \ + if (base == "YZ") \ + return PartBase::YZ; \ + if (base == "XY") \ + return PartBase::XY; \ + if (base == "ZX") \ + return PartBase::ZX; \ + return PartBase::XYZ; \ + } +const char* PartBaseToString(PartBase base); +#define IMPL_PartBaseToString \ + const char* PartBaseToString(PartBase base) \ + { \ + switch (base) { \ + case PartBase::XYZ: \ + return "XYZ"; \ + case PartBase::Average: \ + return "Average"; \ + case PartBase::YZ: \ + return "YZ"; \ + case PartBase::XY: \ + return "XY"; \ + case PartBase::ZX: \ + return "ZX"; \ + default: \ + return "XYZ"; \ + } \ + } std::string PartBaseToDispName(PartBase base); -#define IMPL_PartBaseToDispName \ -std::string PartBaseToDispName(PartBase base) \ -{ \ - switch (base) { \ - case PartBase::XYZ: \ - return std::string("Dynamic"); \ - case PartBase::Average: \ - return std::string("Average"); \ - case PartBase::YZ: \ - return std::string("Side Plane"); \ - case PartBase::XY: \ - return std::string("Front Plane"); \ - case PartBase::ZX: \ - return std::string("Top Plane"); \ - default: \ - return std::string("Dynamic"); \ - } \ -} +#define IMPL_PartBaseToDispName \ + std::string PartBaseToDispName(PartBase base) \ + { \ + switch (base) { \ + case PartBase::XYZ: \ + return std::string("Dynamic"); \ + case PartBase::Average: \ + return std::string("Average"); \ + case PartBase::YZ: \ + return std::string("Side Plane"); \ + case PartBase::XY: \ + return std::string("Front Plane"); \ + case PartBase::ZX: \ + return std::string("Top Plane"); \ + default: \ + return std::string("Dynamic"); \ + } \ + } } diff --git a/dust3d/base/part_target.cc b/dust3d/base/part_target.cc index 2b255627..32c02266 100644 --- a/dust3d/base/part_target.cc +++ b/dust3d/base/part_target.cc @@ -22,12 +22,10 @@ #include -namespace dust3d -{ - +namespace dust3d { + IMPL_PartTargetFromString -IMPL_PartTargetToString -IMPL_PartTargetToDispName + IMPL_PartTargetToString + IMPL_PartTargetToDispName } - diff --git a/dust3d/base/part_target.h b/dust3d/base/part_target.h index 22ca4fe9..e81435e3 100644 --- a/dust3d/base/part_target.h +++ b/dust3d/base/part_target.h @@ -25,59 +25,57 @@ #include -namespace dust3d -{ +namespace dust3d { -enum class PartTarget -{ +enum class PartTarget { Model = 0, CutFace, Count, // FIXME: Enable StitchingLine after the UI is avaliable StitchingLine }; -PartTarget PartTargetFromString(const char *targetString); -#define IMPL_PartTargetFromString \ -PartTarget PartTargetFromString(const char *targetString) \ -{ \ - std::string target = targetString; \ - if (target == "Model") \ - return PartTarget::Model; \ - if (target == "CutFace") \ - return PartTarget::CutFace; \ - if (target == "StitchingLine") \ - return PartTarget::StitchingLine; \ - return PartTarget::Model; \ -} -const char *PartTargetToString(PartTarget target); -#define IMPL_PartTargetToString \ -const char *PartTargetToString(PartTarget target) \ -{ \ - switch (target) { \ - case PartTarget::Model: \ - return "Model"; \ - case PartTarget::CutFace: \ - return "CutFace"; \ - case PartTarget::StitchingLine: \ - return "StitchingLine"; \ - default: \ - return "Model"; \ - } \ -} +PartTarget PartTargetFromString(const char* targetString); +#define IMPL_PartTargetFromString \ + PartTarget PartTargetFromString(const char* targetString) \ + { \ + std::string target = targetString; \ + if (target == "Model") \ + return PartTarget::Model; \ + if (target == "CutFace") \ + return PartTarget::CutFace; \ + if (target == "StitchingLine") \ + return PartTarget::StitchingLine; \ + return PartTarget::Model; \ + } +const char* PartTargetToString(PartTarget target); +#define IMPL_PartTargetToString \ + const char* PartTargetToString(PartTarget target) \ + { \ + switch (target) { \ + case PartTarget::Model: \ + return "Model"; \ + case PartTarget::CutFace: \ + return "CutFace"; \ + case PartTarget::StitchingLine: \ + return "StitchingLine"; \ + default: \ + return "Model"; \ + } \ + } std::string PartTargetToDispName(PartTarget target); -#define IMPL_PartTargetToDispName \ -std::string PartTargetToDispName(PartTarget target) \ -{ \ - switch (target) { \ - case PartTarget::Model: \ - return std::string("Model"); \ - case PartTarget::CutFace: \ - return std::string("Cut Face"); \ - case PartTarget::StitchingLine: \ - return std::string("Stitching Line"); \ - default: \ - return std::string("Model"); \ - } \ -} +#define IMPL_PartTargetToDispName \ + std::string PartTargetToDispName(PartTarget target) \ + { \ + switch (target) { \ + case PartTarget::Model: \ + return std::string("Model"); \ + case PartTarget::CutFace: \ + return std::string("Cut Face"); \ + case PartTarget::StitchingLine: \ + return std::string("Stitching Line"); \ + default: \ + return std::string("Model"); \ + } \ + } } diff --git a/dust3d/base/position_key.cc b/dust3d/base/position_key.cc index 474a86a6..ae1fc38e 100644 --- a/dust3d/base/position_key.cc +++ b/dust3d/base/position_key.cc @@ -19,16 +19,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #include -namespace dust3d -{ +namespace dust3d { long PositionKey::m_toIntFactor = 100000; -PositionKey::PositionKey(const Vector3 &v) : - PositionKey(v.x(), v.y(), v.z()) +PositionKey::PositionKey(const Vector3& v) + : PositionKey(v.x(), v.y(), v.z()) { } @@ -39,7 +38,7 @@ PositionKey::PositionKey(double x, double y, double z) m_intZ = (long)(z * m_toIntFactor); } -bool PositionKey::operator<(const PositionKey &right) const +bool PositionKey::operator<(const PositionKey& right) const { if (m_intX < right.m_intX) return true; @@ -56,11 +55,9 @@ bool PositionKey::operator<(const PositionKey &right) const return false; } -bool PositionKey::operator==(const PositionKey &right) const +bool PositionKey::operator==(const PositionKey& right) const { - return m_intX == right.m_intX && - m_intY == right.m_intY && - m_intZ == right.m_intZ; + return m_intX == right.m_intX && m_intY == right.m_intY && m_intZ == right.m_intZ; } } diff --git a/dust3d/base/position_key.h b/dust3d/base/position_key.h index 61f449f3..53061fd7 100644 --- a/dust3d/base/position_key.h +++ b/dust3d/base/position_key.h @@ -19,22 +19,20 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_POSITION_KEY_H_ #define DUST3D_BASE_POSITION_KEY_H_ #include -namespace dust3d -{ +namespace dust3d { -class PositionKey -{ +class PositionKey { public: - PositionKey(const Vector3 &v); + PositionKey(const Vector3& v); PositionKey(double x, double y, double z); - bool operator<(const PositionKey &right) const; - bool operator==(const PositionKey &right) const; + bool operator<(const PositionKey& right) const; + bool operator==(const PositionKey& right) const; private: long m_intX; diff --git a/dust3d/base/quaternion.h b/dust3d/base/quaternion.h index 30c5e68d..64f584ad 100644 --- a/dust3d/base/quaternion.h +++ b/dust3d/base/quaternion.h @@ -25,53 +25,51 @@ #include -namespace dust3d -{ - +namespace dust3d { + class Quaternion; -inline Quaternion operator*(const Quaternion &q, const double &number); -inline Quaternion operator*(const double &number, const Quaternion &q); -inline Quaternion operator+(const Quaternion &q, const Quaternion &p); -inline Quaternion operator/(const Quaternion &q, const double &number); -inline Quaternion operator/(const double &number, const Quaternion &q); +inline Quaternion operator*(const Quaternion& q, const double& number); +inline Quaternion operator*(const double& number, const Quaternion& q); +inline Quaternion operator+(const Quaternion& q, const Quaternion& p); +inline Quaternion operator/(const Quaternion& q, const double& number); +inline Quaternion operator/(const double& number, const Quaternion& q); -class Quaternion -{ +class Quaternion { public: inline Quaternion() = default; - - inline Quaternion(double w, double x, double y, double z) : - m_data {w, x, y, z} - { - } - - inline Quaternion(const Quaternion &q) : - m_data {q.w(), q.x(), q.y(), q.z()} + + inline Quaternion(double w, double x, double y, double z) + : m_data { w, x, y, z } { } - inline const double &x() const + inline Quaternion(const Quaternion& q) + : m_data { q.w(), q.x(), q.y(), q.z() } + { + } + + inline const double& x() const { return m_data[1]; } - - inline const double &y() const + + inline const double& y() const { return m_data[2]; } - - inline const double &z() const + + inline const double& z() const { return m_data[3]; } - - inline const double &w() const + + inline const double& w() const { return m_data[0]; } - - inline Quaternion &operator*=(const double &number) + + inline Quaternion& operator*=(const double& number) { m_data[0] *= number; m_data[1] *= number; @@ -80,41 +78,40 @@ public: return *this; } - inline static Quaternion slerp(const Quaternion &a, const Quaternion &b, double t) + inline static Quaternion slerp(const Quaternion& a, const Quaternion& b, double t) { if (t <= 0.0) return a; - + if (t >= 1.0) return b; - + double dot = a.w() * b.w() + a.x() * b.x() * a.y() * b.y() + a.z() * b.z(); Quaternion to(b); if (dot < 0.0) { dot *= -1.0; to *= -1.0; } - + double angle = std::acos(dot); double sine = std::sin(angle); if (Math::isZero(sine)) { return a * (1.0 - t) + b * t; } - - return (((Quaternion)(a * std::sin(angle * (1.0f - t)))) + - ((Quaternion)(to * std::sin(angle * t)))) / sine; + + return (((Quaternion)(a * std::sin(angle * (1.0f - t)))) + ((Quaternion)(to * std::sin(angle * t)))) / sine; } - - inline static Quaternion fromAxisAndAngle(const Vector3 &axis, double angle) + + inline static Quaternion fromAxisAndAngle(const Vector3& axis, double angle) { Vector3 axisNormalized = axis.normalized(); double halfAngle = angle * 0.5; double sine = std::sin(halfAngle); - return Quaternion(std::cos(halfAngle), + return Quaternion(std::cos(halfAngle), axisNormalized.x() * sine, axisNormalized.y() * sine, axisNormalized.z() * sine); } - - inline static Quaternion rotationTo(const Vector3 &from, const Vector3 &to) + + inline static Quaternion rotationTo(const Vector3& from, const Vector3& to) { Vector3 a = from.normalized(); Vector3 b = to.normalized(); @@ -129,41 +126,42 @@ public: Vector3 v = Vector3::crossProduct(a, b) / d; return Quaternion(d * 0.5, v.x(), v.y(), v.z()).normalized(); } - + inline Quaternion normalized() const { double length2 = x() * x() + y() * y() + z() * z() + w() * w(); double length = std::sqrt(length2); if (Math::isZero(length)) return Quaternion(); - + return Quaternion(w() / length, x() / length, y() / length, z() / length); } + private: - double m_data[4] = {0.0}; + double m_data[4] = { 0.0 }; }; -inline Quaternion operator*(const Quaternion &q, const double &number) +inline Quaternion operator*(const Quaternion& q, const double& number) { return Quaternion(q.w() * number, q.x() * number, q.y() * number, q.z() * number); } -inline Quaternion operator*(const double &number, const Quaternion &q) +inline Quaternion operator*(const double& number, const Quaternion& q) { return Quaternion(q.w() * number, q.x() * number, q.y() * number, q.z() * number); } -inline Quaternion operator+(const Quaternion &q, const Quaternion &p) +inline Quaternion operator+(const Quaternion& q, const Quaternion& p) { return Quaternion(p.w() + q.w(), p.x() + q.x(), p.y() + q.y(), p.z() + q.z()); } -inline Quaternion operator/(const Quaternion &q, const double &number) +inline Quaternion operator/(const Quaternion& q, const double& number) { return Quaternion(q.w() / number, q.x() / number, q.y() / number, q.z() / number); } -inline Quaternion operator/(const double &number, const Quaternion &q) +inline Quaternion operator/(const double& number, const Quaternion& q) { return Quaternion(q.w() / number, q.x() / number, q.y() / number, q.z() / number); } diff --git a/dust3d/base/rectangle.h b/dust3d/base/rectangle.h index 4351b454..b29b2ebc 100644 --- a/dust3d/base/rectangle.h +++ b/dust3d/base/rectangle.h @@ -23,108 +23,105 @@ #ifndef DUST3D_BASE_RECTANGLE_H_ #define DUST3D_BASE_RECTANGLE_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -class Rectangle -{ +class Rectangle { public: - inline Rectangle() : - m_data {0.0, 0.0, 0.0, 0.0} + inline Rectangle() + : m_data { 0.0, 0.0, 0.0, 0.0 } { } - - inline Rectangle(double x, double y, double width, double height) : - m_data {x, y, width, height} + + inline Rectangle(double x, double y, double width, double height) + : m_data { x, y, width, height } { } - - inline double &operator[](size_t index) + + inline double& operator[](size_t index) { return m_data[index]; } - - inline const double &operator[](size_t index) const + + inline const double& operator[](size_t index) const { return m_data[index]; } - - inline const double &x() const + + inline const double& x() const { return m_data[0]; } - - inline const double &y() const + + inline const double& y() const { return m_data[1]; } - - inline const double &left() const + + inline const double& left() const { return m_data[0]; } - + inline double right() const { return left() + width(); } - - inline const double &top() const + + inline const double& top() const { return m_data[1]; } - + inline double bottom() const { return top() + height(); } - - inline const double &width() const + + inline const double& width() const { return m_data[2]; } - - inline const double &height() const + + inline const double& height() const { return m_data[3]; } - - inline Rectangle intersected(const Rectangle &other) const + + inline Rectangle intersected(const Rectangle& other) const { - const auto &rectangle1 = *this; - const auto &rectangle2 = other; - + const auto& rectangle1 = *this; + const auto& rectangle2 = other; + if (rectangle2.left() >= rectangle1.right()) return Rectangle(); - + if (rectangle2.right() <= rectangle1.left()) return Rectangle(); if (rectangle2.top() >= rectangle1.bottom()) return Rectangle(); - + if (rectangle2.bottom() <= rectangle1.top()) return Rectangle(); - + double left = std::max(rectangle1.left(), rectangle2.left()); double width = std::min(rectangle1.right(), rectangle2.right()) - left; double top = std::max(rectangle1.top(), rectangle2.top()); double height = std::min(rectangle1.bottom(), rectangle2.bottom()) - top; - + return Rectangle(left, top, width, height); } - + inline bool contains(double x, double y) const { - return (x >= left() && x < right()) && - (y >= top() && y < bottom()); + return (x >= left() && x < right()) && (y >= top() && y < bottom()); } - + private: - double m_data[4] = {0.0, 0.0, 0.0, 0.0}; + double m_data[4] = { 0.0, 0.0, 0.0, 0.0 }; }; } diff --git a/dust3d/base/snapshot.h b/dust3d/base/snapshot.h index bdb4dbcc..2eac5709 100644 --- a/dust3d/base/snapshot.h +++ b/dust3d/base/snapshot.h @@ -23,14 +23,12 @@ #ifndef DUST3D_BASE_SNAPSHOT_H_ #define DUST3D_BASE_SNAPSHOT_H_ -#include #include +#include -namespace dust3d -{ - -class Snapshot -{ +namespace dust3d { + +class Snapshot { public: std::map canvas; std::map> nodes; @@ -40,7 +38,7 @@ public: std::map rootComponent; std::vector, std::vector, std::vector>>>>> materials; // std::pair layer: std::pair }; - + } #endif diff --git a/dust3d/base/snapshot_xml.cc b/dust3d/base/snapshot_xml.cc index 9f831f1b..d118ab8d 100644 --- a/dust3d/base/snapshot_xml.cc +++ b/dust3d/base/snapshot_xml.cc @@ -20,28 +20,27 @@ * SOFTWARE. */ -#include -#include -#include #include +#include #include #include -#include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { -static std::string loadComponentReturnChildrenList(Snapshot *snapshot, rapidxml::xml_node<> *parentNode) +static std::string loadComponentReturnChildrenList(Snapshot* snapshot, rapidxml::xml_node<>* parentNode) { std::vector children; - for (rapidxml::xml_node<> *node = parentNode->first_node(); nullptr != node; node = node->next_sibling()) { - rapidxml::xml_attribute<> *idAttribute = node->first_attribute("id"); + for (rapidxml::xml_node<>* node = parentNode->first_node(); nullptr != node; node = node->next_sibling()) { + rapidxml::xml_attribute<>* idAttribute = node->first_attribute("id"); if (nullptr != idAttribute) { std::string componentIdString = idAttribute->value(); children.push_back(componentIdString); - std::map *componentMap = &snapshot->components[componentIdString]; - for (rapidxml::xml_attribute<> *attribute = node->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + std::map* componentMap = &snapshot->components[componentIdString]; + for (rapidxml::xml_attribute<>* attribute = node->first_attribute(); + attribute; attribute = attribute->next_attribute()) { (*componentMap)[attribute->name()] = attribute->value(); } snapshot->components[componentIdString]["children"] = loadComponentReturnChildrenList(snapshot, node); @@ -50,28 +49,28 @@ static std::string loadComponentReturnChildrenList(Snapshot *snapshot, rapidxml: return String::join(children, ","); } -void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t flags) +void loadSnapshotFromXmlString(Snapshot* snapshot, char* xmlString, uint32_t flags) { try { rapidxml::xml_document<> xml; xml.parse<0>(xmlString); - rapidxml::xml_node<> *canvas = xml.first_node("canvas"); + rapidxml::xml_node<>* canvas = xml.first_node("canvas"); if (nullptr != canvas) { if (flags & kSnapshotItemCanvas) { - for (rapidxml::xml_attribute<> *attribute = canvas->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + for (rapidxml::xml_attribute<>* attribute = canvas->first_attribute(); + attribute; attribute = attribute->next_attribute()) { snapshot->canvas[attribute->name()] = attribute->value(); } } if (flags & kSnapshotItemComponent) { - rapidxml::xml_node<> *nodes = canvas->first_node("nodes"); + rapidxml::xml_node<>* nodes = canvas->first_node("nodes"); if (nullptr != nodes) { - for (rapidxml::xml_node<> *node = nodes->first_node(); nullptr != node; node = node->next_sibling()) { - rapidxml::xml_attribute<> *idAttribute = node->first_attribute("id"); + for (rapidxml::xml_node<>* node = nodes->first_node(); nullptr != node; node = node->next_sibling()) { + rapidxml::xml_attribute<>* idAttribute = node->first_attribute("id"); if (nullptr != idAttribute) { - std::map *nodeMap = &snapshot->nodes[idAttribute->value()]; - for (rapidxml::xml_attribute<> *attribute = node->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + std::map* nodeMap = &snapshot->nodes[idAttribute->value()]; + for (rapidxml::xml_attribute<>* attribute = node->first_attribute(); + attribute; attribute = attribute->next_attribute()) { (*nodeMap)[attribute->name()] = attribute->value(); } } @@ -79,14 +78,14 @@ void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t fla } } if (flags & kSnapshotItemComponent) { - rapidxml::xml_node<> *edges = canvas->first_node("edges"); + rapidxml::xml_node<>* edges = canvas->first_node("edges"); if (nullptr != edges) { - for (rapidxml::xml_node<> *node = edges->first_node(); nullptr != node; node = node->next_sibling()) { - rapidxml::xml_attribute<> *idAttribute = node->first_attribute("id"); + for (rapidxml::xml_node<>* node = edges->first_node(); nullptr != node; node = node->next_sibling()) { + rapidxml::xml_attribute<>* idAttribute = node->first_attribute("id"); if (nullptr != idAttribute) { - std::map *edgeMap = &snapshot->edges[idAttribute->value()]; - for (rapidxml::xml_attribute<> *attribute = node->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + std::map* edgeMap = &snapshot->edges[idAttribute->value()]; + for (rapidxml::xml_attribute<>* attribute = node->first_attribute(); + attribute; attribute = attribute->next_attribute()) { (*edgeMap)[attribute->name()] = attribute->value(); } } @@ -94,14 +93,14 @@ void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t fla } } if (flags & kSnapshotItemComponent) { - rapidxml::xml_node<> *parts = canvas->first_node("parts"); + rapidxml::xml_node<>* parts = canvas->first_node("parts"); if (nullptr != parts) { - for (rapidxml::xml_node<> *node = parts->first_node(); nullptr != node; node = node->next_sibling()) { - rapidxml::xml_attribute<> *idAttribute = node->first_attribute("id"); + for (rapidxml::xml_node<>* node = parts->first_node(); nullptr != node; node = node->next_sibling()) { + rapidxml::xml_attribute<>* idAttribute = node->first_attribute("id"); if (nullptr != idAttribute) { - std::map *partMap = &snapshot->parts[idAttribute->value()]; - for (rapidxml::xml_attribute<> *attribute = node->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + std::map* partMap = &snapshot->parts[idAttribute->value()]; + for (rapidxml::xml_attribute<>* attribute = node->first_attribute(); + attribute; attribute = attribute->next_attribute()) { (*partMap)[attribute->name()] = attribute->value(); } } @@ -109,17 +108,17 @@ void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t fla } } if (flags & kSnapshotItemComponent) { - rapidxml::xml_node<> *partIdList = canvas->first_node("partIdList"); + rapidxml::xml_node<>* partIdList = canvas->first_node("partIdList"); if (nullptr != partIdList) { - for (rapidxml::xml_node<> *partId = partIdList->first_node(); nullptr != partId; partId = partId->next_sibling()) { - rapidxml::xml_attribute<> *idAttribute = partId->first_attribute("id"); + for (rapidxml::xml_node<>* partId = partIdList->first_node(); nullptr != partId; partId = partId->next_sibling()) { + rapidxml::xml_attribute<>* idAttribute = partId->first_attribute("id"); if (nullptr != idAttribute) { std::string componentId = to_string(Uuid::createUuid()); - auto &component = snapshot->components[componentId]; + auto& component = snapshot->components[componentId]; component["id"] = componentId; component["linkData"] = idAttribute->value(); component["linkDataType"] = "partId"; - auto &childrenIds = snapshot->rootComponent["children"]; + auto& childrenIds = snapshot->rootComponent["children"]; if (!childrenIds.empty()) childrenIds += ","; childrenIds += componentId; @@ -128,35 +127,35 @@ void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t fla } } if (flags & kSnapshotItemComponent) { - rapidxml::xml_node<> *components = canvas->first_node("components"); + rapidxml::xml_node<>* components = canvas->first_node("components"); if (nullptr != components) { snapshot->rootComponent["children"] = loadComponentReturnChildrenList(snapshot, components); } } if (flags & kSnapshotItemMaterial) { - rapidxml::xml_node<> *materials = canvas->first_node("materials"); + rapidxml::xml_node<>* materials = canvas->first_node("materials"); if (nullptr != materials) { - for (rapidxml::xml_node<> *material = materials->first_node(); nullptr != material; material = material->next_sibling()) { + for (rapidxml::xml_node<>* material = materials->first_node(); nullptr != material; material = material->next_sibling()) { std::pair, std::vector, std::vector>>>> currentMaterial; - for (rapidxml::xml_attribute<> *attribute = material->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + for (rapidxml::xml_attribute<>* attribute = material->first_attribute(); + attribute; attribute = attribute->next_attribute()) { currentMaterial.first[attribute->name()] = attribute->value(); } - rapidxml::xml_node<> *materialLayers = material->first_node("layers"); + rapidxml::xml_node<>* materialLayers = material->first_node("layers"); if (nullptr != materialLayers) { - rapidxml::xml_node<> *layer = materialLayers->first_node("layer"); + rapidxml::xml_node<>* layer = materialLayers->first_node("layer"); if (nullptr != layer) { std::pair, std::vector>> currentMaterialLayer; - for (rapidxml::xml_attribute<> *attribute = layer->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + for (rapidxml::xml_attribute<>* attribute = layer->first_attribute(); + attribute; attribute = attribute->next_attribute()) { currentMaterialLayer.first[attribute->name()] = attribute->value(); } - rapidxml::xml_node<> *layerMaps = layer->first_node("maps"); + rapidxml::xml_node<>* layerMaps = layer->first_node("maps"); if (nullptr != layerMaps) { - for (rapidxml::xml_node<> *mapPerLayer = layerMaps->first_node(); nullptr != mapPerLayer; mapPerLayer = mapPerLayer->next_sibling()) { + for (rapidxml::xml_node<>* mapPerLayer = layerMaps->first_node(); nullptr != mapPerLayer; mapPerLayer = mapPerLayer->next_sibling()) { std::map mapAttributes; - for (rapidxml::xml_attribute<> *attribute = mapPerLayer->first_attribute(); - attribute; attribute = attribute->next_attribute()) { + for (rapidxml::xml_attribute<>* attribute = mapPerLayer->first_attribute(); + attribute; attribute = attribute->next_attribute()) { mapAttributes[attribute->name()] = attribute->value(); } currentMaterialLayer.second.push_back(mapAttributes); @@ -170,23 +169,23 @@ void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, uint32_t fla } } } - } catch (const std::runtime_error &e) { + } catch (const std::runtime_error& e) { dust3dDebug << "Runtime error was: " << e.what(); - } catch (const rapidxml::parse_error &e) { + } catch (const rapidxml::parse_error& e) { dust3dDebug << "Parse error was: " << e.what(); - } catch (const std::exception &e) { + } catch (const std::exception& e) { dust3dDebug << "Error was: " << e.what(); } catch (...) { dust3dDebug << "An unknown error occurred."; } } -static void saveSnapshotComponent(const Snapshot &snapshot, std::string &xmlString, const std::string &componentId, int depth) +static void saveSnapshotComponent(const Snapshot& snapshot, std::string& xmlString, const std::string& componentId, int depth) { const auto findComponent = snapshot.components.find(componentId); if (findComponent == snapshot.components.end()) return; - auto &component = findComponent->second; + auto& component = findComponent->second; std::string prefix(depth, ' '); xmlString += prefix; xmlString += " \n"; - + xmlString += "::const_iterator canvasIterator; - for (canvasIterator = snapshot.canvas.begin(); canvasIterator != snapshot.canvas.end(); canvasIterator++) { - xmlString += " " + canvasIterator->first + "=\"" + canvasIterator->second + "\""; + std::map::const_iterator canvasIterator; + for (canvasIterator = snapshot.canvas.begin(); canvasIterator != snapshot.canvas.end(); canvasIterator++) { + xmlString += " " + canvasIterator->first + "=\"" + canvasIterator->second + "\""; + } + xmlString += ">\n"; + + xmlString += " \n"; + std::map>::const_iterator nodeIterator; + for (nodeIterator = snapshot.nodes.begin(); nodeIterator != snapshot.nodes.end(); nodeIterator++) { + std::map::const_iterator nodeAttributeIterator; + xmlString += " second.begin(); nodeAttributeIterator != nodeIterator->second.end(); nodeAttributeIterator++) { + xmlString += " " + nodeAttributeIterator->first + "=\"" + nodeAttributeIterator->second + "\""; + } + xmlString += "/>\n"; + } + xmlString += " \n"; + + xmlString += " \n"; + std::map>::const_iterator edgeIterator; + for (edgeIterator = snapshot.edges.begin(); edgeIterator != snapshot.edges.end(); edgeIterator++) { + std::map::const_iterator edgeAttributeIterator; + xmlString += " second.begin(); edgeAttributeIterator != edgeIterator->second.end(); edgeAttributeIterator++) { + xmlString += " " + edgeAttributeIterator->first + "=\"" + edgeAttributeIterator->second + "\""; + } + xmlString += "/>\n"; + } + xmlString += " \n"; + + xmlString += " \n"; + std::map>::const_iterator partIterator; + for (partIterator = snapshot.parts.begin(); partIterator != snapshot.parts.end(); partIterator++) { + std::map::const_iterator partAttributeIterator; + xmlString += " second.begin(); partAttributeIterator != partIterator->second.end(); partAttributeIterator++) { + if (String::startsWith(partAttributeIterator->first, "__")) + continue; + xmlString += " " + partAttributeIterator->first + "=\"" + partAttributeIterator->second + "\""; + } + xmlString += "/>\n"; + } + xmlString += " \n"; + + const auto& childrenIds = snapshot.rootComponent.find("children"); + if (childrenIds != snapshot.rootComponent.end()) { + xmlString += " \n"; + for (const auto& componentId : String::split(childrenIds->second, ',')) { + if (componentId.empty()) + continue; + saveSnapshotComponent(snapshot, xmlString, componentId, 0); + } + xmlString += " \n"; + } + + xmlString += " \n"; + std::vector, std::vector, std::vector>>>>>::const_iterator materialIterator; + for (materialIterator = snapshot.materials.begin(); materialIterator != snapshot.materials.end(); materialIterator++) { + std::map::const_iterator materialAttributeIterator; + xmlString += " first.begin(); materialAttributeIterator != materialIterator->first.end(); materialAttributeIterator++) { + xmlString += " " + materialAttributeIterator->first + "=\"" + materialAttributeIterator->second + "\""; } xmlString += ">\n"; + xmlString += " \n"; + std::vector, std::vector>>>::const_iterator layerIterator; + for (layerIterator = materialIterator->second.begin(); layerIterator != materialIterator->second.end(); layerIterator++) { + std::map::const_iterator layerAttributeIterator; + xmlString += " first.begin(); layerAttributeIterator != layerIterator->first.end(); layerAttributeIterator++) { + xmlString += " " + layerAttributeIterator->first + "=\"" + layerAttributeIterator->second + "\""; + } + xmlString += ">\n"; + xmlString += " \n"; + std::vector>::const_iterator mapIterator; + for (mapIterator = layerIterator->second.begin(); mapIterator != layerIterator->second.end(); mapIterator++) { + std::map::const_iterator attributesIterator; + xmlString += " begin(); attributesIterator != mapIterator->end(); + attributesIterator++) { + xmlString += " " + attributesIterator->first + "=\"" + attributesIterator->second + "\""; + } + xmlString += "/>\n"; + } + xmlString += " \n"; + xmlString += " \n"; + } + xmlString += " \n"; + xmlString += " \n"; + } + xmlString += " \n"; - xmlString += " \n"; - std::map>::const_iterator nodeIterator; - for (nodeIterator = snapshot.nodes.begin(); nodeIterator != snapshot.nodes.end(); nodeIterator++) { - std::map::const_iterator nodeAttributeIterator; - xmlString += " second.begin(); nodeAttributeIterator != nodeIterator->second.end(); nodeAttributeIterator++) { - xmlString += " " + nodeAttributeIterator->first + "=\"" + nodeAttributeIterator->second + "\""; - } - xmlString += "/>\n"; - } - xmlString += " \n"; - - xmlString += " \n"; - std::map>::const_iterator edgeIterator; - for (edgeIterator = snapshot.edges.begin(); edgeIterator != snapshot.edges.end(); edgeIterator++) { - std::map::const_iterator edgeAttributeIterator; - xmlString += " second.begin(); edgeAttributeIterator != edgeIterator->second.end(); edgeAttributeIterator++) { - xmlString += " " + edgeAttributeIterator->first + "=\"" + edgeAttributeIterator->second + "\""; - } - xmlString += "/>\n"; - } - xmlString += " \n"; - - xmlString += " \n"; - std::map>::const_iterator partIterator; - for (partIterator = snapshot.parts.begin(); partIterator != snapshot.parts.end(); partIterator++) { - std::map::const_iterator partAttributeIterator; - xmlString += " second.begin(); partAttributeIterator != partIterator->second.end(); partAttributeIterator++) { - if (String::startsWith(partAttributeIterator->first, "__")) - continue; - xmlString += " " + partAttributeIterator->first + "=\"" + partAttributeIterator->second + "\""; - } - xmlString += "/>\n"; - } - xmlString += " \n"; - - const auto &childrenIds = snapshot.rootComponent.find("children"); - if (childrenIds != snapshot.rootComponent.end()) { - xmlString += " \n"; - for (const auto &componentId: String::split(childrenIds->second, ',')) { - if (componentId.empty()) - continue; - saveSnapshotComponent(snapshot, xmlString, componentId, 0); - } - xmlString += " \n"; - } - - xmlString += " \n"; - std::vector, std::vector, std::vector>>>>>::const_iterator materialIterator; - for (materialIterator = snapshot.materials.begin(); materialIterator != snapshot.materials.end(); materialIterator++) { - std::map::const_iterator materialAttributeIterator; - xmlString += " first.begin(); materialAttributeIterator != materialIterator->first.end(); materialAttributeIterator++) { - xmlString += " " + materialAttributeIterator->first + "=\"" + materialAttributeIterator->second + "\""; - } - xmlString += ">\n"; - xmlString += " \n"; - std::vector, std::vector>>>::const_iterator layerIterator; - for (layerIterator = materialIterator->second.begin(); layerIterator != materialIterator->second.end(); layerIterator++) { - std::map::const_iterator layerAttributeIterator; - xmlString += " first.begin(); layerAttributeIterator != layerIterator->first.end(); layerAttributeIterator++) { - xmlString += " " + layerAttributeIterator->first + "=\"" + layerAttributeIterator->second + "\""; - } - xmlString += ">\n"; - xmlString += " \n"; - std::vector>::const_iterator mapIterator; - for (mapIterator = layerIterator->second.begin(); mapIterator != layerIterator->second.end(); mapIterator++) { - std::map::const_iterator attributesIterator; - xmlString += " begin(); attributesIterator != mapIterator->end(); - attributesIterator++) { - xmlString += " " + attributesIterator->first + "=\"" + attributesIterator->second + "\""; - } - xmlString += "/>\n"; - } - xmlString += " \n"; - xmlString += " \n"; - } - xmlString += " \n"; - xmlString += "
\n"; - } - xmlString += " \n"; - xmlString += "\n"; } diff --git a/dust3d/base/snapshot_xml.h b/dust3d/base/snapshot_xml.h index 5ece5362..2b220b4a 100644 --- a/dust3d/base/snapshot_xml.h +++ b/dust3d/base/snapshot_xml.h @@ -23,27 +23,22 @@ #ifndef DUST3D_BASE_SNAPSHOT_XML_H_ #define DUST3D_BASE_SNAPSHOT_XML_H_ -#include #include +#include -namespace dust3d -{ - -#define kSnapshotItemCanvas 0x00000001 -#define kSnapshotItemComponent 0x00000002 -#define kSnapshotItemMaterial 0x00000004 -#define kSnapshotItemMotion 0x00000008 -#define kSnapshotItemAll ( \ - kSnapshotItemCanvas | \ - kSnapshotItemComponent | \ - kSnapshotItemMaterial | \ - kSnapshotItemMotion \ - ) +namespace dust3d { + +#define kSnapshotItemCanvas 0x00000001 +#define kSnapshotItemComponent 0x00000002 +#define kSnapshotItemMaterial 0x00000004 +#define kSnapshotItemMotion 0x00000008 +#define kSnapshotItemAll ( \ + kSnapshotItemCanvas | kSnapshotItemComponent | kSnapshotItemMaterial | kSnapshotItemMotion) + +void loadSnapshotFromXmlString(Snapshot* snapshot, char* xmlString, + uint32_t flags = kSnapshotItemAll); +void saveSnapshotToXmlString(const Snapshot& snapshot, std::string& xmlString); -void loadSnapshotFromXmlString(Snapshot *snapshot, char *xmlString, - uint32_t flags=kSnapshotItemAll); -void saveSnapshotToXmlString(const Snapshot &snapshot, std::string &xmlString); - } #endif diff --git a/dust3d/base/string.cc b/dust3d/base/string.cc index 5c9c6fcb..777c00f6 100644 --- a/dust3d/base/string.cc +++ b/dust3d/base/string.cc @@ -20,21 +20,19 @@ * SOFTWARE. */ -#include #include +#include -namespace dust3d -{ -namespace String -{ - -std::string join(const std::vector &stringList, const char *separator) -{ - return std::accumulate(stringList.begin(), stringList.end(), std::string(), - [=](const std::string &a, const std::string &b) -> std::string { - return a + (a.length() > 0 ? separator : "") + b; - }); -} +namespace dust3d { +namespace String { + + std::string join(const std::vector& stringList, const char* separator) + { + return std::accumulate(stringList.begin(), stringList.end(), std::string(), + [=](const std::string& a, const std::string& b) -> std::string { + return a + (a.length() > 0 ? separator : "") + b; + }); + } } } diff --git a/dust3d/base/string.h b/dust3d/base/string.h index 7e23a812..831c2b97 100644 --- a/dust3d/base/string.h +++ b/dust3d/base/string.h @@ -19,94 +19,93 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_STRING_H_ #define DUST3D_BASE_STRING_H_ -#include -#include -#include #include #include #include +#include +#include +#include -namespace dust3d -{ -namespace String -{ - -inline std::vector split(const std::string &string, char seperator) -{ - std::vector tokens; - std::stringstream stream(string); - std::string token; - while (std::getline(stream, token, seperator)) - tokens.push_back(token); - return tokens; -} +namespace dust3d { +namespace String { -inline std::string &trimLeft(std::string &string) -{ - string.erase(string.begin(), std::find_if(string.begin(), string.end(), [](int ch) { - return !std::isspace(ch); - })); - return string; -} - -inline std::string &trimRight(std::string &string) -{ - string.erase(std::find_if(string.rbegin(), string.rend(), [](int ch) { - return !std::isspace(ch); - }).base(), string.end()); - return string; -} - -inline std::string trimmed(std::string string) -{ - trimLeft(string); - trimRight(string); - return string; -} - -inline std::string doubleQuoteEscapedForXml(const std::string &string) -{ - std::string escapedString; - escapedString.reserve(string.size() + 1); - for (std::string::size_type i = 0; i < string.size(); ++i) { - char c = string[i]; - if ('"' != c) { - escapedString += c; - continue; - } - escapedString +="""; + inline std::vector split(const std::string& string, char seperator) + { + std::vector tokens; + std::stringstream stream(string); + std::string token; + while (std::getline(stream, token, seperator)) + tokens.push_back(token); + return tokens; } - return escapedString; -} -inline float toFloat(const std::string &string) -{ - return (float)std::stod(string); -} + inline std::string& trimLeft(std::string& string) + { + string.erase(string.begin(), std::find_if(string.begin(), string.end(), [](int ch) { + return !std::isspace(ch); + })); + return string; + } -std::string join(const std::vector &stringList, const char *separator); + inline std::string& trimRight(std::string& string) + { + string.erase(std::find_if(string.rbegin(), string.rend(), [](int ch) { + return !std::isspace(ch); + }).base(), + string.end()); + return string; + } -inline std::string valueOrEmpty(const std::map &map, const std::string &key) -{ - auto it = map.find(key); - if (it == map.end()) - return std::string(); - return it->second; -} + inline std::string trimmed(std::string string) + { + trimLeft(string); + trimRight(string); + return string; + } -inline bool isTrue(const std::string &string) -{ - return "true" == string || "True" == string || "1" == string; -} + inline std::string doubleQuoteEscapedForXml(const std::string& string) + { + std::string escapedString; + escapedString.reserve(string.size() + 1); + for (std::string::size_type i = 0; i < string.size(); ++i) { + char c = string[i]; + if ('"' != c) { + escapedString += c; + continue; + } + escapedString += """; + } + return escapedString; + } -inline bool startsWith(const std::string &string, const std::string searchItem) -{ - return string.rfind(searchItem, 0) == 0; -} + inline float toFloat(const std::string& string) + { + return (float)std::stod(string); + } + + std::string join(const std::vector& stringList, const char* separator); + + inline std::string valueOrEmpty(const std::map& map, const std::string& key) + { + auto it = map.find(key); + if (it == map.end()) + return std::string(); + return it->second; + } + + inline bool isTrue(const std::string& string) + { + return "true" == string || "True" == string || "1" == string; + } + + inline bool startsWith(const std::string& string, const std::string searchItem) + { + return string.rfind(searchItem, 0) == 0; + } } } diff --git a/dust3d/base/texture_type.cc b/dust3d/base/texture_type.cc index bac3fb5d..f1cbb7e2 100644 --- a/dust3d/base/texture_type.cc +++ b/dust3d/base/texture_type.cc @@ -22,11 +22,10 @@ #include -namespace dust3d -{ - +namespace dust3d { + IMPL_TextureTypeToString -IMPL_TextureTypeFromString -IMPL_TextureTypeToDispName + IMPL_TextureTypeFromString + IMPL_TextureTypeToDispName } diff --git a/dust3d/base/texture_type.h b/dust3d/base/texture_type.h index 3fb601ed..91128cb6 100644 --- a/dust3d/base/texture_type.h +++ b/dust3d/base/texture_type.h @@ -25,11 +25,9 @@ #include -namespace dust3d -{ - -enum class TextureType -{ +namespace dust3d { + +enum class TextureType { None, BaseColor, Normal, @@ -39,67 +37,67 @@ enum class TextureType Count }; -const char *TextureTypeToString(TextureType type); -#define IMPL_TextureTypeToString \ -const char *TextureTypeToString(TextureType type) \ -{ \ - switch (type) { \ - case TextureType::BaseColor: \ - return "BaseColor"; \ - case TextureType::Normal: \ - return "Normal"; \ - case TextureType::Metallic: \ - return "Metallic"; \ - case TextureType::Roughness: \ - return "Roughness"; \ - case TextureType::AmbientOcclusion: \ - return "AmbientOcclusion"; \ - case TextureType::None: \ - return "None"; \ - default: \ - return ""; \ - } \ -} -TextureType TextureTypeFromString(const char *typeString); -#define IMPL_TextureTypeFromString \ -TextureType TextureTypeFromString(const char *typeString) \ -{ \ - std::string type = typeString; \ - if (type == "BaseColor") \ - return TextureType::BaseColor; \ - if (type == "Normal") \ - return TextureType::Normal; \ - if (type == "Metallic") \ - return TextureType::Metallic; \ - if (type == "Metalness") \ - return TextureType::Metallic; \ - if (type == "Roughness") \ - return TextureType::Roughness; \ - if (type == "AmbientOcclusion") \ - return TextureType::AmbientOcclusion; \ - return TextureType::None; \ -} +const char* TextureTypeToString(TextureType type); +#define IMPL_TextureTypeToString \ + const char* TextureTypeToString(TextureType type) \ + { \ + switch (type) { \ + case TextureType::BaseColor: \ + return "BaseColor"; \ + case TextureType::Normal: \ + return "Normal"; \ + case TextureType::Metallic: \ + return "Metallic"; \ + case TextureType::Roughness: \ + return "Roughness"; \ + case TextureType::AmbientOcclusion: \ + return "AmbientOcclusion"; \ + case TextureType::None: \ + return "None"; \ + default: \ + return ""; \ + } \ + } +TextureType TextureTypeFromString(const char* typeString); +#define IMPL_TextureTypeFromString \ + TextureType TextureTypeFromString(const char* typeString) \ + { \ + std::string type = typeString; \ + if (type == "BaseColor") \ + return TextureType::BaseColor; \ + if (type == "Normal") \ + return TextureType::Normal; \ + if (type == "Metallic") \ + return TextureType::Metallic; \ + if (type == "Metalness") \ + return TextureType::Metallic; \ + if (type == "Roughness") \ + return TextureType::Roughness; \ + if (type == "AmbientOcclusion") \ + return TextureType::AmbientOcclusion; \ + return TextureType::None; \ + } std::string TextureTypeToDispName(TextureType type); -#define IMPL_TextureTypeToDispName \ -std::string TextureTypeToDispName(TextureType type) \ -{ \ - switch (type) { \ - case TextureType::BaseColor: \ - return std::string("Base Color"); \ - case TextureType::Normal: \ - return std::string("Normal Map"); \ - case TextureType::Metallic: \ - return std::string("Metallic"); \ - case TextureType::Roughness: \ - return std::string("Roughness"); \ - case TextureType::AmbientOcclusion: \ - return std::string("Ambient Occlusion"); \ - case TextureType::None: \ - return std::string("None"); \ - default: \ - return ""; \ - } \ -} +#define IMPL_TextureTypeToDispName \ + std::string TextureTypeToDispName(TextureType type) \ + { \ + switch (type) { \ + case TextureType::BaseColor: \ + return std::string("Base Color"); \ + case TextureType::Normal: \ + return std::string("Normal Map"); \ + case TextureType::Metallic: \ + return std::string("Metallic"); \ + case TextureType::Roughness: \ + return std::string("Roughness"); \ + case TextureType::AmbientOcclusion: \ + return std::string("Ambient Occlusion"); \ + case TextureType::None: \ + return std::string("None"); \ + default: \ + return ""; \ + } \ + } } diff --git a/dust3d/base/uuid.cc b/dust3d/base/uuid.cc index edb3cb21..e4e6adf5 100644 --- a/dust3d/base/uuid.cc +++ b/dust3d/base/uuid.cc @@ -22,9 +22,8 @@ #include -namespace dust3d -{ +namespace dust3d { -Uuid::RandomGenerator *Uuid::m_generator = new Uuid::RandomGenerator; +Uuid::RandomGenerator* Uuid::m_generator = new Uuid::RandomGenerator; } // namespace dust3d diff --git a/dust3d/base/uuid.h b/dust3d/base/uuid.h index 54b8e657..5ae8c786 100644 --- a/dust3d/base/uuid.h +++ b/dust3d/base/uuid.h @@ -23,75 +23,65 @@ #ifndef DUST3D_BASE_UUID_H_ #define DUST3D_BASE_UUID_H_ -#include -#include #include #include +#include +#include -namespace dust3d -{ +namespace dust3d { -class Uuid -{ +class Uuid { public: - class RandomGenerator - { + class RandomGenerator { public: - RandomGenerator(): - m_randomGenerator(m_randomDevice() + std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count()), - m_randomDistribution(0, 15) + RandomGenerator() + : m_randomGenerator(m_randomDevice() + std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count()) + , m_randomDistribution(0, 15) { } - + int generate() { return m_randomDistribution(m_randomGenerator); } - + private: std::random_device m_randomDevice; std::mt19937 m_randomGenerator; std::uniform_int_distribution m_randomDistribution; }; - static RandomGenerator *m_generator; + static RandomGenerator* m_generator; Uuid() = default; - - Uuid(const std::string &string) + + Uuid(const std::string& string) { - if (sizeof("{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}") - 1 == string.length() && - '{' == string[0] && - validate(&string[1], string.length() - 2)) { + if (sizeof("{hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh}") - 1 == string.length() && '{' == string[0] && validate(&string[1], string.length() - 2)) { m_uuid = string.substr(1, string.length() - 2); return; } - if (sizeof("hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh") - 1 == string.length() && - validate(&string[0], string.length())) { + if (sizeof("hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh") - 1 == string.length() && validate(&string[0], string.length())) { m_uuid = string; return; } } - static bool validate(const char *string, size_t length) + static bool validate(const char* string, size_t length) { - return length >= 24 && - '-' == string[8] && - '-' == string[13] && - '-' == string[18] && - '-' == string[23]; + return length >= 24 && '-' == string[8] && '-' == string[13] && '-' == string[18] && '-' == string[23]; } - + bool isNull() const { return m_uuid.empty(); } - + std::string toString() const { return "{" + m_uuid + "}"; } - + static Uuid createUuid() { std::ostringstream ss; @@ -134,43 +124,42 @@ public: ss << m_generator->generate(); return Uuid(ss.str()); } + private: - friend std::string to_string(const Uuid &uuid); + friend std::string to_string(const Uuid& uuid); friend struct std::hash; - friend bool operator==(const Uuid &lhs, const Uuid &rhs); - friend bool operator!=(const Uuid &lhs, const Uuid &rhs); - friend bool operator<(const Uuid &lhs, const Uuid &rhs); + friend bool operator==(const Uuid& lhs, const Uuid& rhs); + friend bool operator!=(const Uuid& lhs, const Uuid& rhs); + friend bool operator<(const Uuid& lhs, const Uuid& rhs); std::string m_uuid; }; -inline std::string to_string(const Uuid &uuid) +inline std::string to_string(const Uuid& uuid) { return "{" + uuid.m_uuid + "}"; } -inline bool operator==(const Uuid &lhs, const Uuid &rhs) +inline bool operator==(const Uuid& lhs, const Uuid& rhs) { return lhs.m_uuid == rhs.m_uuid; } -inline bool operator!=(const Uuid &lhs, const Uuid &rhs) +inline bool operator!=(const Uuid& lhs, const Uuid& rhs) { return lhs.m_uuid != rhs.m_uuid; } -inline bool operator<(const Uuid &lhs, const Uuid &rhs) +inline bool operator<(const Uuid& lhs, const Uuid& rhs) { return lhs.m_uuid < rhs.m_uuid; } - + } -namespace std -{ - -template<> -struct hash -{ +namespace std { + +template <> +struct hash { size_t operator()(const dust3d::Uuid& uuid) const { return std::hash()(uuid.m_uuid); diff --git a/dust3d/base/vector2.h b/dust3d/base/vector2.h index 83933979..d07483f7 100644 --- a/dust3d/base/vector2.h +++ b/dust3d/base/vector2.h @@ -32,124 +32,122 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ - + #ifndef DUST3D_BASE_VECTOR2_H_ #define DUST3D_BASE_VECTOR2_H_ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { class Vector2; -inline Vector2 operator*(double number, const Vector2 &v); -inline Vector2 operator*(const Vector2 &v, double number); -inline Vector2 operator+(const Vector2 &a, const Vector2 &b); -inline Vector2 operator-(const Vector2 &a, const Vector2 &b); +inline Vector2 operator*(double number, const Vector2& v); +inline Vector2 operator*(const Vector2& v, double number); +inline Vector2 operator+(const Vector2& a, const Vector2& b); +inline Vector2 operator-(const Vector2& a, const Vector2& b); -class Vector2 -{ +class Vector2 { public: - inline Vector2() : - m_data {0.0, 0.0} + inline Vector2() + : m_data { 0.0, 0.0 } { } - - inline Vector2(double x, double y) : - m_data {x, y} + + inline Vector2(double x, double y) + : m_data { x, y } { } - - inline double &operator[](size_t index) - { - return m_data[index]; - } - - inline const double &operator[](size_t index) const + + inline double& operator[](size_t index) { return m_data[index]; } - inline const double &x() const + inline const double& operator[](size_t index) const + { + return m_data[index]; + } + + inline const double& x() const { return m_data[0]; } - - inline const double &y() const + + inline const double& y() const { return m_data[1]; } - + inline void setX(double x) { m_data[0] = x; } - + inline void setY(double y) { m_data[1] = y; } - - inline const double *data() const + + inline const double* data() const { return &m_data[0]; } - + inline void setData(double x, double y) { m_data[0] = x; m_data[1] = y; } - + inline double lengthSquared() const { return x() * x() + y() * y(); } - + inline double length() const { double length2 = x() * x() + y() * y(); return std::sqrt(length2); } - + inline Vector2 normalized() const { double length2 = x() * x() + y() * y(); - + double length = std::sqrt(length2); if (Math::isZero(length)) return Vector2(); - + return Vector2(x() / length, y() / length); } - + inline void normalize() { double length2 = x() * x() + y() * y(); - + double length = std::sqrt(length2); if (Math::isZero(length)) return; - + m_data[0] = x() / length; m_data[1] = y() / length; } - - inline bool isOnLeft(const Vector2 &a, const Vector2 &b) const + + inline bool isOnLeft(const Vector2& a, const Vector2& b) const { return ((b.x() - a.x()) * (y() - a.y()) - (b.y() - a.y()) * (x() - a.x())) > 0; } - - inline static double dotProduct(const Vector2 &a, const Vector2 &b) + + inline static double dotProduct(const Vector2& a, const Vector2& b) { return a.x() * b.x() + a.y() * b.y(); } - - inline static Vector2 barycentricCoordinates(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Vector2 &point) + + inline static Vector2 barycentricCoordinates(const Vector2& a, const Vector2& b, const Vector2& c, const Vector2& point) { auto v0 = c - a; auto v1 = b - a; @@ -164,11 +162,11 @@ public: auto invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); auto alpha = (dot11 * dot02 - dot01 * dot12) * invDenom; auto beta = (dot00 * dot12 - dot01 * dot02) * invDenom; - + return Vector2(alpha, beta); } - - inline static bool isInTriangle(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Vector2 &point) + + inline static bool isInTriangle(const Vector2& a, const Vector2& b, const Vector2& c, const Vector2& point) { auto alphaAndBeta = barycentricCoordinates(a, b, c, point); if (alphaAndBeta[0] < 0) @@ -179,96 +177,91 @@ public: return false; return true; } - - inline bool isInPolygon(const std::vector &polygon) const + + inline bool isInPolygon(const std::vector& polygon) const { bool inside = false; int i, j; for (i = 0, j = (int)polygon.size() - 1; i < (int)polygon.size(); j = i++) { - if (((polygon[i].y() > y()) != (polygon[j].y() > y())) && - (x() < (polygon[j].x() - polygon[i].x()) * (y() - polygon[i].y()) / (polygon[j].y() - polygon[i].y()) + polygon[i].x())) { + if (((polygon[i].y() > y()) != (polygon[j].y() > y())) && (x() < (polygon[j].x() - polygon[i].x()) * (y() - polygon[i].y()) / (polygon[j].y() - polygon[i].y()) + polygon[i].x())) { inside = !inside; } } return inside; } - - inline bool isInPolygon(const std::vector &polygonVertices, const std::vector &polygonIndices) const + + inline bool isInPolygon(const std::vector& polygonVertices, const std::vector& polygonIndices) const { bool inside = false; int i, j; for (i = 0, j = (int)polygonIndices.size() - 1; i < (int)polygonIndices.size(); j = i++) { - if (((polygonVertices[polygonIndices[i]].y() > y()) != (polygonVertices[polygonIndices[j]].y() > y())) && - (x() < (polygonVertices[polygonIndices[j]].x() - polygonVertices[polygonIndices[i]].x()) * (y() - polygonVertices[polygonIndices[i]].y()) / (polygonVertices[polygonIndices[j]].y() - polygonVertices[polygonIndices[i]].y()) + polygonVertices[polygonIndices[i]].x())) { + if (((polygonVertices[polygonIndices[i]].y() > y()) != (polygonVertices[polygonIndices[j]].y() > y())) && (x() < (polygonVertices[polygonIndices[j]].x() - polygonVertices[polygonIndices[i]].x()) * (y() - polygonVertices[polygonIndices[i]].y()) / (polygonVertices[polygonIndices[j]].y() - polygonVertices[polygonIndices[i]].y()) + polygonVertices[polygonIndices[i]].x())) { inside = !inside; } } return inside; } - - inline Vector2 &operator+=(const Vector2 &other) + + inline Vector2& operator+=(const Vector2& other) { m_data[0] += other.x(); m_data[1] += other.y(); return *this; } - + inline bool isZero() const { - return Math::isZero(m_data[0]) && - Math::isZero(m_data[1]); + return Math::isZero(m_data[0]) && Math::isZero(m_data[1]); } private: - double m_data[2] = {0.0}; + double m_data[2] = { 0.0 }; }; -inline Vector2 operator*(double number, const Vector2 &v) +inline Vector2 operator*(double number, const Vector2& v) { return Vector2(number * v.x(), number * v.y()); } -inline Vector2 operator*(const Vector2 &v, double number) +inline Vector2 operator*(const Vector2& v, double number) { return Vector2(number * v.x(), number * v.y()); } -inline Vector2 operator+(const Vector2 &a, const Vector2 &b) +inline Vector2 operator+(const Vector2& a, const Vector2& b) { return Vector2(a.x() + b.x(), a.y() + b.y()); } -inline Vector2 operator-(const Vector2 &a, const Vector2 &b) +inline Vector2 operator-(const Vector2& a, const Vector2& b) { return Vector2(a.x() - b.x(), a.y() - b.y()); } -inline Vector2 operator/(const Vector2 &v, double number) +inline Vector2 operator/(const Vector2& v, double number) { return Vector2(v.x() / number, v.y() / number); } -inline std::string to_string(const Vector2 &v) +inline std::string to_string(const Vector2& v) { return std::to_string(v.x()) + "," + std::to_string(v.y()); } -inline std::ostream &operator<<(std::ostream &os, const Vector2 &v) +inline std::ostream& operator<<(std::ostream& os, const Vector2& v) { os << v.x() << ',' << v.y(); return os; } -inline bool operator==(const Vector2 &a, const Vector2 &b) +inline bool operator==(const Vector2& a, const Vector2& b) { - return Math::isEqual(a.x(), b.x()) && - Math::isEqual(a.y(), b.y()); + return Math::isEqual(a.x(), b.x()) && Math::isEqual(a.y(), b.y()); } -inline bool operator!=(const Vector2 &a, const Vector2 &b) +inline bool operator!=(const Vector2& a, const Vector2& b) { - return !Math::isEqual(a.x(), b.x()) || - !Math::isEqual(a.y(), b.y()); + return !Math::isEqual(a.x(), b.x()) || !Math::isEqual(a.y(), b.y()); } } diff --git a/dust3d/base/vector3.cc b/dust3d/base/vector3.cc index 62a1caa7..55993d63 100644 --- a/dust3d/base/vector3.cc +++ b/dust3d/base/vector3.cc @@ -22,16 +22,13 @@ #include -namespace dust3d -{ - -Vector3 Vector3::rotated(const Vector3 &unitAxis, double angle) const +namespace dust3d { + +Vector3 Vector3::rotated(const Vector3& unitAxis, double angle) const { double c = std::cos(angle); double s = std::sin(angle); - return *this * c + - Vector3::crossProduct(unitAxis, *this) * s + - unitAxis * Vector3::dotProduct(unitAxis, *this) * (1.0 - c); + return *this * c + Vector3::crossProduct(unitAxis, *this) * s + unitAxis * Vector3::dotProduct(unitAxis, *this) * (1.0 - c); } } diff --git a/dust3d/base/vector3.h b/dust3d/base/vector3.h index ae4971ab..61e29fb3 100644 --- a/dust3d/base/vector3.h +++ b/dust3d/base/vector3.h @@ -19,151 +19,149 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_BASE_VECTOR3_H_ #define DUST3D_BASE_VECTOR3_H_ -#include -#include -#include #include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { class Vector3; -inline Vector3 operator*(double number, const Vector3 &v); -inline Vector3 operator*(const Vector3 &v, double number); -inline Vector3 operator+(const Vector3 &a, const Vector3 &b); -inline Vector3 operator-(const Vector3 &a, const Vector3 &b); -inline Vector3 operator-(const Vector3 &v); -inline Vector3 operator/(const Vector3 &v, double number); +inline Vector3 operator*(double number, const Vector3& v); +inline Vector3 operator*(const Vector3& v, double number); +inline Vector3 operator+(const Vector3& a, const Vector3& b); +inline Vector3 operator-(const Vector3& a, const Vector3& b); +inline Vector3 operator-(const Vector3& v); +inline Vector3 operator/(const Vector3& v, double number); -class Vector3 -{ +class Vector3 { public: - inline Vector3() : - m_data {0.0, 0.0, 0.0} + inline Vector3() + : m_data { 0.0, 0.0, 0.0 } { } - - inline Vector3(double x, double y, double z) : - m_data {x, y, z} + + inline Vector3(double x, double y, double z) + : m_data { x, y, z } { } - - inline Vector3(const Vector2 &vector2) : - m_data {vector2.x(), vector2.y(), 0.0} + + inline Vector3(const Vector2& vector2) + : m_data { vector2.x(), vector2.y(), 0.0 } { } - - inline double &operator[](size_t index) - { - return m_data[index]; - } - - inline const double &operator[](size_t index) const + + inline double& operator[](size_t index) { return m_data[index]; } - inline const double &x() const + inline const double& operator[](size_t index) const + { + return m_data[index]; + } + + inline const double& x() const { return m_data[0]; } - - inline const double &y() const + + inline const double& y() const { return m_data[1]; } - - inline const double &z() const + + inline const double& z() const { return m_data[2]; } - + inline void setX(double x) { m_data[0] = x; } - + inline void setY(double y) { m_data[1] = y; } - + inline void setZ(double z) { m_data[2] = z; } - - inline const double *constData() const + + inline const double* constData() const { return &m_data[0]; } - + inline void setData(double x, double y, double z) { m_data[0] = x; m_data[1] = y; m_data[2] = z; } - + inline double lengthSquared() const { return x() * x() + y() * y() + z() * z(); } - + inline double length() const { double length2 = x() * x() + y() * y() + z() * z(); return std::sqrt(length2); } - + inline Vector3 normalized() const { double length2 = x() * x() + y() * y() + z() * z(); - + double length = std::sqrt(length2); if (Math::isZero(length)) return Vector3(); - + return Vector3(x() / length, y() / length, z() / length); } - + inline void normalize() { double length2 = x() * x() + y() * y() + z() * z(); - + double length = std::sqrt(length2); if (Math::isZero(length)) return; - + m_data[0] = x() / length; m_data[1] = y() / length; m_data[2] = z() / length; } - - inline static Vector3 crossProduct(const Vector3 &a, const Vector3 &b) + + inline static Vector3 crossProduct(const Vector3& a, const Vector3& b) { return Vector3(a.y() * b.z() - a.z() * b.y(), a.z() * b.x() - a.x() * b.z(), a.x() * b.y() - a.y() * b.x()); } - - inline static double dotProduct(const Vector3 &a, const Vector3 &b) + + inline static double dotProduct(const Vector3& a, const Vector3& b) { return a.x() * b.x() + a.y() * b.y() + a.z() * b.z(); } - - inline static Vector3 normal(const Vector3 &a, const Vector3 &b, const Vector3 &c) + + inline static Vector3 normal(const Vector3& a, const Vector3& b, const Vector3& c) { return Vector3::crossProduct(b - a, c - a).normalized(); } - - inline static double angle(const Vector3 &a, const Vector3 &b) + + inline static double angle(const Vector3& a, const Vector3& b) { double dot = Vector3::dotProduct(a.normalized(), b.normalized()); if (dot <= -1.0) @@ -173,95 +171,85 @@ public: else return std::acos(dot); } - + inline bool isZero() const { - return Math::isZero(m_data[0]) && - Math::isZero(m_data[1]) && - Math::isZero(m_data[2]); + return Math::isZero(m_data[0]) && Math::isZero(m_data[1]) && Math::isZero(m_data[2]); } - + inline bool containsNan() const { - return std::isnan(m_data[0]) || - std::isnan(m_data[1]) || - std::isnan(m_data[2]); + return std::isnan(m_data[0]) || std::isnan(m_data[1]) || std::isnan(m_data[2]); } - + inline bool containsInf() const { - return std::isinf(m_data[0]) || - std::isinf(m_data[1]) || - std::isinf(m_data[2]); + return std::isinf(m_data[0]) || std::isinf(m_data[1]) || std::isinf(m_data[2]); } - - inline Vector3 &operator+=(const Vector3 &other) + + inline Vector3& operator+=(const Vector3& other) { m_data[0] += other.x(); m_data[1] += other.y(); m_data[2] += other.z(); return *this; } - - inline Vector3 &operator-=(const Vector3 &other) + + inline Vector3& operator-=(const Vector3& other) { m_data[0] -= other.x(); m_data[1] -= other.y(); m_data[2] -= other.z(); return *this; } - - inline Vector3 &operator*=(double number) + + inline Vector3& operator*=(double number) { m_data[0] *= number; m_data[1] *= number; m_data[2] *= number; return *this; } - - inline Vector3 &operator/=(double number) + + inline Vector3& operator/=(double number) { m_data[0] /= number; m_data[1] /= number; m_data[2] /= number; return *this; } - - inline static double area(const Vector3 &a, const Vector3 &b, const Vector3 &c) + + inline static double area(const Vector3& a, const Vector3& b, const Vector3& c) { auto ab = b - a; auto ac = c - a; return 0.5 * crossProduct(ab, ac).length(); } - - inline static void project(const std::vector &pointsIn3d, std::vector *pointsIn2d, - const Vector3 &normal, const Vector3 &axis, const Vector3 &origin=Vector3()) + + inline static void project(const std::vector& pointsIn3d, std::vector* pointsIn2d, + const Vector3& normal, const Vector3& axis, const Vector3& origin = Vector3()) { Vector3 perpendicularAxis = crossProduct(normal, axis); - for (const auto &it: pointsIn3d) { + for (const auto& it : pointsIn3d) { Vector3 direction = it - origin; - pointsIn2d->push_back({ - dotProduct(direction, axis), - dotProduct(direction, perpendicularAxis) - }); + pointsIn2d->push_back({ dotProduct(direction, axis), + dotProduct(direction, perpendicularAxis) }); } } - - inline static void project(const std::vector &pointsIn3d, std::vector *pointsIn2d, - const Vector3 &normal, const Vector3 &axis, const Vector3 &origin=Vector3()) + + inline static void project(const std::vector& pointsIn3d, std::vector* pointsIn2d, + const Vector3& normal, const Vector3& axis, const Vector3& origin = Vector3()) { Vector3 perpendicularAxis = crossProduct(normal, axis); - for (const auto &it: pointsIn3d) { + for (const auto& it : pointsIn3d) { Vector3 direction = it - origin; - pointsIn2d->push_back({ - dotProduct(direction, axis), + pointsIn2d->push_back({ dotProduct(direction, axis), dotProduct(direction, perpendicularAxis), - 0.0 - }); + 0.0 }); } } - - inline static Vector3 barycentricCoordinates(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &point) + + inline static Vector3 barycentricCoordinates(const Vector3& a, const Vector3& b, const Vector3& c, const Vector3& point) { auto invertedAreaOfAbc = 1.0 / area(a, b, c); auto areaOfPbc = area(point, b, c); @@ -270,10 +258,10 @@ public: auto beta = areaOfPca * invertedAreaOfAbc; return Vector3(alpha, beta, 1.0 - alpha - beta); } - - inline static bool intersectSegmentAndPlane(const Vector3 &segmentPoint0, const Vector3 &segmentPoint1, - const Vector3 &pointOnPlane, const Vector3 &planeNormal, - Vector3 *intersection) + + inline static bool intersectSegmentAndPlane(const Vector3& segmentPoint0, const Vector3& segmentPoint1, + const Vector3& pointOnPlane, const Vector3& planeNormal, + Vector3* intersection) { auto u = segmentPoint1 - segmentPoint0; auto w = segmentPoint0 - pointOnPlane; @@ -289,10 +277,10 @@ public: return true; } - inline static bool intersectSegmentAndTriangle(const Vector3 &segmentPoint0, const Vector3 &segmentPoint1, - const std::vector &triangle, - const Vector3 &triangleNormal, - Vector3 *intersection) + inline static bool intersectSegmentAndTriangle(const Vector3& segmentPoint0, const Vector3& segmentPoint1, + const std::vector& triangle, + const Vector3& triangleNormal, + Vector3* intersection) { Vector3 possibleIntersection; if (!intersectSegmentAndPlane(segmentPoint0, segmentPoint1, @@ -315,77 +303,77 @@ public: *intersection = possibleIntersection; return true; } - - inline static Vector3 projectPointOnLine(const Vector3 &point, const Vector3 &linePointA, const Vector3 &linePointB) + + inline static Vector3 projectPointOnLine(const Vector3& point, const Vector3& linePointA, const Vector3& linePointB) { auto aToPoint = point - linePointA; auto aToB = linePointB - linePointA; return linePointA + Vector3::dotProduct(aToPoint, aToB) / Vector3::dotProduct(aToB, aToB) * aToB; } - - inline static Vector3 projectLineOnPlane(const Vector3 &line, const Vector3 &planeNormal) + + inline static Vector3 projectLineOnPlane(const Vector3& line, const Vector3& planeNormal) { const auto verticalOffset = Vector3::dotProduct(line, planeNormal) * planeNormal; return line - verticalOffset; } - - inline static double angleBetween(const Vector3 &first, const Vector3 &second) + + inline static double angleBetween(const Vector3& first, const Vector3& second) { return std::acos(dotProduct(first.normalized(), second.normalized())); } - - Vector3 rotated(const Vector3 &unitAxis, double angle) const; - + + Vector3 rotated(const Vector3& unitAxis, double angle) const; + private: - double m_data[3] = {0.0}; + double m_data[3] = { 0.0 }; }; -inline Vector3 operator*(double number, const Vector3 &v) +inline Vector3 operator*(double number, const Vector3& v) { return Vector3(number * v.x(), number * v.y(), number * v.z()); } -inline Vector3 operator*(const Vector3 &v, double number) +inline Vector3 operator*(const Vector3& v, double number) { return Vector3(number * v.x(), number * v.y(), number * v.z()); } -inline Vector3 operator*(const Vector3 &a, const Vector3 &b) +inline Vector3 operator*(const Vector3& a, const Vector3& b) { return Vector3(a.x() * b.x(), a.y() * b.y(), a.z() * b.z()); } -inline Vector3 operator/(const Vector3 &a, const Vector3 &b) +inline Vector3 operator/(const Vector3& a, const Vector3& b) { return Vector3(a.x() / b.x(), a.y() / b.y(), a.z() / b.z()); } -inline Vector3 operator+(const Vector3 &a, const Vector3 &b) +inline Vector3 operator+(const Vector3& a, const Vector3& b) { return Vector3(a.x() + b.x(), a.y() + b.y(), a.z() + b.z()); } -inline Vector3 operator-(const Vector3 &a, const Vector3 &b) +inline Vector3 operator-(const Vector3& a, const Vector3& b) { return Vector3(a.x() - b.x(), a.y() - b.y(), a.z() - b.z()); } -inline Vector3 operator-(const Vector3 &v) +inline Vector3 operator-(const Vector3& v) { return Vector3(-v.x(), -v.y(), -v.z()); } -inline Vector3 operator/(const Vector3 &v, double number) +inline Vector3 operator/(const Vector3& v, double number) { return Vector3(v.x() / number, v.y() / number, v.z() / number); } -inline std::string to_string(const Vector3 &v) +inline std::string to_string(const Vector3& v) { return std::to_string(v.x()) + "," + std::to_string(v.y()) + "," + std::to_string(v.z()); } -inline std::ostream &operator<<(std::ostream &os, const Vector3 &v) +inline std::ostream& operator<<(std::ostream& os, const Vector3& v) { os << v.x() << ',' << v.y() << ',' << v.z(); return os; @@ -394,4 +382,3 @@ inline std::ostream &operator<<(std::ostream &os, const Vector3 &v) } #endif - diff --git a/dust3d/mesh/base_normal.cc b/dust3d/mesh/base_normal.cc index cc684ae8..203a027e 100644 --- a/dust3d/mesh/base_normal.cc +++ b/dust3d/mesh/base_normal.cc @@ -22,10 +22,9 @@ #include -namespace dust3d -{ +namespace dust3d { -std::pair BaseNormal::findNearestAxis(const Vector3 &direction) +std::pair BaseNormal::findNearestAxis(const Vector3& direction) { float maxDot = -1; size_t nearAxisIndex = 0; @@ -41,28 +40,28 @@ std::pair BaseNormal::findNearestAxis(const Vector3 &direction) nearAxisIndex = i; } } - return {nearAxisIndex, positive}; + return { nearAxisIndex, positive }; } -std::vector BaseNormal::calculateCircleVertices(double radius, - size_t points, - const Vector3 &aroundAxis, - const Vector3 &startDirection, - const Vector3 &origin) +std::vector BaseNormal::calculateCircleVertices(double radius, + size_t points, + const Vector3& aroundAxis, + const Vector3& startDirection, + const Vector3& origin) { constexpr auto roundAngle = 2.0 * Math::Pi; auto stepAngle = roundAngle / points; std::vector circlePoints; circlePoints.reserve(points); for (double angle = stepAngle * -0.5; - circlePoints.size() < points; - angle += stepAngle) { + circlePoints.size() < points; + angle += stepAngle) { circlePoints.push_back(origin + startDirection.rotated(aroundAxis, angle) * radius); } return circlePoints; } -Vector3 BaseNormal::calculateCircleBaseNormal(const std::vector &vertices) +Vector3 BaseNormal::calculateCircleBaseNormal(const std::vector& vertices) { std::vector edgeDirections(vertices.size()); for (size_t i = 0; i < edgeDirections.size(); ++i) { @@ -77,7 +76,7 @@ Vector3 BaseNormal::calculateCircleBaseNormal(const std::vector &vertic return baseNormal.normalized(); } -Vector3 BaseNormal::calculateTubeBaseNormal(const std::vector &vertices) +Vector3 BaseNormal::calculateTubeBaseNormal(const std::vector& vertices) { std::vector edgeDirections(vertices.size()); for (size_t i = 1; i < edgeDirections.size(); ++i) { @@ -93,10 +92,9 @@ Vector3 BaseNormal::calculateTubeBaseNormal(const std::vector &vertices } if (baseNormal.isZero()) { for (size_t h = 0; h + 1 < edgeDirections.size(); ++h) { - const auto §ionNormal = edgeDirections[h]; + const auto& sectionNormal = edgeDirections[h]; auto axis = BaseNormal::findNearestAxis(sectionNormal); - baseNormal += axis.second * - Vector3::crossProduct(sectionNormal, BaseNormal::nextAxisDirection(axis.first)).normalized(); + baseNormal += axis.second * Vector3::crossProduct(sectionNormal, BaseNormal::nextAxisDirection(axis.first)).normalized(); } } return baseNormal.normalized(); diff --git a/dust3d/mesh/base_normal.h b/dust3d/mesh/base_normal.h index 5d72c897..b76725cc 100644 --- a/dust3d/mesh/base_normal.h +++ b/dust3d/mesh/base_normal.h @@ -23,36 +23,34 @@ #ifndef DUST3D_MESH_BASE_NORMAL_H_ #define DUST3D_MESH_BASE_NORMAL_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -class BaseNormal -{ +class BaseNormal { public: - static std::pair findNearestAxis(const Vector3 &direction); - static inline const Vector3 &axisDirection(size_t index) + static std::pair findNearestAxis(const Vector3& direction); + static inline const Vector3& axisDirection(size_t index) { static const std::vector axisList = { - Vector3 {1, 0, 0}, - Vector3 {0, 1, 0}, - Vector3 {0, 0, 1}, + Vector3 { 1, 0, 0 }, + Vector3 { 0, 1, 0 }, + Vector3 { 0, 0, 1 }, }; return axisList[index]; } - static inline const Vector3 &nextAxisDirection(size_t index) + static inline const Vector3& nextAxisDirection(size_t index) { return axisDirection((index + 1) % 3); } - static std::vector calculateCircleVertices(double radius, - size_t points, - const Vector3 &aroundAxis=Vector3(0.0, 0.0, 1.0), - const Vector3 &startDirection=Vector3(0.0, 1.0, 0.0), - const Vector3 &origin=Vector3(0.0, 0.0, 0.0)); - static Vector3 calculateCircleBaseNormal(const std::vector &vertices); - static Vector3 calculateTubeBaseNormal(const std::vector &vertices); + static std::vector calculateCircleVertices(double radius, + size_t points, + const Vector3& aroundAxis = Vector3(0.0, 0.0, 1.0), + const Vector3& startDirection = Vector3(0.0, 1.0, 0.0), + const Vector3& origin = Vector3(0.0, 0.0, 0.0)); + static Vector3 calculateCircleBaseNormal(const std::vector& vertices); + static Vector3 calculateTubeBaseNormal(const std::vector& vertices); }; } diff --git a/dust3d/mesh/box_mesh.cc b/dust3d/mesh/box_mesh.cc index e5923a9c..5d9f0ce1 100644 --- a/dust3d/mesh/box_mesh.cc +++ b/dust3d/mesh/box_mesh.cc @@ -22,77 +22,77 @@ #include -namespace dust3d -{ +namespace dust3d { static const std::vector g_subdivedBoxObjVertices = { - {-0.025357f, -0.025357f, 0.025357f}, - {-0.025357f, 0.025357f, 0.025357f}, - {-0.025357f, 0.025357f, -0.025357f}, - {-0.025357f, -0.025357f, -0.025357f}, - {0.025357f, -0.025357f, 0.025357f}, - {0.025357f, -0.025357f, -0.025357f}, - {0.025357f, 0.025357f, 0.025357f}, - {0.025357f, 0.025357f, -0.025357f}, - {-0.030913f, -0.030913f, -0.000000f}, - {-0.030913f, -0.000000f, 0.030913f}, - {-0.030913f, 0.030913f, 0.000000f}, - {-0.030913f, 0.000000f, -0.030913f}, - {0.030913f, -0.030913f, -0.000000f}, - {0.000000f, -0.030913f, 0.030913f}, - {-0.000000f, -0.030913f, -0.030913f}, - {0.030913f, -0.000000f, 0.030913f}, - {-0.000000f, 0.030913f, 0.030913f}, - {0.030913f, 0.030913f, 0.000000f}, - {0.030913f, 0.000000f, -0.030913f}, - {-0.000000f, 0.030913f, -0.030913f}, - {-0.042574f, 0.000000f, -0.000000f}, - {-0.000000f, -0.042574f, -0.000000f}, - {0.000000f, -0.000000f, 0.042574f}, - {0.042574f, -0.000000f, -0.000000f}, - {-0.000000f, 0.000000f, -0.042574f}, - {0.000000f, 0.042574f, 0.000000f}, + { -0.025357f, -0.025357f, 0.025357f }, + { -0.025357f, 0.025357f, 0.025357f }, + { -0.025357f, 0.025357f, -0.025357f }, + { -0.025357f, -0.025357f, -0.025357f }, + { 0.025357f, -0.025357f, 0.025357f }, + { 0.025357f, -0.025357f, -0.025357f }, + { 0.025357f, 0.025357f, 0.025357f }, + { 0.025357f, 0.025357f, -0.025357f }, + { -0.030913f, -0.030913f, -0.000000f }, + { -0.030913f, -0.000000f, 0.030913f }, + { -0.030913f, 0.030913f, 0.000000f }, + { -0.030913f, 0.000000f, -0.030913f }, + { 0.030913f, -0.030913f, -0.000000f }, + { 0.000000f, -0.030913f, 0.030913f }, + { -0.000000f, -0.030913f, -0.030913f }, + { 0.030913f, -0.000000f, 0.030913f }, + { -0.000000f, 0.030913f, 0.030913f }, + { 0.030913f, 0.030913f, 0.000000f }, + { 0.030913f, 0.000000f, -0.030913f }, + { -0.000000f, 0.030913f, -0.030913f }, + { -0.042574f, 0.000000f, -0.000000f }, + { -0.000000f, -0.042574f, -0.000000f }, + { 0.000000f, -0.000000f, 0.042574f }, + { 0.042574f, -0.000000f, -0.000000f }, + { -0.000000f, 0.000000f, -0.042574f }, + { 0.000000f, 0.042574f, 0.000000f }, }; static const std::vector> g_subdivedBoxObjFaces = { - {1, 10, 21, 9}, - {10, 2, 11, 21}, - {21, 11, 3, 12}, - {9, 21, 12, 4}, - {5, 14, 22, 13}, - {14, 1, 9, 22}, - {22, 9, 4, 15}, - {13, 22, 15, 6}, - {1, 14, 23, 10}, - {14, 5, 16, 23}, - {23, 16, 7, 17}, - {10, 23, 17, 2}, - {7, 16, 24, 18}, - {16, 5, 13, 24}, - {24, 13, 6, 19}, - {18, 24, 19, 8}, - {4, 12, 25, 15}, - {12, 3, 20, 25}, - {25, 20, 8, 19}, - {15, 25, 19, 6}, - {2, 17, 26, 11}, - {17, 7, 18, 26}, - {26, 18, 8, 20}, - {11, 26, 20, 3}, + { 1, 10, 21, 9 }, + { 10, 2, 11, 21 }, + { 21, 11, 3, 12 }, + { 9, 21, 12, 4 }, + { 5, 14, 22, 13 }, + { 14, 1, 9, 22 }, + { 22, 9, 4, 15 }, + { 13, 22, 15, 6 }, + { 1, 14, 23, 10 }, + { 14, 5, 16, 23 }, + { 23, 16, 7, 17 }, + { 10, 23, 17, 2 }, + { 7, 16, 24, 18 }, + { 16, 5, 13, 24 }, + { 24, 13, 6, 19 }, + { 18, 24, 19, 8 }, + { 4, 12, 25, 15 }, + { 12, 3, 20, 25 }, + { 25, 20, 8, 19 }, + { 15, 25, 19, 6 }, + { 2, 17, 26, 11 }, + { 17, 7, 18, 26 }, + { 26, 18, 8, 20 }, + { 11, 26, 20, 3 }, }; -void buildBoxMesh(const Vector3 &position, float radius, size_t subdivideTimes, std::vector &vertices, std::vector> &faces) +void buildBoxMesh(const Vector3& position, float radius, size_t subdivideTimes, std::vector& vertices, std::vector>& faces) { if (subdivideTimes > 0) { vertices.reserve(g_subdivedBoxObjVertices.size()); auto ratio = 24 * radius; - for (const auto &vertex: g_subdivedBoxObjVertices) { + for (const auto& vertex : g_subdivedBoxObjVertices) { auto newVertex = vertex * ratio + position; vertices.push_back(newVertex); } faces.reserve(g_subdivedBoxObjFaces.size()); - for (const auto &face: g_subdivedBoxObjFaces) { - auto newFace = {face[0] - 1, + for (const auto& face : g_subdivedBoxObjFaces) { + auto newFace = { + face[0] - 1, face[1] - 1, face[2] - 1, face[3] - 1, @@ -102,10 +102,10 @@ void buildBoxMesh(const Vector3 &position, float radius, size_t subdivideTimes, return; } std::vector beginPlane = { - {-radius, -radius, radius}, - { radius, -radius, radius}, - { radius, radius, radius}, - {-radius, radius, radius}, + { -radius, -radius, radius }, + { radius, -radius, radius }, + { radius, radius, radius }, + { -radius, radius, radius }, }; std::vector endPlane = { beginPlane[0], @@ -113,13 +113,13 @@ void buildBoxMesh(const Vector3 &position, float radius, size_t subdivideTimes, beginPlane[2], beginPlane[1] }; - for (auto &vertex: endPlane) { + for (auto& vertex : endPlane) { vertex.setZ(vertex.z() - radius - radius); } - for (const auto &vertex: beginPlane) { + for (const auto& vertex : beginPlane) { vertices.push_back(vertex); } - for (const auto &vertex: endPlane) { + for (const auto& vertex : endPlane) { vertices.push_back(vertex); } std::vector beginLoop = { @@ -135,14 +135,12 @@ void buildBoxMesh(const Vector3 &position, float radius, size_t subdivideTimes, faces.push_back(endLoop); for (size_t i = 0; i < beginLoop.size(); ++i) { size_t j = (i + 1) % beginLoop.size(); - faces.push_back({ - beginLoop[j], + faces.push_back({ beginLoop[j], beginLoop[i], alignedEndLoop[i], - alignedEndLoop[j] - }); + alignedEndLoop[j] }); } - for (auto &vertex: vertices) { + for (auto& vertex : vertices) { vertex += position; } } diff --git a/dust3d/mesh/box_mesh.h b/dust3d/mesh/box_mesh.h index 3322b276..7b2a3d95 100644 --- a/dust3d/mesh/box_mesh.h +++ b/dust3d/mesh/box_mesh.h @@ -26,10 +26,9 @@ #include #include -namespace dust3d -{ - -void buildBoxMesh(const Vector3 &position, float radius, size_t subdivideTimes, std::vector &vertices, std::vector> &faces); +namespace dust3d { + +void buildBoxMesh(const Vector3& position, float radius, size_t subdivideTimes, std::vector& vertices, std::vector>& faces); } diff --git a/dust3d/mesh/centripetal_catmull_rom_spline.cc b/dust3d/mesh/centripetal_catmull_rom_spline.cc index 78437b4c..6aae661c 100644 --- a/dust3d/mesh/centripetal_catmull_rom_spline.cc +++ b/dust3d/mesh/centripetal_catmull_rom_spline.cc @@ -19,32 +19,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #include -namespace dust3d -{ +namespace dust3d { -CentripetalCatmullRomSpline::CentripetalCatmullRomSpline(bool isClosed) : - m_isClosed(isClosed) +CentripetalCatmullRomSpline::CentripetalCatmullRomSpline(bool isClosed) + : m_isClosed(isClosed) { } -const std::vector &CentripetalCatmullRomSpline::splineNodes() +const std::vector& CentripetalCatmullRomSpline::splineNodes() { return m_splineNodes; } -void CentripetalCatmullRomSpline::addPoint(int source, const Vector3 &position, bool isKnot) +void CentripetalCatmullRomSpline::addPoint(int source, const Vector3& position, bool isKnot) { if (isKnot) m_splineKnots.push_back(m_splineNodes.size()); - m_splineNodes.push_back({ - source, position - }); + m_splineNodes.push_back({ source, position }); } -float CentripetalCatmullRomSpline::atKnot(float t, const Vector3 &p0, const Vector3 &p1) +float CentripetalCatmullRomSpline::atKnot(float t, const Vector3& p0, const Vector3& p1) { const float alpha = 0.5f; Vector3 d = p1 - p0; @@ -53,23 +50,23 @@ float CentripetalCatmullRomSpline::atKnot(float t, const Vector3 &p0, const Vect return (b + t); } -void CentripetalCatmullRomSpline::interpolateSegment(std::vector &knots, - size_t from, size_t to) +void CentripetalCatmullRomSpline::interpolateSegment(std::vector& knots, + size_t from, size_t to) { - const Vector3 &p0 = knots[0]; - const Vector3 &p1 = knots[1]; - const Vector3 &p2 = knots[2]; - const Vector3 &p3 = knots[3]; - + const Vector3& p0 = knots[0]; + const Vector3& p1 = knots[1]; + const Vector3& p2 = knots[2]; + const Vector3& p3 = knots[3]; + float s1 = (p2 - p1).length(); float t0 = 0.0f; float t1 = atKnot(t0, p0, p1); float t2 = atKnot(t1, p1, p2); float t3 = atKnot(t2, p2, p3); - + for (size_t index = (from + 1) % m_splineNodes.size(); index != to; index = (index + 1) % m_splineNodes.size()) { - auto &position = m_splineNodes[index].position; + auto& position = m_splineNodes[index].position; float factor = (position - p1).length() / s1; float t = t1 * (1.0f - factor) + t2 * factor; @@ -77,10 +74,10 @@ void CentripetalCatmullRomSpline::interpolateSegment(std::vector &knots Vector3 a1 = (t1 - t) / (t1 - t0) * p0 + (t - t0) / (t1 - t0) * p1; Vector3 a2 = (t2 - t) / (t2 - t1) * p1 + (t - t1) / (t2 - t1) * p2; Vector3 a3 = (t3 - t) / (t3 - t2) * p2 + (t - t2) / (t3 - t2) * p3; - + Vector3 b1 = (t2 - t) / (t2 - t0) * a1 + (t - t0) / (t2 - t0) * a2; Vector3 b2 = (t3 - t) / (t3 - t1) * a2 + (t - t1) / (t3 - t1) * a3; - + position = ((t2 - t) / (t2 - t1) * b1 + (t - t1) / (t2 - t1) * b2); } } @@ -89,7 +86,7 @@ bool CentripetalCatmullRomSpline::interpolate() { if (m_isClosed) return interpolateClosed(); - + return interpolateOpened(); } @@ -97,7 +94,7 @@ bool CentripetalCatmullRomSpline::interpolateOpened() { if (m_splineKnots.size() < 3) return false; - + { std::vector knots = { (m_splineNodes[m_splineKnots[0]].position + (m_splineNodes[m_splineKnots[0]].position - m_splineNodes[m_splineKnots[1]].position)), @@ -107,7 +104,7 @@ bool CentripetalCatmullRomSpline::interpolateOpened() }; interpolateSegment(knots, m_splineKnots[0], m_splineKnots[1]); } - + { size_t tail = m_splineKnots.size() - 1; std::vector knots = { @@ -123,7 +120,7 @@ bool CentripetalCatmullRomSpline::interpolateOpened() size_t h = i - 1; size_t j = i + 1; size_t k = i + 2; - + std::vector knots = { m_splineNodes[m_splineKnots[h]].position, m_splineNodes[m_splineKnots[i]].position, @@ -132,7 +129,7 @@ bool CentripetalCatmullRomSpline::interpolateOpened() }; interpolateSegment(knots, m_splineKnots[i], m_splineKnots[j]); } - + return true; } @@ -140,7 +137,7 @@ bool CentripetalCatmullRomSpline::interpolateClosed() { if (m_splineKnots.size() < 3) return false; - + for (size_t h = 0; h < m_splineKnots.size(); ++h) { size_t i = (h + 1) % m_splineKnots.size(); size_t j = (h + 2) % m_splineKnots.size(); @@ -154,7 +151,7 @@ bool CentripetalCatmullRomSpline::interpolateClosed() }; interpolateSegment(knots, m_splineKnots[i], m_splineKnots[j]); } - + return true; } diff --git a/dust3d/mesh/centripetal_catmull_rom_spline.h b/dust3d/mesh/centripetal_catmull_rom_spline.h index f7750e38..03c281ac 100644 --- a/dust3d/mesh/centripetal_catmull_rom_spline.h +++ b/dust3d/mesh/centripetal_catmull_rom_spline.h @@ -19,38 +19,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_MESH_CENTRIPETAL_CATMULL_ROM_SPLINE_H_ #define DUST3D_MESH_CENTRIPETAL_CATMULL_ROM_SPLINE_H_ -#include #include +#include -namespace dust3d -{ - -class CentripetalCatmullRomSpline -{ +namespace dust3d { + +class CentripetalCatmullRomSpline { public: - struct SplineNode - { + struct SplineNode { int source = -1; Vector3 position; }; - + CentripetalCatmullRomSpline(bool isClosed); - void addPoint(int source, const Vector3 &position, bool isKnot); + void addPoint(int source, const Vector3& position, bool isKnot); bool interpolate(); - const std::vector &splineNodes(); + const std::vector& splineNodes(); + private: std::vector m_splineNodes; std::vector m_splineKnots; - + bool m_isClosed = false; bool interpolateClosed(); bool interpolateOpened(); - float atKnot(float t, const Vector3 &p0, const Vector3 &p1); - void interpolateSegment(std::vector &knots, + float atKnot(float t, const Vector3& p0, const Vector3& p1); + void interpolateSegment(std::vector& knots, size_t from, size_t to); }; diff --git a/dust3d/mesh/hole_stitcher.cc b/dust3d/mesh/hole_stitcher.cc index 454ab5ec..9da25c02 100644 --- a/dust3d/mesh/hole_stitcher.cc +++ b/dust3d/mesh/hole_stitcher.cc @@ -22,39 +22,38 @@ #include -namespace dust3d -{ +namespace dust3d { HoleStitcher::~HoleStitcher() { delete m_wrapper; } -void HoleStitcher::setVertices(const std::vector *vertices) +void HoleStitcher::setVertices(const std::vector* vertices) { m_positions = vertices; } -const std::vector> &HoleStitcher::newlyGeneratedFaces() +const std::vector>& HoleStitcher::newlyGeneratedFaces() { if (m_wrapper) return m_wrapper->newlyGeneratedFaces(); - + return m_newlyGeneratedFaces; } -void HoleStitcher::getFailedEdgeLoops(std::vector &failedEdgeLoops) +void HoleStitcher::getFailedEdgeLoops(std::vector& failedEdgeLoops) { if (m_wrapper) m_wrapper->getFailedEdgeLoops(failedEdgeLoops); } -bool HoleStitcher::stitchByQuads(const std::vector, Vector3>> &edgeLoops) +bool HoleStitcher::stitchByQuads(const std::vector, Vector3>>& edgeLoops) { if (2 != edgeLoops.size()) return false; - const auto &firstEdgeLoop = edgeLoops[0].first; - const auto &secondEdgeLoop = edgeLoops[1].first; + const auto& firstEdgeLoop = edgeLoops[0].first; + const auto& secondEdgeLoop = edgeLoops[1].first; if (firstEdgeLoop.size() < 3 || firstEdgeLoop.size() != secondEdgeLoop.size()) return false; float minDist2 = std::numeric_limits::max(); @@ -63,8 +62,8 @@ bool HoleStitcher::stitchByQuads(const std::vector float sumOfDist2 = 0; std::vector edges; for (size_t i = 0, j = k; i < firstEdgeLoop.size(); ++i, --j) { - const auto &positionOnFirstEdgeLoop = (*m_positions)[firstEdgeLoop[i % firstEdgeLoop.size()]]; - const auto &positionOnSecondEdgeLoop = (*m_positions)[secondEdgeLoop[(j + secondEdgeLoop.size()) % secondEdgeLoop.size()]]; + const auto& positionOnFirstEdgeLoop = (*m_positions)[firstEdgeLoop[i % firstEdgeLoop.size()]]; + const auto& positionOnSecondEdgeLoop = (*m_positions)[secondEdgeLoop[(j + secondEdgeLoop.size()) % secondEdgeLoop.size()]]; auto edge = positionOnSecondEdgeLoop - positionOnFirstEdgeLoop; sumOfDist2 += edge.lengthSquared(); } @@ -84,12 +83,11 @@ bool HoleStitcher::stitchByQuads(const std::vector return true; } -bool HoleStitcher::stitch(const std::vector, Vector3>> &edgeLoops) +bool HoleStitcher::stitch(const std::vector, Vector3>>& edgeLoops) { - if (edgeLoops.size() == 2 && - edgeLoops[0].first.size() == edgeLoops[1].first.size()) + if (edgeLoops.size() == 2 && edgeLoops[0].first.size() == edgeLoops[1].first.size()) return stitchByQuads(edgeLoops); - + m_wrapper = new HoleWrapper; m_wrapper->setVertices(m_positions); m_wrapper->wrap(edgeLoops); diff --git a/dust3d/mesh/hole_stitcher.h b/dust3d/mesh/hole_stitcher.h index dd4679d1..4ec67348 100644 --- a/dust3d/mesh/hole_stitcher.h +++ b/dust3d/mesh/hole_stitcher.h @@ -23,31 +23,28 @@ #ifndef DUST3D_MESH_HOLE_STITCHER_H_ #define DUST3D_MESH_HOLE_STITCHER_H_ -#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -class HoleStitcher -{ +class HoleStitcher { public: ~HoleStitcher(); - void setVertices(const std::vector *vertices); - bool stitch(const std::vector, Vector3>> &edgeLoops); - const std::vector> &newlyGeneratedFaces(); - void getFailedEdgeLoops(std::vector &failedEdgeLoops); + void setVertices(const std::vector* vertices); + bool stitch(const std::vector, Vector3>>& edgeLoops); + const std::vector>& newlyGeneratedFaces(); + void getFailedEdgeLoops(std::vector& failedEdgeLoops); private: - const std::vector *m_positions; + const std::vector* m_positions; std::vector> m_newlyGeneratedFaces; - HoleWrapper *m_wrapper = nullptr; - - bool stitchByQuads(const std::vector, Vector3>> &edgeLoops); + HoleWrapper* m_wrapper = nullptr; + + bool stitchByQuads(const std::vector, Vector3>>& edgeLoops); }; } #endif - diff --git a/dust3d/mesh/hole_wrapper.cc b/dust3d/mesh/hole_wrapper.cc index 9480080a..55dac74a 100644 --- a/dust3d/mesh/hole_wrapper.cc +++ b/dust3d/mesh/hole_wrapper.cc @@ -21,29 +21,28 @@ */ #include -#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -void HoleWrapper::setVertices(const std::vector *vertices) +void HoleWrapper::setVertices(const std::vector* vertices) { m_positions = vertices; } -void HoleWrapper::wrap(const std::vector, Vector3>> &edgeLoops) +void HoleWrapper::wrap(const std::vector, Vector3>>& edgeLoops) { size_t nextPlaneId = 1; - for (const auto &it: edgeLoops) { + for (const auto& it : edgeLoops) { addCandidateVertices(it.first, it.second, nextPlaneId++); } generate(); finalize(); } -const std::vector> &HoleWrapper::newlyGeneratedFaces() +const std::vector>& HoleWrapper::newlyGeneratedFaces() { return m_newlyGeneratedfaces; } @@ -54,45 +53,45 @@ bool HoleWrapper::finished() return false; if (m_candidates.empty()) return true; - for (const auto &it: m_candidates) { + for (const auto& it : m_candidates) { if (!isVertexClosed(it)) return false; } return true; } -void HoleWrapper::getFailedEdgeLoops(std::vector &failedEdgeLoops) +void HoleWrapper::getFailedEdgeLoops(std::vector& failedEdgeLoops) { std::set edgeLoopIndices; - for (const auto &it: m_candidates) { + for (const auto& it : m_candidates) { if (isVertexClosed(it)) continue; edgeLoopIndices.insert(m_sourceVertices[it].sourcePlane - 1); } - for (const auto &index: edgeLoopIndices) { + for (const auto& index : edgeLoopIndices) { failedEdgeLoops.push_back(index); } } -void HoleWrapper::addCandidateVertices(const std::vector &vertices, const Vector3 &planeNormal, size_t planeId) +void HoleWrapper::addCandidateVertices(const std::vector& vertices, const Vector3& planeNormal, size_t planeId) { std::map verticesIndexSet; - for (const auto &oldVertId: vertices) { + for (const auto& oldVertId : vertices) { if (verticesIndexSet.find(oldVertId) == verticesIndexSet.end()) { size_t index = addSourceVertex((*m_positions)[oldVertId], planeId, oldVertId); - verticesIndexSet.insert({oldVertId, index}); + verticesIndexSet.insert({ oldVertId, index }); } } for (size_t i = 0; i < vertices.size(); ++i) { - const auto &oldVertId = vertices[i]; - const auto &oldNextVertId = vertices[(i + 1) % vertices.size()]; + const auto& oldVertId = vertices[i]; + const auto& oldNextVertId = vertices[(i + 1) % vertices.size()]; auto vertexIndex = verticesIndexSet[oldVertId]; auto nextVertexIndex = verticesIndexSet[oldNextVertId]; addStartup(nextVertexIndex, vertexIndex, planeNormal); } } -size_t HoleWrapper::addSourceVertex(const Vector3 &position, size_t sourcePlane, size_t tag) +size_t HoleWrapper::addSourceVertex(const Vector3& position, size_t sourcePlane, size_t tag) { auto addedIndex = m_sourceVertices.size(); @@ -104,29 +103,29 @@ size_t HoleWrapper::addSourceVertex(const Vector3 &position, size_t sourcePlane, m_sourceVertices.push_back(sourceVertex); m_candidates.push_back(addedIndex); - + return addedIndex; } -void HoleWrapper::addStartup(size_t p1, size_t p2, const Vector3 &baseNormal) +void HoleWrapper::addStartup(size_t p1, size_t p2, const Vector3& baseNormal) { if (m_items.empty()) addItem(p1, p2, baseNormal); - m_generatedFaceEdgesMap.insert({WrapItemKey {p2, p1}, {0, false}}); + m_generatedFaceEdgesMap.insert({ WrapItemKey { p2, p1 }, { 0, false } }); } -Vector3 HoleWrapper::calculateFaceVector(size_t p1, size_t p2, const Vector3 &baseNormal) +Vector3 HoleWrapper::calculateFaceVector(size_t p1, size_t p2, const Vector3& baseNormal) { - const auto &v1 = m_sourceVertices[p1]; - const auto &v2 = m_sourceVertices[p2]; + const auto& v1 = m_sourceVertices[p1]; + const auto& v2 = m_sourceVertices[p2]; auto seg = v2.position - v1.position; return Vector3::crossProduct(seg, baseNormal); } -void HoleWrapper::addItem(size_t p1, size_t p2, const Vector3 &baseNormal) +void HoleWrapper::addItem(size_t p1, size_t p2, const Vector3& baseNormal) { - const auto &v1 = m_sourceVertices[p1]; - const auto &v2 = m_sourceVertices[p2]; + const auto& v1 = m_sourceVertices[p1]; + const auto& v2 = m_sourceVertices[p2]; if (!m_items.empty() && v1.sourcePlane == v2.sourcePlane) return; if (findItem(p1, p2).second || findItem(p2, p1).second) @@ -141,23 +140,23 @@ void HoleWrapper::addItem(size_t p1, size_t p2, const Vector3 &baseNormal) item.baseNormal = baseNormal; item.processed = false; m_items.push_back(item); - m_itemsMap.insert({WrapItemKey {p1, p2}, index}); + m_itemsMap.insert({ WrapItemKey { p1, p2 }, index }); m_itemsList.push_front(index); } std::pair HoleWrapper::findItem(size_t p1, size_t p2) { - auto key = WrapItemKey {p1, p2}; + auto key = WrapItemKey { p1, p2 }; auto findResult = m_itemsMap.find(key); if (findResult == m_itemsMap.end()) { - return {0, false}; + return { 0, false }; } - return {findResult->second, true}; + return { findResult->second, true }; } bool HoleWrapper::isEdgeGenerated(size_t p1, size_t p2) { - auto key = WrapItemKey {p1, p2}; + auto key = WrapItemKey { p1, p2 }; if (m_generatedFaceEdgesMap.find(key) == m_generatedFaceEdgesMap.end()) return false; return true; @@ -165,12 +164,12 @@ bool HoleWrapper::isEdgeGenerated(size_t p1, size_t p2) float HoleWrapper::angleOfBaseFaceAndPoint(size_t itemIndex, size_t vertexIndex) { - const auto &item = m_items[itemIndex]; + const auto& item = m_items[itemIndex]; if (item.p1 == vertexIndex || item.p2 == vertexIndex) return 0.0; - const auto &v1 = m_sourceVertices[item.p1]; - const auto &v2 = m_sourceVertices[item.p2]; - const auto &vp = m_sourceVertices[vertexIndex]; + const auto& v1 = m_sourceVertices[item.p1]; + const auto& v2 = m_sourceVertices[item.p2]; + const auto& vp = m_sourceVertices[vertexIndex]; if (v1.sourcePlane == v2.sourcePlane && v1.sourcePlane == vp.sourcePlane) return 0.0; auto vd1 = calculateFaceVector(item.p1, item.p2, item.baseNormal); @@ -184,7 +183,7 @@ std::pair HoleWrapper::findBestVertexOnTheLeft(size_t itemIndex) auto p1 = m_items[itemIndex].p1; auto p2 = m_items[itemIndex].p2; auto maxAngle = 0.0; - std::pair result = {0, false}; + std::pair result = { 0, false }; for (auto it = m_candidates.begin(); it != m_candidates.end(); /*void*/) { auto cand = *it; if (isVertexClosed(cand)) { @@ -197,7 +196,7 @@ std::pair HoleWrapper::findBestVertexOnTheLeft(size_t itemIndex) auto angle = angleOfBaseFaceAndPoint(itemIndex, cand); if (angle > maxAngle) { maxAngle = angle; - result = {cand, true}; + result = { cand, true }; } } return result; @@ -205,18 +204,17 @@ std::pair HoleWrapper::findBestVertexOnTheLeft(size_t itemIndex) std::pair HoleWrapper::peekItem() { - for (const auto &itemIndex : m_itemsList) { + for (const auto& itemIndex : m_itemsList) { if (!m_items[itemIndex].processed) { - return {itemIndex, true}; + return { itemIndex, true }; } } - return {0, false}; + return { 0, false }; } bool HoleWrapper::isEdgeClosed(size_t p1, size_t p2) { - return m_generatedFaceEdgesMap.find(WrapItemKey {p1, p2}) != m_generatedFaceEdgesMap.end() && - m_generatedFaceEdgesMap.find(WrapItemKey {p2, p1}) != m_generatedFaceEdgesMap.end(); + return m_generatedFaceEdgesMap.find(WrapItemKey { p1, p2 }) != m_generatedFaceEdgesMap.end() && m_generatedFaceEdgesMap.find(WrapItemKey { p2, p1 }) != m_generatedFaceEdgesMap.end(); } bool HoleWrapper::isVertexClosed(size_t vertexIndex) @@ -224,7 +222,7 @@ bool HoleWrapper::isVertexClosed(size_t vertexIndex) auto findResult = m_generatedVertexEdgesMap.find(vertexIndex); if (findResult == m_generatedVertexEdgesMap.end()) return false; - for (const auto &otherIndex: findResult->second) { + for (const auto& otherIndex : findResult->second) { if (!isEdgeClosed(vertexIndex, otherIndex)) return false; } @@ -251,12 +249,12 @@ void HoleWrapper::generate() m_sourceVertices[p2].position, m_sourceVertices[p3].position); auto faceIndex = m_generatedFaces.size(); - m_generatedFaces.push_back(Face3 {p1, p2, p3, baseNormal, faceIndex}); + m_generatedFaces.push_back(Face3 { p1, p2, p3, baseNormal, faceIndex }); addItem(p3, p2, baseNormal); addItem(p1, p3, baseNormal); - m_generatedFaceEdgesMap.insert({WrapItemKey {p1, p2}, {faceIndex, true}}); - m_generatedFaceEdgesMap.insert({WrapItemKey {p2, p3}, {faceIndex, true}}); - m_generatedFaceEdgesMap.insert({WrapItemKey {p3, p1}, {faceIndex, true}}); + m_generatedFaceEdgesMap.insert({ WrapItemKey { p1, p2 }, { faceIndex, true } }); + m_generatedFaceEdgesMap.insert({ WrapItemKey { p2, p3 }, { faceIndex, true } }); + m_generatedFaceEdgesMap.insert({ WrapItemKey { p3, p1 }, { faceIndex, true } }); m_generatedVertexEdgesMap[p1].push_back(p2); m_generatedVertexEdgesMap[p1].push_back(p3); m_generatedVertexEdgesMap[p2].push_back(p3); @@ -267,44 +265,42 @@ void HoleWrapper::generate() } } -size_t HoleWrapper::anotherVertexIndexOfFace3(const Face3 &f, size_t p1, size_t p2) +size_t HoleWrapper::anotherVertexIndexOfFace3(const Face3& f, size_t p1, size_t p2) { - std::vector indices = {f.p1, f.p2, f.p3}; - for (const auto &index : indices) { + std::vector indices = { f.p1, f.p2, f.p3 }; + for (const auto& index : indices) { if (index != p1 && index != p2) return index; } return 0; } -std::pair HoleWrapper::findPairFace3(const Face3 &f, std::map &usedIds, std::vector &q) +std::pair HoleWrapper::findPairFace3(const Face3& f, std::map& usedIds, std::vector& q) { - std::vector indices = {f.p1, f.p2, f.p3}; + std::vector indices = { f.p1, f.p2, f.p3 }; for (size_t i = 0; i < indices.size(); ++i) { auto j = (i + 1) % indices.size(); auto k = (i + 2) % indices.size(); - auto findPairedFace3Id = m_generatedFaceEdgesMap.find(WrapItemKey {indices[j], indices[i]}); + auto findPairedFace3Id = m_generatedFaceEdgesMap.find(WrapItemKey { indices[j], indices[i] }); if (findPairedFace3Id != m_generatedFaceEdgesMap.end() && findPairedFace3Id->second.second) { auto pairedFace3Id = findPairedFace3Id->second.first; if (usedIds.find(pairedFace3Id) != usedIds.end()) continue; - const auto &pairedFace3 = m_generatedFaces[pairedFace3Id]; + const auto& pairedFace3 = m_generatedFaces[pairedFace3Id]; if (!almostEqual(pairedFace3.normal, f.normal)) continue; auto anotherIndex = anotherVertexIndexOfFace3(pairedFace3, indices[j], indices[i]); - auto mergedF = Face4 {indices[i], anotherIndex, indices[j], indices[k]}; + auto mergedF = Face4 { indices[i], anotherIndex, indices[j], indices[k] }; q.push_back(mergedF); - return {pairedFace3Id, true}; + return { pairedFace3Id, true }; } } - return {0, false}; + return { 0, false }; } -bool HoleWrapper::almostEqual(const Vector3 &v1, const Vector3 &v2) +bool HoleWrapper::almostEqual(const Vector3& v1, const Vector3& v2) { - return abs(v1.x() - v2.x()) <= 0.01 && - abs(v1.y() - v2.y()) <= 0.01 && - abs(v1.z() - v2.z()) <= 0.01; + return abs(v1.x() - v2.x()) <= 0.01 && abs(v1.y() - v2.y()) <= 0.01 && abs(v1.z() - v2.z()) <= 0.01; } void HoleWrapper::finalize() @@ -312,13 +308,13 @@ void HoleWrapper::finalize() std::vector quads; std::map usedIds; m_finalizeFinished = true; - for (const auto &f: m_generatedFaces) { + for (const auto& f : m_generatedFaces) { if (usedIds.find(f.index) != usedIds.end()) continue; - usedIds.insert({f.index, true}); + usedIds.insert({ f.index, true }); auto paired = findPairFace3(f, usedIds, quads); if (paired.second) { - usedIds.insert({paired.first, true}); + usedIds.insert({ paired.first, true }); continue; } std::vector addedVertices = { @@ -328,7 +324,7 @@ void HoleWrapper::finalize() }; m_newlyGeneratedfaces.push_back(addedVertices); } - for (const auto &f: quads) { + for (const auto& f : quads) { std::vector addedVertices = { m_sourceVertices[f.p1].tag, m_sourceVertices[f.p2].tag, diff --git a/dust3d/mesh/hole_wrapper.h b/dust3d/mesh/hole_wrapper.h index 273f7dca..6e670efe 100644 --- a/dust3d/mesh/hole_wrapper.h +++ b/dust3d/mesh/hole_wrapper.h @@ -23,30 +23,27 @@ #ifndef DUST3D_MESH_HOLE_WRAPPER_H_ #define DUST3D_MESH_HOLE_WRAPPER_H_ -#include -#include #include #include +#include +#include -namespace dust3d -{ - -class HoleWrapper -{ +namespace dust3d { + +class HoleWrapper { public: - void setVertices(const std::vector *vertices); - void wrap(const std::vector, Vector3>> &edgeLoops); - const std::vector> &newlyGeneratedFaces(); + void setVertices(const std::vector* vertices); + void wrap(const std::vector, Vector3>>& edgeLoops); + const std::vector>& newlyGeneratedFaces(); bool finished(); - void getFailedEdgeLoops(std::vector &failedEdgeLoops); + void getFailedEdgeLoops(std::vector& failedEdgeLoops); private: - struct WrapItemKey - { + struct WrapItemKey { size_t p1; size_t p2; - - bool operator <(const WrapItemKey &right) const + + bool operator<(const WrapItemKey& right) const { if (p1 < right.p1) return true; @@ -59,45 +56,41 @@ private: return false; } }; - - struct WrapItem - { + + struct WrapItem { Vector3 baseNormal; size_t p1; size_t p2; size_t p3; bool processed; }; - - struct Face3 - { + + struct Face3 { size_t p1; size_t p2; size_t p3; Vector3 normal; size_t index; }; - - struct Face4 - { + + struct Face4 { size_t p1; size_t p2; size_t p3; size_t p4; }; - - struct SourceVertex - { + + struct SourceVertex { Vector3 position; size_t sourcePlane; size_t index; size_t tag; }; - + std::vector m_items; std::map m_itemsMap; std::deque m_itemsList; - const std::vector *m_positions; + const std::vector* m_positions; std::vector m_candidates; std::vector m_sourceVertices; std::vector m_generatedFaces; @@ -105,12 +98,12 @@ private: std::map> m_generatedVertexEdgesMap; bool m_finalizeFinished = false; std::vector> m_newlyGeneratedfaces; - - void addCandidateVertices(const std::vector &vertices, const Vector3 &planeNormal, size_t planeId); - size_t addSourceVertex(const Vector3 &position, size_t sourcePlane, size_t tag); - void addStartup(size_t p1, size_t p2, const Vector3 &baseNormal); - Vector3 calculateFaceVector(size_t p1, size_t p2, const Vector3 &baseNormal); - void addItem(size_t p1, size_t p2, const Vector3 &baseNormal); + + void addCandidateVertices(const std::vector& vertices, const Vector3& planeNormal, size_t planeId); + size_t addSourceVertex(const Vector3& position, size_t sourcePlane, size_t tag); + void addStartup(size_t p1, size_t p2, const Vector3& baseNormal); + Vector3 calculateFaceVector(size_t p1, size_t p2, const Vector3& baseNormal); + void addItem(size_t p1, size_t p2, const Vector3& baseNormal); std::pair findItem(size_t p1, size_t p2); bool isEdgeGenerated(size_t p1, size_t p2); float angleOfBaseFaceAndPoint(size_t itemIndex, size_t vertexIndex); @@ -119,10 +112,10 @@ private: bool isEdgeClosed(size_t p1, size_t p2); bool isVertexClosed(size_t vertexIndex); void generate(); - size_t anotherVertexIndexOfFace3(const Face3 &f, size_t p1, size_t p2); - std::pair findPairFace3(const Face3 &f, std::map &usedIds, std::vector &q); + size_t anotherVertexIndexOfFace3(const Face3& f, size_t p1, size_t p2); + std::pair findPairFace3(const Face3& f, std::map& usedIds, std::vector& q); void finalize(); - bool almostEqual(const Vector3 &v1, const Vector3 &v2); + bool almostEqual(const Vector3& v1, const Vector3& v2); }; } diff --git a/dust3d/mesh/isotropic_halfedge_mesh.cc b/dust3d/mesh/isotropic_halfedge_mesh.cc index b13f84bf..409d9d8e 100644 --- a/dust3d/mesh/isotropic_halfedge_mesh.cc +++ b/dust3d/mesh/isotropic_halfedge_mesh.cc @@ -20,100 +20,99 @@ * SOFTWARE. */ -#include #include #include #include +#include -namespace dust3d -{ +namespace dust3d { IsotropicHalfedgeMesh::~IsotropicHalfedgeMesh() { while (nullptr != m_vertexAllocLink) { - Vertex *vertex = m_vertexAllocLink; + Vertex* vertex = m_vertexAllocLink; m_vertexAllocLink = vertex->_allocLink; delete vertex; } - + while (nullptr != m_faceAllocLink) { - Face *face = m_faceAllocLink; + Face* face = m_faceAllocLink; m_faceAllocLink = face->_allocLink; delete face; } - + while (nullptr != m_halfedgeAllocLink) { - Halfedge *halfedge = m_halfedgeAllocLink; + Halfedge* halfedge = m_halfedgeAllocLink; m_halfedgeAllocLink = halfedge->_allocLink; delete halfedge; } } -IsotropicHalfedgeMesh::IsotropicHalfedgeMesh(const std::vector &vertices, - const std::vector> &faces) +IsotropicHalfedgeMesh::IsotropicHalfedgeMesh(const std::vector& vertices, + const std::vector>& faces) { - std::vector halfedgeVertices; + std::vector halfedgeVertices; halfedgeVertices.reserve(vertices.size()); int sourceIndex = 0; - for (const auto &it: vertices) { - Vertex *vertex = newVertex(); + for (const auto& it : vertices) { + Vertex* vertex = newVertex(); vertex->position = it; vertex->sourceIndex = sourceIndex++; halfedgeVertices.push_back(vertex); } - - std::vector halfedgeFaces; + + std::vector halfedgeFaces; halfedgeFaces.reserve(faces.size()); - for (const auto &it: faces) { - Face *face = newFace(); + for (const auto& it : faces) { + Face* face = newFace(); halfedgeFaces.push_back(face); } - std::unordered_map halfedgeMap; + std::unordered_map halfedgeMap; for (size_t faceIndex = 0; faceIndex < faces.size(); ++faceIndex) { - const auto &indices = faces[faceIndex]; + const auto& indices = faces[faceIndex]; if (3 != indices.size()) { dust3dDebug << "Found non-triangle, face count:" << indices.size(); continue; } - std::vector halfedges(indices.size()); + std::vector halfedges(indices.size()); for (size_t i = 0; i < 3; ++i) { size_t j = (i + 1) % 3; - const auto &first = indices[i]; - const auto &second = indices[j]; - - Vertex *vertex = halfedgeVertices[first]; + const auto& first = indices[i]; + const auto& second = indices[j]; + + Vertex* vertex = halfedgeVertices[first]; ++vertex->initialFaces; - - Halfedge *halfedge = newHalfedge(); + + Halfedge* halfedge = newHalfedge(); halfedge->startVertex = vertex; halfedge->leftFace = halfedgeFaces[faceIndex]; - + if (nullptr == halfedge->leftFace->halfedge) { halfedge->leftFace->halfedge = halfedge; } if (nullptr == vertex->firstHalfedge) { vertex->firstHalfedge = halfedge; } - + halfedges[i] = halfedge; - - auto insertResult = halfedgeMap.insert({makeHalfedgeKey(first, second), halfedge}); + + auto insertResult = halfedgeMap.insert({ makeHalfedgeKey(first, second), halfedge }); if (!insertResult.second) { dust3dDebug << "Found repeated halfedge:" << first << "," << second; } } linkFaceHalfedges(halfedges); } - for (auto &it: halfedgeMap) { + for (auto& it : halfedgeMap) { auto halfedgeIt = halfedgeMap.find(swapHalfedgeKey(it.first)); if (halfedgeIt == halfedgeMap.end()) continue; it.second->oppositeHalfedge = halfedgeIt->second; halfedgeIt->second->oppositeHalfedge = it.second; } - - for (Vertex *vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { + + for (Vertex* vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { vertex->_isBoundary = false; vertex->_valence = vertexValence(vertex, &vertex->_isBoundary); if (vertex->_isBoundary) { @@ -127,7 +126,7 @@ IsotropicHalfedgeMesh::IsotropicHalfedgeMesh(const std::vector &vertice } } -void IsotropicHalfedgeMesh::linkFaceHalfedges(std::vector &halfedges) +void IsotropicHalfedgeMesh::linkFaceHalfedges(std::vector& halfedges) { for (size_t i = 0; i < halfedges.size(); ++i) { size_t j = (i + 1) % halfedges.size(); @@ -136,14 +135,14 @@ void IsotropicHalfedgeMesh::linkFaceHalfedges(std::vector &halfedges, - IsotropicHalfedgeMesh::Face *leftFace) +void IsotropicHalfedgeMesh::updateFaceHalfedgesLeftFace(std::vector& halfedges, + IsotropicHalfedgeMesh::Face* leftFace) { - for (auto &it: halfedges) + for (auto& it : halfedges) it->leftFace = leftFace; } -void IsotropicHalfedgeMesh::linkHalfedgePair(IsotropicHalfedgeMesh::Halfedge *first, IsotropicHalfedgeMesh::Halfedge *second) +void IsotropicHalfedgeMesh::linkHalfedgePair(IsotropicHalfedgeMesh::Halfedge* first, IsotropicHalfedgeMesh::Halfedge* second) { if (nullptr != first) first->oppositeHalfedge = second; @@ -155,11 +154,11 @@ double IsotropicHalfedgeMesh::averageEdgeLength() { double totalLength = 0.0; size_t halfedgeCount = 0; - for (Face *face = m_firstFace; nullptr != face; face = face->nextFace) { - const auto &startHalfedge = face->halfedge; - Halfedge *halfedge = startHalfedge; + for (Face* face = m_firstFace; nullptr != face; face = face->nextFace) { + const auto& startHalfedge = face->halfedge; + Halfedge* halfedge = startHalfedge; do { - const auto &nextHalfedge = halfedge->nextHalfedge; + const auto& nextHalfedge = halfedge->nextHalfedge; totalLength += (halfedge->startVertex->position - nextHalfedge->startVertex->position).length(); ++halfedgeCount; } while (halfedge != startHalfedge); @@ -169,13 +168,13 @@ double IsotropicHalfedgeMesh::averageEdgeLength() return totalLength / halfedgeCount; } -IsotropicHalfedgeMesh::Face *IsotropicHalfedgeMesh::newFace() +IsotropicHalfedgeMesh::Face* IsotropicHalfedgeMesh::newFace() { - Face *face = new Face; - + Face* face = new Face; + face->_allocLink = m_faceAllocLink; m_faceAllocLink = face; - + face->debugIndex = ++m_debugFaceIndex; if (nullptr != m_lastFace) { m_lastFace->nextFace = face; @@ -187,13 +186,13 @@ IsotropicHalfedgeMesh::Face *IsotropicHalfedgeMesh::newFace() return face; } -IsotropicHalfedgeMesh::Vertex *IsotropicHalfedgeMesh::newVertex() +IsotropicHalfedgeMesh::Vertex* IsotropicHalfedgeMesh::newVertex() { - Vertex *vertex = new Vertex; - + Vertex* vertex = new Vertex; + vertex->_allocLink = m_vertexAllocLink; m_vertexAllocLink = vertex; - + vertex->debugIndex = ++m_debugVertexIndex; if (nullptr != m_lastVertex) { m_lastVertex->nextVertex = vertex; @@ -205,18 +204,18 @@ IsotropicHalfedgeMesh::Vertex *IsotropicHalfedgeMesh::newVertex() return vertex; } -IsotropicHalfedgeMesh::Halfedge *IsotropicHalfedgeMesh::newHalfedge() +IsotropicHalfedgeMesh::Halfedge* IsotropicHalfedgeMesh::newHalfedge() { - Halfedge *halfedge = new Halfedge; - + Halfedge* halfedge = new Halfedge; + halfedge->_allocLink = m_halfedgeAllocLink; m_halfedgeAllocLink = halfedge; - + halfedge->debugIndex = ++m_debugHalfedgeIndex; return halfedge; } -IsotropicHalfedgeMesh::Face *IsotropicHalfedgeMesh::moveToNextFace(IsotropicHalfedgeMesh::Face *face) +IsotropicHalfedgeMesh::Face* IsotropicHalfedgeMesh::moveToNextFace(IsotropicHalfedgeMesh::Face* face) { if (nullptr == face) { face = m_firstFace; @@ -231,7 +230,7 @@ IsotropicHalfedgeMesh::Face *IsotropicHalfedgeMesh::moveToNextFace(IsotropicHalf return face; } -IsotropicHalfedgeMesh::Vertex *IsotropicHalfedgeMesh::moveToNextVertex(IsotropicHalfedgeMesh::Vertex *vertex) +IsotropicHalfedgeMesh::Vertex* IsotropicHalfedgeMesh::moveToNextVertex(IsotropicHalfedgeMesh::Vertex* vertex) { if (nullptr == vertex) { vertex = m_firstVertex; @@ -246,22 +245,22 @@ IsotropicHalfedgeMesh::Vertex *IsotropicHalfedgeMesh::moveToNextVertex(Isotropic return vertex; } -void IsotropicHalfedgeMesh::breakFace(IsotropicHalfedgeMesh::Face *leftOldFace, - IsotropicHalfedgeMesh::Halfedge *halfedge, - IsotropicHalfedgeMesh::Vertex *breakPointVertex, - std::vector &leftNewFaceHalfedges, - std::vector &leftOldFaceHalfedges) +void IsotropicHalfedgeMesh::breakFace(IsotropicHalfedgeMesh::Face* leftOldFace, + IsotropicHalfedgeMesh::Halfedge* halfedge, + IsotropicHalfedgeMesh::Vertex* breakPointVertex, + std::vector& leftNewFaceHalfedges, + std::vector& leftOldFaceHalfedges) { - std::vector leftFaceHalfedges = { + std::vector leftFaceHalfedges = { halfedge->previousHalfedge, halfedge, halfedge->nextHalfedge }; - - Face *leftNewFace = newFace(); + + Face* leftNewFace = newFace(); leftNewFace->halfedge = leftFaceHalfedges[2]; leftFaceHalfedges[2]->leftFace = leftNewFace; - + leftNewFaceHalfedges.push_back(newHalfedge()); leftNewFaceHalfedges.push_back(newHalfedge()); leftNewFaceHalfedges.push_back(leftFaceHalfedges[2]); @@ -269,45 +268,43 @@ void IsotropicHalfedgeMesh::breakFace(IsotropicHalfedgeMesh::Face *leftOldFace, updateFaceHalfedgesLeftFace(leftNewFaceHalfedges, leftNewFace); leftNewFaceHalfedges[0]->startVertex = leftFaceHalfedges[0]->startVertex; leftNewFaceHalfedges[1]->startVertex = breakPointVertex; - + leftOldFaceHalfedges.push_back(leftFaceHalfedges[0]); leftOldFaceHalfedges.push_back(halfedge); leftOldFaceHalfedges.push_back(newHalfedge()); linkFaceHalfedges(leftOldFaceHalfedges); updateFaceHalfedgesLeftFace(leftOldFaceHalfedges, leftOldFace); leftOldFaceHalfedges[2]->startVertex = breakPointVertex; - + breakPointVertex->firstHalfedge = leftNewFaceHalfedges[1]; - + linkHalfedgePair(leftNewFaceHalfedges[0], leftOldFaceHalfedges[2]); - + leftOldFace->halfedge = leftOldFaceHalfedges[0]; } -void IsotropicHalfedgeMesh::breakEdge(IsotropicHalfedgeMesh::Halfedge *halfedge) +void IsotropicHalfedgeMesh::breakEdge(IsotropicHalfedgeMesh::Halfedge* halfedge) { - Face *leftOldFace = halfedge->leftFace; - Halfedge *oppositeHalfedge = halfedge->oppositeHalfedge; - Face *rightOldFace = nullptr; - + Face* leftOldFace = halfedge->leftFace; + Halfedge* oppositeHalfedge = halfedge->oppositeHalfedge; + Face* rightOldFace = nullptr; + if (nullptr != oppositeHalfedge) rightOldFace = oppositeHalfedge->leftFace; - - Vertex *breakPointVertex = newVertex(); - breakPointVertex->position = (halfedge->startVertex->position + - halfedge->nextHalfedge->startVertex->position) * 0.5; - - breakPointVertex->featured = halfedge->startVertex->featured && - halfedge->nextHalfedge->startVertex->featured; - std::vector leftNewFaceHalfedges; - std::vector leftOldFaceHalfedges; + Vertex* breakPointVertex = newVertex(); + breakPointVertex->position = (halfedge->startVertex->position + halfedge->nextHalfedge->startVertex->position) * 0.5; + + breakPointVertex->featured = halfedge->startVertex->featured && halfedge->nextHalfedge->startVertex->featured; + + std::vector leftNewFaceHalfedges; + std::vector leftOldFaceHalfedges; breakFace(leftOldFace, halfedge, breakPointVertex, leftNewFaceHalfedges, leftOldFaceHalfedges); - + if (nullptr != rightOldFace) { - std::vector rightNewFaceHalfedges; - std::vector rightOldFaceHalfedges; + std::vector rightNewFaceHalfedges; + std::vector rightOldFaceHalfedges; breakFace(rightOldFace, oppositeHalfedge, breakPointVertex, rightNewFaceHalfedges, rightOldFaceHalfedges); linkHalfedgePair(leftOldFaceHalfedges[1], rightNewFaceHalfedges[1]); @@ -315,14 +312,14 @@ void IsotropicHalfedgeMesh::breakEdge(IsotropicHalfedgeMesh::Halfedge *halfedge) } } -void IsotropicHalfedgeMesh::collectVerticesAroundVertex(Vertex *vertex, - std::set *vertices) +void IsotropicHalfedgeMesh::collectVerticesAroundVertex(Vertex* vertex, + std::set* vertices) { - const auto &startHalfedge = vertex->firstHalfedge; + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) return; - - Halfedge *loopHalfedge = startHalfedge; + + Halfedge* loopHalfedge = startHalfedge; do { vertices->insert(loopHalfedge->nextHalfedge->startVertex); if (nullptr == loopHalfedge->oppositeHalfedge) { @@ -339,15 +336,15 @@ void IsotropicHalfedgeMesh::collectVerticesAroundVertex(Vertex *vertex, } while (loopHalfedge != startHalfedge); } -size_t IsotropicHalfedgeMesh::vertexValence(Vertex *vertex, bool *isBoundary) +size_t IsotropicHalfedgeMesh::vertexValence(Vertex* vertex, bool* isBoundary) { - const auto &startHalfedge = vertex->firstHalfedge; + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) return 0; - + size_t valence = 0; - - Halfedge *loopHalfedge = startHalfedge; + + Halfedge* loopHalfedge = startHalfedge; do { ++valence; if (nullptr == loopHalfedge->oppositeHalfedge) { @@ -364,30 +361,28 @@ size_t IsotropicHalfedgeMesh::vertexValence(Vertex *vertex, bool *isBoundary) } loopHalfedge = loopHalfedge->oppositeHalfedge->nextHalfedge; } while (loopHalfedge != startHalfedge); - + return valence; } -bool IsotropicHalfedgeMesh::testLengthSquaredAroundVertex(Vertex *vertex, - const Vector3 &target, +bool IsotropicHalfedgeMesh::testLengthSquaredAroundVertex(Vertex* vertex, + const Vector3& target, double maxEdgeLengthSquared) { - const auto &startHalfedge = vertex->firstHalfedge; + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) return false; - - Halfedge *loopHalfedge = startHalfedge; + + Halfedge* loopHalfedge = startHalfedge; do { - if ((loopHalfedge->nextHalfedge->startVertex->position - - target).lengthSquared() > maxEdgeLengthSquared) { - return true; + if ((loopHalfedge->nextHalfedge->startVertex->position - target).lengthSquared() > maxEdgeLengthSquared) { + return true; } if (nullptr == loopHalfedge->oppositeHalfedge) { loopHalfedge = startHalfedge; do { - if ((loopHalfedge->previousHalfedge->startVertex->position - - target).lengthSquared() > maxEdgeLengthSquared) { - return true; + if ((loopHalfedge->previousHalfedge->startVertex->position - target).lengthSquared() > maxEdgeLengthSquared) { + return true; } loopHalfedge = loopHalfedge->previousHalfedge->oppositeHalfedge; if (nullptr == loopHalfedge) @@ -397,17 +392,17 @@ bool IsotropicHalfedgeMesh::testLengthSquaredAroundVertex(Vertex *vertex, } loopHalfedge = loopHalfedge->oppositeHalfedge->nextHalfedge; } while (loopHalfedge != startHalfedge); - + return false; } -void IsotropicHalfedgeMesh::pointerVertexToNewVertex(Vertex *vertex, Vertex *replacement) +void IsotropicHalfedgeMesh::pointerVertexToNewVertex(Vertex* vertex, Vertex* replacement) { - const auto &startHalfedge = vertex->firstHalfedge; + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) return; - - Halfedge *loopHalfedge = startHalfedge; + + Halfedge* loopHalfedge = startHalfedge; do { loopHalfedge->startVertex = replacement; if (nullptr == loopHalfedge->oppositeHalfedge) { @@ -424,174 +419,164 @@ void IsotropicHalfedgeMesh::pointerVertexToNewVertex(Vertex *vertex, Vertex *rep } while (loopHalfedge != startHalfedge); } -void IsotropicHalfedgeMesh::relaxVertex(Vertex *vertex) +void IsotropicHalfedgeMesh::relaxVertex(Vertex* vertex) { if (vertex->_isBoundary || vertex->_valence <= 0) return; - - const auto &startHalfedge = vertex->firstHalfedge; + + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) return; - + Vector3 position; - - Halfedge *loopHalfedge = startHalfedge; + + Halfedge* loopHalfedge = startHalfedge; do { position += loopHalfedge->oppositeHalfedge->startVertex->position; loopHalfedge = loopHalfedge->oppositeHalfedge->nextHalfedge; } while (loopHalfedge != startHalfedge); - + position /= vertex->_valence; - + Vector3 projectedPosition = Vector3::projectPointOnLine(vertex->position, position, position + vertex->_normal); if (projectedPosition.containsNan() || projectedPosition.containsInf()) { vertex->position = position; return; } - + vertex->position = projectedPosition; } -bool IsotropicHalfedgeMesh::flipEdge(Halfedge *halfedge) +bool IsotropicHalfedgeMesh::flipEdge(Halfedge* halfedge) { - Vertex *topVertex = halfedge->previousHalfedge->startVertex; - Vertex *bottomVertex = halfedge->oppositeHalfedge->previousHalfedge->startVertex; - - Vertex *leftVertex = halfedge->startVertex; - Vertex *rightVertex = halfedge->oppositeHalfedge->startVertex; + Vertex* topVertex = halfedge->previousHalfedge->startVertex; + Vertex* bottomVertex = halfedge->oppositeHalfedge->previousHalfedge->startVertex; + + Vertex* leftVertex = halfedge->startVertex; + Vertex* rightVertex = halfedge->oppositeHalfedge->startVertex; bool isLeftBoundary = false; int leftValence = (int)vertexValence(leftVertex, &isLeftBoundary); if (leftValence <= 3) return false; - + bool isRightBoundary = false; int rightValence = (int)vertexValence(rightVertex, &isRightBoundary); if (rightValence <= 3) return false; - + bool isTopBoundary = false; int topValence = (int)vertexValence(topVertex, &isTopBoundary); - + bool isBottomBoundary = false; int bottomValence = (int)vertexValence(bottomVertex, &isBottomBoundary); - + auto deviation = [](int valence, bool isBoundary) { return std::pow(valence - (isBoundary ? 4 : 6), 2); }; - - int oldDeviation = deviation(topValence, isTopBoundary) + - deviation(bottomValence, isBottomBoundary) + - deviation(leftValence, isLeftBoundary) + - deviation(rightValence, isRightBoundary); - int newDeviation = deviation(topValence + 1, isTopBoundary) + - deviation(bottomValence + 1, isBottomBoundary) + - deviation(leftValence - 1, isLeftBoundary) + - deviation(rightValence - 1, isRightBoundary); - + + int oldDeviation = deviation(topValence, isTopBoundary) + deviation(bottomValence, isBottomBoundary) + deviation(leftValence, isLeftBoundary) + deviation(rightValence, isRightBoundary); + int newDeviation = deviation(topValence + 1, isTopBoundary) + deviation(bottomValence + 1, isBottomBoundary) + deviation(leftValence - 1, isLeftBoundary) + deviation(rightValence - 1, isRightBoundary); + if (newDeviation >= oldDeviation) return false; - - Halfedge *opposite = halfedge->oppositeHalfedge; - - Face *topFace = halfedge->leftFace; - Face *bottomFace = opposite->leftFace; - + + Halfedge* opposite = halfedge->oppositeHalfedge; + + Face* topFace = halfedge->leftFace; + Face* bottomFace = opposite->leftFace; + if (leftVertex->firstHalfedge == halfedge) leftVertex->firstHalfedge = opposite->nextHalfedge; - + if (rightVertex->firstHalfedge == opposite) rightVertex->firstHalfedge = halfedge->nextHalfedge; - + halfedge->nextHalfedge->leftFace = bottomFace; opposite->nextHalfedge->leftFace = topFace; - + halfedge->startVertex = bottomVertex; opposite->startVertex = topVertex; - + topFace->halfedge = halfedge; bottomFace->halfedge = opposite; - std::vector newLeftHalfedges = { + std::vector newLeftHalfedges = { halfedge->previousHalfedge, opposite->nextHalfedge, halfedge }; - std::vector newRightHalfedges = { + std::vector newRightHalfedges = { opposite->previousHalfedge, halfedge->nextHalfedge, opposite, }; - + linkFaceHalfedges(newLeftHalfedges); linkFaceHalfedges(newRightHalfedges); return true; } -bool IsotropicHalfedgeMesh::collapseEdge(Halfedge *halfedge, double maxEdgeLengthSquared) -{ - Halfedge *opposite = halfedge->oppositeHalfedge; - - Vertex *topVertex = halfedge->previousHalfedge->startVertex; - Vertex *bottomVertex = opposite->previousHalfedge->startVertex; - +bool IsotropicHalfedgeMesh::collapseEdge(Halfedge* halfedge, double maxEdgeLengthSquared) +{ + Halfedge* opposite = halfedge->oppositeHalfedge; + + Vertex* topVertex = halfedge->previousHalfedge->startVertex; + Vertex* bottomVertex = opposite->previousHalfedge->startVertex; + if (topVertex == bottomVertex) return false; - + if (topVertex->featured) return false; - + if (bottomVertex->featured) return false; - - Vector3 collapseTo = (halfedge->startVertex->position + - halfedge->nextHalfedge->startVertex->position) * 0.5; - + + Vector3 collapseTo = (halfedge->startVertex->position + halfedge->nextHalfedge->startVertex->position) * 0.5; + if (testLengthSquaredAroundVertex(halfedge->startVertex, collapseTo, maxEdgeLengthSquared)) return false; if (testLengthSquaredAroundVertex(halfedge->nextHalfedge->startVertex, collapseTo, maxEdgeLengthSquared)) return false; - - std::set neighborVertices; - std::set otherNeighborVertices; + + std::set neighborVertices; + std::set otherNeighborVertices; collectVerticesAroundVertex(halfedge->startVertex, &neighborVertices); collectVerticesAroundVertex(halfedge->nextHalfedge->startVertex, &otherNeighborVertices); - std::vector sharedNeighborVertices; + std::vector sharedNeighborVertices; std::set_intersection(neighborVertices.begin(), neighborVertices.end(), otherNeighborVertices.begin(), otherNeighborVertices.end(), std::back_inserter(sharedNeighborVertices)); if (sharedNeighborVertices.size() > 2) { return false; } - - Vertex *leftVertex = halfedge->startVertex; - Vertex *rightVertex = opposite->startVertex; - Face *topFace = halfedge->leftFace; - Face *bottomFace = opposite->leftFace; + + Vertex* leftVertex = halfedge->startVertex; + Vertex* rightVertex = opposite->startVertex; + Face* topFace = halfedge->leftFace; + Face* bottomFace = opposite->leftFace; pointerVertexToNewVertex(leftVertex, rightVertex); - - if (topFace == rightVertex->firstHalfedge->leftFace || - bottomFace == rightVertex->firstHalfedge->leftFace) { + + if (topFace == rightVertex->firstHalfedge->leftFace || bottomFace == rightVertex->firstHalfedge->leftFace) { rightVertex->firstHalfedge = opposite->previousHalfedge->oppositeHalfedge; } - if (topFace == topVertex->firstHalfedge->leftFace || - bottomFace == topVertex->firstHalfedge->leftFace) { + if (topFace == topVertex->firstHalfedge->leftFace || bottomFace == topVertex->firstHalfedge->leftFace) { topVertex->firstHalfedge = halfedge->nextHalfedge->oppositeHalfedge; } - if (bottomFace == bottomVertex->firstHalfedge->leftFace || - bottomFace == bottomVertex->firstHalfedge->leftFace) { + if (bottomFace == bottomVertex->firstHalfedge->leftFace || bottomFace == bottomVertex->firstHalfedge->leftFace) { bottomVertex->firstHalfedge = opposite->nextHalfedge->oppositeHalfedge; } - + linkHalfedgePair(halfedge->previousHalfedge->oppositeHalfedge, halfedge->nextHalfedge->oppositeHalfedge); linkHalfedgePair(opposite->previousHalfedge->oppositeHalfedge, opposite->nextHalfedge->oppositeHalfedge); - + rightVertex->position = collapseTo; - + leftVertex->removed = true; topFace->removed = true; bottomFace->removed = true; @@ -601,7 +586,7 @@ bool IsotropicHalfedgeMesh::collapseEdge(Halfedge *halfedge, double maxEdgeLengt void IsotropicHalfedgeMesh::updateVertexValences() { - for (Vertex *vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { + for (Vertex* vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { if (vertex->removed) continue; vertex->_isBoundary = false; @@ -611,10 +596,10 @@ void IsotropicHalfedgeMesh::updateVertexValences() void IsotropicHalfedgeMesh::updateTriangleNormals() { - for (Face *face = m_firstFace; nullptr != face; face = face->nextFace) { + for (Face* face = m_firstFace; nullptr != face; face = face->nextFace) { if (face->removed) continue; - auto &startHalfedge = face->halfedge; + auto& startHalfedge = face->halfedge; face->_normal = Vector3::normal(startHalfedge->previousHalfedge->startVertex->position, startHalfedge->startVertex->position, startHalfedge->nextHalfedge->startVertex->position); @@ -623,60 +608,58 @@ void IsotropicHalfedgeMesh::updateTriangleNormals() void IsotropicHalfedgeMesh::updateVertexNormals() { - for (Vertex *vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { + for (Vertex* vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { if (vertex->removed) continue; vertex->_normal = Vector3(); } - - for (Face *face = m_firstFace; nullptr != face; face = face->nextFace) { + + for (Face* face = m_firstFace; nullptr != face; face = face->nextFace) { if (face->removed) continue; - auto &startHalfedge = face->halfedge; - Vector3 faceNormal = face->_normal * - Vector3::area(startHalfedge->previousHalfedge->startVertex->position, - startHalfedge->startVertex->position, - startHalfedge->nextHalfedge->startVertex->position); + auto& startHalfedge = face->halfedge; + Vector3 faceNormal = face->_normal * Vector3::area(startHalfedge->previousHalfedge->startVertex->position, startHalfedge->startVertex->position, startHalfedge->nextHalfedge->startVertex->position); startHalfedge->previousHalfedge->startVertex->_normal += faceNormal; startHalfedge->startVertex->_normal += faceNormal; startHalfedge->nextHalfedge->startVertex->_normal += faceNormal; } - - for (Vertex *vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { + + for (Vertex* vertex = m_firstVertex; nullptr != vertex; vertex = vertex->nextVertex) { if (vertex->removed) continue; vertex->_normal.normalize(); } } -void IsotropicHalfedgeMesh::featureHalfedge(Halfedge *halfedge, double radians) +void IsotropicHalfedgeMesh::featureHalfedge(Halfedge* halfedge, double radians) { if (-1 != halfedge->featureState) return; - - auto &opposite = halfedge->oppositeHalfedge; + + auto& opposite = halfedge->oppositeHalfedge; if (nullptr == opposite) { halfedge->startVertex->featured = true; halfedge->featureState = 1; return; } - - if (Vector3::angle(halfedge->leftFace->_normal, - opposite->leftFace->_normal) >= radians) { + + if (Vector3::angle(halfedge->leftFace->_normal, + opposite->leftFace->_normal) + >= radians) { halfedge->featureState = opposite->featureState = 1; halfedge->startVertex->featured = opposite->startVertex->featured = true; return; } - + halfedge->featureState = opposite->featureState = 0; } void IsotropicHalfedgeMesh::featureBoundaries() { - for (Face *face = m_firstFace; nullptr != face; face = face->nextFace) { + for (Face* face = m_firstFace; nullptr != face; face = face->nextFace) { if (face->removed) continue; - auto &startHalfedge = face->halfedge; + auto& startHalfedge = face->halfedge; if (nullptr == startHalfedge->previousHalfedge->oppositeHalfedge) { startHalfedge->previousHalfedge->startVertex->featured = true; } @@ -691,10 +674,10 @@ void IsotropicHalfedgeMesh::featureBoundaries() void IsotropicHalfedgeMesh::featureEdges(double radians) { - for (Face *face = m_firstFace; nullptr != face; face = face->nextFace) { + for (Face* face = m_firstFace; nullptr != face; face = face->nextFace) { if (face->removed) continue; - auto &startHalfedge = face->halfedge; + auto& startHalfedge = face->halfedge; featureHalfedge(startHalfedge->previousHalfedge, radians); featureHalfedge(startHalfedge, radians); featureHalfedge(startHalfedge->nextHalfedge, radians); diff --git a/dust3d/mesh/isotropic_halfedge_mesh.h b/dust3d/mesh/isotropic_halfedge_mesh.h index 1c41600b..cfcf318f 100644 --- a/dust3d/mesh/isotropic_halfedge_mesh.h +++ b/dust3d/mesh/isotropic_halfedge_mesh.h @@ -23,23 +23,20 @@ #ifndef DUST3D_MESH_ISOTROPIC_HALFEDGE_MESH_H_ #define DUST3D_MESH_ISOTROPIC_HALFEDGE_MESH_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -class IsotropicHalfedgeMesh -{ +class IsotropicHalfedgeMesh { public: struct Halfedge; - - struct Vertex - { + + struct Vertex { Vector3 position; - Halfedge *firstHalfedge = nullptr; - Vertex *previousVertex = nullptr; - Vertex *nextVertex = nullptr; + Halfedge* firstHalfedge = nullptr; + Vertex* previousVertex = nullptr; + Vertex* nextVertex = nullptr; int initialFaces = 0; int _valence = -1; bool _isBoundary = false; @@ -48,100 +45,99 @@ public: size_t debugIndex = 0; int sourceIndex = -1; bool featured = false; - Vertex *_allocLink = nullptr; + Vertex* _allocLink = nullptr; }; - struct Face - { - Halfedge *halfedge = nullptr; - Face *previousFace = nullptr; - Face *nextFace = nullptr; + struct Face { + Halfedge* halfedge = nullptr; + Face* previousFace = nullptr; + Face* nextFace = nullptr; Vector3 _normal; bool removed = false; size_t debugIndex = 0; - Face *_allocLink = nullptr; + Face* _allocLink = nullptr; }; - struct Halfedge - { - Vertex *startVertex = nullptr; - Face *leftFace = nullptr; - Halfedge *nextHalfedge = nullptr; - Halfedge *previousHalfedge = nullptr; - Halfedge *oppositeHalfedge = nullptr; + struct Halfedge { + Vertex* startVertex = nullptr; + Face* leftFace = nullptr; + Halfedge* nextHalfedge = nullptr; + Halfedge* previousHalfedge = nullptr; + Halfedge* oppositeHalfedge = nullptr; int featureState = -1; size_t debugIndex = 0; - Halfedge *_allocLink = nullptr; + Halfedge* _allocLink = nullptr; }; - - IsotropicHalfedgeMesh(const std::vector &vertices, - const std::vector> &faces); + + IsotropicHalfedgeMesh(const std::vector& vertices, + const std::vector>& faces); ~IsotropicHalfedgeMesh(); - + double averageEdgeLength(); - void breakEdge(Halfedge *halfedge); - bool collapseEdge(Halfedge *halfedge, double maxEdgeLengthSquared); - bool flipEdge(Halfedge *halfedge); - void relaxVertex(Vertex *vertex); - size_t vertexValence(Vertex *vertex, bool *isBoundary=nullptr); - Face *moveToNextFace(Face *face); - Vertex *moveToNextVertex(Vertex *vertex); + void breakEdge(Halfedge* halfedge); + bool collapseEdge(Halfedge* halfedge, double maxEdgeLengthSquared); + bool flipEdge(Halfedge* halfedge); + void relaxVertex(Vertex* vertex); + size_t vertexValence(Vertex* vertex, bool* isBoundary = nullptr); + Face* moveToNextFace(Face* face); + Vertex* moveToNextVertex(Vertex* vertex); void updateVertexValences(); void updateVertexNormals(); void updateTriangleNormals(); void featureEdges(double radians); void featureBoundaries(); + private: - Vertex *m_firstVertex = nullptr; - Vertex *m_lastVertex = nullptr; - Face *m_firstFace = nullptr; - Face *m_lastFace = nullptr; + Vertex* m_firstVertex = nullptr; + Vertex* m_lastVertex = nullptr; + Face* m_firstFace = nullptr; + Face* m_lastFace = nullptr; size_t m_debugVertexIndex = 0; size_t m_debugFaceIndex = 0; size_t m_debugHalfedgeIndex = 0; - Vertex *m_vertexAllocLink = nullptr; - Face *m_faceAllocLink = nullptr; - Halfedge *m_halfedgeAllocLink = nullptr; - + Vertex* m_vertexAllocLink = nullptr; + Face* m_faceAllocLink = nullptr; + Halfedge* m_halfedgeAllocLink = nullptr; + static inline uint64_t makeHalfedgeKey(size_t first, size_t second) { return (first << 32) | second; } - + static inline uint64_t swapHalfedgeKey(uint64_t key) { return makeHalfedgeKey(key & 0xffffffff, key >> 32); } - - Face *firstFace() + + Face* firstFace() { return m_firstFace; } - - Vertex *firstVertex() + + Vertex* firstVertex() { return m_firstVertex; } - - Face *newFace(); - Vertex *newVertex(); - Halfedge *newHalfedge(); - void linkFaceHalfedges(std::vector &halfedges); - void updateFaceHalfedgesLeftFace(std::vector &halfedges, - Face *leftFace); - void linkHalfedgePair(Halfedge *first, Halfedge *second); - void breakFace(Face *leftOldFace, - Halfedge *halfedge, - Vertex *breakPointVertex, - std::vector &leftNewFaceHalfedges, - std::vector &leftOldFaceHalfedges); - void pointerVertexToNewVertex(Vertex *vertex, Vertex *replacement); - bool testLengthSquaredAroundVertex(Vertex *vertex, - const Vector3 &target, + + Face* newFace(); + Vertex* newVertex(); + Halfedge* newHalfedge(); + void linkFaceHalfedges(std::vector& halfedges); + void updateFaceHalfedgesLeftFace(std::vector& halfedges, + Face* leftFace); + void linkHalfedgePair(Halfedge* first, Halfedge* second); + void breakFace(Face* leftOldFace, + Halfedge* halfedge, + Vertex* breakPointVertex, + std::vector& leftNewFaceHalfedges, + std::vector& leftOldFaceHalfedges); + void pointerVertexToNewVertex(Vertex* vertex, Vertex* replacement); + bool testLengthSquaredAroundVertex(Vertex* vertex, + const Vector3& target, double maxEdgeLengthSquared); - void collectVerticesAroundVertex(Vertex *vertex, - std::set *vertices); - void featureHalfedge(Halfedge *halfedge, double radians); + void collectVerticesAroundVertex(Vertex* vertex, + std::set* vertices); + void featureHalfedge(Halfedge* halfedge, double radians); }; } diff --git a/dust3d/mesh/isotropic_remesher.cc b/dust3d/mesh/isotropic_remesher.cc index 7d1b66e6..1c254c84 100644 --- a/dust3d/mesh/isotropic_remesher.cc +++ b/dust3d/mesh/isotropic_remesher.cc @@ -20,13 +20,12 @@ * SOFTWARE. */ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { IsotropicRemesher::~IsotropicRemesher() { @@ -54,31 +53,31 @@ void IsotropicRemesher::setTargetTriangleCount(size_t triangleCount) void IsotropicRemesher::buildAxisAlignedBoundingBoxTree() { m_triangleBoxes = new std::vector(m_triangles->size()); - + for (size_t i = 0; i < (*m_triangleBoxes).size(); ++i) { addTriagleToAxisAlignedBoundingBox((*m_triangles)[i], &(*m_triangleBoxes)[i]); (*m_triangleBoxes)[i].updateCenter(); } - + std::vector faceIndices; for (size_t i = 0; i < (*m_triangleBoxes).size(); ++i) faceIndices.push_back(i); - + AxisAlignedBoudingBox groupBox; - for (const auto &i: faceIndices) { + for (const auto& i : faceIndices) { addTriagleToAxisAlignedBoundingBox((*m_triangles)[i], &groupBox); } groupBox.updateCenter(); - + delete m_axisAlignedBoundingBoxTree; - m_axisAlignedBoundingBoxTree = new AxisAlignedBoudingBoxTree(m_triangleBoxes, + m_axisAlignedBoundingBoxTree = new AxisAlignedBoudingBoxTree(m_triangleBoxes, faceIndices, groupBox); } -IsotropicRemesher::IsotropicRemesher(const std::vector *vertices, - const std::vector> *triangles) : - m_vertices(vertices), - m_triangles(triangles) +IsotropicRemesher::IsotropicRemesher(const std::vector* vertices, + const std::vector>* triangles) + : m_vertices(vertices) + , m_triangles(triangles) { m_halfedgeMesh = new IsotropicHalfedgeMesh(*m_vertices, *m_triangles); m_initialAverageEdgeLength = m_halfedgeMesh->averageEdgeLength(); @@ -94,19 +93,18 @@ void IsotropicRemesher::remesh(size_t iteration) delete m_triangleNormals; m_triangleNormals = new std::vector; m_triangleNormals->reserve(m_triangles->size()); - for (const auto &it: *m_triangles) { + for (const auto& it : *m_triangles) { m_triangleNormals->push_back( - Vector3::normal((*m_vertices)[it[0]], - (*m_vertices)[it[1]], - (*m_vertices)[it[2]]) - ); + Vector3::normal((*m_vertices)[it[0]], + (*m_vertices)[it[1]], + (*m_vertices)[it[2]])); } double targetLength = m_targetEdgeLength > 0 ? m_targetEdgeLength : m_initialAverageEdgeLength; - + if (m_targetTriangleCount > 0) { double totalArea = 0.0; - for (const auto &it: *m_triangles) { + for (const auto& it : *m_triangles) { totalArea += Vector3::area((*m_vertices)[it[0]], (*m_vertices)[it[1]], (*m_vertices)[it[2]]); } double triangleArea = totalArea / m_targetTriangleCount; @@ -114,13 +112,13 @@ void IsotropicRemesher::remesh(size_t iteration) } double minTargetLength = 4.0 / 5.0 * targetLength; - double maxTargetLength= 4.0 / 3.0 * targetLength; - + double maxTargetLength = 4.0 / 3.0 * targetLength; + double minTargetLengthSquared = minTargetLength * minTargetLength; double maxTargetLengthSquared = maxTargetLength * maxTargetLength; - + buildAxisAlignedBoundingBoxTree(); - + bool skipSplitOnce = true; if (m_sharpEdgeThresholdRadians > 0) { splitLongEdges(maxTargetLengthSquared); @@ -130,7 +128,7 @@ void IsotropicRemesher::remesh(size_t iteration) splitLongEdges(maxTargetLengthSquared); m_halfedgeMesh->featureBoundaries(); } - + for (size_t i = 0; i < iteration; ++i) { if (skipSplitOnce) { skipSplitOnce = false; @@ -141,20 +139,18 @@ void IsotropicRemesher::remesh(size_t iteration) flipEdges(); shiftVertices(); projectVertices(); - } } void IsotropicRemesher::splitLongEdges(double maxEdgeLengthSquared) { - for (IsotropicHalfedgeMesh::Face *face = m_halfedgeMesh->moveToNextFace(nullptr); - nullptr != face; - ) { - const auto &startHalfedge = face->halfedge; + for (IsotropicHalfedgeMesh::Face* face = m_halfedgeMesh->moveToNextFace(nullptr); + nullptr != face;) { + const auto& startHalfedge = face->halfedge; face = m_halfedgeMesh->moveToNextFace(face); - IsotropicHalfedgeMesh::Halfedge *halfedge = startHalfedge; + IsotropicHalfedgeMesh::Halfedge* halfedge = startHalfedge; do { - const auto &nextHalfedge = halfedge->nextHalfedge; + const auto& nextHalfedge = halfedge->nextHalfedge; double lengthSquared = (halfedge->startVertex->position - nextHalfedge->startVertex->position).lengthSquared(); if (lengthSquared > maxEdgeLengthSquared) { m_halfedgeMesh->breakEdge(halfedge); @@ -165,27 +161,26 @@ void IsotropicRemesher::splitLongEdges(double maxEdgeLengthSquared) } } -IsotropicHalfedgeMesh *IsotropicRemesher::remeshedHalfedgeMesh() +IsotropicHalfedgeMesh* IsotropicRemesher::remeshedHalfedgeMesh() { return m_halfedgeMesh; } void IsotropicRemesher::collapseShortEdges(double minEdgeLengthSquared, double maxEdgeLengthSquared) { - for (IsotropicHalfedgeMesh::Face *face = m_halfedgeMesh->moveToNextFace(nullptr); - nullptr != face; - ) { + for (IsotropicHalfedgeMesh::Face* face = m_halfedgeMesh->moveToNextFace(nullptr); + nullptr != face;) { if (face->removed) { face = m_halfedgeMesh->moveToNextFace(face); continue; } size_t f = face->debugIndex; - const auto &startHalfedge = face->halfedge; + const auto& startHalfedge = face->halfedge; face = m_halfedgeMesh->moveToNextFace(face); - IsotropicHalfedgeMesh::Halfedge *halfedge = startHalfedge; + IsotropicHalfedgeMesh::Halfedge* halfedge = startHalfedge; size_t loopCount = 0; do { - const auto &nextHalfedge = halfedge->nextHalfedge; + const auto& nextHalfedge = halfedge->nextHalfedge; double lengthSquared = (halfedge->startVertex->position - nextHalfedge->startVertex->position).lengthSquared(); if (lengthSquared < minEdgeLengthSquared) { if (!halfedge->startVertex->featured && !nextHalfedge->startVertex->featured) { @@ -201,14 +196,13 @@ void IsotropicRemesher::collapseShortEdges(double minEdgeLengthSquared, double m void IsotropicRemesher::flipEdges() { - for (IsotropicHalfedgeMesh::Face *face = m_halfedgeMesh->moveToNextFace(nullptr); - nullptr != face; - ) { - const auto &startHalfedge = face->halfedge; + for (IsotropicHalfedgeMesh::Face* face = m_halfedgeMesh->moveToNextFace(nullptr); + nullptr != face;) { + const auto& startHalfedge = face->halfedge; face = m_halfedgeMesh->moveToNextFace(face); - IsotropicHalfedgeMesh::Halfedge *halfedge = startHalfedge; + IsotropicHalfedgeMesh::Halfedge* halfedge = startHalfedge; do { - const auto &nextHalfedge = halfedge->nextHalfedge; + const auto& nextHalfedge = halfedge->nextHalfedge; if (nullptr != halfedge->oppositeHalfedge) { if (!halfedge->startVertex->featured && !nextHalfedge->startVertex->featured) { if (m_halfedgeMesh->flipEdge(halfedge)) { @@ -226,10 +220,10 @@ void IsotropicRemesher::shiftVertices() m_halfedgeMesh->updateVertexValences(); m_halfedgeMesh->updateTriangleNormals(); m_halfedgeMesh->updateVertexNormals(); - - for (IsotropicHalfedgeMesh::Vertex *vertex = m_halfedgeMesh->moveToNextVertex(nullptr); - nullptr != vertex; - vertex = m_halfedgeMesh->moveToNextVertex(vertex)) { + + for (IsotropicHalfedgeMesh::Vertex* vertex = m_halfedgeMesh->moveToNextVertex(nullptr); + nullptr != vertex; + vertex = m_halfedgeMesh->moveToNextVertex(vertex)) { if (vertex->featured) continue; m_halfedgeMesh->relaxVertex(vertex); @@ -238,21 +232,21 @@ void IsotropicRemesher::shiftVertices() void IsotropicRemesher::projectVertices() { - for (IsotropicHalfedgeMesh::Vertex *vertex = m_halfedgeMesh->moveToNextVertex(nullptr); - nullptr != vertex; - vertex = m_halfedgeMesh->moveToNextVertex(vertex)) { + for (IsotropicHalfedgeMesh::Vertex* vertex = m_halfedgeMesh->moveToNextVertex(nullptr); + nullptr != vertex; + vertex = m_halfedgeMesh->moveToNextVertex(vertex)) { if (vertex->featured) continue; - - const auto &startHalfedge = vertex->firstHalfedge; + + const auto& startHalfedge = vertex->firstHalfedge; if (nullptr == startHalfedge) continue; std::vector rayBox(1); - auto &box = rayBox[0]; + auto& box = rayBox[0]; box.update(vertex->position); - IsotropicHalfedgeMesh::Halfedge *loopHalfedge = startHalfedge; + IsotropicHalfedgeMesh::Halfedge* loopHalfedge = startHalfedge; do { box.update(loopHalfedge->nextHalfedge->startVertex->position); if (nullptr == loopHalfedge->oppositeHalfedge) { @@ -267,19 +261,19 @@ void IsotropicRemesher::projectVertices() } loopHalfedge = loopHalfedge->oppositeHalfedge->nextHalfedge; } while (loopHalfedge != startHalfedge); - + AxisAlignedBoudingBoxTree testTree(&rayBox, - {0}, + { 0 }, rayBox[0]); std::vector> pairs; m_axisAlignedBoundingBoxTree->test(m_axisAlignedBoundingBoxTree->root(), testTree.root(), &rayBox, &pairs); - + std::vector> hits; - + auto boundingBoxSize = box.upperBound() - box.lowerBound(); Vector3 segment = vertex->_normal * (boundingBoxSize[0] + boundingBoxSize[1] + boundingBoxSize[2]); - for (const auto &it: pairs) { - const auto &triangle = (*m_triangles)[it.first]; + for (const auto& it : pairs) { + const auto& triangle = (*m_triangles)[it.first]; std::vector trianglePositions = { (*m_vertices)[triangle[0]], (*m_vertices)[triangle[1]], @@ -287,7 +281,7 @@ void IsotropicRemesher::projectVertices() }; Vector3 intersection; if (Vector3::intersectSegmentAndPlane(vertex->position - segment, vertex->position + segment, - trianglePositions[0], + trianglePositions[0], (*m_triangleNormals)[it.first], &intersection)) { std::vector normals; @@ -295,16 +289,14 @@ void IsotropicRemesher::projectVertices() size_t j = (i + 1) % 3; normals.push_back(Vector3::normal(intersection, trianglePositions[i], trianglePositions[j])); } - if (Vector3::dotProduct(normals[0], normals[1]) > 0 && - Vector3::dotProduct(normals[0], normals[2]) > 0) { - hits.push_back({intersection, (vertex->position - intersection).lengthSquared()}); + if (Vector3::dotProduct(normals[0], normals[1]) > 0 && Vector3::dotProduct(normals[0], normals[2]) > 0) { + hits.push_back({ intersection, (vertex->position - intersection).lengthSquared() }); } } } - + if (!hits.empty()) { - vertex->position = std::min_element(hits.begin(), hits.end(), [](const std::pair &first, - const std::pair &second) { + vertex->position = std::min_element(hits.begin(), hits.end(), [](const std::pair& first, const std::pair& second) { return first.second < second.second; })->first; } diff --git a/dust3d/mesh/isotropic_remesher.h b/dust3d/mesh/isotropic_remesher.h index a28325f4..8da1e311 100644 --- a/dust3d/mesh/isotropic_remesher.h +++ b/dust3d/mesh/isotropic_remesher.h @@ -23,47 +23,45 @@ #ifndef DUST3D_MESH_ISOTROPIC_REMESHER_H_ #define DUST3D_MESH_ISOTROPIC_REMESHER_H_ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { class IsotropicHalfedgeMesh; -class IsotropicRemesher -{ +class IsotropicRemesher { public: - IsotropicRemesher(const std::vector *vertices, - const std::vector> *triangles); + IsotropicRemesher(const std::vector* vertices, + const std::vector>* triangles); ~IsotropicRemesher(); double initialAverageEdgeLength(); void setSharpEdgeIncludedAngle(double degrees); void setTargetEdgeLength(double edgeLength); void setTargetTriangleCount(size_t triangleCount); void remesh(size_t iteration); - IsotropicHalfedgeMesh *remeshedHalfedgeMesh(); - + IsotropicHalfedgeMesh* remeshedHalfedgeMesh(); + private: - const std::vector *m_vertices = nullptr; - const std::vector> *m_triangles = nullptr; - std::vector *m_triangleNormals = nullptr; - IsotropicHalfedgeMesh *m_halfedgeMesh = nullptr; - std::vector *m_triangleBoxes = nullptr; - AxisAlignedBoudingBoxTree *m_axisAlignedBoundingBoxTree = nullptr; + const std::vector* m_vertices = nullptr; + const std::vector>* m_triangles = nullptr; + std::vector* m_triangleNormals = nullptr; + IsotropicHalfedgeMesh* m_halfedgeMesh = nullptr; + std::vector* m_triangleBoxes = nullptr; + AxisAlignedBoudingBoxTree* m_axisAlignedBoundingBoxTree = nullptr; double m_sharpEdgeThresholdRadians = 0; double m_targetEdgeLength = 0; double m_initialAverageEdgeLength = 0; size_t m_targetTriangleCount = 0; - - void addTriagleToAxisAlignedBoundingBox(const std::vector &triangle, AxisAlignedBoudingBox *box) + + void addTriagleToAxisAlignedBoundingBox(const std::vector& triangle, AxisAlignedBoudingBox* box) { for (size_t i = 0; i < 3; ++i) box->update((*m_vertices)[triangle[i]]); } - + void splitLongEdges(double maxEdgeLength); void collapseShortEdges(double minEdgeLengthSquared, double maxEdgeLengthSquared); void flipEdges(); diff --git a/dust3d/mesh/mesh_combiner.cc b/dust3d/mesh/mesh_combiner.cc index eacb37d9..030943c3 100644 --- a/dust3d/mesh/mesh_combiner.cc +++ b/dust3d/mesh/mesh_combiner.cc @@ -20,16 +20,15 @@ * SOFTWARE. */ -#include #include -#include +#include #include +#include #include -namespace dust3d -{ +namespace dust3d { -MeshCombiner::Mesh::Mesh(const std::vector &vertices, const std::vector> &faces) +MeshCombiner::Mesh::Mesh(const std::vector& vertices, const std::vector>& faces) { m_vertices = std::make_unique>(vertices); m_triangles = std::make_unique>>(); @@ -40,7 +39,7 @@ MeshCombiner::Mesh::Mesh(const std::vector &vertices, const std::vector m_solidMesh->prepare(); } -MeshCombiner::Mesh::Mesh(const Mesh &other) +MeshCombiner::Mesh::Mesh(const Mesh& other) { m_vertices = std::make_unique>(); m_triangles = std::make_unique>>(); @@ -55,11 +54,11 @@ MeshCombiner::Mesh::~Mesh() { } -void MeshCombiner::Mesh::fetch(std::vector &vertices, std::vector> &faces) const +void MeshCombiner::Mesh::fetch(std::vector& vertices, std::vector>& faces) const { if (nullptr != m_vertices) vertices = *m_vertices; - + if (nullptr != m_triangles) faces = *m_triangles; } @@ -69,26 +68,26 @@ bool MeshCombiner::Mesh::isNull() const return nullptr == m_vertices || m_vertices->empty(); } -MeshCombiner::Mesh *MeshCombiner::combine(const Mesh &firstMesh, const Mesh &secondMesh, Method method, - std::vector> *combinedVerticesComeFrom) +MeshCombiner::Mesh* MeshCombiner::combine(const Mesh& firstMesh, const Mesh& secondMesh, Method method, + std::vector>* combinedVerticesComeFrom) { if (firstMesh.isNull() || secondMesh.isNull()) - return nullptr; + return nullptr; SolidMeshBooleanOperation booleanOperation(firstMesh.m_solidMesh.get(), secondMesh.m_solidMesh.get()); if (!booleanOperation.combine()) return nullptr; - + std::map> verticesSourceMap; - - auto addToSourceMap = [&](SolidMesh *solidMesh, Source source) { + + auto addToSourceMap = [&](SolidMesh* solidMesh, Source source) { size_t vertexIndex = 0; - const std::vector *vertices = solidMesh->vertices(); + const std::vector* vertices = solidMesh->vertices(); if (nullptr == vertices) return; - for (const auto &point: *vertices) { - verticesSourceMap.insert({{point.x(), point.y(), point.z()}, - {source, vertexIndex}}); + for (const auto& point : *vertices) { + verticesSourceMap.insert({ { point.x(), point.y(), point.z() }, + { source, vertexIndex } }); ++vertexIndex; } }; @@ -96,7 +95,7 @@ MeshCombiner::Mesh *MeshCombiner::combine(const Mesh &firstMesh, const Mesh &sec addToSourceMap(firstMesh.m_solidMesh.get(), Source::First); addToSourceMap(secondMesh.m_solidMesh.get(), Source::Second); } - + std::vector> resultTriangles; if (Method::Union == method) { booleanOperation.fetchUnion(resultTriangles); @@ -105,14 +104,14 @@ MeshCombiner::Mesh *MeshCombiner::combine(const Mesh &firstMesh, const Mesh &sec } else { return nullptr; } - - const auto &resultVertices = booleanOperation.resultVertices(); + + const auto& resultVertices = booleanOperation.resultVertices(); if (nullptr != combinedVerticesComeFrom) { combinedVerticesComeFrom->clear(); - for (const auto &point: resultVertices) { + for (const auto& point : resultVertices) { auto findSource = verticesSourceMap.find(PositionKey(point.x(), point.y(), point.z())); if (findSource == verticesSourceMap.end()) { - combinedVerticesComeFrom->push_back({Source::None, 0}); + combinedVerticesComeFrom->push_back({ Source::None, 0 }); } else { combinedVerticesComeFrom->push_back(findSource->second); } diff --git a/dust3d/mesh/mesh_combiner.h b/dust3d/mesh/mesh_combiner.h index 68f76d5a..8fe8751c 100644 --- a/dust3d/mesh/mesh_combiner.h +++ b/dust3d/mesh/mesh_combiner.h @@ -23,50 +23,45 @@ #ifndef DUST3D_MESH_MESH_COMBINER_H_ #define DUST3D_MESH_MESH_COMBINER_H_ -#include -#include #include #include +#include +#include -namespace dust3d -{ - -class MeshCombiner -{ +namespace dust3d { + +class MeshCombiner { public: - enum class Method - { + enum class Method { Union, Diff }; - - enum class Source - { + + enum class Source { None, First, Second }; - class Mesh - { + class Mesh { public: Mesh() = default; - Mesh(const std::vector &vertices, const std::vector> &faces); - Mesh(const Mesh &other); + Mesh(const std::vector& vertices, const std::vector>& faces); + Mesh(const Mesh& other); ~Mesh(); - void fetch(std::vector &vertices, std::vector> &faces) const; + void fetch(std::vector& vertices, std::vector>& faces) const; bool isNull() const; - + friend MeshCombiner; - + private: std::unique_ptr m_solidMesh; std::unique_ptr> m_vertices; std::unique_ptr>> m_triangles; }; - - static Mesh *combine(const Mesh &firstMesh, const Mesh &secondMesh, Method method, - std::vector> *combinedVerticesComeFrom=nullptr); + + static Mesh* combine(const Mesh& firstMesh, const Mesh& secondMesh, Method method, + std::vector>* combinedVerticesComeFrom = nullptr); }; } diff --git a/dust3d/mesh/mesh_generator.cc b/dust3d/mesh/mesh_generator.cc index a6660245..52886396 100644 --- a/dust3d/mesh/mesh_generator.cc +++ b/dust3d/mesh/mesh_generator.cc @@ -20,33 +20,32 @@ * SOFTWARE. */ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include -#include #include -#include -#include #include -#include -#include #include -#include +#include +#include -namespace dust3d -{ +namespace dust3d { double MeshGenerator::m_minimalRadius = 0.001; -MeshGenerator::MeshGenerator(Snapshot *snapshot) : - m_snapshot(snapshot) +MeshGenerator::MeshGenerator(Snapshot* snapshot) + : m_snapshot(snapshot) { } @@ -71,19 +70,19 @@ bool MeshGenerator::isSuccessful() return m_isSuccessful; } -const std::set &MeshGenerator::generatedPreviewComponentIds() +const std::set& MeshGenerator::generatedPreviewComponentIds() { return m_generatedPreviewComponentIds; } -Object *MeshGenerator::takeObject() +Object* MeshGenerator::takeObject() { - Object *object = m_object; + Object* object = m_object; m_object = nullptr; return object; } -void MeshGenerator::chamferFace(std::vector *face) +void MeshGenerator::chamferFace(std::vector* face) { auto oldFace = *face; face->clear(); @@ -94,7 +93,7 @@ void MeshGenerator::chamferFace(std::vector *face) } } -void MeshGenerator::subdivideFace(std::vector *face) +void MeshGenerator::subdivideFace(std::vector* face) { auto oldFace = *face; face->resize(oldFace.size() * 2); @@ -106,33 +105,33 @@ void MeshGenerator::subdivideFace(std::vector *face) } } -bool MeshGenerator::isWatertight(const std::vector> &faces) +bool MeshGenerator::isWatertight(const std::vector>& faces) { std::set> halfEdges; - for (const auto &face: faces) { + for (const auto& face : faces) { for (size_t i = 0; i < face.size(); ++i) { size_t j = (i + 1) % face.size(); - auto insertResult = halfEdges.insert({face[i], face[j]}); + auto insertResult = halfEdges.insert({ face[i], face[j] }); if (!insertResult.second) return false; } } - for (const auto &it: halfEdges) { - if (halfEdges.find({it.second, it.first}) == halfEdges.end()) + for (const auto& it : halfEdges) { + if (halfEdges.find({ it.second, it.first }) == halfEdges.end()) return false; } return true; } -void MeshGenerator::recoverQuads(const std::vector &vertices, const std::vector> &triangles, const std::set> &sharedQuadEdges, std::vector> &triangleAndQuads) +void MeshGenerator::recoverQuads(const std::vector& vertices, const std::vector>& triangles, const std::set>& sharedQuadEdges, std::vector>& triangleAndQuads) { std::vector verticesPositionKeys; - for (const auto &position: vertices) { + for (const auto& position : vertices) { verticesPositionKeys.push_back(PositionKey(position)); } std::map, std::pair> triangleEdgeMap; for (size_t i = 0; i < triangles.size(); i++) { - const auto &faceIndices = triangles[i]; + const auto& faceIndices = triangles[i]; if (faceIndices.size() == 3) { triangleEdgeMap[std::make_pair(faceIndices[0], faceIndices[1])] = std::make_pair(i, faceIndices[2]); triangleEdgeMap[std::make_pair(faceIndices[1], faceIndices[2])] = std::make_pair(i, faceIndices[0]); @@ -141,7 +140,7 @@ void MeshGenerator::recoverQuads(const std::vector &vertices, const std } std::unordered_set unionedFaces; std::vector> newUnionedFaceIndices; - for (const auto &edge: triangleEdgeMap) { + for (const auto& edge : triangleEdgeMap) { if (unionedFaces.find(edge.second.first) != unionedFaces.end()) continue; auto pair = std::make_pair(verticesPositionKeys[edge.first.first], verticesPositionKeys[edge.first.second]); @@ -172,13 +171,13 @@ void MeshGenerator::recoverQuads(const std::vector &vertices, const std void MeshGenerator::collectParts() { - for (const auto &node: m_snapshot->nodes) { + for (const auto& node : m_snapshot->nodes) { std::string partId = String::valueOrEmpty(node.second, "partId"); if (partId.empty()) continue; m_partNodeIds[partId].insert(node.first); } - for (const auto &edge: m_snapshot->edges) { + for (const auto& edge : m_snapshot->edges) { std::string partId = String::valueOrEmpty(edge.second, "partId"); if (partId.empty()) continue; @@ -186,7 +185,7 @@ void MeshGenerator::collectParts() } } -bool MeshGenerator::checkIsPartDirty(const std::string &partIdString) +bool MeshGenerator::checkIsPartDirty(const std::string& partIdString) { auto findPart = m_snapshot->parts.find(partIdString); if (findPart == m_snapshot->parts.end()) { @@ -195,7 +194,7 @@ bool MeshGenerator::checkIsPartDirty(const std::string &partIdString) return String::isTrue(String::valueOrEmpty(findPart->second, "__dirty")); } -bool MeshGenerator::checkIsPartDependencyDirty(const std::string &partIdString) +bool MeshGenerator::checkIsPartDependencyDirty(const std::string& partIdString) { auto findPart = m_snapshot->parts.find(partIdString); if (findPart == m_snapshot->parts.end()) { @@ -207,7 +206,7 @@ bool MeshGenerator::checkIsPartDependencyDirty(const std::string &partIdString) if (checkIsPartDirty(cutFaceString)) return true; } - for (const auto &nodeIdString: m_partNodeIds[partIdString]) { + for (const auto& nodeIdString : m_partNodeIds[partIdString]) { auto findNode = m_snapshot->nodes.find(nodeIdString); if (findNode == m_snapshot->nodes.end()) { continue; @@ -222,11 +221,11 @@ bool MeshGenerator::checkIsPartDependencyDirty(const std::string &partIdString) return false; } -bool MeshGenerator::checkIsComponentDirty(const std::string &componentIdString) +bool MeshGenerator::checkIsComponentDirty(const std::string& componentIdString) { bool isDirty = false; - - const std::map *component = &m_snapshot->rootComponent; + + const std::map* component = &m_snapshot->rootComponent; if (componentIdString != to_string(Uuid())) { auto findComponent = m_snapshot->components.find(componentIdString); if (findComponent == m_snapshot->components.end()) { @@ -234,11 +233,11 @@ bool MeshGenerator::checkIsComponentDirty(const std::string &componentIdString) } component = &findComponent->second; } - + if (String::isTrue(String::valueOrEmpty(*component, "__dirty"))) { isDirty = true; } - + std::string linkDataType = String::valueOrEmpty(*component, "linkDataType"); if ("partId" == linkDataType) { std::string partId = String::valueOrEmpty(*component, "linkData"); @@ -252,18 +251,18 @@ bool MeshGenerator::checkIsComponentDirty(const std::string &componentIdString) } } } - - for (const auto &childId: String::split(String::valueOrEmpty(*component, "children"), ',')) { + + for (const auto& childId : String::split(String::valueOrEmpty(*component, "children"), ',')) { if (childId.empty()) continue; if (checkIsComponentDirty(childId)) { isDirty = true; } } - + if (isDirty) m_dirtyComponentIds.insert(componentIdString); - + return isDirty; } @@ -272,7 +271,7 @@ void MeshGenerator::checkDirtyFlags() checkIsComponentDirty(to_string(Uuid())); } -void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, std::vector &cutTemplate) +void MeshGenerator::cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector& cutTemplate) { Uuid cutFaceLinkedPartId = Uuid(cutFaceString); if (!cutFaceLinkedPartId.isNull()) { @@ -282,25 +281,25 @@ void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, // void } else { // Build node info map - for (const auto &nodeIdString: m_partNodeIds[cutFaceString]) { + for (const auto& nodeIdString : m_partNodeIds[cutFaceString]) { auto findNode = m_snapshot->nodes.find(nodeIdString); if (findNode == m_snapshot->nodes.end()) { continue; } - auto &node = findNode->second; + auto& node = findNode->second; float radius = String::toFloat(String::valueOrEmpty(node, "radius")); float x = (String::toFloat(String::valueOrEmpty(node, "x")) - m_mainProfileMiddleX); float y = (m_mainProfileMiddleY - String::toFloat(String::valueOrEmpty(node, "y"))); - cutFaceNodeMap.insert({nodeIdString, std::make_tuple(radius, x, y)}); + cutFaceNodeMap.insert({ nodeIdString, std::make_tuple(radius, x, y) }); } // Build edge link std::map> cutFaceNodeLinkMap; - for (const auto &edgeIdString: m_partEdgeIds[cutFaceString]) { + for (const auto& edgeIdString : m_partEdgeIds[cutFaceString]) { auto findEdge = m_snapshot->edges.find(edgeIdString); if (findEdge == m_snapshot->edges.end()) { continue; } - auto &edge = findEdge->second; + auto& edge = findEdge->second; std::string fromNodeIdString = String::valueOrEmpty(edge, "from"); std::string toNodeIdString = String::valueOrEmpty(edge, "to"); cutFaceNodeLinkMap[fromNodeIdString].push_back(toNodeIdString); @@ -309,36 +308,35 @@ void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, // Find endpoint std::string endPointNodeIdString; std::vector>> endpointNodes; - for (const auto &it: cutFaceNodeLinkMap) { + for (const auto& it : cutFaceNodeLinkMap) { if (1 == it.second.size()) { - const auto &findNode = cutFaceNodeMap.find(it.first); + const auto& findNode = cutFaceNodeMap.find(it.first); if (findNode != cutFaceNodeMap.end()) - endpointNodes.push_back({it.first, findNode->second}); + endpointNodes.push_back({ it.first, findNode->second }); } } bool isRing = endpointNodes.empty(); if (endpointNodes.empty()) { - for (const auto &it: cutFaceNodeMap) { - endpointNodes.push_back({it.first, it.second}); + for (const auto& it : cutFaceNodeMap) { + endpointNodes.push_back({ it.first, it.second }); } } if (!endpointNodes.empty()) { // Calculate the center points Vector2 sumOfPositions; - for (const auto &it: endpointNodes) { + for (const auto& it : endpointNodes) { sumOfPositions += Vector2(std::get<1>(it.second), std::get<2>(it.second)); } Vector2 center = sumOfPositions / endpointNodes.size(); - + // Calculate all the directions emit from center to the endpoint, // choose the minimal angle, angle: (0, 0 -> -1, -1) to the direction const Vector3 referenceDirection = Vector3(-1, -1, 0).normalized(); int choosenEndpoint = -1; float choosenRadian = 0; for (int i = 0; i < (int)endpointNodes.size(); ++i) { - const auto &it = endpointNodes[i]; - Vector2 direction2d = (Vector2(std::get<1>(it.second), std::get<2>(it.second)) - - center); + const auto& it = endpointNodes[i]; + Vector2 direction2d = (Vector2(std::get<1>(it.second), std::get<2>(it.second)) - center); Vector3 direction = Vector3(direction2d.x(), direction2d.y(), 0).normalized(); float radian = Vector3::angleBetween(referenceDirection, direction); if (-1 == choosenEndpoint || radian < choosenRadian) { @@ -351,8 +349,8 @@ void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, // Loop all linked nodes std::vector> cutFaceNodes; std::set cutFaceVisitedNodeIds; - std::function loopNodeLink; - loopNodeLink = [&](const std::string &fromNodeIdString) { + std::function loopNodeLink; + loopNodeLink = [&](const std::string& fromNodeIdString) { auto findCutFaceNode = cutFaceNodeMap.find(fromNodeIdString); if (findCutFaceNode == cutFaceNodeMap.end()) return; @@ -366,7 +364,7 @@ void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, auto findNeighbor = cutFaceNodeLinkMap.find(fromNodeIdString); if (findNeighbor == cutFaceNodeLinkMap.end()) return; - for (const auto &it: findNeighbor->second) { + for (const auto& it : findNeighbor->second) { if (cutFaceVisitedNodeIds.find(it) == cutFaceVisitedNodeIds.end()) { loopNodeLink(it); break; @@ -387,18 +385,18 @@ void MeshGenerator::cutFaceStringToCutTemplate(const std::string &cutFaceString, } } -void MeshGenerator::flattenLinks(const std::unordered_map &links, - std::vector *array, - bool *isCircle) +void MeshGenerator::flattenLinks(const std::unordered_map& links, + std::vector* array, + bool* isCircle) { if (links.empty()) return; - for (const auto &it: links) { + for (const auto& it : links) { if (links.end() == links.find(it.second)) { *isCircle = false; std::unordered_map reversedLinks; - for (const auto &it: links) - reversedLinks.insert({it.second, it.first}); + for (const auto& it : links) + reversedLinks.insert({ it.second, it.first }); size_t current = it.second; for (;;) { array->push_back(current); @@ -425,41 +423,40 @@ void MeshGenerator::flattenLinks(const std::unordered_map &links } } -bool MeshGenerator::fetchPartOrderedNodes(const std::string &partIdString, std::vector *meshNodes, bool *isCircle) +bool MeshGenerator::fetchPartOrderedNodes(const std::string& partIdString, std::vector* meshNodes, bool* isCircle) { std::vector builderNodes; std::map builderNodeIdStringToIndexMap; - for (const auto &nodeIdString: m_partNodeIds[partIdString]) { + for (const auto& nodeIdString : m_partNodeIds[partIdString]) { auto findNode = m_snapshot->nodes.find(nodeIdString); if (findNode == m_snapshot->nodes.end()) { continue; } - auto &node = findNode->second; - + auto& node = findNode->second; + float radius = String::toFloat(String::valueOrEmpty(node, "radius")); float x = (String::toFloat(String::valueOrEmpty(node, "x")) - m_mainProfileMiddleX); float y = (m_mainProfileMiddleY - String::toFloat(String::valueOrEmpty(node, "y"))); float z = (m_sideProfileMiddleX - String::toFloat(String::valueOrEmpty(node, "z"))); - builderNodeIdStringToIndexMap.insert({nodeIdString, builderNodes.size()}); + builderNodeIdStringToIndexMap.insert({ nodeIdString, builderNodes.size() }); builderNodes.emplace_back(MeshNode { - Vector3((double)x, (double)y, (double)z), (double)radius - }); + Vector3((double)x, (double)y, (double)z), (double)radius }); } - + if (builderNodes.empty()) { dust3dDebug << "Expected at least one node in part:" << partIdString; return false; } std::unordered_map builderNodeLinks; - for (const auto &edgeIdString: m_partEdgeIds[partIdString]) { + for (const auto& edgeIdString : m_partEdgeIds[partIdString]) { auto findEdge = m_snapshot->edges.find(edgeIdString); if (findEdge == m_snapshot->edges.end()) { continue; } - auto &edge = findEdge->second; - + auto& edge = findEdge->second; + std::string fromNodeIdString = String::valueOrEmpty(edge, "from"); std::string toNodeIdString = String::valueOrEmpty(edge, "to"); @@ -485,9 +482,9 @@ bool MeshGenerator::fetchPartOrderedNodes(const std::string &partIdString, std:: return true; } -std::unique_ptr MeshGenerator::combineStitchingMesh(const std::vector &partIdStrings, - const std::vector &componentIdStrings, - GeneratedComponent &componentCache) +std::unique_ptr MeshGenerator::combineStitchingMesh(const std::vector& partIdStrings, + const std::vector& componentIdStrings, + GeneratedComponent& componentCache) { std::vector splines; splines.reserve(partIdStrings.size()); @@ -495,7 +492,7 @@ std::unique_ptr MeshGenerator::combineStitchingMesh(const st for (size_t i = 0; i < componentIdStrings.size(); ++i) componentIds[i] = componentIdStrings[i]; for (size_t partIndex = 0; partIndex < partIdStrings.size(); ++partIndex) { - const auto &partIdString = partIdStrings[partIndex]; + const auto& partIdString = partIdStrings[partIndex]; bool isCircle = false; bool isClosing = false; std::vector orderedBuilderNodes; @@ -506,24 +503,23 @@ std::unique_ptr MeshGenerator::combineStitchingMesh(const st std::move(orderedBuilderNodes), isCircle, isClosing, - componentIds[partIndex] - }); + componentIds[partIndex] }); } auto stitchMeshBuilder = std::make_unique(std::move(splines)); stitchMeshBuilder->build(); - collectSharedQuadEdges(stitchMeshBuilder->generatedVertices(), + collectSharedQuadEdges(stitchMeshBuilder->generatedVertices(), stitchMeshBuilder->generatedFaces(), &componentCache.sharedQuadEdges); - auto mesh = std::make_unique(stitchMeshBuilder->generatedVertices(), + auto mesh = std::make_unique(stitchMeshBuilder->generatedVertices(), stitchMeshBuilder->generatedFaces()); if (mesh && mesh->isNull()) mesh.reset(); // Generate preview for each stitching line - for (const auto &spline: stitchMeshBuilder->splines()) { + for (const auto& spline : stitchMeshBuilder->splines()) { RopeMesh::BuildParameters buildParameters; RopeMesh ropeMesh(buildParameters); std::vector positions(spline.nodes.size()); @@ -537,16 +533,16 @@ std::unique_ptr MeshGenerator::combineStitchingMesh(const st size_t startIndex = stitchingLinePreview.vertices.size(); stitchingLinePreview.color = Color(1.0, 1.0, 1.0, 0.2); - for (const auto &ropeVertex: ropeMesh.resultVertices()) { + for (const auto& ropeVertex : ropeMesh.resultVertices()) { stitchingLinePreview.vertices.emplace_back(ropeVertex); } stitchingLinePreview.vertexProperties.resize(stitchingLinePreview.vertices.size()); - auto modelProperty = std::tuple { + auto modelProperty = std::tuple { stitchingLinePreview.color, stitchingLinePreview.metalness, stitchingLinePreview.roughness }; - auto lineProperty = std::tuple { + auto lineProperty = std::tuple { Color(1.0, 1.0, 1.0, 1.0), stitchingLinePreview.metalness, stitchingLinePreview.roughness @@ -557,12 +553,11 @@ std::unique_ptr MeshGenerator::combineStitchingMesh(const st for (size_t i = startIndex; i < stitchingLinePreview.vertexProperties.size(); ++i) { stitchingLinePreview.vertexProperties[i] = lineProperty; } - for (const auto &ropeTriangles: ropeMesh.resultTriangles()) { + for (const auto& ropeTriangles : ropeMesh.resultTriangles()) { stitchingLinePreview.triangles.emplace_back(std::vector { startIndex + ropeTriangles[0], startIndex + ropeTriangles[1], - startIndex + ropeTriangles[2] - }); + startIndex + ropeTriangles[2] }); } addComponentPreview(spline.sourceId, ComponentPreview(stitchingLinePreview)); } @@ -570,16 +565,16 @@ std::unique_ptr MeshGenerator::combineStitchingMesh(const st return mesh; } -std::unique_ptr MeshGenerator::combinePartMesh(const std::string &partIdString, - bool *hasError) +std::unique_ptr MeshGenerator::combinePartMesh(const std::string& partIdString, + bool* hasError) { auto findPart = m_snapshot->parts.find(partIdString); if (findPart == m_snapshot->parts.end()) { return nullptr; } - + Uuid partId = Uuid(partIdString); - auto &part = findPart->second; + auto& part = findPart->second; bool isDisabled = String::isTrue(String::valueOrEmpty(part, "disabled")); std::string __mirroredByPartId = String::valueOrEmpty(part, "__mirroredByPartId"); @@ -597,7 +592,7 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st float hollowThickness = 0.0; auto target = PartTargetFromString(String::valueOrEmpty(part, "target").c_str()); auto base = PartBaseFromString(String::valueOrEmpty(part, "base").c_str()); - + std::string searchPartIdString = __mirrorFromPartId.empty() ? partIdString : __mirrorFromPartId; std::string cutFaceString = String::valueOrEmpty(part, "cutFace"); @@ -607,44 +602,44 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st chamferFace(&cutTemplate); if (subdived) subdivideFace(&cutTemplate); - + std::string cutRotationString = String::valueOrEmpty(part, "cutRotation"); if (!cutRotationString.empty()) { cutRotation = String::toFloat(cutRotationString); } - + std::string hollowThicknessString = String::valueOrEmpty(part, "hollowThickness"); if (!hollowThicknessString.empty()) { hollowThickness = String::toFloat(hollowThicknessString); } - + std::string thicknessString = String::valueOrEmpty(part, "deformThickness"); if (!thicknessString.empty()) { deformThickness = String::toFloat(thicknessString); } - + std::string widthString = String::valueOrEmpty(part, "deformWidth"); if (!widthString.empty()) { deformWidth = String::toFloat(widthString); } - + bool deformUnified = String::isTrue(String::valueOrEmpty(part, "deformUnified")); - + Uuid materialId; std::string materialIdString = String::valueOrEmpty(part, "materialId"); if (!materialIdString.empty()) materialId = Uuid(materialIdString); - + float colorSolubility = 0; std::string colorSolubilityString = String::valueOrEmpty(part, "colorSolubility"); if (!colorSolubilityString.empty()) colorSolubility = String::toFloat(colorSolubilityString); - + float metalness = 0; std::string metalnessString = String::valueOrEmpty(part, "metallic"); if (!metalnessString.empty()) metalness = String::toFloat(metalnessString); - + float roughness = 1.0; std::string roughnessString = String::valueOrEmpty(part, "roughness"); if (!roughnessString.empty()) @@ -655,7 +650,7 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st if (!fetchPartOrderedNodes(searchPartIdString, &meshNodes, &isCircle)) return nullptr; - auto &partCache = m_cacheContext->parts[partIdString]; + auto& partCache = m_cacheContext->parts[partIdString]; partCache.objectNodes.clear(); partCache.objectEdges.clear(); partCache.objectNodeVertices.clear(); @@ -681,9 +676,9 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st partCache.vertices = tubeMeshBuilder->generatedVertices(); partCache.faces = tubeMeshBuilder->generatedFaces(); if (!__mirrorFromPartId.empty()) { - for (auto &it: partCache.vertices) + for (auto& it : partCache.vertices) it.setX(-it.x()); - for (auto &it: partCache.faces) + for (auto& it : partCache.faces) std::reverse(it.begin(), it.end()); } } else if (PartTarget::CutFace == target) { @@ -696,7 +691,7 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st bool hasMeshError = false; std::unique_ptr mesh; - + mesh = std::make_unique(partCache.vertices, partCache.faces); if (mesh->isNull()) { hasMeshError = true; @@ -705,11 +700,11 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st if (nullptr != mesh) { partCache.isSuccessful = true; } - + if (mesh && mesh->isNull()) { mesh.reset(); } - + if (hasMeshError && target == PartTarget::Model) { *hasError = true; } @@ -1058,9 +1053,9 @@ std::unique_ptr MeshGenerator::combinePartMesh(const std::st } */ -const std::map *MeshGenerator::findComponent(const std::string &componentIdString) +const std::map* MeshGenerator::findComponent(const std::string& componentIdString) { - const std::map *component = &m_snapshot->rootComponent; + const std::map* component = &m_snapshot->rootComponent; if (componentIdString != to_string(Uuid())) { auto findComponent = m_snapshot->components.find(componentIdString); if (findComponent == m_snapshot->components.end()) { @@ -1071,7 +1066,7 @@ const std::map *MeshGenerator::findComponent(const std return component; } -CombineMode MeshGenerator::componentCombineMode(const std::map *component) +CombineMode MeshGenerator::componentCombineMode(const std::map* component) { if (nullptr == component) return CombineMode::Normal; @@ -1083,7 +1078,7 @@ CombineMode MeshGenerator::componentCombineMode(const std::map *component) +std::string MeshGenerator::componentColorName(const std::map* component) { if (nullptr == component) return std::string(); @@ -1094,7 +1089,7 @@ std::string MeshGenerator::componentColorName(const std::mapparts.end()) { return std::string(); } - auto &part = findPart->second; + auto& part = findPart->second; std::string colorSolubility = String::valueOrEmpty(part, "colorSolubility"); if (!colorSolubility.empty()) { return std::string("+"); @@ -1107,12 +1102,12 @@ std::string MeshGenerator::componentColorName(const std::map MeshGenerator::combineComponentMesh(const std::string &componentIdString, CombineMode *combineMode) +std::unique_ptr MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode) { std::unique_ptr mesh; - + Uuid componentId; - const std::map *component = &m_snapshot->rootComponent; + const std::map* component = &m_snapshot->rootComponent; if (componentIdString != to_string(Uuid())) { componentId = Uuid(componentIdString); auto findComponent = m_snapshot->components.find(componentIdString); @@ -1123,23 +1118,23 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st } *combineMode = componentCombineMode(component); - - auto &componentCache = m_cacheContext->components[componentIdString]; - + + auto& componentCache = m_cacheContext->components[componentIdString]; + if (m_cacheEnabled) { if (m_dirtyComponentIds.find(componentIdString) == m_dirtyComponentIds.end()) { if (nullptr != componentCache.mesh) return std::make_unique(*componentCache.mesh); } } - + componentCache.sharedQuadEdges.clear(); componentCache.noneSeamVertices.clear(); componentCache.objectNodes.clear(); componentCache.objectEdges.clear(); componentCache.objectNodeVertices.clear(); componentCache.mesh.reset(); - + std::string linkDataType = String::valueOrEmpty(*component, "linkDataType"); if ("partId" == linkDataType) { std::string partIdString = String::valueOrEmpty(*component, "linkData"); @@ -1148,16 +1143,16 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st if (hasError) { m_isSuccessful = false; } - const auto &partCache = m_cacheContext->parts[partIdString]; + const auto& partCache = m_cacheContext->parts[partIdString]; if (partCache.joined) { - for (const auto &vertex: partCache.vertices) + for (const auto& vertex : partCache.vertices) componentCache.noneSeamVertices.insert(vertex); collectSharedQuadEdges(partCache.vertices, partCache.faces, &componentCache.sharedQuadEdges); - for (const auto &it: partCache.objectNodes) + for (const auto& it : partCache.objectNodes) componentCache.objectNodes.push_back(it); - for (const auto &it: partCache.objectEdges) + for (const auto& it : partCache.objectEdges) componentCache.objectEdges.push_back(it); - for (const auto &it: partCache.objectNodeVertices) + for (const auto& it : partCache.objectNodeVertices) componentCache.objectNodeVertices.push_back(it); } ComponentPreview preview; @@ -1177,10 +1172,10 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st auto lastCombineMode = CombineMode::Count; std::vector stitchingParts; std::vector stitchingComponents; - for (const auto &childIdString: String::split(String::valueOrEmpty(*component, "children"), ',')) { + for (const auto& childIdString : String::split(String::valueOrEmpty(*component, "children"), ',')) { if (childIdString.empty()) continue; - const auto &child = findComponent(childIdString); + const auto& child = findComponent(childIdString); if (nullptr == child) continue; if ("partId" == String::valueOrEmpty(*child, "linkDataType")) { @@ -1196,7 +1191,7 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st } auto combineMode = componentCombineMode(child); if (lastCombineMode != combineMode || lastCombineMode == CombineMode::Inversion) { - combineGroups.push_back({combineMode, {}}); + combineGroups.push_back({ combineMode, {} }); ++currentGroupIndex; lastCombineMode = combineMode; } @@ -1206,14 +1201,14 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st combineGroups[currentGroupIndex].second.push_back(childIdString); } std::vector, CombineMode, std::string>> groupMeshes; - for (const auto &group: combineGroups) { + for (const auto& group : combineGroups) { auto childMesh = combineComponentChildGroupMesh(group.second, componentCache); if (nullptr == childMesh || childMesh->isNull()) continue; groupMeshes.emplace_back(std::make_tuple(std::move(childMesh), group.first, String::join(group.second, "|"))); } if (!stitchingParts.empty()) { - auto stitchingMesh = combineStitchingMesh(stitchingParts, stitchingComponents, componentCache); + auto stitchingMesh = combineStitchingMesh(stitchingParts, stitchingComponents, componentCache); if (stitchingMesh && !stitchingMesh->isNull()) { groupMeshes.emplace_back(std::make_tuple(std::move(stitchingMesh), CombineMode::Normal, String::join(stitchingComponents, ":"))); } @@ -1224,25 +1219,25 @@ std::unique_ptr MeshGenerator::combineComponentMesh(const st mesh->fetch(preview.vertices, preview.triangles); addComponentPreview(componentId, std::move(preview)); } - + if (nullptr != mesh) componentCache.mesh = std::make_unique(*mesh); - + if (nullptr != mesh && mesh->isNull()) { mesh.reset(); } - + return mesh; } -std::unique_ptr MeshGenerator::combineMultipleMeshes(std::vector, CombineMode, std::string>> &&multipleMeshes, bool recombine) +std::unique_ptr MeshGenerator::combineMultipleMeshes(std::vector, CombineMode, std::string>>&& multipleMeshes, bool recombine) { std::unique_ptr mesh; std::string meshIdStrings; - for (auto &it: multipleMeshes) { + for (auto& it : multipleMeshes) { auto subMesh = std::move(std::get<0>(it)); - const auto &childCombineMode = std::get<1>(it); - const std::string &subMeshIdString = std::get<2>(it); + const auto& childCombineMode = std::get<1>(it); + const std::string& subMeshIdString = std::get<2>(it); if (nullptr == subMesh || subMesh->isNull()) { continue; } @@ -1250,11 +1245,9 @@ std::unique_ptr MeshGenerator::combineMultipleMeshes(std::ve mesh = std::move(subMesh); meshIdStrings = subMeshIdString; continue; - } - auto combinerMethod = childCombineMode == CombineMode::Inversion ? - MeshCombiner::Method::Diff : MeshCombiner::Method::Union; - auto combinerMethodString = combinerMethod == MeshCombiner::Method::Union ? - "+" : "-"; + } + auto combinerMethod = childCombineMode == CombineMode::Inversion ? MeshCombiner::Method::Diff : MeshCombiner::Method::Union; + auto combinerMethodString = combinerMethod == MeshCombiner::Method::Union ? "+" : "-"; meshIdStrings += combinerMethodString + subMeshIdString; if (recombine) meshIdStrings += "!"; @@ -1270,9 +1263,9 @@ std::unique_ptr MeshGenerator::combineMultipleMeshes(std::ve combinerMethod, recombine); if (nullptr != newMesh) - m_cacheContext->cachedCombination.insert({meshIdStrings, std::make_unique(*newMesh)}); + m_cacheContext->cachedCombination.insert({ meshIdStrings, std::make_unique(*newMesh) }); else - m_cacheContext->cachedCombination.insert({meshIdStrings, nullptr}); + m_cacheContext->cachedCombination.insert({ meshIdStrings, nullptr }); } if (newMesh && !newMesh->isNull()) { mesh = std::move(newMesh); @@ -1286,39 +1279,39 @@ std::unique_ptr MeshGenerator::combineMultipleMeshes(std::ve return mesh; } -std::unique_ptr MeshGenerator::combineComponentChildGroupMesh(const std::vector &componentIdStrings, GeneratedComponent &componentCache) +std::unique_ptr MeshGenerator::combineComponentChildGroupMesh(const std::vector& componentIdStrings, GeneratedComponent& componentCache) { std::vector, CombineMode, std::string>> multipleMeshes; - for (const auto &childIdString: componentIdStrings) { + for (const auto& childIdString : componentIdStrings) { CombineMode childCombineMode = CombineMode::Normal; std::unique_ptr subMesh = combineComponentMesh(childIdString, &childCombineMode); - + if (CombineMode::Uncombined == childCombineMode) { continue; } - - const auto &childComponentCache = m_cacheContext->components[childIdString]; - for (const auto &vertex: childComponentCache.noneSeamVertices) + + const auto& childComponentCache = m_cacheContext->components[childIdString]; + for (const auto& vertex : childComponentCache.noneSeamVertices) componentCache.noneSeamVertices.insert(vertex); - for (const auto &it: childComponentCache.sharedQuadEdges) + for (const auto& it : childComponentCache.sharedQuadEdges) componentCache.sharedQuadEdges.insert(it); - for (const auto &it: childComponentCache.objectNodes) + for (const auto& it : childComponentCache.objectNodes) componentCache.objectNodes.push_back(it); - for (const auto &it: childComponentCache.objectEdges) + for (const auto& it : childComponentCache.objectEdges) componentCache.objectEdges.push_back(it); - for (const auto &it: childComponentCache.objectNodeVertices) + for (const auto& it : childComponentCache.objectNodeVertices) componentCache.objectNodeVertices.push_back(it); - + if (nullptr == subMesh || subMesh->isNull()) { continue; } - + multipleMeshes.emplace_back(std::make_tuple(std::move(subMesh), childCombineMode, childIdString)); } return combineMultipleMeshes(std::move(multipleMeshes)); } -std::unique_ptr MeshGenerator::combineTwoMeshes(const MeshCombiner::Mesh &first, const MeshCombiner::Mesh &second, +std::unique_ptr MeshGenerator::combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second, MeshCombiner::Method method, bool recombine) { @@ -1353,38 +1346,34 @@ std::unique_ptr MeshGenerator::combineTwoMeshes(const MeshCo return newMesh; } -void MeshGenerator::makeXmirror(const std::vector &sourceVertices, const std::vector> &sourceFaces, - std::vector *destVertices, std::vector> *destFaces) +void MeshGenerator::makeXmirror(const std::vector& sourceVertices, const std::vector>& sourceFaces, + std::vector* destVertices, std::vector>* destFaces) { - for (const auto &mirrorFrom: sourceVertices) { + for (const auto& mirrorFrom : sourceVertices) { destVertices->push_back(Vector3(-mirrorFrom.x(), mirrorFrom.y(), mirrorFrom.z())); } std::vector> newFaces; - for (const auto &mirrorFrom: sourceFaces) { + for (const auto& mirrorFrom : sourceFaces) { auto newFace = mirrorFrom; std::reverse(newFace.begin(), newFace.end()); destFaces->push_back(newFace); } } -void MeshGenerator::collectSharedQuadEdges(const std::vector &vertices, const std::vector> &faces, - std::set> *sharedQuadEdges) +void MeshGenerator::collectSharedQuadEdges(const std::vector& vertices, const std::vector>& faces, + std::set>* sharedQuadEdges) { - for (const auto &face: faces) { + for (const auto& face : faces) { if (face.size() != 4) continue; - sharedQuadEdges->insert({ - PositionKey(vertices[face[0]]), - PositionKey(vertices[face[2]]) - }); - sharedQuadEdges->insert({ - PositionKey(vertices[face[1]]), - PositionKey(vertices[face[3]]) - }); + sharedQuadEdges->insert({ PositionKey(vertices[face[0]]), + PositionKey(vertices[face[2]]) }); + sharedQuadEdges->insert({ PositionKey(vertices[face[1]]), + PositionKey(vertices[face[3]]) }); } } -void MeshGenerator::setGeneratedCacheContext(GeneratedCacheContext *cacheContext) +void MeshGenerator::setGeneratedCacheContext(GeneratedCacheContext* cacheContext) { m_cacheContext = cacheContext; } @@ -1401,18 +1390,18 @@ void MeshGenerator::setWeldEnabled(bool enabled) void MeshGenerator::collectErroredParts() { - for (const auto &it: m_cacheContext->parts) { + for (const auto& it : m_cacheContext->parts) { if (!it.second.isSuccessful) { if (!it.second.joined) continue; - - auto updateVertexIndices = [=](std::vector> &faces, size_t vertexStartIndex) { - for (auto &it: faces) { - for (auto &subIt: it) + + auto updateVertexIndices = [=](std::vector>& faces, size_t vertexStartIndex) { + for (auto& it : faces) { + for (auto& subIt : it) subIt += vertexStartIndex; } }; - + auto errorTriangleAndQuads = it.second.faces; updateVertexIndices(errorTriangleAndQuads, m_object->vertices.size()); m_object->vertices.insert(m_object->vertices.end(), it.second.vertices.begin(), it.second.vertices.end()); @@ -1421,36 +1410,35 @@ void MeshGenerator::collectErroredParts() } } -void MeshGenerator::postprocessObject(Object *object) +void MeshGenerator::postprocessObject(Object* object) { std::vector combinedFacesNormals; - for (const auto &face: object->triangles) { + for (const auto& face : object->triangles) { combinedFacesNormals.push_back(Vector3::normal( object->vertices[face[0]], object->vertices[face[1]], - object->vertices[face[2]] - )); + object->vertices[face[2]])); } - + object->triangleNormals = combinedFacesNormals; - + std::vector> sourceNodes; resolveTriangleSourceNode(*object, m_nodeVertices, sourceNodes, &object->vertexSourceNodes); object->setTriangleSourceNodes(sourceNodes); - + std::map, Color> sourceNodeToColorMap; - for (const auto &node: object->nodes) - sourceNodeToColorMap.insert({{node.partId, node.nodeId}, node.color}); - + for (const auto& node : object->nodes) + sourceNodeToColorMap.insert({ { node.partId, node.nodeId }, node.color }); + object->triangleColors.resize(object->triangles.size(), Color::createWhite()); - const std::vector> *triangleSourceNodes = object->triangleSourceNodes(); + const std::vector>* triangleSourceNodes = object->triangleSourceNodes(); if (nullptr != triangleSourceNodes) { for (size_t triangleIndex = 0; triangleIndex < object->triangles.size(); triangleIndex++) { - const auto &source = (*triangleSourceNodes)[triangleIndex]; + const auto& source = (*triangleSourceNodes)[triangleIndex]; object->triangleColors[triangleIndex] = sourceNodeToColorMap[source]; } } - + std::vector> triangleVertexNormals; smoothNormal(object->vertices, object->triangles, @@ -1460,7 +1448,7 @@ void MeshGenerator::postprocessObject(Object *object) object->setTriangleVertexNormals(triangleVertexNormals); } -void MeshGenerator::collectIncombinableMesh(const MeshCombiner::Mesh *mesh, const GeneratedComponent &componentCache) +void MeshGenerator::collectIncombinableMesh(const MeshCombiner::Mesh* mesh, const GeneratedComponent& componentCache) { if (nullptr == mesh) return; @@ -1469,107 +1457,99 @@ void MeshGenerator::collectIncombinableMesh(const MeshCombiner::Mesh *mesh, cons std::vector> uncombinedFaces; mesh->fetch(uncombinedVertices, uncombinedFaces); std::vector> uncombinedTriangleAndQuads; - + recoverQuads(uncombinedVertices, uncombinedFaces, componentCache.sharedQuadEdges, uncombinedTriangleAndQuads); - + auto vertexStartIndex = m_object->vertices.size(); - auto updateVertexIndices = [=](std::vector> &faces) { - for (auto &it: faces) { - for (auto &subIt: it) + auto updateVertexIndices = [=](std::vector>& faces) { + for (auto& it : faces) { + for (auto& subIt : it) subIt += vertexStartIndex; } }; updateVertexIndices(uncombinedFaces); updateVertexIndices(uncombinedTriangleAndQuads); - + m_object->vertices.insert(m_object->vertices.end(), uncombinedVertices.begin(), uncombinedVertices.end()); m_object->triangles.insert(m_object->triangles.end(), uncombinedFaces.begin(), uncombinedFaces.end()); m_object->triangleAndQuads.insert(m_object->triangleAndQuads.end(), uncombinedTriangleAndQuads.begin(), uncombinedTriangleAndQuads.end()); } -void MeshGenerator::collectUncombinedComponent(const std::string &componentIdString) +void MeshGenerator::collectUncombinedComponent(const std::string& componentIdString) { - const auto &component = findComponent(componentIdString); + const auto& component = findComponent(componentIdString); if (CombineMode::Uncombined == componentCombineMode(component)) { - const auto &componentCache = m_cacheContext->components[componentIdString]; + const auto& componentCache = m_cacheContext->components[componentIdString]; if (nullptr == componentCache.mesh || componentCache.mesh->isNull()) { return; } - + m_object->nodes.insert(m_object->nodes.end(), componentCache.objectNodes.begin(), componentCache.objectNodes.end()); m_object->edges.insert(m_object->edges.end(), componentCache.objectEdges.begin(), componentCache.objectEdges.end()); m_nodeVertices.insert(m_nodeVertices.end(), componentCache.objectNodeVertices.begin(), componentCache.objectNodeVertices.end()); - + collectIncombinableMesh(componentCache.mesh.get(), componentCache); return; } - for (const auto &childIdString: String::split(String::valueOrEmpty(*component, "children"), ',')) { + for (const auto& childIdString : String::split(String::valueOrEmpty(*component, "children"), ',')) { if (childIdString.empty()) continue; collectUncombinedComponent(childIdString); } } -void MeshGenerator::setDefaultPartColor(const Color &color) +void MeshGenerator::setDefaultPartColor(const Color& color) { m_defaultPartColor = color; } -std::string MeshGenerator::reverseUuid(const std::string &uuidString) +std::string MeshGenerator::reverseUuid(const std::string& uuidString) { Uuid uuid(uuidString); std::string newIdString = to_string(uuid); - std::string newRawId = newIdString.substr(1, 8) + - newIdString.substr(10, 4) + - newIdString.substr(15, 4) + - newIdString.substr(20, 4) + - newIdString.substr(25, 12); + std::string newRawId = newIdString.substr(1, 8) + newIdString.substr(10, 4) + newIdString.substr(15, 4) + newIdString.substr(20, 4) + newIdString.substr(25, 12); std::reverse(newRawId.begin(), newRawId.end()); - return "{" + newRawId.substr(0, 8) + "-" + - newRawId.substr(8, 4) + "-" + - newRawId.substr(12, 4) + "-" + - newRawId.substr(16, 4) + "-" + - newRawId.substr(20, 12) + "}"; + return "{" + newRawId.substr(0, 8) + "-" + newRawId.substr(8, 4) + "-" + newRawId.substr(12, 4) + "-" + newRawId.substr(16, 4) + "-" + newRawId.substr(20, 12) + "}"; } void MeshGenerator::preprocessMirror() { std::vector> newParts; std::map partOldToNewMap; - for (auto &partIt: m_snapshot->parts) { + for (auto& partIt : m_snapshot->parts) { bool xMirrored = String::isTrue(String::valueOrEmpty(partIt.second, "xMirrored")); if (!xMirrored) continue; std::map mirroredPart = partIt.second; - + std::string newPartIdString = reverseUuid(mirroredPart["id"]); - partOldToNewMap.insert({mirroredPart["id"], newPartIdString}); + partOldToNewMap.insert({ mirroredPart["id"], newPartIdString }); mirroredPart["__mirrorFromPartId"] = mirroredPart["id"]; mirroredPart["id"] = newPartIdString; mirroredPart["__dirty"] = "true"; newParts.push_back(mirroredPart); } - - for (const auto &it: partOldToNewMap) + + for (const auto& it : partOldToNewMap) m_snapshot->parts[it.second]["__mirroredByPartId"] = it.first; - + std::map parentMap; - for (auto &componentIt: m_snapshot->components) { - for (const auto &childId: String::split(String::valueOrEmpty(componentIt.second, "children"), ',')) { + for (auto& componentIt : m_snapshot->components) { + for (const auto& childId : String::split(String::valueOrEmpty(componentIt.second, "children"), ',')) { if (childId.empty()) continue; parentMap[childId] = componentIt.first; } } - for (const auto &childId: String::split(String::valueOrEmpty(m_snapshot->rootComponent, "children"), ',')) { + for (const auto& childId : String::split(String::valueOrEmpty(m_snapshot->rootComponent, "children"), ',')) { if (childId.empty()) continue; parentMap[childId] = std::string(); } - + std::vector> newComponents; - for (auto &componentIt: m_snapshot->components) { + for (auto& componentIt : m_snapshot->components) { std::string linkDataType = String::valueOrEmpty(componentIt.second, "linkDataType"); if ("partId" != linkDataType) continue; @@ -1586,10 +1566,10 @@ void MeshGenerator::preprocessMirror() newComponents.push_back(mirroredComponent); } - for (const auto &it: newParts) { + for (const auto& it : newParts) { m_snapshot->parts[String::valueOrEmpty(it, "id")] = it; } - for (const auto &it: newComponents) { + for (const auto& it : newComponents) { std::string idString = String::valueOrEmpty(it, "id"); std::string parentIdString = parentMap[idString]; m_snapshot->components[idString] = it; @@ -1601,7 +1581,7 @@ void MeshGenerator::preprocessMirror() } } -void MeshGenerator::addComponentPreview(const Uuid &componentId, ComponentPreview &&preview) +void MeshGenerator::addComponentPreview(const Uuid& componentId, ComponentPreview&& preview) { m_generatedPreviewComponentIds.insert(componentId); m_generatedComponentPreviews[componentId] = std::move(preview); @@ -1613,13 +1593,13 @@ void MeshGenerator::generate() return; m_isSuccessful = true; - + m_mainProfileMiddleX = String::toFloat(String::valueOrEmpty(m_snapshot->canvas, "originX")); m_mainProfileMiddleY = String::toFloat(String::valueOrEmpty(m_snapshot->canvas, "originY")); m_sideProfileMiddleX = String::toFloat(String::valueOrEmpty(m_snapshot->canvas, "originZ")); - + preprocessMirror(); - + m_object = new Object; m_object->meshId = m_id; @@ -1629,7 +1609,7 @@ void MeshGenerator::generate() needDeleteCacheContext = true; } else { m_cacheEnabled = true; - for (auto it = m_cacheContext->parts.begin(); it != m_cacheContext->parts.end(); ) { + for (auto it = m_cacheContext->parts.begin(); it != m_cacheContext->parts.end();) { if (m_snapshot->parts.find(it->first) == m_snapshot->parts.end()) { auto mirrorFrom = m_cacheContext->partMirrorIdMap.find(it->first); if (mirrorFrom != m_cacheContext->partMirrorIdMap.end()) { @@ -1644,9 +1624,9 @@ void MeshGenerator::generate() } it++; } - for (auto it = m_cacheContext->components.begin(); it != m_cacheContext->components.end(); ) { + for (auto it = m_cacheContext->components.begin(); it != m_cacheContext->components.end();) { if (m_snapshot->components.find(it->first) == m_snapshot->components.end()) { - for (auto combinationIt = m_cacheContext->cachedCombination.begin(); combinationIt != m_cacheContext->cachedCombination.end(); ) { + for (auto combinationIt = m_cacheContext->cachedCombination.begin(); combinationIt != m_cacheContext->cachedCombination.end();) { if (std::string::npos != combinationIt->first.find(it->first)) { combinationIt = m_cacheContext->cachedCombination.erase(combinationIt); continue; @@ -1659,12 +1639,12 @@ void MeshGenerator::generate() it++; } } - + collectParts(); checkDirtyFlags(); - - for (const auto &dirtyComponentId: m_dirtyComponentIds) { - for (auto combinationIt = m_cacheContext->cachedCombination.begin(); combinationIt != m_cacheContext->cachedCombination.end(); ) { + + for (const auto& dirtyComponentId : m_dirtyComponentIds) { + for (auto combinationIt = m_cacheContext->cachedCombination.begin(); combinationIt != m_cacheContext->cachedCombination.end();) { if (std::string::npos != combinationIt->first.find(dirtyComponentId)) { combinationIt = m_cacheContext->cachedCombination.erase(combinationIt); continue; @@ -1672,18 +1652,18 @@ void MeshGenerator::generate() combinationIt++; } } - + m_dirtyComponentIds.insert(to_string(Uuid())); - + CombineMode combineMode; auto combinedMesh = combineComponentMesh(to_string(Uuid()), &combineMode); - - const auto &componentCache = m_cacheContext->components[to_string(Uuid())]; - + + const auto& componentCache = m_cacheContext->components[to_string(Uuid())]; + m_object->nodes = componentCache.objectNodes; m_object->edges = componentCache.objectEdges; m_nodeVertices = componentCache.objectNodeVertices; - + std::vector combinedVertices; std::vector> combinedFaces; if (nullptr != combinedMesh) { @@ -1706,10 +1686,10 @@ void MeshGenerator::generate() m_object->vertices = combinedVertices; m_object->triangles = combinedFaces; } - + // Recursively check uncombined components collectUncombinedComponent(to_string(Uuid())); - + collectErroredParts(); postprocessObject(m_object); @@ -1720,4 +1700,3 @@ void MeshGenerator::generate() } } - diff --git a/dust3d/mesh/mesh_generator.h b/dust3d/mesh/mesh_generator.h index fec2bfe7..9af41ce4 100644 --- a/dust3d/mesh/mesh_generator.h +++ b/dust3d/mesh/mesh_generator.h @@ -23,29 +23,26 @@ #ifndef DUST3D_MESH_MESH_GENERATOR_H_ #define DUST3D_MESH_MESH_GENERATOR_H_ -#include -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { -class MeshGenerator -{ +class MeshGenerator { public: static double m_minimalRadius; - struct GeneratedPart - { + struct GeneratedPart { std::vector vertices; std::vector> faces; std::vector objectNodes; @@ -58,8 +55,7 @@ public: bool joined = true; }; - struct GeneratedComponent - { + struct GeneratedComponent { std::unique_ptr mesh; std::set> sharedQuadEdges; std::set noneSeamVertices; @@ -68,47 +64,45 @@ public: std::vector>> objectNodeVertices; }; - struct GeneratedCacheContext - { + struct GeneratedCacheContext { std::map components; std::map parts; std::map partMirrorIdMap; std::map> cachedCombination; }; - - struct ComponentPreview - { + + struct ComponentPreview { std::vector vertices; std::vector> triangles; Color color = Color(1.0, 1.0, 1.0); float metalness = 0.0; float roughness = 1.0; - std::vector> vertexProperties; + std::vector> vertexProperties; }; - MeshGenerator(Snapshot *snapshot); + MeshGenerator(Snapshot* snapshot); ~MeshGenerator(); bool isSuccessful(); - const std::set &generatedPreviewComponentIds(); - const std::map &generatedComponentPreviews(); - Object *takeObject(); + const std::set& generatedPreviewComponentIds(); + const std::map& generatedComponentPreviews(); + Object* takeObject(); virtual void generate(); - void setGeneratedCacheContext(GeneratedCacheContext *cacheContext); + void setGeneratedCacheContext(GeneratedCacheContext* cacheContext); void setSmoothShadingThresholdAngleDegrees(float degrees); - void setDefaultPartColor(const Color &color); + void setDefaultPartColor(const Color& color); void setId(uint64_t id); void setWeldEnabled(bool enabled); uint64_t id(); - + protected: std::set m_generatedPreviewComponentIds; std::map m_generatedComponentPreviews; - Object *m_object = nullptr; - + Object* m_object = nullptr; + private: Color m_defaultPartColor = Color::createWhite(); - Snapshot *m_snapshot = nullptr; - GeneratedCacheContext *m_cacheContext = nullptr; + Snapshot* m_snapshot = nullptr; + GeneratedCacheContext* m_cacheContext = nullptr; std::set m_dirtyComponentIds; std::set m_dirtyPartIds; float m_mainProfileMiddleX = 0; @@ -122,48 +116,48 @@ private: float m_smoothShadingThresholdAngleDegrees = 60; uint64_t m_id = 0; bool m_weldEnabled = true; - + void collectParts(); - void collectIncombinableMesh(const MeshCombiner::Mesh *mesh, const GeneratedComponent &componentCache); - bool checkIsComponentDirty(const std::string &componentIdString); - bool checkIsPartDirty(const std::string &partIdString); - bool checkIsPartDependencyDirty(const std::string &partIdString); + void collectIncombinableMesh(const MeshCombiner::Mesh* mesh, const GeneratedComponent& componentCache); + bool checkIsComponentDirty(const std::string& componentIdString); + bool checkIsPartDirty(const std::string& partIdString); + bool checkIsPartDependencyDirty(const std::string& partIdString); void checkDirtyFlags(); - std::unique_ptr combinePartMesh(const std::string &partIdString, - bool *hasError); - std::unique_ptr combineComponentMesh(const std::string &componentIdString, CombineMode *combineMode); - void makeXmirror(const std::vector &sourceVertices, const std::vector> &sourceFaces, - std::vector *destVertices, std::vector> *destFaces); - void collectSharedQuadEdges(const std::vector &vertices, const std::vector> &faces, - std::set> *sharedQuadEdges); - std::unique_ptr combineTwoMeshes(const MeshCombiner::Mesh &first, const MeshCombiner::Mesh &second, + std::unique_ptr combinePartMesh(const std::string& partIdString, + bool* hasError); + std::unique_ptr combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode); + void makeXmirror(const std::vector& sourceVertices, const std::vector>& sourceFaces, + std::vector* destVertices, std::vector>* destFaces); + void collectSharedQuadEdges(const std::vector& vertices, const std::vector>& faces, + std::set>* sharedQuadEdges); + std::unique_ptr combineTwoMeshes(const MeshCombiner::Mesh& first, const MeshCombiner::Mesh& second, MeshCombiner::Method method, - bool recombine=true); - const std::map *findComponent(const std::string &componentIdString); - CombineMode componentCombineMode(const std::map *component); - std::unique_ptr combineComponentChildGroupMesh(const std::vector &componentIdStrings, - GeneratedComponent &componentCache); - std::unique_ptr combineMultipleMeshes(std::vector, CombineMode, std::string>> &&multipleMeshes, bool recombine=true); - std::unique_ptr combineStitchingMesh(const std::vector &partIdStrings, - const std::vector &componentIdStrings, - GeneratedComponent &componentCache); - std::string componentColorName(const std::map *component); - void collectUncombinedComponent(const std::string &componentIdString); - void cutFaceStringToCutTemplate(const std::string &cutFaceString, std::vector &cutTemplate); - void postprocessObject(Object *object); + bool recombine = true); + const std::map* findComponent(const std::string& componentIdString); + CombineMode componentCombineMode(const std::map* component); + std::unique_ptr combineComponentChildGroupMesh(const std::vector& componentIdStrings, + GeneratedComponent& componentCache); + std::unique_ptr combineMultipleMeshes(std::vector, CombineMode, std::string>>&& multipleMeshes, bool recombine = true); + std::unique_ptr combineStitchingMesh(const std::vector& partIdStrings, + const std::vector& componentIdStrings, + GeneratedComponent& componentCache); + std::string componentColorName(const std::map* component); + void collectUncombinedComponent(const std::string& componentIdString); + void cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector& cutTemplate); + void postprocessObject(Object* object); void collectErroredParts(); void preprocessMirror(); - std::string reverseUuid(const std::string &uuidString); - void recoverQuads(const std::vector &vertices, const std::vector> &triangles, const std::set> &sharedQuadEdges, std::vector> &triangleAndQuads); - void addComponentPreview(const Uuid &componentId, ComponentPreview &&preview); - bool fetchPartOrderedNodes(const std::string &partIdString, std::vector *meshNodes, bool *isCircle); + std::string reverseUuid(const std::string& uuidString); + void recoverQuads(const std::vector& vertices, const std::vector>& triangles, const std::set>& sharedQuadEdges, std::vector>& triangleAndQuads); + void addComponentPreview(const Uuid& componentId, ComponentPreview&& preview); + bool fetchPartOrderedNodes(const std::string& partIdString, std::vector* meshNodes, bool* isCircle); - static void chamferFace(std::vector *face); - static void subdivideFace(std::vector *face); - static bool isWatertight(const std::vector> &faces); - static void flattenLinks(const std::unordered_map &links, - std::vector *array, - bool *isCircle); + static void chamferFace(std::vector* face); + static void subdivideFace(std::vector* face); + static bool isWatertight(const std::vector>& faces); + static void flattenLinks(const std::unordered_map& links, + std::vector* array, + bool* isCircle); }; } diff --git a/dust3d/mesh/mesh_node.h b/dust3d/mesh/mesh_node.h index 765d4a34..c88471d6 100644 --- a/dust3d/mesh/mesh_node.h +++ b/dust3d/mesh/mesh_node.h @@ -23,14 +23,12 @@ #ifndef DUST3D_MESH_MESH_NODE_H_ #define DUST3D_MESH_MESH_NODE_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -struct MeshNode -{ +struct MeshNode { Vector3 origin; double radius; Uuid sourceId; diff --git a/dust3d/mesh/mesh_recombiner.cc b/dust3d/mesh/mesh_recombiner.cc index f382df58..55808fcc 100644 --- a/dust3d/mesh/mesh_recombiner.cc +++ b/dust3d/mesh/mesh_recombiner.cc @@ -20,35 +20,34 @@ * SOFTWARE. */ -#include #include -#include -#include #include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { -#define MAX_EDGE_LOOP_LENGTH 1000 +#define MAX_EDGE_LOOP_LENGTH 1000 -void MeshRecombiner::setVertices(const std::vector *vertices, - const std::vector> *verticesSourceIndices) +void MeshRecombiner::setVertices(const std::vector* vertices, + const std::vector>* verticesSourceIndices) { m_vertices = vertices; m_verticesSourceIndices = verticesSourceIndices; } -void MeshRecombiner::setFaces(const std::vector> *faces) +void MeshRecombiner::setFaces(const std::vector>* faces) { m_faces = faces; } -bool MeshRecombiner::convertHalfEdgesToEdgeLoops(const std::vector> &halfEdges, - std::vector> *edgeLoops) +bool MeshRecombiner::convertHalfEdgesToEdgeLoops(const std::vector>& halfEdges, + std::vector>* edgeLoops) { std::map vertexLinkMap; - for (const auto &halfEdge: halfEdges) { + for (const auto& halfEdge : halfEdges) { auto inserResult = vertexLinkMap.insert(halfEdge); if (!inserResult.second) { return false; @@ -77,7 +76,7 @@ bool MeshRecombiner::convertHalfEdgesToEdgeLoops(const std::vectorpush_back(edgeLoop); @@ -85,12 +84,12 @@ bool MeshRecombiner::convertHalfEdgesToEdgeLoops(const std::vector> &seamEdges, - std::map *vertexToIslandMap) +size_t MeshRecombiner::splitSeamVerticesToIslands(const std::map>& seamEdges, + std::map* vertexToIslandMap) { std::set visited; size_t nextIslandId = 0; - for (const auto &it: seamEdges) { + for (const auto& it : seamEdges) { std::queue vertices; vertices.push(it.first); bool hasVertexJoin = false; @@ -100,11 +99,11 @@ size_t MeshRecombiner::splitSeamVerticesToIslands(const std::mapinsert({v, nextIslandId}); + vertexToIslandMap->insert({ v, nextIslandId }); hasVertexJoin = true; const auto findNeighbors = seamEdges.find(v); if (findNeighbors != seamEdges.end()) { - for (const auto &neighbor: findNeighbors->second) { + for (const auto& neighbor : findNeighbors->second) { vertices.push(neighbor); } } @@ -115,14 +114,14 @@ size_t MeshRecombiner::splitSeamVerticesToIslands(const std::map, size_t> &halfEdgeToFaceMap) +bool MeshRecombiner::buildHalfEdgeToFaceMap(std::map, size_t>& halfEdgeToFaceMap) { bool isSuccessful = true; for (size_t faceIndex = 0; faceIndex < m_faces->size(); ++faceIndex) { - const auto &face = (*m_faces)[faceIndex]; + const auto& face = (*m_faces)[faceIndex]; for (size_t i = 0; i < face.size(); ++i) { size_t j = (i + 1) % face.size(); - const auto insertResult = halfEdgeToFaceMap.insert({{face[i], face[j]}, faceIndex}); + const auto insertResult = halfEdgeToFaceMap.insert({ { face[i], face[j] }, faceIndex }); if (!insertResult.second) { isSuccessful = false; } @@ -134,11 +133,11 @@ bool MeshRecombiner::buildHalfEdgeToFaceMap(std::map, bool MeshRecombiner::recombine() { buildHalfEdgeToFaceMap(m_halfEdgeToFaceMap); - + std::map> seamLink; - for (const auto &face: *m_faces) { + for (const auto& face : *m_faces) { for (size_t i = 0; i < face.size(); ++i) { - const auto &index = face[i]; + const auto& index = face[i]; auto source = (*m_verticesSourceIndices)[index]; if (MeshCombiner::Source::None == source.first) { auto next = face[(i + 1) % face.size()]; @@ -151,18 +150,18 @@ bool MeshRecombiner::recombine() } std::map seamVertexToIslandMap; size_t islands = splitSeamVerticesToIslands(seamLink, &seamVertexToIslandMap); - + std::map, std::pair> edgesInSeamArea; for (size_t faceIndex = 0; faceIndex < (*m_faces).size(); ++faceIndex) { - const auto &face = (*m_faces)[faceIndex]; + const auto& face = (*m_faces)[faceIndex]; bool containsSeamVertex = false; bool inFirstGroup = false; size_t island = 0; for (size_t i = 0; i < face.size(); ++i) { - const auto &index = face[i]; + const auto& index = face[i]; auto source = (*m_verticesSourceIndices)[index]; if (MeshCombiner::Source::None == source.first) { - const auto &findIsland = seamVertexToIslandMap.find(index); + const auto& findIsland = seamVertexToIslandMap.find(index); if (findIsland != seamVertexToIslandMap.end()) { containsSeamVertex = true; island = findIsland->second; @@ -172,52 +171,50 @@ bool MeshRecombiner::recombine() } } if (containsSeamVertex) { - m_facesInSeamArea.insert({faceIndex, island}); + m_facesInSeamArea.insert({ faceIndex, island }); for (size_t i = 0; i < face.size(); ++i) { - const auto &index = face[i]; - const auto &next = face[(i + 1) % face.size()]; - std::pair edge = {index, next}; - edgesInSeamArea.insert({edge, {island, inFirstGroup}}); + const auto& index = face[i]; + const auto& next = face[(i + 1) % face.size()]; + std::pair edge = { index, next }; + edgesInSeamArea.insert({ edge, { island, inFirstGroup } }); } } } - - struct IslandData - { + + struct IslandData { std::vector> halfedges[2]; std::vector> edgeLoops[2]; }; std::map islandsMap; - - for (const auto &edge: edgesInSeamArea) { - if (edgesInSeamArea.find({edge.first.second, edge.first.first}) == edgesInSeamArea.end()) { + + for (const auto& edge : edgesInSeamArea) { + if (edgesInSeamArea.find({ edge.first.second, edge.first.first }) == edgesInSeamArea.end()) { islandsMap[edge.second.first].halfedges[edge.second.second ? 0 : 1].push_back(edge.first); } } - for (auto &it: islandsMap) { + for (auto& it : islandsMap) { for (size_t side = 0; side < 2; ++side) { if (!convertHalfEdgesToEdgeLoops(it.second.halfedges[side], &it.second.edgeLoops[side])) { it.second.edgeLoops[side].clear(); } } } - - for (auto &it: islandsMap) { + + for (auto& it : islandsMap) { for (size_t side = 0; side < 2; ++side) { for (size_t i = 0; i < it.second.edgeLoops[side].size(); ++i) { - auto &edgeLoop = it.second.edgeLoops[side][i]; + auto& edgeLoop = it.second.edgeLoops[side][i]; size_t totalAdjustedTriangles = 0; size_t adjustedTriangles = 0; - while ((adjustedTriangles=adjustTrianglesFromSeam(edgeLoop, it.first)) > 0) { + while ((adjustedTriangles = adjustTrianglesFromSeam(edgeLoop, it.first)) > 0) { totalAdjustedTriangles += adjustedTriangles; } } } } - - for (auto &it: islandsMap) { - if (1 == it.second.edgeLoops[0].size() && - it.second.edgeLoops[0].size() == it.second.edgeLoops[1].size()) { + + for (auto& it : islandsMap) { + if (1 == it.second.edgeLoops[0].size() && it.second.edgeLoops[0].size() == it.second.edgeLoops[1].size()) { if (bridge(it.second.edgeLoops[0][0], it.second.edgeLoops[1][0])) { m_goodSeams.insert(it.first); } @@ -230,7 +227,7 @@ bool MeshRecombiner::recombine() return true; } -size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector &edgeLoop, size_t seamIndex) +size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector& edgeLoop, size_t seamIndex) { if (edgeLoop.size() <= 3) return 0; @@ -238,13 +235,13 @@ size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector &edgeLoop, si std::vector halfEdgeToFaces; for (size_t i = 0; i < edgeLoop.size(); ++i) { size_t j = (i + 1) % edgeLoop.size(); - auto findFace = m_halfEdgeToFaceMap.find({edgeLoop[j], edgeLoop[i]}); + auto findFace = m_halfEdgeToFaceMap.find({ edgeLoop[j], edgeLoop[i] }); if (findFace == m_halfEdgeToFaceMap.end()) { return 0; } halfEdgeToFaces.push_back(findFace->second); } - + std::vector removedFaceIndices; std::set ignored; for (size_t i = 0; i < edgeLoop.size(); ++i) { @@ -256,10 +253,10 @@ size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector &edgeLoop, si continue; } } - + if (!ignored.empty()) { std::vector newEdgeLoop; - for (const auto &v: edgeLoop) { + for (const auto& v : edgeLoop) { if (ignored.find(v) != ignored.end()) continue; newEdgeLoop.push_back(v); @@ -267,17 +264,17 @@ size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector &edgeLoop, si if (newEdgeLoop.size() < 3) return 0; edgeLoop = newEdgeLoop; - for (const auto &faceIndex: removedFaceIndices) - m_facesInSeamArea.insert({faceIndex, seamIndex}); + for (const auto& faceIndex : removedFaceIndices) + m_facesInSeamArea.insert({ faceIndex, seamIndex }); } - + return ignored.size(); } -size_t MeshRecombiner::otherVertexOfTriangle(const std::vector &face, const std::vector &indices) +size_t MeshRecombiner::otherVertexOfTriangle(const std::vector& face, const std::vector& indices) { - for (const auto &v: face) { - for (const auto &u: indices) { + for (const auto& v : face) { + for (const auto& u : indices) { if (u != v) return u; } @@ -288,30 +285,29 @@ size_t MeshRecombiner::otherVertexOfTriangle(const std::vector &face, co void MeshRecombiner::copyNonSeamFacesAsRegenerated() { for (size_t faceIndex = 0; faceIndex < m_faces->size(); ++faceIndex) { - const auto &findFaceInSeam = m_facesInSeamArea.find(faceIndex); - if (findFaceInSeam != m_facesInSeamArea.end() && - m_goodSeams.find(findFaceInSeam->second) != m_goodSeams.end()) + const auto& findFaceInSeam = m_facesInSeamArea.find(faceIndex); + if (findFaceInSeam != m_facesInSeamArea.end() && m_goodSeams.find(findFaceInSeam->second) != m_goodSeams.end()) continue; m_regeneratedFaces.push_back((*m_faces)[faceIndex]); } } -const std::vector &MeshRecombiner::regeneratedVertices() +const std::vector& MeshRecombiner::regeneratedVertices() { return m_regeneratedVertices; } -const std::vector> &MeshRecombiner::regeneratedVerticesSourceIndices() +const std::vector>& MeshRecombiner::regeneratedVerticesSourceIndices() { return m_regeneratedVerticesSourceIndices; } -const std::vector> &MeshRecombiner::regeneratedFaces() +const std::vector>& MeshRecombiner::regeneratedFaces() { return m_regeneratedFaces; } -size_t MeshRecombiner::nearestIndex(const Vector3 &position, const std::vector &edgeLoop) +size_t MeshRecombiner::nearestIndex(const Vector3& position, const std::vector& edgeLoop) { float minDist2 = std::numeric_limits::max(); size_t choosenIndex = 0; @@ -325,48 +321,48 @@ size_t MeshRecombiner::nearestIndex(const Vector3 &position, const std::vector &first, const std::vector &second) +bool MeshRecombiner::bridge(const std::vector& first, const std::vector& second) { - const std::vector *large = &first; - const std::vector *small = &second; + const std::vector* large = &first; + const std::vector* small = &second; if (large->size() < small->size()) std::swap(large, small); std::vector> matchedPairs; std::map nearestIndicesFromLargeToSmall; for (size_t i = 0; i < small->size(); ++i) { - const auto &positionOnSmall = (*m_vertices)[(*small)[i]]; + const auto& positionOnSmall = (*m_vertices)[(*small)[i]]; size_t nearestIndexOnLarge = nearestIndex(positionOnSmall, *large); auto matchResult = nearestIndicesFromLargeToSmall.find(nearestIndexOnLarge); size_t nearestIndexOnSmall; if (matchResult == nearestIndicesFromLargeToSmall.end()) { - const auto &positionOnLarge = (*m_vertices)[(*large)[nearestIndexOnLarge]]; + const auto& positionOnLarge = (*m_vertices)[(*large)[nearestIndexOnLarge]]; nearestIndexOnSmall = nearestIndex(positionOnLarge, *small); - nearestIndicesFromLargeToSmall.insert({nearestIndexOnLarge, nearestIndexOnSmall}); + nearestIndicesFromLargeToSmall.insert({ nearestIndexOnLarge, nearestIndexOnSmall }); } else { nearestIndexOnSmall = matchResult->second; } if (nearestIndexOnSmall == i) { - matchedPairs.push_back({nearestIndexOnSmall, nearestIndexOnLarge}); + matchedPairs.push_back({ nearestIndexOnSmall, nearestIndexOnLarge }); } } if (matchedPairs.empty()) return false; - + for (size_t i = 0; i < matchedPairs.size(); ++i) { size_t j = (i + 1) % matchedPairs.size(); std::vector smallSide; std::vector largeSide; for (size_t indexOnSmall = matchedPairs[i].first; - ; - indexOnSmall = (indexOnSmall + 1) % small->size()) { + ; + indexOnSmall = (indexOnSmall + 1) % small->size()) { smallSide.push_back((*small)[indexOnSmall]); if (indexOnSmall == matchedPairs[j].first) break; } for (size_t indexOnLarge = matchedPairs[j].second; - ; - indexOnLarge = (indexOnLarge + 1) % large->size()) { + ; + indexOnLarge = (indexOnLarge + 1) % large->size()) { largeSide.push_back((*large)[indexOnLarge]); if (indexOnLarge == matchedPairs[i].second) break; @@ -374,53 +370,44 @@ bool MeshRecombiner::bridge(const std::vector &first, const std::vector< std::reverse(largeSide.begin(), largeSide.end()); fillPairs(smallSide, largeSide); } - + return true; } -void MeshRecombiner::fillPairs(const std::vector &small, const std::vector &large) +void MeshRecombiner::fillPairs(const std::vector& small, const std::vector& large) { size_t smallIndex = 0; size_t largeIndex = 0; - while (smallIndex + 1 < small.size() || - largeIndex + 1 < large.size()) { + while (smallIndex + 1 < small.size() || largeIndex + 1 < large.size()) { if (smallIndex + 1 < small.size() && largeIndex + 1 < large.size()) { float angleOnSmallEdgeLoop = Vector3::angleBetween((*m_vertices)[large[largeIndex]] - (*m_vertices)[small[smallIndex]], (*m_vertices)[small[smallIndex + 1]] - (*m_vertices)[small[smallIndex]]); float angleOnLargeEdgeLoop = Vector3::angleBetween((*m_vertices)[small[smallIndex]] - (*m_vertices)[large[largeIndex]], (*m_vertices)[large[largeIndex + 1]] - (*m_vertices)[large[largeIndex]]); if (angleOnSmallEdgeLoop < angleOnLargeEdgeLoop) { - m_regeneratedFaces.push_back({ - small[smallIndex], + m_regeneratedFaces.push_back({ small[smallIndex], small[smallIndex + 1], - large[largeIndex] - }); + large[largeIndex] }); ++smallIndex; continue; } - m_regeneratedFaces.push_back({ - large[largeIndex + 1], + m_regeneratedFaces.push_back({ large[largeIndex + 1], large[largeIndex], - small[smallIndex] - }); + small[smallIndex] }); ++largeIndex; continue; } if (smallIndex + 1 >= small.size()) { - m_regeneratedFaces.push_back({ - large[largeIndex + 1], + m_regeneratedFaces.push_back({ large[largeIndex + 1], large[largeIndex], - small[smallIndex] - }); + small[smallIndex] }); ++largeIndex; continue; } if (largeIndex + 1 >= large.size()) { - m_regeneratedFaces.push_back({ - small[smallIndex], + m_regeneratedFaces.push_back({ small[smallIndex], small[smallIndex + 1], - large[largeIndex] - }); + large[largeIndex] }); ++smallIndex; continue; } @@ -432,17 +419,17 @@ void MeshRecombiner::removeReluctantVertices() { std::vector> rearrangedFaces; std::map oldToNewIndexMap; - for (const auto &face: m_regeneratedFaces) { + for (const auto& face : m_regeneratedFaces) { std::vector newFace; - for (const auto &index: face) { - const auto &findIndex = oldToNewIndexMap.find(index); + for (const auto& index : face) { + const auto& findIndex = oldToNewIndexMap.find(index); if (findIndex != oldToNewIndexMap.end()) { newFace.push_back(findIndex->second); } else { size_t newIndex = m_regeneratedVertices.size(); m_regeneratedVertices.push_back((*m_vertices)[index]); m_regeneratedVerticesSourceIndices.push_back((*m_verticesSourceIndices)[index]); - oldToNewIndexMap.insert({index, newIndex}); + oldToNewIndexMap.insert({ index, newIndex }); newFace.push_back(newIndex); } } diff --git a/dust3d/mesh/mesh_recombiner.h b/dust3d/mesh/mesh_recombiner.h index fba42216..a7bb6d8b 100644 --- a/dust3d/mesh/mesh_recombiner.h +++ b/dust3d/mesh/mesh_recombiner.h @@ -23,51 +23,49 @@ #ifndef DUST3D_MESH_MESH_RECOMBINER_H_ #define DUST3D_MESH_MESH_RECOMBINER_H_ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { -class MeshRecombiner -{ +class MeshRecombiner { public: - void setVertices(const std::vector *vertices, - const std::vector> *verticesSourceIndices); - void setFaces(const std::vector> *faces); - const std::vector ®eneratedVertices(); - const std::vector> ®eneratedVerticesSourceIndices(); - const std::vector> ®eneratedFaces(); + void setVertices(const std::vector* vertices, + const std::vector>* verticesSourceIndices); + void setFaces(const std::vector>* faces); + const std::vector& regeneratedVertices(); + const std::vector>& regeneratedVerticesSourceIndices(); + const std::vector>& regeneratedFaces(); bool recombine(); - + private: - const std::vector *m_vertices = nullptr; - const std::vector> *m_verticesSourceIndices = nullptr; - const std::vector> *m_faces = nullptr; + const std::vector* m_vertices = nullptr; + const std::vector>* m_verticesSourceIndices = nullptr; + const std::vector>* m_faces = nullptr; std::vector m_regeneratedVertices; std::vector> m_regeneratedVerticesSourceIndices; std::vector> m_regeneratedFaces; std::map, size_t> m_halfEdgeToFaceMap; std::map m_facesInSeamArea; std::set m_goodSeams; - + bool addFaceToHalfEdgeToFaceMap(size_t faceIndex, - std::map, size_t> &halfEdgeToFaceMap); - bool buildHalfEdgeToFaceMap(std::map, size_t> &halfEdgeToFaceMap); - bool convertHalfEdgesToEdgeLoops(const std::vector> &halfEdges, - std::vector> *edgeLoops); - size_t splitSeamVerticesToIslands(const std::map> &seamEdges, - std::map *vertexToIslandMap); + std::map, size_t>& halfEdgeToFaceMap); + bool buildHalfEdgeToFaceMap(std::map, size_t>& halfEdgeToFaceMap); + bool convertHalfEdgesToEdgeLoops(const std::vector>& halfEdges, + std::vector>* edgeLoops); + size_t splitSeamVerticesToIslands(const std::map>& seamEdges, + std::map* vertexToIslandMap); void copyNonSeamFacesAsRegenerated(); - size_t adjustTrianglesFromSeam(std::vector &edgeLoop, size_t seamIndex); - size_t otherVertexOfTriangle(const std::vector &face, const std::vector &indices); - bool bridge(const std::vector &first, const std::vector &second); - size_t nearestIndex(const Vector3 &position, const std::vector &edgeLoop); + size_t adjustTrianglesFromSeam(std::vector& edgeLoop, size_t seamIndex); + size_t otherVertexOfTriangle(const std::vector& face, const std::vector& indices); + bool bridge(const std::vector& first, const std::vector& second); + size_t nearestIndex(const Vector3& position, const std::vector& edgeLoop); void removeReluctantVertices(); - void fillPairs(const std::vector &small, const std::vector &large); - void updateEdgeLoopNeighborVertices(const std::vector &edgeLoop); + void fillPairs(const std::vector& small, const std::vector& large); + void updateEdgeLoopNeighborVertices(const std::vector& edgeLoop); }; } diff --git a/dust3d/mesh/re_triangulator.cc b/dust3d/mesh/re_triangulator.cc index 05531752..aec32bf3 100644 --- a/dust3d/mesh/re_triangulator.cc +++ b/dust3d/mesh/re_triangulator.cc @@ -19,53 +19,52 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - -#include -#include + #include -#include #include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { -ReTriangulator::ReTriangulator(const std::vector &points, - const Vector3 &normal) : - m_projectNormal(normal) +ReTriangulator::ReTriangulator(const std::vector& points, + const Vector3& normal) + : m_projectNormal(normal) { m_projectAxis = (points[1] - points[0]).normalized(); m_projectOrigin = points[0]; - + Vector3::project(points, &m_points, m_projectNormal, m_projectAxis, m_projectOrigin); } -void ReTriangulator::setEdges(const std::vector &points, - const std::unordered_map> *neighborMapFrom3) +void ReTriangulator::setEdges(const std::vector& points, + const std::unordered_map>* neighborMapFrom3) { Vector3::project(points, &m_points, m_projectNormal, m_projectAxis, m_projectOrigin); m_neighborMapFrom3 = neighborMapFrom3; } -void ReTriangulator::lookupPolylinesFromNeighborMap(const std::unordered_map> &neighborMap) +void ReTriangulator::lookupPolylinesFromNeighborMap(const std::unordered_map>& neighborMap) { std::vector endpoints; endpoints.reserve(neighborMap.size()); - for (const auto &it: neighborMap) { + for (const auto& it : neighborMap) { if (it.second.size() == 1) { endpoints.push_back(it.first); } } - for (const auto &it: neighborMap) { + for (const auto& it : neighborMap) { if (it.second.size() > 1) { endpoints.push_back(it.first); } } std::unordered_set visited; - for (const auto &startEndpoint: endpoints) { + for (const auto& startEndpoint : endpoints) { if (visited.find(startEndpoint) != visited.end()) continue; std::queue q; @@ -79,7 +78,7 @@ void ReTriangulator::lookupPolylinesFromNeighborMap(const std::unordered_mapsecond) { + for (const auto& it : neighborIt->second) { if (visited.find(it) == visited.end()) { q.push(it); break; @@ -98,10 +97,10 @@ void ReTriangulator::lookupPolylinesFromNeighborMap(const std::unordered_map> edgePoints(3); for (int polylineIndex = 0; polylineIndex < (int)m_polylines.size(); ++polylineIndex) { - const auto &polyline = m_polylines[polylineIndex]; + const auto& polyline = m_polylines[polylineIndex]; int frontEdge = attachPointToTriangleEdge(m_points[polyline.front()]); int backEdge = attachPointToTriangleEdge(m_points[polyline.back()]); - edgePoints[frontEdge].push_back({ - polyline.front(), + edgePoints[frontEdge].push_back({ polyline.front(), polyline.back(), polylineIndex, false, - (m_points[polyline.front()] - m_points[frontEdge]).lengthSquared() - }); - edgePoints[backEdge].push_back({ - polyline.back(), + (m_points[polyline.front()] - m_points[frontEdge]).lengthSquared() }); + edgePoints[backEdge].push_back({ polyline.back(), polyline.front(), polylineIndex, true, - (m_points[polyline.back()] - m_points[backEdge]).lengthSquared() - }); + (m_points[polyline.back()] - m_points[backEdge]).lengthSquared() }); } - for (auto &it: edgePoints) { - std::sort(it.begin(), it.end(), [](const EdgePoint &first, const EdgePoint &second) { + for (auto& it : edgePoints) { + std::sort(it.begin(), it.end(), [](const EdgePoint& first, const EdgePoint& second) { return first.squaredDistance < second.squaredDistance; }); } - + // Turn triangle to ring std::vector ringPoints; for (size_t i = 0; i < 3; ++i) { - ringPoints.push_back({i}); - for (const auto &it: edgePoints[i]) + ringPoints.push_back({ i }); + for (const auto& it : edgePoints[i]) ringPoints.push_back(it); } - + // Make polyline link std::unordered_map pointRingPositionMap; for (size_t i = 0; i < ringPoints.size(); ++i) { - const auto &it = ringPoints[i]; + const auto& it = ringPoints[i]; if (-1 == it.polylineIndex) continue; - pointRingPositionMap.insert({it.pointIndex, i}); + pointRingPositionMap.insert({ it.pointIndex, i }); } for (size_t i = 0; i < ringPoints.size(); ++i) { - auto &it = ringPoints[i]; + auto& it = ringPoints[i]; if (-1 == it.polylineIndex) continue; auto findLinkTo = pointRingPositionMap.find(it.linkToPointIndex); @@ -228,18 +220,18 @@ bool ReTriangulator::buildPolygons() std::vector polygon; auto loopIndex = startIndex; do { - auto &it = ringPoints[loopIndex]; + auto& it = ringPoints[loopIndex]; visited.insert(loopIndex); if (-1 == it.polylineIndex) { polygon.push_back(it.pointIndex); loopIndex = (loopIndex + 1) % ringPoints.size(); } else if (-1 != it.linkTo) { - const auto &polyline = m_polylines[it.polylineIndex]; + const auto& polyline = m_polylines[it.polylineIndex]; if (it.reversed) { for (int i = (int)polyline.size() - 1; i >= 0; --i) polygon.push_back(polyline[i]); } else { - for (const auto &pointIndex: polyline) + for (const auto& pointIndex : polyline) polygon.push_back(pointIndex); } startQueue.push((loopIndex + 1) % ringPoints.size()); @@ -251,34 +243,34 @@ bool ReTriangulator::buildPolygons() } while (loopIndex != startIndex); m_polygons.push_back(polygon); } - + return true; } void ReTriangulator::triangulate() { for (size_t polygonIndex = 0; polygonIndex < m_polygons.size(); ++polygonIndex) { - const auto &polygon = m_polygons[polygonIndex]; + const auto& polygon = m_polygons[polygonIndex]; std::vector>> polygonAndHoles; std::vector pointIndices; std::vector> border; - for (const auto &it: polygon) { + for (const auto& it : polygon) { pointIndices.push_back(it); - const auto &v = m_points[it]; - border.push_back(std::array {v.x(), v.y()}); + const auto& v = m_points[it]; + border.push_back(std::array { v.x(), v.y() }); } polygonAndHoles.push_back(border); - + auto findHoles = m_polygonHoles.find(polygonIndex); if (findHoles != m_polygonHoles.end()) { - for (const auto &h: findHoles->second) { + for (const auto& h : findHoles->second) { std::vector> hole; - for (const auto &it: m_innerPolygons[h]) { + for (const auto& it : m_innerPolygons[h]) { pointIndices.push_back(it); - const auto &v = m_points[it]; - hole.push_back(std::array {v.x(), v.y()}); + const auto& v = m_points[it]; + hole.push_back(std::array { v.x(), v.y() }); } polygonAndHoles.push_back(hole); } @@ -291,59 +283,55 @@ void ReTriangulator::triangulate() // Vector3(m_points[pointIndices[indices[i + 1]]]), // Vector3(m_points[pointIndices[indices[i + 2]]])); //dust3dDebug << "triangleArea:" << (triangleArea * 10000) << "isZero:" << Math::isZero(triangleArea) << (triangleArea <= 0 ? "Negative" : ""); - m_triangles.push_back({ - pointIndices[indices[i]], + m_triangles.push_back({ pointIndices[indices[i]], pointIndices[indices[i + 1]], - pointIndices[indices[i + 2]] - }); + pointIndices[indices[i + 2]] }); } } - + for (size_t polygonIndex = 0; polygonIndex < m_innerPolygons.size(); ++polygonIndex) { - const auto &polygon = m_innerPolygons[polygonIndex]; + const auto& polygon = m_innerPolygons[polygonIndex]; std::vector>> polygonAndHoles; std::vector pointIndices; std::vector> border; - for (const auto &it: polygon) { + for (const auto& it : polygon) { pointIndices.push_back(it); - const auto &v = m_points[it]; - border.push_back(std::array {v.x(), v.y()}); + const auto& v = m_points[it]; + border.push_back(std::array { v.x(), v.y() }); } polygonAndHoles.push_back(border); - + auto childrenIt = m_innerChildrenMap.find(polygonIndex); if (childrenIt != m_innerChildrenMap.end()) { auto children = childrenIt->second; - for (const auto &child: childrenIt->second) { + for (const auto& child : childrenIt->second) { auto grandChildrenIt = m_innerChildrenMap.find(child); if (grandChildrenIt != m_innerChildrenMap.end()) { - for (const auto &grandChild: grandChildrenIt->second) { + for (const auto& grandChild : grandChildrenIt->second) { dust3dDebug << "Grand child removed:" << grandChild; children.erase(grandChild); } } } - for (const auto &child: children) { + for (const auto& child : children) { std::vector> hole; - for (const auto &it: m_innerPolygons[child]) { + for (const auto& it : m_innerPolygons[child]) { pointIndices.push_back(it); - const auto &v = m_points[it]; - hole.push_back(std::array {v.x(), v.y()}); + const auto& v = m_points[it]; + hole.push_back(std::array { v.x(), v.y() }); } polygonAndHoles.push_back(hole); } } - + std::vector indices = mapbox::earcut(polygonAndHoles); m_triangles.reserve(indices.size() / 3); for (size_t i = 0; i < indices.size(); i += 3) { - m_triangles.push_back({ - pointIndices[indices[i]], + m_triangles.push_back({ pointIndices[indices[i]], pointIndices[indices[i + 1]], - pointIndices[indices[i + 2]] - }); + pointIndices[indices[i + 2]] }); } } } @@ -360,12 +348,12 @@ bool ReTriangulator::reTriangulate() return true; } -const std::vector> &ReTriangulator::polygons() const +const std::vector>& ReTriangulator::polygons() const { return m_polygons; } -const std::vector> &ReTriangulator::triangles() const +const std::vector>& ReTriangulator::triangles() const { return m_triangles; } diff --git a/dust3d/mesh/re_triangulator.h b/dust3d/mesh/re_triangulator.h index 1b81675e..2d143b09 100644 --- a/dust3d/mesh/re_triangulator.h +++ b/dust3d/mesh/re_triangulator.h @@ -19,34 +19,33 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_MESH_RE_TRIANGULATOR_H_ #define DUST3D_MESH_RE_TRIANGULATOR_H_ +#include +#include #include #include -#include -#include -namespace dust3d -{ - -class ReTriangulator -{ +namespace dust3d { + +class ReTriangulator { public: - ReTriangulator(const std::vector &points, - const Vector3 &normal); - void setEdges(const std::vector &points, - const std::unordered_map> *neighborMapFrom3); + ReTriangulator(const std::vector& points, + const Vector3& normal); + void setEdges(const std::vector& points, + const std::unordered_map>* neighborMapFrom3); bool reTriangulate(); - const std::vector> &polygons() const; - const std::vector> &triangles() const; + const std::vector>& polygons() const; + const std::vector>& triangles() const; + private: Vector3 m_projectAxis; Vector3 m_projectOrigin; Vector3 m_projectNormal; std::vector m_points; - const std::unordered_map> *m_neighborMapFrom3 = nullptr; + const std::unordered_map>* m_neighborMapFrom3 = nullptr; std::vector> m_polylines; std::vector> m_innerPolygons; std::vector> m_polygons; @@ -54,9 +53,9 @@ private: std::unordered_map> m_innerChildrenMap; std::unordered_map> m_polygonHoles; std::vector> m_triangles; - - void lookupPolylinesFromNeighborMap(const std::unordered_map> &neighborMap); - int attachPointToTriangleEdge(const Vector2 &point); + + void lookupPolylinesFromNeighborMap(const std::unordered_map>& neighborMap); + int attachPointToTriangleEdge(const Vector2& point); bool buildPolygons(); void buildPolygonHierarchy(); void triangulate(); diff --git a/dust3d/mesh/resolve_triangle_source_node.cc b/dust3d/mesh/resolve_triangle_source_node.cc index 2047e983..03683e31 100644 --- a/dust3d/mesh/resolve_triangle_source_node.cc +++ b/dust3d/mesh/resolve_triangle_source_node.cc @@ -20,21 +20,18 @@ * SOFTWARE. */ -#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -struct HalfColorEdge -{ +struct HalfColorEdge { int cornVertexIndex; std::pair source; }; -struct CandidateEdge -{ +struct CandidateEdge { std::pair source; int fromVertexIndex; int toVertexIndex; @@ -42,44 +39,42 @@ struct CandidateEdge float length; }; -static void fixRemainVertexSourceNodes(const Object &object, std::vector> &triangleSourceNodes, - std::vector> *vertexSourceNodes) +static void fixRemainVertexSourceNodes(const Object& object, std::vector>& triangleSourceNodes, + std::vector>* vertexSourceNodes) { if (nullptr != vertexSourceNodes) { std::map, size_t>> remainVertexSourcesMap; for (size_t faceIndex = 0; faceIndex < object.triangles.size(); ++faceIndex) { - for (const auto &vertexIndex: object.triangles[faceIndex]) { + for (const auto& vertexIndex : object.triangles[faceIndex]) { if (!(*vertexSourceNodes)[vertexIndex].second.isNull()) continue; remainVertexSourcesMap[vertexIndex][triangleSourceNodes[faceIndex]]++; } } - for (const auto &it: remainVertexSourcesMap) { - (*vertexSourceNodes)[it.first] = std::max_element(it.second.begin(), it.second.end(), []( - const std::map, size_t>::value_type &first, - const std::map, size_t>::value_type &second) { + for (const auto& it : remainVertexSourcesMap) { + (*vertexSourceNodes)[it.first] = std::max_element(it.second.begin(), it.second.end(), [](const std::map, size_t>::value_type& first, const std::map, size_t>::value_type& second) { return first.second < second.second; })->first; } } } -void resolveTriangleSourceNode(const Object &object, - const std::vector>> &nodeVertices, - std::vector> &triangleSourceNodes, - std::vector> *vertexSourceNodes) +void resolveTriangleSourceNode(const Object& object, + const std::vector>>& nodeVertices, + std::vector>& triangleSourceNodes, + std::vector>* vertexSourceNodes) { std::map> vertexSourceMap; std::map> positionMap; std::map, HalfColorEdge> halfColorEdgeMap; std::set brokenTriangleSet; - for (const auto &it: nodeVertices) { - positionMap.insert({PositionKey(it.first), it.second}); + for (const auto& it : nodeVertices) { + positionMap.insert({ PositionKey(it.first), it.second }); } if (nullptr != vertexSourceNodes) vertexSourceNodes->resize(object.vertices.size()); for (auto x = 0u; x < object.vertices.size(); x++) { - const Vector3 *resultVertex = &object.vertices[x]; + const Vector3* resultVertex = &object.vertices[x]; std::pair source; auto findPosition = positionMap.find(PositionKey(*resultVertex)); if (findPosition != positionMap.end()) { @@ -92,7 +87,7 @@ void resolveTriangleSourceNode(const Object &object, std::vector, int>> colorTypes; for (int i = 0; i < 3; i++) { int index = triangle[i]; - const auto &findResult = vertexSourceMap.find(index); + const auto& findResult = vertexSourceMap.find(index); if (findResult != vertexSourceMap.end()) { std::pair source = findResult->second; bool colorExisted = false; @@ -114,7 +109,7 @@ void resolveTriangleSourceNode(const Object &object, continue; } if (colorTypes.size() != 1 || 3 == colorTypes[0].second) { - std::sort(colorTypes.begin(), colorTypes.end(), [](const std::pair, int> &a, const std::pair, int> &b) -> bool { + std::sort(colorTypes.begin(), colorTypes.end(), [](const std::pair, int>& a, const std::pair, int>& b) -> bool { return a.second > b.second; }); } @@ -137,7 +132,7 @@ void resolveTriangleSourceNode(const Object &object, } std::map, int> brokenTriangleMapByEdge; std::vector candidateEdges; - for (const auto &x: brokenTriangleSet) { + for (const auto& x : brokenTriangleSet) { const auto triangle = object.triangles[x]; for (int i = 0; i < 3; i++) { int oppositeStartIndex = triangle[(i + 1) % 3]; @@ -145,7 +140,7 @@ void resolveTriangleSourceNode(const Object &object, auto selfPair = std::make_pair(oppositeStopIndex, oppositeStartIndex); brokenTriangleMapByEdge[selfPair] = x; auto oppositePair = std::make_pair(oppositeStartIndex, oppositeStopIndex); - const auto &findOpposite = halfColorEdgeMap.find(oppositePair); + const auto& findOpposite = halfColorEdgeMap.find(oppositePair); if (findOpposite == halfColorEdgeMap.end()) continue; Vector3 selfPositions[3] = { @@ -179,7 +174,7 @@ void resolveTriangleSourceNode(const Object &object, fixRemainVertexSourceNodes(object, triangleSourceNodes, vertexSourceNodes); return; } - std::sort(candidateEdges.begin(), candidateEdges.end(), [](const CandidateEdge &a, const CandidateEdge &b) -> bool { + std::sort(candidateEdges.begin(), candidateEdges.end(), [](const CandidateEdge& a, const CandidateEdge& b) -> bool { if (a.dot > b.dot) return true; else if (a.dot < b.dot) @@ -187,13 +182,13 @@ void resolveTriangleSourceNode(const Object &object, return a.length > b.length; }); for (auto cand = 0u; cand < candidateEdges.size(); cand++) { - const auto &candidate = candidateEdges[cand]; + const auto& candidate = candidateEdges[cand]; if (brokenTriangleSet.empty()) break; std::vector> toResolvePairs; toResolvePairs.push_back(std::make_pair(candidate.fromVertexIndex, candidate.toVertexIndex)); for (auto order = 0u; order < toResolvePairs.size(); order++) { - const auto &findTriangle = brokenTriangleMapByEdge.find(toResolvePairs[order]); + const auto& findTriangle = brokenTriangleMapByEdge.find(toResolvePairs[order]); if (findTriangle == brokenTriangleMapByEdge.end()) continue; int x = findTriangle->second; diff --git a/dust3d/mesh/resolve_triangle_source_node.h b/dust3d/mesh/resolve_triangle_source_node.h index b2749eab..0d1737c5 100644 --- a/dust3d/mesh/resolve_triangle_source_node.h +++ b/dust3d/mesh/resolve_triangle_source_node.h @@ -23,17 +23,16 @@ #ifndef DUST3D_MESH_RESOLVE_TRIANGLE_SOURCE_NODE_H_ #define DUST3D_MESH_RESOLVE_TRIANGLE_SOURCE_NODE_H_ -#include #include +#include + +namespace dust3d { + +void resolveTriangleSourceNode(const Object& object, + const std::vector>>& nodeVertices, + std::vector>& triangleSourceNodes, + std::vector>* vertexSourceNodes = nullptr); -namespace dust3d -{ - -void resolveTriangleSourceNode(const Object &object, - const std::vector>> &nodeVertices, - std::vector> &triangleSourceNodes, - std::vector> *vertexSourceNodes=nullptr); - } #endif diff --git a/dust3d/mesh/resolve_triangle_tangent.cc b/dust3d/mesh/resolve_triangle_tangent.cc index 57a7672b..65b006d1 100644 --- a/dust3d/mesh/resolve_triangle_tangent.cc +++ b/dust3d/mesh/resolve_triangle_tangent.cc @@ -20,31 +20,30 @@ * SOFTWARE. */ -#include #include +#include -namespace dust3d -{ - -void resolveTriangleTangent(const dust3d::Object &object, std::vector &tangents) +namespace dust3d { + +void resolveTriangleTangent(const dust3d::Object& object, std::vector& tangents) { tangents.resize(object.triangles.size()); - + if (nullptr == object.triangleVertexUvs()) return; - - const std::vector> &triangleVertexUvs = *object.triangleVertexUvs(); - + + const std::vector>& triangleVertexUvs = *object.triangleVertexUvs(); + for (decltype(object.triangles.size()) i = 0; i < object.triangles.size(); i++) { - tangents[i] = {0, 0, 0}; - const auto &uv = triangleVertexUvs[i]; - Vector2 uv1 = {uv[0][0], uv[0][1]}; - Vector2 uv2 = {uv[1][0], uv[1][1]}; - Vector2 uv3 = {uv[2][0], uv[2][1]}; - const auto &triangle = object.triangles[i]; - const Vector3 &pos1 = object.vertices[triangle[0]]; - const Vector3 &pos2 = object.vertices[triangle[1]]; - const Vector3 &pos3 = object.vertices[triangle[2]]; + tangents[i] = { 0, 0, 0 }; + const auto& uv = triangleVertexUvs[i]; + Vector2 uv1 = { uv[0][0], uv[0][1] }; + Vector2 uv2 = { uv[1][0], uv[1][1] }; + Vector2 uv3 = { uv[2][0], uv[2][1] }; + const auto& triangle = object.triangles[i]; + const Vector3& pos1 = object.vertices[triangle[0]]; + const Vector3& pos2 = object.vertices[triangle[1]]; + const Vector3& pos3 = object.vertices[triangle[2]]; Vector3 edge1 = pos2 - pos1; Vector3 edge2 = pos3 - pos1; Vector2 deltaUv1 = uv2 - uv1; diff --git a/dust3d/mesh/resolve_triangle_tangent.h b/dust3d/mesh/resolve_triangle_tangent.h index 4600de98..e4178d50 100644 --- a/dust3d/mesh/resolve_triangle_tangent.h +++ b/dust3d/mesh/resolve_triangle_tangent.h @@ -26,10 +26,9 @@ #include #include -namespace dust3d -{ +namespace dust3d { -void resolveTriangleTangent(const dust3d::Object &object, std::vector &tangents); +void resolveTriangleTangent(const dust3d::Object& object, std::vector& tangents); } diff --git a/dust3d/mesh/rope_mesh.cc b/dust3d/mesh/rope_mesh.cc index 12dd3742..6a38fd1d 100644 --- a/dust3d/mesh/rope_mesh.cc +++ b/dust3d/mesh/rope_mesh.cc @@ -25,25 +25,24 @@ #include #include -namespace dust3d -{ +namespace dust3d { -RopeMesh::RopeMesh(const BuildParameters ¶meters): - m_buildParameters(parameters) +RopeMesh::RopeMesh(const BuildParameters& parameters) + : m_buildParameters(parameters) { } -const std::vector &RopeMesh::resultVertices() +const std::vector& RopeMesh::resultVertices() { return m_resultVertices; } -const std::vector> &RopeMesh::resultTriangles() +const std::vector>& RopeMesh::resultTriangles() { return m_resultTriangles; } -void RopeMesh::addRope(const std::vector &positions, bool isCircle) +void RopeMesh::addRope(const std::vector& positions, bool isCircle) { if (positions.size() < 2) { dust3dDebug << "Expected at least 2 nodes, current:" << positions.size(); @@ -55,9 +54,9 @@ void RopeMesh::addRope(const std::vector &positions, bool isCircle) Vector3 forwardDirection = (positions[1] - positions[0]).normalized(); for (size_t i = isCircle ? 0 : 1; i < positions.size(); ++i) { size_t j = (i + 1) % positions.size(); - auto circlePositions = BaseNormal::calculateCircleVertices(m_buildParameters.defaultRadius, - m_buildParameters.sectionSegments, - forwardDirection, + auto circlePositions = BaseNormal::calculateCircleVertices(m_buildParameters.defaultRadius, + m_buildParameters.sectionSegments, + forwardDirection, baseNormal, positions[i]); std::vector indices(circlePositions.size()); @@ -70,16 +69,14 @@ void RopeMesh::addRope(const std::vector &positions, bool isCircle) } for (size_t j = isCircle ? 0 : 1; j < circles.size(); ++j) { size_t i = (j + circles.size() - 1) % circles.size(); - const auto &circlesI = circles[i]; - const auto &circlesJ = circles[j]; + const auto& circlesI = circles[i]; + const auto& circlesJ = circles[j]; for (size_t m = 0; m < circlesI.size(); ++m) { size_t n = (m + 1) % circlesI.size(); m_resultTriangles.emplace_back(std::vector { - circlesI[m], circlesI[n], circlesJ[n] - }); + circlesI[m], circlesI[n], circlesJ[n] }); m_resultTriangles.emplace_back(std::vector { - circlesJ[n], circlesJ[m], circlesI[m] - }); + circlesJ[n], circlesJ[m], circlesI[m] }); } } } diff --git a/dust3d/mesh/rope_mesh.h b/dust3d/mesh/rope_mesh.h index a264bc18..99fa3435 100644 --- a/dust3d/mesh/rope_mesh.h +++ b/dust3d/mesh/rope_mesh.h @@ -23,25 +23,23 @@ #ifndef DUST3D_MESH_ROPE_MESH_H_ #define DUST3D_MESH_ROPE_MESH_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -class RopeMesh -{ +class RopeMesh { public: - struct BuildParameters - { + struct BuildParameters { double defaultRadius = 0.008; size_t sectionSegments = 8; }; - RopeMesh(const BuildParameters ¶meters); - void addRope(const std::vector &positions, bool isCircle); - const std::vector &resultVertices(); - const std::vector> &resultTriangles(); + RopeMesh(const BuildParameters& parameters); + void addRope(const std::vector& positions, bool isCircle); + const std::vector& resultVertices(); + const std::vector>& resultTriangles(); + private: std::vector m_resultVertices; std::vector> m_resultTriangles; diff --git a/dust3d/mesh/section_preview_mesh_builder.cc b/dust3d/mesh/section_preview_mesh_builder.cc index dc224915..347442c6 100644 --- a/dust3d/mesh/section_preview_mesh_builder.cc +++ b/dust3d/mesh/section_preview_mesh_builder.cc @@ -23,20 +23,19 @@ #include #include -namespace dust3d -{ +namespace dust3d { -SectionPreviewMeshBuilder::SectionPreviewMeshBuilder(const std::vector &cutFace): - m_cutFace(cutFace) +SectionPreviewMeshBuilder::SectionPreviewMeshBuilder(const std::vector& cutFace) + : m_cutFace(cutFace) { } -const std::vector &SectionPreviewMeshBuilder::resultVertices() +const std::vector& SectionPreviewMeshBuilder::resultVertices() { return m_resultVertices; } -const std::vector> &SectionPreviewMeshBuilder::resultTriangles() +const std::vector>& SectionPreviewMeshBuilder::resultTriangles() { return m_resultTriangles; } diff --git a/dust3d/mesh/section_preview_mesh_builder.h b/dust3d/mesh/section_preview_mesh_builder.h index d428b3b4..4d0aaa05 100644 --- a/dust3d/mesh/section_preview_mesh_builder.h +++ b/dust3d/mesh/section_preview_mesh_builder.h @@ -23,20 +23,19 @@ #ifndef DUST3D_MESH_SECTION_PREVIEW_MESH_BUILDER_H_ #define DUST3D_MESH_SECTION_PREVIEW_MESH_BUILDER_H_ -#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -class SectionPreviewMeshBuilder -{ +class SectionPreviewMeshBuilder { public: - SectionPreviewMeshBuilder(const std::vector &cutFace); + SectionPreviewMeshBuilder(const std::vector& cutFace); void build(); - const std::vector &resultVertices(); - const std::vector> &resultTriangles(); + const std::vector& resultVertices(); + const std::vector>& resultTriangles(); + private: std::vector m_cutFace; std::vector m_resultVertices; @@ -45,5 +44,4 @@ private: } - #endif diff --git a/dust3d/mesh/smooth_normal.cc b/dust3d/mesh/smooth_normal.cc index d74729e3..0a687736 100644 --- a/dust3d/mesh/smooth_normal.cc +++ b/dust3d/mesh/smooth_normal.cc @@ -20,54 +20,53 @@ * SOFTWARE. */ -#include #include +#include -namespace dust3d -{ - -void smoothNormal(const std::vector &vertices, - const std::vector> &triangles, - const std::vector &triangleNormals, +namespace dust3d { + +void smoothNormal(const std::vector& vertices, + const std::vector>& triangles, + const std::vector& triangleNormals, float thresholdAngleDegrees, - std::vector> *triangleVertexNormals) + std::vector>* triangleVertexNormals) { std::vector>> triangleVertexNormalsMapByIndices(vertices.size()); std::vector angleAreaWeightedNormals; for (size_t triangleIndex = 0; triangleIndex < triangles.size(); ++triangleIndex) { - const auto &sourceTriangle = triangles[triangleIndex]; + const auto& sourceTriangle = triangles[triangleIndex]; if (sourceTriangle.size() != 3) { continue; } - const auto &v1 = vertices[sourceTriangle[0]]; - const auto &v2 = vertices[sourceTriangle[1]]; - const auto &v3 = vertices[sourceTriangle[2]]; + const auto& v1 = vertices[sourceTriangle[0]]; + const auto& v2 = vertices[sourceTriangle[1]]; + const auto& v3 = vertices[sourceTriangle[2]]; float area = Vector3::area(v1, v2, v3); - float angles[] = {(float)Math::radiansToDegrees(Vector3::angleBetween(v2-v1, v3-v1)), - (float)Math::radiansToDegrees(Vector3::angleBetween(v1-v2, v3-v2)), - (float)Math::radiansToDegrees(Vector3::angleBetween(v1-v3, v2-v3))}; + float angles[] = { (float)Math::radiansToDegrees(Vector3::angleBetween(v2 - v1, v3 - v1)), + (float)Math::radiansToDegrees(Vector3::angleBetween(v1 - v2, v3 - v2)), + (float)Math::radiansToDegrees(Vector3::angleBetween(v1 - v3, v2 - v3)) }; for (int i = 0; i < 3; ++i) { if (sourceTriangle[i] >= vertices.size()) { continue; } - triangleVertexNormalsMapByIndices[sourceTriangle[i]].push_back({triangleIndex, angleAreaWeightedNormals.size()}); + triangleVertexNormalsMapByIndices[sourceTriangle[i]].push_back({ triangleIndex, angleAreaWeightedNormals.size() }); angleAreaWeightedNormals.push_back(triangleNormals[triangleIndex] * area * angles[i]); } } std::vector finalNormals = angleAreaWeightedNormals; std::map, float> degreesBetweenFacesMap; for (size_t vertexIndex = 0; vertexIndex < vertices.size(); ++vertexIndex) { - const auto &triangleVertices = triangleVertexNormalsMapByIndices[vertexIndex]; - for (const auto &triangleVertex: triangleVertices) { - for (const auto &otherTriangleVertex: triangleVertices) { + const auto& triangleVertices = triangleVertexNormalsMapByIndices[vertexIndex]; + for (const auto& triangleVertex : triangleVertices) { + for (const auto& otherTriangleVertex : triangleVertices) { if (triangleVertex.first == otherTriangleVertex.first) continue; float degrees = 0; - auto findDegreesResult = degreesBetweenFacesMap.find({triangleVertex.first, otherTriangleVertex.first}); + auto findDegreesResult = degreesBetweenFacesMap.find({ triangleVertex.first, otherTriangleVertex.first }); if (findDegreesResult == degreesBetweenFacesMap.end()) { degrees = Math::radiansToDegrees(Vector3::angleBetween(triangleNormals[triangleVertex.first], triangleNormals[otherTriangleVertex.first])); - degreesBetweenFacesMap.insert({{triangleVertex.first, otherTriangleVertex.first}, degrees}); - degreesBetweenFacesMap.insert({{otherTriangleVertex.first, triangleVertex.first}, degrees}); + degreesBetweenFacesMap.insert({ { triangleVertex.first, otherTriangleVertex.first }, degrees }); + degreesBetweenFacesMap.insert({ { otherTriangleVertex.first, triangleVertex.first }, degrees }); } else { degrees = findDegreesResult->second; } @@ -78,14 +77,12 @@ void smoothNormal(const std::vector &vertices, } } } - for (auto &item: finalNormals) + for (auto& item : finalNormals) item.normalize(); - triangleVertexNormals->resize(triangles.size(), { - Vector3(), Vector3(), Vector3() - }); + triangleVertexNormals->resize(triangles.size(), { Vector3(), Vector3(), Vector3() }); size_t index = 0; for (size_t i = 0; i < triangles.size(); ++i) { - auto &normals = (*triangleVertexNormals)[i]; + auto& normals = (*triangleVertexNormals)[i]; for (size_t j = 0; j < 3; ++j) { if (index < finalNormals.size()) normals[j] = finalNormals[index]; diff --git a/dust3d/mesh/smooth_normal.h b/dust3d/mesh/smooth_normal.h index b1731460..860e777b 100644 --- a/dust3d/mesh/smooth_normal.h +++ b/dust3d/mesh/smooth_normal.h @@ -25,15 +25,14 @@ #include -namespace dust3d -{ - -void smoothNormal(const std::vector &vertices, - const std::vector> &triangles, - const std::vector &triangleNormals, +namespace dust3d { + +void smoothNormal(const std::vector& vertices, + const std::vector>& triangles, + const std::vector& triangleNormals, float thresholdAngleDegrees, - std::vector> *triangleVertexNormals); - + std::vector>* triangleVertexNormals); + } #endif diff --git a/dust3d/mesh/solid_mesh.cc b/dust3d/mesh/solid_mesh.cc index 7f9c4592..ce39e7d6 100644 --- a/dust3d/mesh/solid_mesh.cc +++ b/dust3d/mesh/solid_mesh.cc @@ -19,11 +19,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #include -namespace dust3d -{ +namespace dust3d { SolidMesh::~SolidMesh() { @@ -32,12 +31,12 @@ SolidMesh::~SolidMesh() delete m_triangleAxisAlignedBoundingBoxes; } -void SolidMesh::setVertices(const std::vector *vertices) +void SolidMesh::setVertices(const std::vector* vertices) { m_vertices = vertices; } -void SolidMesh::setTriangles(const std::vector> *triangles) +void SolidMesh::setTriangles(const std::vector>* triangles) { m_triangles = triangles; } @@ -46,35 +45,34 @@ void SolidMesh::prepare() { if (nullptr == m_triangles) return; - + m_triangleNormals = new std::vector; m_triangleNormals->reserve(m_triangles->size()); - for (const auto &it: *m_triangles) { + for (const auto& it : *m_triangles) { m_triangleNormals->push_back( - Vector3::normal((*m_vertices)[it[0]], - (*m_vertices)[it[1]], - (*m_vertices)[it[2]]) - ); + Vector3::normal((*m_vertices)[it[0]], + (*m_vertices)[it[1]], + (*m_vertices)[it[2]])); } - + m_triangleAxisAlignedBoundingBoxes = new std::vector(m_triangles->size()); - + for (size_t i = 0; i < m_triangleAxisAlignedBoundingBoxes->size(); ++i) { addTriagleToAxisAlignedBoundingBox((*m_triangles)[i], &(*m_triangleAxisAlignedBoundingBoxes)[i]); (*m_triangleAxisAlignedBoundingBoxes)[i].updateCenter(); } - + std::vector firstGroupOfFacesIn; for (size_t i = 0; i < m_triangleAxisAlignedBoundingBoxes->size(); ++i) firstGroupOfFacesIn.push_back(i); - + AxisAlignedBoudingBox groupBox; - for (const auto &i: firstGroupOfFacesIn) { + for (const auto& i : firstGroupOfFacesIn) { addTriagleToAxisAlignedBoundingBox((*m_triangles)[i], &groupBox); } groupBox.updateCenter(); - - m_axisAlignedBoundingBoxTree = new AxisAlignedBoudingBoxTree(m_triangleAxisAlignedBoundingBoxes, + + m_axisAlignedBoundingBoxTree = new AxisAlignedBoudingBoxTree(m_triangleAxisAlignedBoundingBoxes, firstGroupOfFacesIn, groupBox); } diff --git a/dust3d/mesh/solid_mesh.h b/dust3d/mesh/solid_mesh.h index 9a7d7a85..4786d45c 100644 --- a/dust3d/mesh/solid_mesh.h +++ b/dust3d/mesh/solid_mesh.h @@ -19,62 +19,61 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_MESH_SOLID_MESH_H_ #define DUST3D_MESH_SOLID_MESH_H_ -#include -#include #include +#include +#include -namespace dust3d -{ +namespace dust3d { -class SolidMesh -{ +class SolidMesh { public: ~SolidMesh(); - void setVertices(const std::vector *vertices); - void setTriangles(const std::vector> *triangles); - - const std::vector *vertices() const + void setVertices(const std::vector* vertices); + void setTriangles(const std::vector>* triangles); + + const std::vector* vertices() const { return m_vertices; } - const std::vector> *triangles() const + const std::vector>* triangles() const { return m_triangles; } - - const std::vector *triangleNormals() const + + const std::vector* triangleNormals() const { return m_triangleNormals; } - - const AxisAlignedBoudingBoxTree *axisAlignedBoundingBoxTree() const + + const AxisAlignedBoudingBoxTree* axisAlignedBoundingBoxTree() const { return m_axisAlignedBoundingBoxTree; } - - const std::vector *triangleAxisAlignedBoundingBoxes() const + + const std::vector* triangleAxisAlignedBoundingBoxes() const { return m_triangleAxisAlignedBoundingBoxes; } - + void prepare(); + private: - void addTriagleToAxisAlignedBoundingBox(const std::vector &triangle, AxisAlignedBoudingBox *box) + void addTriagleToAxisAlignedBoundingBox(const std::vector& triangle, AxisAlignedBoudingBox* box) { for (size_t i = 0; i < 3; ++i) box->update((*m_vertices)[triangle[i]]); } - - const std::vector *m_vertices = nullptr; - const std::vector> *m_triangles = nullptr; - std::vector *m_triangleNormals = nullptr; - AxisAlignedBoudingBoxTree *m_axisAlignedBoundingBoxTree = nullptr; - std::vector *m_triangleAxisAlignedBoundingBoxes = nullptr; + + const std::vector* m_vertices = nullptr; + const std::vector>* m_triangles = nullptr; + std::vector* m_triangleNormals = nullptr; + AxisAlignedBoudingBoxTree* m_axisAlignedBoundingBoxTree = nullptr; + std::vector* m_triangleAxisAlignedBoundingBoxes = nullptr; }; } diff --git a/dust3d/mesh/solid_mesh_boolean_operation.cc b/dust3d/mesh/solid_mesh_boolean_operation.cc index 2f943d9a..434c7554 100644 --- a/dust3d/mesh/solid_mesh_boolean_operation.cc +++ b/dust3d/mesh/solid_mesh_boolean_operation.cc @@ -19,30 +19,29 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - -#include -#include -#include + #include #include #include -#include #include +#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { static const std::vector g_testAxisList = { - {std::numeric_limits::max(), std::numeric_limits::epsilon(), std::numeric_limits::epsilon()}, - {std::numeric_limits::epsilon(), std::numeric_limits::max(), std::numeric_limits::epsilon()}, - {std::numeric_limits::epsilon(), std::numeric_limits::epsilon(), std::numeric_limits::max()}, + { std::numeric_limits::max(), std::numeric_limits::epsilon(), std::numeric_limits::epsilon() }, + { std::numeric_limits::epsilon(), std::numeric_limits::max(), std::numeric_limits::epsilon() }, + { std::numeric_limits::epsilon(), std::numeric_limits::epsilon(), std::numeric_limits::max() }, }; -SolidMeshBooleanOperation::SolidMeshBooleanOperation(const SolidMesh *m_firstMesh, - const SolidMesh *m_secondMesh) : - m_firstMesh(m_firstMesh), - m_secondMesh(m_secondMesh) +SolidMeshBooleanOperation::SolidMeshBooleanOperation(const SolidMesh* m_firstMesh, + const SolidMesh* m_secondMesh) + : m_firstMesh(m_firstMesh) + , m_secondMesh(m_secondMesh) { } @@ -50,26 +49,26 @@ SolidMeshBooleanOperation::~SolidMeshBooleanOperation() { } -bool SolidMeshBooleanOperation::isPointInMesh(const Vector3 &testPosition, - const SolidMesh *targetMesh, - const AxisAlignedBoudingBoxTree *meshBoxTree, - const Vector3 &testAxis) +bool SolidMeshBooleanOperation::isPointInMesh(const Vector3& testPosition, + const SolidMesh* targetMesh, + const AxisAlignedBoudingBoxTree* meshBoxTree, + const Vector3& testAxis) { Vector3 testEnd = testPosition + testAxis; bool inside = false; std::vector rayBox(1); - auto &box = rayBox[0]; + auto& box = rayBox[0]; box.update(testPosition); box.update(testEnd); AxisAlignedBoudingBoxTree testTree(&rayBox, - {0}, + { 0 }, rayBox[0]); std::vector> pairs; meshBoxTree->test(meshBoxTree->root(), testTree.root(), &rayBox, &pairs); std::set hits; - - for (const auto &it: pairs) { - const auto &triangle = (*targetMesh->triangles())[it.first]; + + for (const auto& it : pairs) { + const auto& triangle = (*targetMesh->triangles())[it.first]; std::vector trianglePositions = { (*targetMesh->vertices())[triangle[0]], (*targetMesh->vertices())[triangle[1]], @@ -77,7 +76,7 @@ bool SolidMeshBooleanOperation::isPointInMesh(const Vector3 &testPosition, }; Vector3 intersection; if (Vector3::intersectSegmentAndPlane(testPosition, testEnd, - trianglePositions[0], + trianglePositions[0], (*targetMesh->triangleNormals())[it.first], &intersection)) { std::vector normals; @@ -85,8 +84,7 @@ bool SolidMeshBooleanOperation::isPointInMesh(const Vector3 &testPosition, size_t j = (i + 1) % 3; normals.push_back(Vector3::normal(intersection, trianglePositions[i], trianglePositions[j])); } - if (Vector3::dotProduct(normals[0], normals[1]) > 0 && - Vector3::dotProduct(normals[0], normals[2]) > 0) { + if (Vector3::dotProduct(normals[0], normals[1]) > 0 && Vector3::dotProduct(normals[0], normals[2]) > 0) { hits.insert(PositionKey(intersection)); } } @@ -98,27 +96,27 @@ bool SolidMeshBooleanOperation::isPointInMesh(const Vector3 &testPosition, void SolidMeshBooleanOperation::searchPotentialIntersectedPairs() { - const AxisAlignedBoudingBoxTree *leftTree = m_firstMesh->axisAlignedBoundingBoxTree(); - const AxisAlignedBoudingBoxTree *rightTree = m_secondMesh->axisAlignedBoundingBoxTree(); - + const AxisAlignedBoudingBoxTree* leftTree = m_firstMesh->axisAlignedBoundingBoxTree(); + const AxisAlignedBoudingBoxTree* rightTree = m_secondMesh->axisAlignedBoundingBoxTree(); + leftTree->test(leftTree->root(), rightTree->root(), m_secondMesh->triangleAxisAlignedBoundingBoxes(), &m_potentialIntersectedPairs); } -bool SolidMeshBooleanOperation::intersectTwoFaces(size_t firstIndex, size_t secondIndex, std::pair &newEdge) +bool SolidMeshBooleanOperation::intersectTwoFaces(size_t firstIndex, size_t secondIndex, std::pair& newEdge) { - const auto &firstFace = (*m_firstMesh->triangles())[firstIndex]; - const auto &secondFace = (*m_secondMesh->triangles())[secondIndex]; + const auto& firstFace = (*m_firstMesh->triangles())[firstIndex]; + const auto& secondFace = (*m_secondMesh->triangles())[secondIndex]; int coplanar = 0; - if (!tri_tri_intersection_test_3d((double *)(*m_firstMesh->vertices())[firstFace[0]].constData(), - (double *)(*m_firstMesh->vertices())[firstFace[1]].constData(), - (double *)(*m_firstMesh->vertices())[firstFace[2]].constData(), - (double *)(*m_secondMesh->vertices())[secondFace[0]].constData(), - (double *)(*m_secondMesh->vertices())[secondFace[1]].constData(), - (double *)(*m_secondMesh->vertices())[secondFace[2]].constData(), + if (!tri_tri_intersection_test_3d((double*)(*m_firstMesh->vertices())[firstFace[0]].constData(), + (double*)(*m_firstMesh->vertices())[firstFace[1]].constData(), + (double*)(*m_firstMesh->vertices())[firstFace[2]].constData(), + (double*)(*m_secondMesh->vertices())[secondFace[0]].constData(), + (double*)(*m_secondMesh->vertices())[secondFace[1]].constData(), + (double*)(*m_secondMesh->vertices())[secondFace[2]].constData(), &coplanar, - (double *)newEdge.first.constData(), - (double *)newEdge.second.constData())) { + (double*)newEdge.first.constData(), + (double*)newEdge.second.constData())) { return false; } if (coplanar) @@ -126,12 +124,12 @@ bool SolidMeshBooleanOperation::intersectTwoFaces(size_t firstIndex, size_t seco return true; } -bool SolidMeshBooleanOperation::buildPolygonsFromEdges(const std::unordered_map> &edges, - std::vector> &polygons) +bool SolidMeshBooleanOperation::buildPolygonsFromEdges(const std::unordered_map>& edges, + std::vector>& polygons) { std::unordered_set visited; - for (const auto &edge: edges) { - const auto &startEndpoint = edge.first; + for (const auto& edge : edges) { + const auto& startEndpoint = edge.first; if (visited.find(startEndpoint) != visited.end()) continue; std::queue q; @@ -145,7 +143,7 @@ bool SolidMeshBooleanOperation::buildPolygonsFromEdges(const std::unordered_map< auto neighborIt = edges.find(loop); if (neighborIt == edges.end()) break; - for (const auto &it: neighborIt->second) { + for (const auto& it : neighborIt->second) { if (visited.find(it) == visited.end()) { q.push(it); break; @@ -156,56 +154,56 @@ bool SolidMeshBooleanOperation::buildPolygonsFromEdges(const std::unordered_map< dust3dDebug << "buildPolygonsFromEdges failed, too short"; return false; } - + auto neighborOfLast = edges.find(polyline.back()); if (neighborOfLast->second.find(startEndpoint) == neighborOfLast->second.end()) { dust3dDebug << "buildPolygonsFromEdges failed, could not form a ring"; return false; } - + polygons.push_back(polyline); } - + return true; } -void SolidMeshBooleanOperation::buildFaceGroups(const std::vector> &intersections, - const std::unordered_map &halfEdges, - const std::vector> &triangles, - size_t remainingStartTriangleIndex, - size_t remainingTriangleCount, - std::vector> &triangleGroups) +void SolidMeshBooleanOperation::buildFaceGroups(const std::vector>& intersections, + const std::unordered_map& halfEdges, + const std::vector>& triangles, + size_t remainingStartTriangleIndex, + size_t remainingTriangleCount, + std::vector>& triangleGroups) { std::unordered_map halfEdgeGroupMap; size_t groupIndex = 0; std::queue> waitQ; - for (const auto &intersection: intersections) { + for (const auto& intersection : intersections) { for (size_t i = 0; i < intersection.size(); ++i) { size_t j = (i + 1) % intersection.size(); { auto halfEdge = makeHalfEdgeKey(intersection[i], intersection[j]); - halfEdgeGroupMap.insert({halfEdge, groupIndex}); + halfEdgeGroupMap.insert({ halfEdge, groupIndex }); auto halfEdgeIt = halfEdges.find(halfEdge); if (halfEdgeIt != halfEdges.end()) { - waitQ.push({halfEdgeIt->second, groupIndex}); + waitQ.push({ halfEdgeIt->second, groupIndex }); } } { auto halfEdge = makeHalfEdgeKey(intersection[j], intersection[i]); - halfEdgeGroupMap.insert({halfEdge, groupIndex + 1}); + halfEdgeGroupMap.insert({ halfEdge, groupIndex + 1 }); auto halfEdgeIt = halfEdges.find(halfEdge); if (halfEdgeIt != halfEdges.end()) { - waitQ.push({halfEdgeIt->second, groupIndex + 1}); + waitQ.push({ halfEdgeIt->second, groupIndex + 1 }); } } } groupIndex += 2; } - + triangleGroups.resize(groupIndex); std::unordered_set visitedTriangles; - - auto processQueue = [&](std::queue> &q) { + + auto processQueue = [&](std::queue>& q) { while (!q.empty()) { auto triangleAndGroupIndex = q.front(); q.pop(); @@ -213,51 +211,51 @@ void SolidMeshBooleanOperation::buildFaceGroups(const std::vectorsecond, triangleAndGroupIndex.second}); + q.push({ halfEdgeIt->second, triangleAndGroupIndex.second }); } else { //dust3dDebug << "HalfEdge not found:" << halfEdge.second << " " << halfEdge.first; } } } }; - + processQueue(waitQ); - + size_t endIndex = remainingStartTriangleIndex + remainingTriangleCount; for (size_t triangleIndex = remainingStartTriangleIndex; triangleIndex < endIndex; ++triangleIndex) { if (visitedTriangles.find(triangleIndex) != visitedTriangles.end()) continue; triangleGroups.push_back(std::vector()); - waitQ.push({triangleIndex, groupIndex}); + waitQ.push({ triangleIndex, groupIndex }); ++groupIndex; processQueue(waitQ); } } -size_t SolidMeshBooleanOperation::addNewPoint(const Vector3 &position) +size_t SolidMeshBooleanOperation::addNewPoint(const Vector3& position) { - auto insertResult = m_newPositionMap.insert({PositionKey(position), m_newVertices.size()}); + auto insertResult = m_newPositionMap.insert({ PositionKey(position), m_newVertices.size() }); if (insertResult.second) { m_newVertices.push_back(position); } return insertResult.first->second; } -bool SolidMeshBooleanOperation::addUnintersectedTriangles(const SolidMesh *mesh, - const std::unordered_set &usedFaces, - std::unordered_map *halfEdges) +bool SolidMeshBooleanOperation::addUnintersectedTriangles(const SolidMesh* mesh, + const std::unordered_set& usedFaces, + std::unordered_map* halfEdges) { size_t oldVertexCount = m_newVertices.size(); - const auto &vertices = *mesh->vertices(); + const auto& vertices = *mesh->vertices(); m_newVertices.reserve(m_newVertices.size() + vertices.size()); m_newVertices.insert(m_newVertices.end(), vertices.begin(), vertices.end()); @@ -266,23 +264,21 @@ bool SolidMeshBooleanOperation::addUnintersectedTriangles(const SolidMesh *mesh, for (size_t i = 0; i < triangleCount; ++i) { if (usedFaces.find(i) != usedFaces.end()) continue; - const auto &oldTriangle = (*mesh->triangles())[i]; + const auto& oldTriangle = (*mesh->triangles())[i]; size_t newInsertedIndex = m_newTriangles.size(); - m_newTriangles.push_back({ - oldTriangle[0] + oldVertexCount, + m_newTriangles.push_back({ oldTriangle[0] + oldVertexCount, oldTriangle[1] + oldVertexCount, - oldTriangle[2] + oldVertexCount - }); - const auto &newInsertedTriangle = m_newTriangles.back(); - if (!halfEdges->insert({makeHalfEdgeKey(newInsertedTriangle[0], newInsertedTriangle[1]), newInsertedIndex}).second) { + oldTriangle[2] + oldVertexCount }); + const auto& newInsertedTriangle = m_newTriangles.back(); + if (!halfEdges->insert({ makeHalfEdgeKey(newInsertedTriangle[0], newInsertedTriangle[1]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[0] << "," << newInsertedTriangle[1]; return false; } - if (!halfEdges->insert({makeHalfEdgeKey(newInsertedTriangle[1], newInsertedTriangle[2]), newInsertedIndex}).second) { + if (!halfEdges->insert({ makeHalfEdgeKey(newInsertedTriangle[1], newInsertedTriangle[2]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[0] << "," << newInsertedTriangle[1]; return false; } - if (!halfEdges->insert({makeHalfEdgeKey(newInsertedTriangle[2], newInsertedTriangle[0]), newInsertedIndex}).second) { + if (!halfEdges->insert({ makeHalfEdgeKey(newInsertedTriangle[2], newInsertedTriangle[0]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[0] << "," << newInsertedTriangle[1]; return false; } @@ -294,31 +290,30 @@ bool SolidMeshBooleanOperation::combine() { searchPotentialIntersectedPairs(); - struct IntersectedContext - { + struct IntersectedContext { std::vector points; std::map positionMap; std::unordered_map> neighborMap; }; - + std::unordered_map firstTriangleIntersectedContext; std::unordered_map secondTriangleIntersectedContext; - - auto addIntersectedPoint = [](IntersectedContext &context, const Vector3 &position) { - auto insertResult = context.positionMap.insert({PositionKey(position), context.points.size()}); + + auto addIntersectedPoint = [](IntersectedContext& context, const Vector3& position) { + auto insertResult = context.positionMap.insert({ PositionKey(position), context.points.size() }); if (insertResult.second) context.points.push_back(position); return insertResult.first->second; }; - for (const auto &pair: m_potentialIntersectedPairs) { + for (const auto& pair : m_potentialIntersectedPairs) { std::pair newEdge; if (intersectTwoFaces(pair.first, pair.second, newEdge)) { m_firstIntersectedFaces.insert(pair.first); m_secondIntersectedFaces.insert(pair.second); - + { - auto &context = firstTriangleIntersectedContext[pair.first]; + auto& context = firstTriangleIntersectedContext[pair.first]; size_t firstPointIndex = 3 + addIntersectedPoint(context, newEdge.first); size_t secondPointIndex = 3 + addIntersectedPoint(context, newEdge.second); if (firstPointIndex != secondPointIndex) { @@ -326,9 +321,9 @@ bool SolidMeshBooleanOperation::combine() context.neighborMap[secondPointIndex].insert(firstPointIndex); } } - + { - auto &context = secondTriangleIntersectedContext[pair.second]; + auto& context = secondTriangleIntersectedContext[pair.second]; size_t firstPointIndex = 3 + addIntersectedPoint(context, newEdge.first); size_t secondPointIndex = 3 + addIntersectedPoint(context, newEdge.second); if (firstPointIndex != secondPointIndex) { @@ -345,21 +340,18 @@ bool SolidMeshBooleanOperation::combine() std::vector> secondIntersections; std::unordered_map firstHalfEdges; std::unordered_map secondHalfEdges; - - auto reTriangulate = [&](const std::unordered_map &context, - const SolidMesh *mesh, - size_t startOldVertex, - std::unordered_map> &edges, - std::unordered_map &halfEdges) { - for (const auto &it: context) { - const auto &triangle = (*mesh->triangles())[it.first]; - ReTriangulator reTriangulator({ - (*mesh->vertices())[triangle[0]], - (*mesh->vertices())[triangle[1]], - (*mesh->vertices())[triangle[2]] - }, - (*mesh->triangleNormals())[it.first] - ); + + auto reTriangulate = [&](const std::unordered_map& context, + const SolidMesh* mesh, + size_t startOldVertex, + std::unordered_map>& edges, + std::unordered_map& halfEdges) { + for (const auto& it : context) { + const auto& triangle = (*mesh->triangles())[it.first]; + ReTriangulator reTriangulator({ (*mesh->vertices())[triangle[0]], + (*mesh->vertices())[triangle[1]], + (*mesh->vertices())[triangle[2]] }, + (*mesh->triangleNormals())[it.first]); reTriangulator.setEdges(it.second.points, &it.second.neighborMap); if (!reTriangulator.reTriangulate()) { @@ -371,29 +363,27 @@ bool SolidMeshBooleanOperation::combine() newIndices.push_back(startOldVertex + triangle[0]); newIndices.push_back(startOldVertex + triangle[1]); newIndices.push_back(startOldVertex + triangle[2]); - for (const auto &point: it.second.points) + for (const auto& point : it.second.points) newIndices.push_back(addNewPoint(point)); - for (const auto &triangle: reTriangulator.triangles()) { + for (const auto& triangle : reTriangulator.triangles()) { size_t newInsertedIndex = m_newTriangles.size(); - m_newTriangles.push_back({ - newIndices[triangle[0]], + m_newTriangles.push_back({ newIndices[triangle[0]], newIndices[triangle[1]], - newIndices[triangle[2]] - }); - const auto &newInsertedTriangle = m_newTriangles.back(); - if (!halfEdges.insert({makeHalfEdgeKey(newInsertedTriangle[0], newInsertedTriangle[1]), newInsertedIndex}).second) { + newIndices[triangle[2]] }); + const auto& newInsertedTriangle = m_newTriangles.back(); + if (!halfEdges.insert({ makeHalfEdgeKey(newInsertedTriangle[0], newInsertedTriangle[1]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[0] << "," << newInsertedTriangle[1]; } - if (!halfEdges.insert({makeHalfEdgeKey(newInsertedTriangle[1], newInsertedTriangle[2]), newInsertedIndex}).second) { + if (!halfEdges.insert({ makeHalfEdgeKey(newInsertedTriangle[1], newInsertedTriangle[2]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[1] << "," << newInsertedTriangle[2]; } - if (!halfEdges.insert({makeHalfEdgeKey(newInsertedTriangle[2], newInsertedTriangle[0]), newInsertedIndex}).second) { + if (!halfEdges.insert({ makeHalfEdgeKey(newInsertedTriangle[2], newInsertedTriangle[0]), newInsertedIndex }).second) { dust3dDebug << "Found repeated halfedge:" << newInsertedTriangle[3] << "," << newInsertedTriangle[0]; } } - for (const auto &it: it.second.neighborMap) { + for (const auto& it : it.second.neighborMap) { auto from = newIndices[it.first]; - for (const auto &it2: it.second) { + for (const auto& it2 : it.second) { auto to = newIndices[it2]; edges[from].insert(to); edges[to].insert(from); @@ -408,19 +398,19 @@ bool SolidMeshBooleanOperation::combine() dust3dDebug << "Add first mesh remaining triangles failed"; } size_t firstRemainingTriangleCount = m_newTriangles.size() - firstRemainingStartTriangleIndex; - + size_t secondRemainingStartTriangleIndex = m_newTriangles.size(); if (!addUnintersectedTriangles(m_secondMesh, m_secondIntersectedFaces, &secondHalfEdges)) { dust3dDebug << "Add second mesh remaining triangles failed"; } size_t secondRemainingTriangleCount = m_newTriangles.size() - secondRemainingStartTriangleIndex; - if (!reTriangulate(firstTriangleIntersectedContext, + if (!reTriangulate(firstTriangleIntersectedContext, m_firstMesh, 0, firstEdges, firstHalfEdges)) { dust3dDebug << "Retriangulate first mesh failed"; return false; } - if (!reTriangulate(secondTriangleIntersectedContext, + if (!reTriangulate(secondTriangleIntersectedContext, m_secondMesh, m_firstMesh->vertices()->size(), secondEdges, secondHalfEdges)) { dust3dDebug << "Retriangulate second mesh failed"; return false; @@ -456,24 +446,22 @@ bool SolidMeshBooleanOperation::combine() return true; } -void SolidMeshBooleanOperation::decideGroupSide(const std::vector> &groups, - const SolidMesh *mesh, - const AxisAlignedBoudingBoxTree *tree, - std::vector &groupSides) +void SolidMeshBooleanOperation::decideGroupSide(const std::vector>& groups, + const SolidMesh* mesh, + const AxisAlignedBoudingBoxTree* tree, + std::vector& groupSides) { groupSides.resize(groups.size()); for (size_t i = 0; i < groups.size(); ++i) { - const auto &group = groups[i]; + const auto& group = groups[i]; if (group.empty()) continue; size_t insideCount = 0; size_t totalCount = 0; for (size_t pickIndex = 0; pickIndex < 1 && pickIndex < group.size(); ++pickIndex) { for (size_t axisIndex = 0; axisIndex < g_testAxisList.size(); ++axisIndex) { - const auto &pickedTriangle = m_newTriangles[group[pickIndex]]; - bool inside = isPointInMesh((m_newVertices[pickedTriangle[0]] + - m_newVertices[pickedTriangle[1]] + - m_newVertices[pickedTriangle[2]]) / 3.0, + const auto& pickedTriangle = m_newTriangles[group[pickIndex]]; + bool inside = isPointInMesh((m_newVertices[pickedTriangle[0]] + m_newVertices[pickedTriangle[1]] + m_newVertices[pickedTriangle[2]]) / 3.0, mesh, tree, g_testAxisList[axisIndex]); @@ -486,62 +474,60 @@ void SolidMeshBooleanOperation::decideGroupSide(const std::vector> &resultTriangles) +void SolidMeshBooleanOperation::fetchUnion(std::vector>& resultTriangles) { for (size_t i = 0; i < m_firstGroupSides.size(); ++i) { if (m_firstGroupSides[i]) continue; - for (const auto &it: m_firstTriangleGroups[i]) + for (const auto& it : m_firstTriangleGroups[i]) resultTriangles.push_back(m_newTriangles[it]); } - + for (size_t i = 0; i < m_secondGroupSides.size(); ++i) { if (m_secondGroupSides[i]) continue; - for (const auto &it: m_secondTriangleGroups[i]) + for (const auto& it : m_secondTriangleGroups[i]) resultTriangles.push_back(m_newTriangles[it]); } } -void SolidMeshBooleanOperation::fetchDiff(std::vector> &resultTriangles) +void SolidMeshBooleanOperation::fetchDiff(std::vector>& resultTriangles) { for (size_t i = 0; i < m_firstGroupSides.size(); ++i) { if (m_firstGroupSides[i]) continue; - for (const auto &it: m_firstTriangleGroups[i]) + for (const auto& it : m_firstTriangleGroups[i]) resultTriangles.push_back(m_newTriangles[it]); } - + for (size_t i = 0; i < m_secondGroupSides.size(); ++i) { if (!m_secondGroupSides[i]) continue; - for (const auto &it: m_secondTriangleGroups[i]) { + for (const auto& it : m_secondTriangleGroups[i]) { auto triangle = m_newTriangles[it]; - resultTriangles.push_back({ - triangle[2], triangle[1], triangle[0] - }); + resultTriangles.push_back({ triangle[2], triangle[1], triangle[0] }); } } } -void SolidMeshBooleanOperation::fetchIntersect(std::vector> &resultTriangles) +void SolidMeshBooleanOperation::fetchIntersect(std::vector>& resultTriangles) { for (size_t i = 0; i < m_firstGroupSides.size(); ++i) { if (!m_firstGroupSides[i]) continue; - for (const auto &it: m_firstTriangleGroups[i]) + for (const auto& it : m_firstTriangleGroups[i]) resultTriangles.push_back(m_newTriangles[it]); } - + for (size_t i = 0; i < m_secondGroupSides.size(); ++i) { if (!m_secondGroupSides[i]) continue; - for (const auto &it: m_secondTriangleGroups[i]) + for (const auto& it : m_secondTriangleGroups[i]) resultTriangles.push_back(m_newTriangles[it]); } } -const std::vector &SolidMeshBooleanOperation::resultVertices() +const std::vector& SolidMeshBooleanOperation::resultVertices() { return m_newVertices; } diff --git a/dust3d/mesh/solid_mesh_boolean_operation.h b/dust3d/mesh/solid_mesh_boolean_operation.h index 0f42cbf6..ebe35643 100644 --- a/dust3d/mesh/solid_mesh_boolean_operation.h +++ b/dust3d/mesh/solid_mesh_boolean_operation.h @@ -19,35 +19,34 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_MESH_SOLID_MESH_BOOLEAN_OPERATION_H_ #define DUST3D_MESH_SOLID_MESH_BOOLEAN_OPERATION_H_ +#include +#include +#include +#include #include #include -#include -#include -#include -#include -namespace dust3d -{ +namespace dust3d { -class SolidMeshBooleanOperation -{ +class SolidMeshBooleanOperation { public: - SolidMeshBooleanOperation(const SolidMesh *firstMesh, - const SolidMesh *secondMesh); + SolidMeshBooleanOperation(const SolidMesh* firstMesh, + const SolidMesh* secondMesh); ~SolidMeshBooleanOperation(); bool combine(); - void fetchUnion(std::vector> &resultTriangles); - void fetchDiff(std::vector> &resultTriangles); - void fetchIntersect(std::vector> &resultTriangles); - - const std::vector &resultVertices(); + void fetchUnion(std::vector>& resultTriangles); + void fetchDiff(std::vector>& resultTriangles); + void fetchIntersect(std::vector>& resultTriangles); + + const std::vector& resultVertices(); + private: - const SolidMesh *m_firstMesh = nullptr; - const SolidMesh *m_secondMesh = nullptr; + const SolidMesh* m_firstMesh = nullptr; + const SolidMesh* m_secondMesh = nullptr; std::vector> m_potentialIntersectedPairs; std::vector m_newVertices; std::vector> m_newTriangles; @@ -60,40 +59,40 @@ private: std::unordered_set m_secondIntersectedFaces; std::unordered_map> m_firstFacesAroundVertexMap; std::unordered_map> m_secondFacesAroundVertexMap; - + static inline uint64_t makeHalfEdgeKey(size_t first, size_t second) { return (first << 32) | second; } - - void addTriagleToAxisAlignedBoundingBox(const SolidMesh &mesh, const std::vector &triangle, AxisAlignedBoudingBox *box) + + void addTriagleToAxisAlignedBoundingBox(const SolidMesh& mesh, const std::vector& triangle, AxisAlignedBoudingBox* box) { for (size_t i = 0; i < 3; ++i) box->update((*mesh.vertices())[triangle[i]]); } - + void searchPotentialIntersectedPairs(); - bool intersectTwoFaces(size_t firstIndex, size_t secondIndex, std::pair &newEdge); - bool buildPolygonsFromEdges(const std::unordered_map> &edges, - std::vector> &polygons); - bool isPointInMesh(const Vector3 &testPosition, - const SolidMesh *targetMesh, - const AxisAlignedBoudingBoxTree *meshBoxTree, - const Vector3 &testAxis); - void buildFaceGroups(const std::vector> &intersections, - const std::unordered_map &halfEdges, - const std::vector> &triangles, + bool intersectTwoFaces(size_t firstIndex, size_t secondIndex, std::pair& newEdge); + bool buildPolygonsFromEdges(const std::unordered_map>& edges, + std::vector>& polygons); + bool isPointInMesh(const Vector3& testPosition, + const SolidMesh* targetMesh, + const AxisAlignedBoudingBoxTree* meshBoxTree, + const Vector3& testAxis); + void buildFaceGroups(const std::vector>& intersections, + const std::unordered_map& halfEdges, + const std::vector>& triangles, size_t remainingStartTriangleIndex, size_t remainingTriangleCount, - std::vector> &triangleGroups); - size_t addNewPoint(const Vector3 &position); - bool addUnintersectedTriangles(const SolidMesh *mesh, - const std::unordered_set &usedFaces, - std::unordered_map *halfEdges); - void decideGroupSide(const std::vector> &groups, - const SolidMesh *mesh, - const AxisAlignedBoudingBoxTree *tree, - std::vector &groupSides); + std::vector>& triangleGroups); + size_t addNewPoint(const Vector3& position); + bool addUnintersectedTriangles(const SolidMesh* mesh, + const std::unordered_set& usedFaces, + std::unordered_map* halfEdges); + void decideGroupSide(const std::vector>& groups, + const SolidMesh* mesh, + const AxisAlignedBoudingBoxTree* tree, + std::vector& groupSides); }; } diff --git a/dust3d/mesh/stitch_mesh_builder.cc b/dust3d/mesh/stitch_mesh_builder.cc index a898b402..06fbd17c 100644 --- a/dust3d/mesh/stitch_mesh_builder.cc +++ b/dust3d/mesh/stitch_mesh_builder.cc @@ -20,24 +20,23 @@ * SOFTWARE. */ -#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -StitchMeshBuilder::StitchMeshBuilder(std::vector &&splines) +StitchMeshBuilder::StitchMeshBuilder(std::vector&& splines) { m_splines = std::move(splines); } -const std::vector &StitchMeshBuilder::generatedVertices() const +const std::vector& StitchMeshBuilder::generatedVertices() const { return m_generatedVertices; } -const std::vector> &StitchMeshBuilder::generatedFaces() const +const std::vector>& StitchMeshBuilder::generatedFaces() const { return m_generatedFaces; } @@ -46,7 +45,7 @@ void StitchMeshBuilder::interpolateSplinesToHaveEqualSizeOfNodesExceptClosingSpl { std::vector interpolatedSplines = m_splines; for (size_t i = 0; i < m_splines.size(); ++i) { - const auto &spline = m_splines[i]; + const auto& spline = m_splines[i]; if (spline.isClosing) continue; std::vector polyline(spline.nodes.size()); @@ -58,7 +57,7 @@ void StitchMeshBuilder::interpolateSplinesToHaveEqualSizeOfNodesExceptClosingSpl std::vector segmentPoints; std::vector segmentRadiuses; splitPolylineToSegments(polyline, radiuses, m_targetSegments, &segmentPoints, &segmentRadiuses); - auto &interpolatedSpline = interpolatedSplines[i]; + auto& interpolatedSpline = interpolatedSplines[i]; interpolatedSpline.nodes.resize(segmentPoints.size()); for (size_t j = 0; j < spline.nodes.size(); ++j) { interpolatedSpline.nodes[j].origin = segmentPoints[j]; @@ -68,12 +67,12 @@ void StitchMeshBuilder::interpolateSplinesToHaveEqualSizeOfNodesExceptClosingSpl m_splines = std::move(interpolatedSplines); } -std::vector> StitchMeshBuilder::convertSplinesToStitchingPoints(const std::vector &splines) +std::vector> StitchMeshBuilder::convertSplinesToStitchingPoints(const std::vector& splines) { std::vector> stitchingPoints(splines.size()); - + for (size_t i = 0; i < splines.size(); ++i) { - const auto &spline = splines[i]; + const auto& spline = splines[i]; stitchingPoints[i].resize(spline.nodes.size()); for (size_t k = 0; k < spline.nodes.size(); ++k) { stitchingPoints[i][k].originVertex = m_generatedVertices.size(); @@ -86,7 +85,7 @@ std::vector> StitchMeshBuilder::c return stitchingPoints; } -double StitchMeshBuilder::segmentsLength(const std::vector &segmentPoints) +double StitchMeshBuilder::segmentsLength(const std::vector& segmentPoints) { double totalLength = 0.0; for (size_t j = 1; j < segmentPoints.size(); ++j) { @@ -96,11 +95,11 @@ double StitchMeshBuilder::segmentsLength(const std::vector &segmentPoin return totalLength; } -void StitchMeshBuilder::splitPolylineToSegments(const std::vector &polyline, - const std::vector &radiuses, +void StitchMeshBuilder::splitPolylineToSegments(const std::vector& polyline, + const std::vector& radiuses, size_t targetSegments, - std::vector *targetPoints, - std::vector *targetRadiuses) + std::vector* targetPoints, + std::vector* targetRadiuses) { if (polyline.size() < 2) return; @@ -147,7 +146,7 @@ void StitchMeshBuilder::splitPolylineToSegments(const std::vector &poly } } -void StitchMeshBuilder::generateMeshFromStitchingPoints(const std::vector> &stitchingPoints) +void StitchMeshBuilder::generateMeshFromStitchingPoints(const std::vector>& stitchingPoints) { for (size_t j = 1; j < stitchingPoints.size(); ++j) { size_t i = j - 1; @@ -155,8 +154,8 @@ void StitchMeshBuilder::generateMeshFromStitchingPoints(const std::vector &a, - const std::vector &b) +void StitchMeshBuilder::generateMeshFromStitchingPoints(const std::vector& a, + const std::vector& b) { if (a.size() != b.size()) { dust3dDebug << "Unmatch sizes of stitching points, a:" << a.size() << "b:" << b.size(); @@ -172,8 +171,7 @@ void StitchMeshBuilder::generateMeshFromStitchingPoints(const std::vector sourcePositions(nodes.size()); for (size_t i = 0; i < nodes.size(); ++i) { sourcePositions[i] = nodes[i].origin; @@ -200,9 +198,7 @@ void StitchMeshBuilder::interpolateSplinesForBackClosing() std::vector interpolatedPositions(nodes.size()); std::vector interpolatedRadiuses(nodes.size()); for (size_t i = 0; i < nodes.size(); ++i) { - interpolatedPositions[i] = sourceOrigin + - sourceVectors[i].rotated(Vector3::crossProduct(sourceVectors[i], targetDirection), Math::Pi * 0.25) * - ((nodes[i].origin - sourceOrigin).length() + (nodes[i].origin - targetPosition).length() * 0.5) * 0.5; + interpolatedPositions[i] = sourceOrigin + sourceVectors[i].rotated(Vector3::crossProduct(sourceVectors[i], targetDirection), Math::Pi * 0.25) * ((nodes[i].origin - sourceOrigin).length() + (nodes[i].origin - targetPosition).length() * 0.5) * 0.5; interpolatedRadiuses[i] = nodes[i].radius * 0.5; } m_splines.back().nodes.resize(nodes.size()); @@ -212,12 +208,12 @@ void StitchMeshBuilder::interpolateSplinesForBackClosing() } } -void StitchMeshBuilder::addQuadButMaybeTriangle(const std::vector &quadButMaybeTriangle) +void StitchMeshBuilder::addQuadButMaybeTriangle(const std::vector& quadButMaybeTriangle) { std::vector finalFace; std::unordered_set used; finalFace.reserve(4); - for (const auto &it: quadButMaybeTriangle) { + for (const auto& it : quadButMaybeTriangle) { auto insertResult = used.insert(it); if (insertResult.second) finalFace.push_back(it); @@ -225,7 +221,7 @@ void StitchMeshBuilder::addQuadButMaybeTriangle(const std::vector &quadB m_generatedFaces.emplace_back(finalFace); } -const std::vector &StitchMeshBuilder::splines() const +const std::vector& StitchMeshBuilder::splines() const { return m_splines; } @@ -234,13 +230,13 @@ void StitchMeshBuilder::build() { if (m_splines.empty()) return; - + // Calculate target segments m_targetSegments = 1; - for (const auto &it: m_splines) { + for (const auto& it : m_splines) { m_targetSegments = std::max(m_targetSegments, it.nodes.size() - 1); } - + // TODO: Make sure there is no closing nodes in the middle // Interpolate splines to make sure every spline have equal size of nodes, except the closing splines @@ -261,7 +257,7 @@ void StitchMeshBuilder::build() // Generate normals for all vertices m_generatedNormals.resize(m_generatedVertices.size()); - for (const auto &quad: m_generatedFaces) { + for (const auto& quad : m_generatedFaces) { for (size_t i = 0; i < 4; ++i) { size_t j = (i + 1) % 4; size_t k = (j + 1) % 4; @@ -271,7 +267,7 @@ void StitchMeshBuilder::build() m_generatedNormals[quad[k]] += faceNormal; } } - for (auto &it: m_generatedNormals) + for (auto& it : m_generatedNormals) it.normalize(); // Generate other side of faces @@ -288,11 +284,10 @@ void StitchMeshBuilder::build() // This is to allow 2,1,0 to be grouped as triangle in the later quad to triangles processing. // If not follow this order, the front triangle and back triangle maybe cross over because of not be parallel. m_generatedFaces.emplace_back(std::vector { - oneSideVertexCount + quad[2], - oneSideVertexCount + quad[1], + oneSideVertexCount + quad[2], + oneSideVertexCount + quad[1], oneSideVertexCount + quad[0], - oneSideVertexCount + quad[3] - }); + oneSideVertexCount + quad[3] }); } // Move all vertices off distance at radius @@ -306,11 +301,10 @@ void StitchMeshBuilder::build() for (size_t j = 1; j <= m_targetSegments; ++j) { size_t i = j - 1; m_generatedFaces.emplace_back(std::vector { - oneSideVertexCount + i, - i, - j, - oneSideVertexCount + j - }); + oneSideVertexCount + i, + i, + j, + oneSideVertexCount + j }); } // Stitch layers for last stitching line @@ -321,32 +315,28 @@ void StitchMeshBuilder::build() size_t i = j - 1; addQuadButMaybeTriangle(std::vector { oneSideVertexCount + j + offsetBetweenFirstAndLastBorder, - oneSideVertexCount + i + offsetBetweenFirstAndLastBorder, - oneSideVertexCount + (m_targetSegments - i) + offsetBetweenFirstAndLastBorder, - oneSideVertexCount + (m_targetSegments - j) + offsetBetweenFirstAndLastBorder - }); + oneSideVertexCount + i + offsetBetweenFirstAndLastBorder, + oneSideVertexCount + (m_targetSegments - i) + offsetBetweenFirstAndLastBorder, + oneSideVertexCount + (m_targetSegments - j) + offsetBetweenFirstAndLastBorder }); addQuadButMaybeTriangle(std::vector { (m_targetSegments - j) + offsetBetweenFirstAndLastBorder, - (m_targetSegments - i) + offsetBetweenFirstAndLastBorder, + (m_targetSegments - i) + offsetBetweenFirstAndLastBorder, i + offsetBetweenFirstAndLastBorder, - j + offsetBetweenFirstAndLastBorder - }); + j + offsetBetweenFirstAndLastBorder }); } m_generatedFaces.emplace_back(std::vector { (m_targetSegments - 0) + offsetBetweenFirstAndLastBorder, - 0 + offsetBetweenFirstAndLastBorder, + 0 + offsetBetweenFirstAndLastBorder, oneSideVertexCount + 0 + offsetBetweenFirstAndLastBorder, - oneSideVertexCount + (m_targetSegments - 0) + offsetBetweenFirstAndLastBorder - }); - } else { + oneSideVertexCount + (m_targetSegments - 0) + offsetBetweenFirstAndLastBorder }); + } else { for (size_t j = 1; j <= m_targetSegments; ++j) { size_t i = j - 1; m_generatedFaces.emplace_back(std::vector { oneSideVertexCount + j + offsetBetweenFirstAndLastBorder, - j + offsetBetweenFirstAndLastBorder, - i + offsetBetweenFirstAndLastBorder, - oneSideVertexCount + i + offsetBetweenFirstAndLastBorder - }); + j + offsetBetweenFirstAndLastBorder, + i + offsetBetweenFirstAndLastBorder, + oneSideVertexCount + i + offsetBetweenFirstAndLastBorder }); } } @@ -355,10 +345,9 @@ void StitchMeshBuilder::build() size_t i = j - 1; m_generatedFaces.emplace_back(std::vector { oneSideVertexCount + j * (m_targetSegments + 1), - j * (m_targetSegments + 1), - i * (m_targetSegments + 1), - oneSideVertexCount + i * (m_targetSegments + 1) - }); + j * (m_targetSegments + 1), + i * (m_targetSegments + 1), + oneSideVertexCount + i * (m_targetSegments + 1) }); } // Stitch layers for all tail nodes of stitching lines @@ -367,10 +356,9 @@ void StitchMeshBuilder::build() size_t i = j - 1; m_generatedFaces.emplace_back(std::vector { oneSideVertexCount + i * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder, - i * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder, - j * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder, - oneSideVertexCount + j * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder - }); + i * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder, + j * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder, + oneSideVertexCount + j * (m_targetSegments + 1) + offsetBetweenSecondAndThirdBorder }); } // TODO: Process circle diff --git a/dust3d/mesh/stitch_mesh_builder.h b/dust3d/mesh/stitch_mesh_builder.h index 6c8cdece..9c5b68a5 100644 --- a/dust3d/mesh/stitch_mesh_builder.h +++ b/dust3d/mesh/stitch_mesh_builder.h @@ -23,33 +23,29 @@ #ifndef DUST3D_MESH_STITCH_MESH_BUILDER_H_ #define DUST3D_MESH_STITCH_MESH_BUILDER_H_ -#include #include +#include #include -namespace dust3d -{ +namespace dust3d { -class StitchMeshBuilder -{ +class StitchMeshBuilder { public: - struct Spline - { + struct Spline { std::vector nodes; bool isCircle = false; bool isClosing = false; Uuid sourceId; }; - StitchMeshBuilder(std::vector &&splines); + StitchMeshBuilder(std::vector&& splines); void build(); - const std::vector &generatedVertices() const; - const std::vector> &generatedFaces() const; - const std::vector &splines() const; + const std::vector& generatedVertices() const; + const std::vector>& generatedFaces() const; + const std::vector& splines() const; private: - struct StitchingPoint - { + struct StitchingPoint { size_t originVertex; double radius; }; @@ -62,18 +58,18 @@ private: size_t m_targetSegments = 0; void interpolateSplinesToHaveEqualSizeOfNodesExceptClosingSplines(); - std::vector> convertSplinesToStitchingPoints(const std::vector &splines); - void generateMeshFromStitchingPoints(const std::vector> &stitchingPoints); - void generateMeshFromStitchingPoints(const std::vector &a, - const std::vector &b); - void splitPolylineToSegments(const std::vector &polyline, - const std::vector &radiuses, + std::vector> convertSplinesToStitchingPoints(const std::vector& splines); + void generateMeshFromStitchingPoints(const std::vector>& stitchingPoints); + void generateMeshFromStitchingPoints(const std::vector& a, + const std::vector& b); + void splitPolylineToSegments(const std::vector& polyline, + const std::vector& radiuses, size_t targetSegments, - std::vector *targetPoints, - std::vector *targetRadiuses); - double segmentsLength(const std::vector &segmentPoints); + std::vector* targetPoints, + std::vector* targetRadiuses); + double segmentsLength(const std::vector& segmentPoints); void interpolateSplinesForBackClosing(); - void addQuadButMaybeTriangle(const std::vector &quadButMaybeTriangle); + void addQuadButMaybeTriangle(const std::vector& quadButMaybeTriangle); }; } diff --git a/dust3d/mesh/stroke_mesh_builder.cc b/dust3d/mesh/stroke_mesh_builder.cc index 7158d6ad..16999e6a 100644 --- a/dust3d/mesh/stroke_mesh_builder.cc +++ b/dust3d/mesh/stroke_mesh_builder.cc @@ -20,22 +20,21 @@ * SOFTWARE. */ -#include #include -#include -#include #include #include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { size_t StrokeMeshBuilder::Node::nextOrNeighborOtherThan(size_t neighborIndex) const { if (this->next != neighborIndex && this->next != this->index) return this->next; - for (const auto &it: this->neighbors) { + for (const auto& it : this->neighbors) { if (it != neighborIndex) return it; } @@ -84,42 +83,42 @@ void StrokeMeshBuilder::setHollowThickness(float hollowThickness) void StrokeMeshBuilder::setNodeOriginInfo(size_t nodeIndex, int nearOriginNodeIndex, int farOriginNodeIndex) { - auto &node = m_nodes[nodeIndex]; + auto& node = m_nodes[nodeIndex]; node.nearOriginNodeIndex = nearOriginNodeIndex; node.farOriginNodeIndex = farOriginNodeIndex; } -const std::vector &StrokeMeshBuilder::generatedVertices() +const std::vector& StrokeMeshBuilder::generatedVertices() { return m_generatedVertices; } -const std::vector> &StrokeMeshBuilder::generatedFaces() +const std::vector>& StrokeMeshBuilder::generatedFaces() { return m_generatedFaces; } -const std::vector &StrokeMeshBuilder::generatedVerticesSourceNodeIndices() +const std::vector& StrokeMeshBuilder::generatedVerticesSourceNodeIndices() { return m_generatedVerticesSourceNodeIndices; } -const std::vector &StrokeMeshBuilder::nodes() const +const std::vector& StrokeMeshBuilder::nodes() const { return m_nodes; } -const std::vector &StrokeMeshBuilder::nodeIndices() const +const std::vector& StrokeMeshBuilder::nodeIndices() const { return m_nodeIndices; } -const Vector3 &StrokeMeshBuilder::nodeTraverseDirection(size_t nodeIndex) const +const Vector3& StrokeMeshBuilder::nodeTraverseDirection(size_t nodeIndex) const { return m_nodes[nodeIndex].traverseDirection; } -const Vector3 &StrokeMeshBuilder::nodeBaseNormal(size_t nodeIndex) const +const Vector3& StrokeMeshBuilder::nodeBaseNormal(size_t nodeIndex) const { return m_nodes[nodeIndex].baseNormal; } @@ -129,10 +128,10 @@ size_t StrokeMeshBuilder::nodeTraverseOrder(size_t nodeIndex) const return m_nodes[nodeIndex].traverseOrder; } -size_t StrokeMeshBuilder::addNode(const Vector3 &position, float radius, const std::vector &cutTemplate, float cutRotation) +size_t StrokeMeshBuilder::addNode(const Vector3& position, float radius, const std::vector& cutTemplate, float cutRotation) { size_t nodeIndex = m_nodes.size(); - + Node node; node.position = position; node.radius = radius; @@ -140,29 +139,29 @@ size_t StrokeMeshBuilder::addNode(const Vector3 &position, float radius, const s node.cutRotation = cutRotation; node.next = nodeIndex; node.index = nodeIndex; - + m_nodes.push_back(node); - + return nodeIndex; } -void StrokeMeshBuilder::addEdge(size_t firstNodeIndex, +void StrokeMeshBuilder::addEdge(size_t firstNodeIndex, size_t secondNodeIndex) { - auto &fromNode = m_nodes[firstNodeIndex]; + auto& fromNode = m_nodes[firstNodeIndex]; fromNode.next = secondNodeIndex; fromNode.neighbors.push_back(secondNodeIndex); - - auto &toNode = m_nodes[secondNodeIndex]; + + auto& toNode = m_nodes[secondNodeIndex]; toNode.neighbors.push_back(firstNodeIndex); } -Vector3 StrokeMeshBuilder::calculateBaseNormalFromTraverseDirection(const Vector3 &traverseDirection) +Vector3 StrokeMeshBuilder::calculateBaseNormalFromTraverseDirection(const Vector3& traverseDirection) { const std::vector axisList = { - Vector3 {1, 0, 0}, - Vector3 {0, 1, 0}, - Vector3 {0, 0, 1}, + Vector3 { 1, 0, 0 }, + Vector3 { 0, 1, 0 }, + Vector3 { 0, 0, 1 }, }; float maxDot = -1; size_t nearAxisIndex = 0; @@ -184,47 +183,47 @@ Vector3 StrokeMeshBuilder::calculateBaseNormalFromTraverseDirection(const Vector return reversed ? -baseNormal : baseNormal; } -std::vector StrokeMeshBuilder::makeCut(const Vector3 &cutCenter, - float radius, - const std::vector &cutTemplate, - const Vector3 &cutNormal, - const Vector3 &baseNormal) +std::vector StrokeMeshBuilder::makeCut(const Vector3& cutCenter, + float radius, + const std::vector& cutTemplate, + const Vector3& cutNormal, + const Vector3& baseNormal) { std::vector resultCut; Vector3 u = Vector3::crossProduct(cutNormal, baseNormal).normalized(); Vector3 v = Vector3::crossProduct(u, cutNormal).normalized(); auto uFactor = u * radius; auto vFactor = v * radius; - for (const auto &t: cutTemplate) { + for (const auto& t : cutTemplate) { resultCut.push_back(cutCenter + (uFactor * t.x() + vFactor * t.y())); } return resultCut; } -void StrokeMeshBuilder::insertCutVertices(const std::vector &cut, - std::vector *vertices, +void StrokeMeshBuilder::insertCutVertices(const std::vector& cut, + std::vector* vertices, size_t nodeIndex, - const Vector3 &cutNormal) + const Vector3& cutNormal) { size_t indexInCut = 0; - for (const auto &position: cut) { + for (const auto& position : cut) { size_t vertexIndex = m_generatedVertices.size(); m_generatedVertices.push_back(position); m_generatedVerticesSourceNodeIndices.push_back(nodeIndex); m_generatedVerticesCutDirects.push_back(cutNormal); - + GeneratedVertexInfo info; info.orderInCut = indexInCut; info.cutSize = cut.size(); m_generatedVerticesInfos.push_back(info); - + vertices->push_back(vertexIndex); - + ++indexInCut; } } -std::vector StrokeMeshBuilder::edgeloopFlipped(const std::vector &edgeLoop) +std::vector StrokeMeshBuilder::edgeloopFlipped(const std::vector& edgeLoop) { auto reversed = edgeLoop; std::reverse(reversed.begin(), reversed.end()); @@ -235,7 +234,7 @@ std::vector StrokeMeshBuilder::edgeloopFlipped(const std::vector void StrokeMeshBuilder::buildMesh() { if (1 == m_nodes.size()) { - const Node &node = m_nodes[0]; + const Node& node = m_nodes[0]; int subdivideTimes = (int)(node.cutTemplate.size() / 4) - 1; if (subdivideTimes < 0) subdivideTimes = 0; @@ -244,9 +243,9 @@ void StrokeMeshBuilder::buildMesh() m_generatedVerticesCutDirects.resize(m_generatedVertices.size(), node.traverseDirection); return; } - + for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; if (!Math::isZero(node.cutRotation)) { float degree = node.cutRotation * 180; node.baseNormal = node.baseNormal.rotated(node.traverseDirection, Math::radiansFromDegrees(degree)); @@ -263,21 +262,21 @@ void StrokeMeshBuilder::interpolateCutEdges() { if (m_cuts.empty()) return; - + size_t bigCutIndex = 0; double maxRadius = 0.0; for (size_t i = 0; i < m_cuts.size(); ++i) { size_t j = (i + 1) % m_cuts.size(); if (m_cuts[i].size() != m_cuts[j].size()) return; - const auto &nodeIndex = m_generatedVerticesSourceNodeIndices[m_cuts[i][0]]; + const auto& nodeIndex = m_generatedVerticesSourceNodeIndices[m_cuts[i][0]]; if (m_nodes[nodeIndex].radius > maxRadius) { maxRadius = m_nodes[nodeIndex].radius; bigCutIndex = i; } } - - const auto &cut = m_cuts[bigCutIndex]; + + const auto& cut = m_cuts[bigCutIndex]; double sumOfLegnth = 0; std::vector edgeLengths; edgeLengths.reserve(cut.size()); @@ -294,7 +293,7 @@ void StrokeMeshBuilder::interpolateCutEdges() for (size_t cutIndex = 0; cutIndex < m_cuts.size(); ++cutIndex) { newCuts[cutIndex].push_back(m_cuts[cutIndex][index]); } - const auto &oldEdgeLength = edgeLengths[index]; + const auto& oldEdgeLength = edgeLengths[index]; if (targetLength >= oldEdgeLength) continue; size_t newInsertNum = oldEdgeLength / targetLength; @@ -310,7 +309,7 @@ void StrokeMeshBuilder::interpolateCutEdges() auto newPosition = m_generatedVertices[m_cuts[cutIndex][index]] * firstFactor + m_generatedVertices[m_cuts[cutIndex][nextIndex]] * factor; newCuts[cutIndex].push_back(m_generatedVertices.size()); m_generatedVertices.push_back(newPosition); - const auto &oldIndex = m_cuts[cutIndex][index]; + const auto& oldIndex = m_cuts[cutIndex][index]; m_generatedVerticesCutDirects.push_back(m_generatedVerticesCutDirects[oldIndex]); m_generatedVerticesSourceNodeIndices.push_back(m_generatedVerticesSourceNodeIndices[oldIndex]); m_generatedVerticesInfos.push_back(m_generatedVerticesInfos[oldIndex]); @@ -325,22 +324,22 @@ void StrokeMeshBuilder::stitchCuts() { for (size_t i = m_isRing ? 0 : 1; i < m_nodeIndices.size(); ++i) { size_t h = (i + m_nodeIndices.size() - 1) % m_nodeIndices.size(); - const auto &nodeH = m_nodes[m_nodeIndices[h]]; - const auto &nodeI = m_nodes[m_nodeIndices[i]]; - const auto &cutH = m_cuts[h]; + const auto& nodeH = m_nodes[m_nodeIndices[h]]; + const auto& nodeI = m_nodes[m_nodeIndices[i]]; + const auto& cutH = m_cuts[h]; auto reversedCutI = edgeloopFlipped(m_cuts[i]); std::vector, Vector3>> edgeLoops = { - {cutH, -nodeH.traverseDirection}, - {reversedCutI, nodeI.traverseDirection}, + { cutH, -nodeH.traverseDirection }, + { reversedCutI, nodeI.traverseDirection }, }; HoleStitcher stitcher; stitcher.setVertices(&m_generatedVertices); stitcher.stitch(edgeLoops); - for (const auto &face: stitcher.newlyGeneratedFaces()) { + for (const auto& face : stitcher.newlyGeneratedFaces()) { m_generatedFaces.push_back(face); } } - + // Fill endpoints if (!m_isRing) { if (m_cuts.size() < 2) @@ -349,29 +348,29 @@ void StrokeMeshBuilder::stitchCuts() // Generate mesh for hollow size_t startVertexIndex = m_generatedVertices.size(); for (size_t i = 0; i < startVertexIndex; ++i) { - const auto &position = m_generatedVertices[i]; - const auto &node = m_nodes[m_generatedVerticesSourceNodeIndices[i]]; + const auto& position = m_generatedVertices[i]; + const auto& node = m_nodes[m_generatedVerticesSourceNodeIndices[i]]; auto ray = position - node.position; - + auto newPosition = position - ray * m_hollowThickness; m_generatedVertices.push_back(newPosition); m_generatedVerticesCutDirects.push_back(m_generatedVerticesCutDirects[i]); m_generatedVerticesSourceNodeIndices.push_back(m_generatedVerticesSourceNodeIndices[i]); m_generatedVerticesInfos.push_back(m_generatedVerticesInfos[i]); } - + size_t oldFaceNum = m_generatedFaces.size(); for (size_t i = 0; i < oldFaceNum; ++i) { auto newFace = m_generatedFaces[i]; std::reverse(newFace.begin(), newFace.end()); - for (auto &it: newFace) + for (auto& it : newFace) it += startVertexIndex; m_generatedFaces.push_back(newFace); } - - std::vector> revisedCuts = {m_cuts[0], - edgeloopFlipped(m_cuts[m_cuts.size() - 1])}; - for (const auto &cut: revisedCuts) { + + std::vector> revisedCuts = { m_cuts[0], + edgeloopFlipped(m_cuts[m_cuts.size() - 1]) }; + for (const auto& cut : revisedCuts) { for (size_t i = 0; i < cut.size(); ++i) { size_t j = (i + 1) % cut.size(); std::vector quad; @@ -387,7 +386,7 @@ void StrokeMeshBuilder::stitchCuts() m_generatedFaces.push_back(m_cuts[0]); m_generatedFaces.push_back(edgeloopFlipped(m_cuts[m_cuts.size() - 1])); } else { - auto remeshAndAddCut = [&](const std::vector &inputFace) { + auto remeshAndAddCut = [&](const std::vector& inputFace) { std::vector> remeshedFaces; size_t oldVertexCount = m_generatedVertices.size(); isotropicTriangulate(m_generatedVertices, inputFace, &remeshedFaces); @@ -397,7 +396,7 @@ void StrokeMeshBuilder::stitchCuts() m_generatedVerticesSourceNodeIndices.push_back(m_generatedVerticesSourceNodeIndices[oldIndex]); m_generatedVerticesInfos.push_back(m_generatedVerticesInfos[oldIndex]); } - for (const auto &it: remeshedFaces) + for (const auto& it : remeshedFaces) m_generatedFaces.push_back(it); }; remeshAndAddCut(m_cuts[0]); @@ -411,16 +410,16 @@ void StrokeMeshBuilder::reviseTraverseDirections() { std::vector> revised; for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - const auto &node = m_nodes[m_nodeIndices[i]]; + const auto& node = m_nodes[m_nodeIndices[i]]; if (-1 != node.nearOriginNodeIndex && -1 != node.farOriginNodeIndex) { - const auto &nearOriginNode = m_nodes[node.nearOriginNodeIndex]; - const auto &farOriginNode = m_nodes[node.farOriginNodeIndex]; + const auto& nearOriginNode = m_nodes[node.nearOriginNodeIndex]; + const auto& farOriginNode = m_nodes[node.farOriginNodeIndex]; float nearDistance = (node.position - nearOriginNode.position).length(); float farDistance = (node.position - farOriginNode.position).length(); float totalDistance = nearDistance + farDistance; float distanceFactor = nearDistance / totalDistance; - const Vector3 *revisedNearCutNormal = nullptr; - const Vector3 *revisedFarCutNormal = nullptr; + const Vector3* revisedNearCutNormal = nullptr; + const Vector3* revisedFarCutNormal = nullptr; if (distanceFactor <= 0.5) { revisedNearCutNormal = &nearOriginNode.traverseDirection; revisedFarCutNormal = &node.traverseDirection; @@ -437,10 +436,10 @@ void StrokeMeshBuilder::reviseTraverseDirections() newTraverseDirection = (*revisedNearCutNormal * (1.0 - distanceFactor) + *revisedFarCutNormal * distanceFactor).normalized(); if (Vector3::dotProduct(newTraverseDirection, node.traverseDirection) <= 0) newTraverseDirection = -newTraverseDirection; - revised.push_back({node.index, newTraverseDirection}); + revised.push_back({ node.index, newTraverseDirection }); } } - for (const auto &it: revised) + for (const auto& it : revised) m_nodes[it.first].traverseDirection = it.second; } @@ -456,15 +455,13 @@ void StrokeMeshBuilder::localAverageBaseNormals() h = i > 0 ? i - 1 : i; j = i + 1 < m_nodeIndices.size() ? i + 1 : i; } - const auto &nodeH = m_nodes[m_nodeIndices[h]]; - const auto &nodeI = m_nodes[m_nodeIndices[i]]; - const auto &nodeJ = m_nodes[m_nodeIndices[j]]; - averaged.push_back({ - nodeI.index, - (nodeH.baseNormal + nodeI.baseNormal + nodeJ.baseNormal).normalized() - }); + const auto& nodeH = m_nodes[m_nodeIndices[h]]; + const auto& nodeI = m_nodes[m_nodeIndices[i]]; + const auto& nodeJ = m_nodes[m_nodeIndices[j]]; + averaged.push_back({ nodeI.index, + (nodeH.baseNormal + nodeI.baseNormal + nodeJ.baseNormal).normalized() }); } - for (const auto &it: averaged) + for (const auto& it : averaged) m_nodes[it.first].baseNormal = it.second; } @@ -472,17 +469,16 @@ void StrokeMeshBuilder::unifyBaseNormals() { for (size_t i = 1; i < m_nodeIndices.size(); ++i) { size_t h = m_nodeIndices[i - 1]; - const auto &nodeH = m_nodes[m_nodeIndices[h]]; - auto &nodeI = m_nodes[m_nodeIndices[i]]; + const auto& nodeH = m_nodes[m_nodeIndices[h]]; + auto& nodeI = m_nodes[m_nodeIndices[i]]; if (Vector3::dotProduct(nodeI.baseNormal, nodeH.baseNormal) < 0) nodeI.baseNormal = -nodeI.baseNormal; } } -void StrokeMeshBuilder::reviseNodeBaseNormal(Node &node) +void StrokeMeshBuilder::reviseNodeBaseNormal(Node& node) { - Vector3 orientedBaseNormal = Vector3::dotProduct(node.traverseDirection, node.baseNormal) >= 0 ? - node.baseNormal : -node.baseNormal; + Vector3 orientedBaseNormal = Vector3::dotProduct(node.traverseDirection, node.baseNormal) >= 0 ? node.baseNormal : -node.baseNormal; if (orientedBaseNormal.isZero()) { orientedBaseNormal = calculateBaseNormalFromTraverseDirection(node.traverseDirection); } @@ -493,17 +489,17 @@ bool StrokeMeshBuilder::prepare() { if (m_nodes.empty()) return false; - + if (1 == m_nodes.size()) { - auto &node = m_nodes[0]; + auto& node = m_nodes[0]; node.traverseOrder = 0; node.traverseDirection = Vector3(0, 1, 0); node.baseNormal = Vector3(0, 0, 1); return true; } - + m_nodeIndices = sortedNodeIndices(&m_isRing); - + if (m_nodeIndices.empty()) return false; @@ -518,7 +514,7 @@ bool StrokeMeshBuilder::prepare() } edgeDirections.push_back((m_nodes[m_nodeIndices[j]].position - m_nodes[m_nodeIndices[i]].position).normalized()); } - + for (size_t i = 0; i < m_nodeIndices.size(); ++i) { size_t h; if (m_isRing) { @@ -529,10 +525,10 @@ bool StrokeMeshBuilder::prepare() m_nodes[m_nodeIndices[i]].traverseDirection = (edgeDirections[h] + edgeDirections[i]).normalized(); } reviseTraverseDirections(); - + // Base plane constraints if (!m_baseNormalOnX || !m_baseNormalOnY || !m_baseNormalOnZ) { - for (auto &it: edgeDirections) { + for (auto& it : edgeDirections) { if (!m_baseNormalOnX) it.setX(0); if (!m_baseNormalOnY) @@ -549,11 +545,11 @@ bool StrokeMeshBuilder::prepare() auto baseNormal = Vector3::crossProduct(edgeDirections[h], edgeDirections[i]); if (!baseNormal.isZero()) { if (!validBaseNormalPosArray.empty()) { - const auto &lastNode = m_nodes[m_nodeIndices[validBaseNormalPosArray[validBaseNormalPosArray.size() - 1]]]; + const auto& lastNode = m_nodes[m_nodeIndices[validBaseNormalPosArray[validBaseNormalPosArray.size() - 1]]]; if (Vector3::dotProduct(lastNode.baseNormal, baseNormal) < 0) baseNormal = -baseNormal; } - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = baseNormal; validBaseNormalPosArray.push_back(i); continue; @@ -563,38 +559,38 @@ bool StrokeMeshBuilder::prepare() if (validBaseNormalPosArray.empty()) { Vector3 baseNormal; for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - const auto &node = m_nodes[m_nodeIndices[i]]; + const auto& node = m_nodes[m_nodeIndices[i]]; baseNormal += calculateBaseNormalFromTraverseDirection(node.traverseDirection); } baseNormal.normalize(); for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = baseNormal; } } else if (1 == validBaseNormalPosArray.size()) { auto baseNormal = m_nodes[m_nodeIndices[validBaseNormalPosArray[0]]].baseNormal; for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = baseNormal; } } else { if (!m_isRing) { auto prePos = validBaseNormalPosArray[0]; - const auto &preNode = m_nodes[m_nodeIndices[prePos]]; + const auto& preNode = m_nodes[m_nodeIndices[prePos]]; auto preBaseNormal = preNode.baseNormal; auto afterPos = validBaseNormalPosArray[validBaseNormalPosArray.size() - 1]; - const auto &afterNode = m_nodes[m_nodeIndices[afterPos]]; + const auto& afterNode = m_nodes[m_nodeIndices[afterPos]]; auto afterBaseNormal = afterNode.baseNormal; for (size_t i = 0; i < prePos; ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = preBaseNormal; } for (size_t i = afterPos + 1; i < m_nodeIndices.size(); ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = afterBaseNormal; } } - auto updateInBetweenBaseNormal = [this](const Node &nodeU, const Node &nodeV, Node &updateNode) { + auto updateInBetweenBaseNormal = [this](const Node& nodeU, const Node& nodeV, Node& updateNode) { float distanceU = (updateNode.position - nodeU.position).length(); float distanceV = (updateNode.position - nodeV.position).length(); float totalDistance = distanceU + distanceV; @@ -606,24 +602,24 @@ bool StrokeMeshBuilder::prepare() for (size_t k = m_isRing ? 0 : 1; k < validBaseNormalPosArray.size(); ++k) { size_t u = validBaseNormalPosArray[(k + validBaseNormalPosArray.size() - 1) % validBaseNormalPosArray.size()]; size_t v = validBaseNormalPosArray[k]; - const auto &nodeU = m_nodes[m_nodeIndices[u]]; - const auto &nodeV = m_nodes[m_nodeIndices[v]]; - for (size_t i = (u + 1) % m_nodeIndices.size(); - i != v; - i = (i + 1) % m_nodeIndices.size()) { - auto &node = m_nodes[m_nodeIndices[i]]; + const auto& nodeU = m_nodes[m_nodeIndices[u]]; + const auto& nodeV = m_nodes[m_nodeIndices[v]]; + for (size_t i = (u + 1) % m_nodeIndices.size(); + i != v; + i = (i + 1) % m_nodeIndices.size()) { + auto& node = m_nodes[m_nodeIndices[i]]; updateInBetweenBaseNormal(nodeU, nodeV, node); } } if (m_baseNormalAverageEnabled) { Vector3 baseNormal; for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - const auto &node = m_nodes[m_nodeIndices[i]]; + const auto& node = m_nodes[m_nodeIndices[i]]; baseNormal += node.baseNormal; } baseNormal.normalize(); for (size_t i = 0; i < m_nodeIndices.size(); ++i) { - auto &node = m_nodes[m_nodeIndices[i]]; + auto& node = m_nodes[m_nodeIndices[i]]; node.baseNormal = baseNormal; } } else { @@ -639,14 +635,14 @@ bool StrokeMeshBuilder::prepare() return true; } -std::vector StrokeMeshBuilder::sortedNodeIndices(bool *isRing) +std::vector StrokeMeshBuilder::sortedNodeIndices(bool* isRing) { std::vector nodeIndices; - + size_t startingNodeIndex = 0; if (!calculateStartingNodeIndex(&startingNodeIndex, isRing)) return nodeIndices; - + size_t fromNodeIndex = startingNodeIndex; std::unordered_set visited; auto nodeIndex = fromNodeIndex; @@ -655,50 +651,51 @@ std::vector StrokeMeshBuilder::sortedNodeIndices(bool *isRing) break; visited.insert(nodeIndex); nodeIndices.push_back(nodeIndex); - const auto &node = m_nodes[nodeIndex]; + const auto& node = m_nodes[nodeIndex]; size_t neighborIndex = node.nextOrNeighborOtherThan(fromNodeIndex); if (neighborIndex == nodeIndex) break; fromNodeIndex = nodeIndex; nodeIndex = neighborIndex; }; - + return nodeIndices; } -bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t *startingNodeIndex, - bool *isRing) +bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t* startingNodeIndex, + bool* isRing) { if (m_nodes.empty()) return false; - + if (1 == m_nodes.size()) { *startingNodeIndex = 0; *isRing = false; return true; } - - auto findNearestNodeWithWorldCenter = [&](const std::vector &nodeIndices) { + + auto findNearestNodeWithWorldCenter = [&](const std::vector& nodeIndices) { std::vector> dist2Array; - for (const auto &i: nodeIndices) { - dist2Array.push_back({i, (float)m_nodes[i].position.lengthSquared()}); + for (const auto& i : nodeIndices) { + dist2Array.push_back({ i, (float)m_nodes[i].position.lengthSquared() }); } - return std::min_element(dist2Array.begin(), dist2Array.end(), - [](const std::pair &first, - const std::pair &second) { - return first.second < second.second; - })->first; + return std::min_element(dist2Array.begin(), dist2Array.end(), + [](const std::pair& first, + const std::pair& second) { + return first.second < second.second; + }) + ->first; }; - + auto findEndpointNodeIndices = [&]() { std::vector endpointIndices; - for (const auto &it: m_nodes) { + for (const auto& it : m_nodes) { if (1 == it.neighbors.size()) endpointIndices.push_back(it.index); } return endpointIndices; }; - + auto endpointIndices = findEndpointNodeIndices(); if (2 != endpointIndices.size()) { // Invalid endpoint count, there must be a ring, choose the node which is nearest with world center @@ -712,7 +709,7 @@ bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t *startingNodeIndex, *isRing = true; return true; } - + auto countAlignedDirections = [&](size_t nodeIndex) { size_t alignedCount = 0; size_t fromNodeIndex = nodeIndex; @@ -721,7 +718,7 @@ bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t *startingNodeIndex, if (visited.find(nodeIndex) != visited.end()) break; visited.insert(nodeIndex); - const auto &node = m_nodes[nodeIndex]; + const auto& node = m_nodes[nodeIndex]; size_t neighborIndex = node.nextOrNeighborOtherThan(fromNodeIndex); if (neighborIndex == nodeIndex) break; @@ -732,20 +729,19 @@ bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t *startingNodeIndex, }; return alignedCount; }; - - auto chooseStartingEndpointByAlignedDirections = [&](const std::vector &endpointIndices) { + + auto chooseStartingEndpointByAlignedDirections = [&](const std::vector& endpointIndices) { std::vector> alignedDirections(endpointIndices.size()); for (size_t i = 0; i < endpointIndices.size(); ++i) { auto nodeIndex = endpointIndices[i]; - alignedDirections[i] = {nodeIndex, countAlignedDirections(nodeIndex)}; + alignedDirections[i] = { nodeIndex, countAlignedDirections(nodeIndex) }; } - std::sort(alignedDirections.begin(), alignedDirections.end(), [](const std::pair &first, - const std::pair &second) { + std::sort(alignedDirections.begin(), alignedDirections.end(), [](const std::pair& first, const std::pair& second) { return first.second > second.second; }); if (alignedDirections[0].second > alignedDirections[1].second) return alignedDirections[0].first; - std::vector nodeIndices = {alignedDirections[0].first, alignedDirections[1].first}; + std::vector nodeIndices = { alignedDirections[0].first, alignedDirections[1].first }; return findNearestNodeWithWorldCenter(nodeIndices); }; @@ -754,7 +750,7 @@ bool StrokeMeshBuilder::calculateStartingNodeIndex(size_t *startingNodeIndex, return true; } -Vector3 StrokeMeshBuilder::calculateDeformPosition(const Vector3 &vertexPosition, const Vector3 &ray, const Vector3 &deformNormal, float deformFactor) +Vector3 StrokeMeshBuilder::calculateDeformPosition(const Vector3& vertexPosition, const Vector3& ray, const Vector3& deformNormal, float deformFactor) { Vector3 revisedNormal = Vector3::dotProduct(ray, deformNormal) < 0.0 ? -deformNormal : deformNormal; Vector3 projectRayOnRevisedNormal = revisedNormal * (Vector3::dotProduct(ray, revisedNormal) / revisedNormal.lengthSquared()); @@ -766,15 +762,15 @@ void StrokeMeshBuilder::applyDeform() { float maxRadius = 0.0; if (m_deformUnified) { - for (const auto &node: m_nodes) { + for (const auto& node : m_nodes) { if (node.radius > maxRadius) maxRadius = node.radius; } } for (size_t i = 0; i < m_generatedVertices.size(); ++i) { - auto &position = m_generatedVertices[i]; - const auto &node = m_nodes[m_generatedVerticesSourceNodeIndices[i]]; - const auto &cutDirect = m_generatedVerticesCutDirects[i]; + auto& position = m_generatedVertices[i]; + const auto& node = m_nodes[m_generatedVerticesSourceNodeIndices[i]]; + const auto& cutDirect = m_generatedVerticesCutDirects[i]; auto ray = position - node.position; Vector3 sum; size_t count = 0; @@ -803,7 +799,7 @@ bool StrokeMeshBuilder::build() { if (!prepare()) return false; - + buildMesh(); applyDeform(); interpolateCutEdges(); diff --git a/dust3d/mesh/stroke_mesh_builder.h b/dust3d/mesh/stroke_mesh_builder.h index d7aaab36..e459e04a 100644 --- a/dust3d/mesh/stroke_mesh_builder.h +++ b/dust3d/mesh/stroke_mesh_builder.h @@ -23,36 +23,32 @@ #ifndef DUST3D_MESH_STOKE_MESH_BUILDER_H_ #define DUST3D_MESH_STOKE_MESH_BUILDER_H_ -#include #include -#include +#include #include #include +#include -namespace dust3d -{ +namespace dust3d { -class StrokeMeshBuilder -{ +class StrokeMeshBuilder { public: - struct CutFaceTransform - { + struct CutFaceTransform { Vector3 translation; float scale; Vector3 uFactor; Vector3 vFactor; bool reverse = false; }; - - struct Node - { + + struct Node { float radius; Vector3 position; std::vector cutTemplate; float cutRotation; int nearOriginNodeIndex = -1; int farOriginNodeIndex = -1; - + size_t index; std::vector neighbors; size_t next; @@ -60,11 +56,11 @@ public: Vector3 traverseDirection; Vector3 baseNormal; size_t traverseOrder; - + size_t nextOrNeighborOtherThan(size_t neighborIndex) const; }; - - size_t addNode(const Vector3 &position, float radius, const std::vector &cutTemplate, float cutRotation); + + size_t addNode(const Vector3& position, float radius, const std::vector& cutTemplate, float cutRotation); void addEdge(size_t firstNodeIndex, size_t secondNodeIndex); void setNodeOriginInfo(size_t nodeIndex, int nearOriginNodeIndex, int farOriginNodeIndex); void setDeformThickness(float thickness); @@ -76,25 +72,25 @@ public: void enableBaseNormalOnZ(bool enabled); void enableBaseNormalAverage(bool enabled); bool buildBaseNormalsOnly(); - const std::vector &nodes() const; - const std::vector &nodeIndices() const; - const Vector3 &nodeTraverseDirection(size_t nodeIndex) const; - const Vector3 &nodeBaseNormal(size_t nodeIndex) const; + const std::vector& nodes() const; + const std::vector& nodeIndices() const; + const Vector3& nodeTraverseDirection(size_t nodeIndex) const; + const Vector3& nodeBaseNormal(size_t nodeIndex) const; size_t nodeTraverseOrder(size_t nodeIndex) const; bool build(); - const std::vector &generatedVertices(); - const std::vector> &generatedFaces(); - const std::vector &generatedVerticesSourceNodeIndices(); - - static Vector3 calculateDeformPosition(const Vector3 &vertexPosition, const Vector3 &ray, const Vector3 &deformNormal, float deformFactor); - static Vector3 calculateBaseNormalFromTraverseDirection(const Vector3 &traverseDirection); + const std::vector& generatedVertices(); + const std::vector>& generatedFaces(); + const std::vector& generatedVerticesSourceNodeIndices(); + + static Vector3 calculateDeformPosition(const Vector3& vertexPosition, const Vector3& ray, const Vector3& deformNormal, float deformFactor); + static Vector3 calculateBaseNormalFromTraverseDirection(const Vector3& traverseDirection); + private: - struct GeneratedVertexInfo - { + struct GeneratedVertexInfo { size_t orderInCut; size_t cutSize; }; - + std::vector m_nodes; float m_deformThickness = 1.0f; float m_deformWidth = 1.0f; @@ -105,7 +101,7 @@ private: bool m_baseNormalAverageEnabled = false; float m_hollowThickness = 0.0f; bool m_deformUnified = false; - + bool m_isRing = false; std::vector m_nodeIndices; std::vector m_generatedVertices; @@ -113,28 +109,28 @@ private: std::vector m_generatedVerticesSourceNodeIndices; std::vector m_generatedVerticesInfos; std::vector> m_generatedFaces; - + std::vector> m_cuts; - + bool prepare(); - std::vector makeCut(const Vector3 &cutCenter, - float radius, - const std::vector &cutTemplate, - const Vector3 &cutNormal, - const Vector3 &baseNormal); - void insertCutVertices(const std::vector &cut, - std::vector *vertices, + std::vector makeCut(const Vector3& cutCenter, + float radius, + const std::vector& cutTemplate, + const Vector3& cutNormal, + const Vector3& baseNormal); + void insertCutVertices(const std::vector& cut, + std::vector* vertices, size_t nodeIndex, - const Vector3 &cutNormal); + const Vector3& cutNormal); void buildMesh(); - std::vector sortedNodeIndices(bool *isRing); - bool calculateStartingNodeIndex(size_t *startingNodeIndex, - bool *isRing); + std::vector sortedNodeIndices(bool* isRing); + bool calculateStartingNodeIndex(size_t* startingNodeIndex, + bool* isRing); void reviseTraverseDirections(); void localAverageBaseNormals(); void unifyBaseNormals(); - std::vector edgeloopFlipped(const std::vector &edgeLoop); - void reviseNodeBaseNormal(Node &node); + std::vector edgeloopFlipped(const std::vector& edgeLoop); + void reviseNodeBaseNormal(Node& node); void applyDeform(); void interpolateCutEdges(); void stitchCuts(); diff --git a/dust3d/mesh/stroke_modifier.cc b/dust3d/mesh/stroke_modifier.cc index 5509ed2d..c25b211b 100644 --- a/dust3d/mesh/stroke_modifier.cc +++ b/dust3d/mesh/stroke_modifier.cc @@ -20,13 +20,12 @@ * SOFTWARE. */ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ +namespace dust3d { void StrokeModifier::enableIntermediateAddition() { @@ -38,10 +37,10 @@ void StrokeModifier::enableSmooth() m_smooth = true; } -size_t StrokeModifier::addNode(const Vector3 &position, float radius, const std::vector &cutTemplate, float cutRotation) +size_t StrokeModifier::addNode(const Vector3& position, float radius, const std::vector& cutTemplate, float cutRotation) { size_t nodeIndex = m_nodes.size(); - + Node node; node.isOriginal = true; node.position = position; @@ -50,23 +49,23 @@ size_t StrokeModifier::addNode(const Vector3 &position, float radius, const std: node.cutRotation = cutRotation; node.originNodeIndex = nodeIndex; m_nodes.push_back(node); - + return nodeIndex; } size_t StrokeModifier::addEdge(size_t firstNodeIndex, size_t secondNodeIndex) { size_t edgeIndex = m_edges.size(); - + Edge edge; edge.firstNodeIndex = firstNodeIndex; edge.secondNodeIndex = secondNodeIndex; m_edges.push_back(edge); - + return edgeIndex; } -void StrokeModifier::createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode) +void StrokeModifier::createIntermediateNode(const Node& firstNode, const Node& secondNode, float factor, Node* resultNode) { float firstFactor = 1.0 - factor; resultNode->position = firstNode.position * firstFactor + secondNode.position * factor; @@ -88,12 +87,12 @@ void StrokeModifier::createIntermediateNode(const Node &firstNode, const Node &s void StrokeModifier::subdivide() { - for (auto &node: m_nodes) { + for (auto& node : m_nodes) { subdivideFace(&node.cutTemplate); } } -void StrokeModifier::subdivideFace(std::vector *face) +void StrokeModifier::subdivideFace(std::vector* face) { auto oldFace = *face; face->resize(oldFace.size() * 2); @@ -105,11 +104,11 @@ void StrokeModifier::subdivideFace(std::vector *face) } } -float StrokeModifier::averageCutTemplateEdgeLength(const std::vector &cutTemplate) +float StrokeModifier::averageCutTemplateEdgeLength(const std::vector& cutTemplate) { if (cutTemplate.empty()) return 0; - + float sum = 0; for (size_t i = 0; i < cutTemplate.size(); ++i) { size_t j = (i + 1) % cutTemplate.size(); @@ -121,14 +120,14 @@ float StrokeModifier::averageCutTemplateEdgeLength(const std::vector &c void StrokeModifier::roundEnd() { std::map> neighbors; - for (const auto &edge: m_edges) { + for (const auto& edge : m_edges) { neighbors[edge.firstNodeIndex].push_back(edge.secondNodeIndex); neighbors[edge.secondNodeIndex].push_back(edge.firstNodeIndex); } - for (const auto &it: neighbors) { + for (const auto& it : neighbors) { if (1 == it.second.size()) { - const Node ¤tNode = m_nodes[it.first]; - const Node &neighborNode = m_nodes[it.second[0]]; + const Node& currentNode = m_nodes[it.first]; + const Node& neighborNode = m_nodes[it.second[0]]; Node endNode; endNode.radius = currentNode.radius * 0.5; endNode.position = currentNode.position + (currentNode.position - neighborNode.position).normalized() * endNode.radius; @@ -142,7 +141,7 @@ void StrokeModifier::roundEnd() } } -void StrokeModifier::createIntermediateCutTemplateEdges(std::vector &cutTemplate, float averageCutTemplateLength) +void StrokeModifier::createIntermediateCutTemplateEdges(std::vector& cutTemplate, float averageCutTemplateLength) { std::vector newCutTemplate; auto pointCount = cutTemplate.size(); @@ -172,17 +171,17 @@ void StrokeModifier::finalize() { if (!m_intermediateAdditionEnabled) return; - - for (auto &node: m_nodes) { + + for (auto& node : m_nodes) { node.averageCutTemplateLength = averageCutTemplateEdgeLength(node.cutTemplate); createIntermediateCutTemplateEdges(node.cutTemplate, node.averageCutTemplateLength); } - + auto oldEdges = m_edges; m_edges.clear(); - for (const auto &edge: oldEdges) { - const Node &firstNode = m_nodes[edge.firstNodeIndex]; - const Node &secondNode = m_nodes[edge.secondNodeIndex]; + for (const auto& edge : oldEdges) { + const Node& firstNode = m_nodes[edge.firstNodeIndex]; + const Node& secondNode = m_nodes[edge.secondNodeIndex]; auto firstAverageCutTemplateEdgeLength = firstNode.averageCutTemplateLength * firstNode.radius; auto secondAverageCutTemplateEdgeLength = secondNode.averageCutTemplateLength * secondNode.radius; float targetEdgeLength = (firstAverageCutTemplateEdgeLength + secondAverageCutTemplateEdgeLength) * 0.5; @@ -204,8 +203,8 @@ void StrokeModifier::finalize() float factor = stepFactor; for (size_t i = 0; i < newInsertNum && factor < 1.0; factor += stepFactor, ++i) { Node intermediateNode; - const Node &firstNode = m_nodes[edge.firstNodeIndex]; - const Node &secondNode = m_nodes[edge.secondNodeIndex]; + const Node& firstNode = m_nodes[edge.firstNodeIndex]; + const Node& secondNode = m_nodes[edge.secondNodeIndex]; createIntermediateNode(firstNode, secondNode, factor, &intermediateNode); size_t intermedidateNodeIndex = m_nodes.size(); nodeIndices.push_back(intermedidateNodeIndex); @@ -216,7 +215,7 @@ void StrokeModifier::finalize() addEdge(nodeIndices[i - 1], nodeIndices[i]); } } - + if (m_smooth) smooth(); } @@ -224,13 +223,13 @@ void StrokeModifier::finalize() void StrokeModifier::smooth() { std::unordered_map> neighborMap; - for (const auto &edge: m_edges) { + for (const auto& edge : m_edges) { neighborMap[edge.firstNodeIndex].push_back(edge.secondNodeIndex); neighborMap[edge.secondNodeIndex].push_back(edge.firstNodeIndex); } - + int startEndpoint = 0; - for (const auto &edge: m_edges) { + for (const auto& edge : m_edges) { auto findNeighbor = neighborMap.find(edge.firstNodeIndex); if (findNeighbor == neighborMap.end()) continue; @@ -248,7 +247,7 @@ void StrokeModifier::smooth() } if (-1 == startEndpoint) return; - + int loopIndex = startEndpoint; int previousIndex = -1; bool isRing = false; @@ -259,7 +258,7 @@ void StrokeModifier::smooth() if (findNeighbor == neighborMap.end()) return; int nextIndex = -1; - for (const auto &index: findNeighbor->second) { + for (const auto& index : findNeighbor->second) { if (index == previousIndex) continue; if (index == startEndpoint) { @@ -272,30 +271,30 @@ void StrokeModifier::smooth() previousIndex = loopIndex; loopIndex = nextIndex; } - + CentripetalCatmullRomSpline spline(isRing); for (size_t i = 0; i < loop.size(); ++i) { - const auto &nodeIndex = loop[i]; - const auto &node = m_nodes[nodeIndex]; + const auto& nodeIndex = loop[i]; + const auto& node = m_nodes[nodeIndex]; bool isKnot = node.originNodeIndex == nodeIndex; spline.addPoint((int)nodeIndex, node.position, isKnot); } if (!spline.interpolate()) return; - for (const auto &it: spline.splineNodes()) { + for (const auto& it : spline.splineNodes()) { if (-1 == it.source) continue; - auto &node = m_nodes[it.source]; + auto& node = m_nodes[it.source]; node.position = it.position; } } -const std::vector &StrokeModifier::nodes() const +const std::vector& StrokeModifier::nodes() const { return m_nodes; } -const std::vector &StrokeModifier::edges() const +const std::vector& StrokeModifier::edges() const { return m_edges; } diff --git a/dust3d/mesh/stroke_modifier.h b/dust3d/mesh/stroke_modifier.h index 166b5198..4d2c898f 100644 --- a/dust3d/mesh/stroke_modifier.h +++ b/dust3d/mesh/stroke_modifier.h @@ -23,17 +23,14 @@ #ifndef DUST3D_MESH_STROKE_MODIFIER_H_ #define DUST3D_MESH_STROKE_MODIFIER_H_ -#include #include +#include -namespace dust3d -{ - -class StrokeModifier -{ +namespace dust3d { + +class StrokeModifier { public: - struct Node - { + struct Node { bool isOriginal = false; Vector3 position; float radius = 0.0; @@ -44,35 +41,33 @@ public: int originNodeIndex = 0; float averageCutTemplateLength; }; - - struct Edge - { + + struct Edge { size_t firstNodeIndex; size_t secondNodeIndex; }; - - size_t addNode(const Vector3 &position, float radius, const std::vector &cutTemplate, float cutRotation); + + size_t addNode(const Vector3& position, float radius, const std::vector& cutTemplate, float cutRotation); size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex); void subdivide(); void roundEnd(); void enableIntermediateAddition(); void enableSmooth(); - const std::vector &nodes() const; - const std::vector &edges() const; + const std::vector& nodes() const; + const std::vector& edges() const; void finalize(); - - static void subdivideFace(std::vector *face); - + + static void subdivideFace(std::vector* face); + private: - std::vector m_nodes; std::vector m_edges; bool m_intermediateAdditionEnabled = false; bool m_smooth = false; - - void createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode); - float averageCutTemplateEdgeLength(const std::vector &cutTemplate); - void createIntermediateCutTemplateEdges(std::vector &cutTemplate, float averageCutTemplateLength); + + void createIntermediateNode(const Node& firstNode, const Node& secondNode, float factor, Node* resultNode); + float averageCutTemplateEdgeLength(const std::vector& cutTemplate); + void createIntermediateCutTemplateEdges(std::vector& cutTemplate, float averageCutTemplateLength); void smooth(); }; diff --git a/dust3d/mesh/triangulate.cc b/dust3d/mesh/triangulate.cc index e4c05607..b9bc9026 100644 --- a/dust3d/mesh/triangulate.cc +++ b/dust3d/mesh/triangulate.cc @@ -21,80 +21,73 @@ */ #include -#include #include -#include -#include #include +#include +#include +#include -namespace dust3d -{ - -void triangulate(const std::vector &vertices, - const std::vector &faceIndices, - std::vector> *triangles) +namespace dust3d { + +void triangulate(const std::vector& vertices, + const std::vector& faceIndices, + std::vector>* triangles) { if (4 == faceIndices.size()) { - triangles->push_back({ - faceIndices[0], + triangles->push_back({ faceIndices[0], faceIndices[1], - faceIndices[2] - }); - triangles->push_back({ - faceIndices[2], + faceIndices[2] }); + triangles->push_back({ faceIndices[2], faceIndices[3], - faceIndices[0] - }); + faceIndices[0] }); return; } - + Vector3 normal; for (size_t i = 0; i < faceIndices.size(); ++i) { auto j = (i + 1) % faceIndices.size(); auto k = (i + 2) % faceIndices.size(); - const auto &enter = vertices[faceIndices[i]]; - const auto &cone = vertices[faceIndices[j]]; - const auto &leave = vertices[faceIndices[k]]; + const auto& enter = vertices[faceIndices[i]]; + const auto& cone = vertices[faceIndices[j]]; + const auto& leave = vertices[faceIndices[k]]; normal += Vector3::normal(enter, cone, leave); } normal.normalize(); - + Vector3 axis = (vertices[1] - vertices[0]).normalized(); Vector3 origin = vertices[0]; - + std::vector pointsIn3d(faceIndices.size()); for (size_t i = 0; i < faceIndices.size(); ++i) pointsIn3d[i] = vertices[faceIndices[i]]; - + std::vector pointsIn2d; Vector3::project(pointsIn3d, &pointsIn2d, normal, axis, origin); - + std::vector>> polygons; std::vector pointIndices; std::vector> border; border.reserve(pointsIn2d.size()); - for (const auto &v: pointsIn2d) { - border.push_back(std::array {v.x(), v.y()}); + for (const auto& v : pointsIn2d) { + border.push_back(std::array { v.x(), v.y() }); } polygons.push_back(border); - + std::vector indices = mapbox::earcut(polygons); for (size_t i = 0; i < indices.size(); i += 3) { - triangles->push_back({ - faceIndices[indices[i]], + triangles->push_back({ faceIndices[indices[i]], faceIndices[indices[i + 1]], - faceIndices[indices[i + 2]] - }); + faceIndices[indices[i + 2]] }); } } -void triangulate(const std::vector &vertices, - const std::vector> &faces, - std::vector> *triangles) +void triangulate(const std::vector& vertices, + const std::vector>& faces, + std::vector>* triangles) { - for (const auto &faceIndices: faces) { + for (const auto& faceIndices : faces) { if (faceIndices.size() <= 3) { triangles->push_back(faceIndices); continue; @@ -103,50 +96,46 @@ void triangulate(const std::vector &vertices, } } -void isotropicTriangulate(std::vector &vertices, - const std::vector &faceIndices, - std::vector> *triangles) +void isotropicTriangulate(std::vector& vertices, + const std::vector& faceIndices, + std::vector>* triangles) { if (faceIndices.empty()) return; - + double edgeLength = 0.0; for (size_t i = 0; i < faceIndices.size(); ++i) { size_t j = (i + 1) % faceIndices.size(); edgeLength += (vertices[faceIndices[i]] - vertices[faceIndices[j]]).length(); } double targetEdgeLength = 1.2 * edgeLength / faceIndices.size(); - + std::vector> firstStepTriangles; triangulate(vertices, faceIndices, &firstStepTriangles); - + IsotropicRemesher isotropicRemesher(&vertices, &firstStepTriangles); isotropicRemesher.setTargetEdgeLength(targetEdgeLength); isotropicRemesher.remesh(3); - + size_t outputIndex = vertices.size(); - IsotropicHalfedgeMesh *halfedgeMesh = isotropicRemesher.remeshedHalfedgeMesh(); - for (IsotropicHalfedgeMesh::Vertex *vertex = halfedgeMesh->moveToNextVertex(nullptr); - nullptr != vertex; - vertex = halfedgeMesh->moveToNextVertex(vertex)) { + IsotropicHalfedgeMesh* halfedgeMesh = isotropicRemesher.remeshedHalfedgeMesh(); + for (IsotropicHalfedgeMesh::Vertex* vertex = halfedgeMesh->moveToNextVertex(nullptr); + nullptr != vertex; + vertex = halfedgeMesh->moveToNextVertex(vertex)) { if (-1 != vertex->sourceIndex) continue; vertex->sourceIndex = outputIndex++; - vertices.push_back({ - vertex->position[0], + vertices.push_back({ vertex->position[0], vertex->position[1], - vertex->position[2] - }); + vertex->position[2] }); } - for (IsotropicHalfedgeMesh::Face *face = halfedgeMesh->moveToNextFace(nullptr); - nullptr != face; - face = halfedgeMesh->moveToNextFace(face)) { - triangles->push_back({ - (size_t)face->halfedge->previousHalfedge->startVertex->sourceIndex, + for (IsotropicHalfedgeMesh::Face* face = halfedgeMesh->moveToNextFace(nullptr); + nullptr != face; + face = halfedgeMesh->moveToNextFace(face)) { + triangles->push_back({ (size_t)face->halfedge->previousHalfedge->startVertex->sourceIndex, (size_t)face->halfedge->startVertex->sourceIndex, - (size_t)face->halfedge->nextHalfedge->startVertex->sourceIndex - }); + (size_t)face->halfedge->nextHalfedge->startVertex->sourceIndex }); } } - + } \ No newline at end of file diff --git a/dust3d/mesh/triangulate.h b/dust3d/mesh/triangulate.h index 5805c74b..d6cfeb81 100644 --- a/dust3d/mesh/triangulate.h +++ b/dust3d/mesh/triangulate.h @@ -25,21 +25,20 @@ #include -namespace dust3d -{ - -void triangulate(const std::vector &vertices, - const std::vector &faceIndices, - std::vector> *triangles); - -void triangulate(const std::vector &vertices, - const std::vector> &faces, - std::vector> *triangles); - -void isotropicTriangulate(std::vector &vertices, - const std::vector &faceIndices, - std::vector> *triangles); - +namespace dust3d { + +void triangulate(const std::vector& vertices, + const std::vector& faceIndices, + std::vector>* triangles); + +void triangulate(const std::vector& vertices, + const std::vector>& faces, + std::vector>* triangles); + +void isotropicTriangulate(std::vector& vertices, + const std::vector& faceIndices, + std::vector>* triangles); + } #endif diff --git a/dust3d/mesh/trim_vertices.cc b/dust3d/mesh/trim_vertices.cc index e80c8174..7a30a574 100644 --- a/dust3d/mesh/trim_vertices.cc +++ b/dust3d/mesh/trim_vertices.cc @@ -23,10 +23,9 @@ #include #include -namespace dust3d -{ +namespace dust3d { -void trimVertices(std::vector *vertices, bool normalize) +void trimVertices(std::vector* vertices, bool normalize) { float xLow = std::numeric_limits::max(); float xHigh = std::numeric_limits::lowest(); @@ -34,7 +33,7 @@ void trimVertices(std::vector *vertices, bool normalize) float yHigh = std::numeric_limits::lowest(); float zLow = std::numeric_limits::max(); float zHigh = std::numeric_limits::lowest(); - for (const auto &position: *vertices) { + for (const auto& position : *vertices) { if (position.x() < xLow) xLow = position.x(); else if (position.x() > xHigh) @@ -62,13 +61,13 @@ void trimVertices(std::vector *vertices, bool normalize) longSize = zSize; if (Math::isZero(longSize)) longSize = 0.000001; - for (auto &position: *vertices) { + for (auto& position : *vertices) { position.setX((position.x() - xMiddle) / longSize); position.setY((position.y() - yMiddle) / longSize); position.setZ((position.z() - zMiddle) / longSize); } } else { - for (auto &position: *vertices) { + for (auto& position : *vertices) { position.setX((position.x() - xMiddle)); position.setY((position.y() - yMiddle)); position.setZ((position.z() - zMiddle)); diff --git a/dust3d/mesh/trim_vertices.h b/dust3d/mesh/trim_vertices.h index 6264138f..c79f9a23 100644 --- a/dust3d/mesh/trim_vertices.h +++ b/dust3d/mesh/trim_vertices.h @@ -23,13 +23,12 @@ #ifndef DUST3D_MESH_TRIM_VERTICES_H_ #define DUST3D_MESH_TRIM_VERTICES_H_ -#include #include +#include -namespace dust3d -{ +namespace dust3d { -void trimVertices(std::vector *vertices, bool normalize); +void trimVertices(std::vector* vertices, bool normalize); } diff --git a/dust3d/mesh/tube_mesh_builder.cc b/dust3d/mesh/tube_mesh_builder.cc index d7efbafe..f0cd98ba 100644 --- a/dust3d/mesh/tube_mesh_builder.cc +++ b/dust3d/mesh/tube_mesh_builder.cc @@ -24,27 +24,26 @@ #include #include -namespace dust3d -{ +namespace dust3d { -TubeMeshBuilder::TubeMeshBuilder(const BuildParameters &buildParameters, std::vector &&nodes, bool isCircle): - m_buildParameters(buildParameters), - m_nodes(std::move(nodes)), - m_isCircle(isCircle) +TubeMeshBuilder::TubeMeshBuilder(const BuildParameters& buildParameters, std::vector&& nodes, bool isCircle) + : m_buildParameters(buildParameters) + , m_nodes(std::move(nodes)) + , m_isCircle(isCircle) { } -const Vector3 &TubeMeshBuilder::generatedBaseNormal() +const Vector3& TubeMeshBuilder::generatedBaseNormal() { return m_generatedBaseNormal; } -const std::vector &TubeMeshBuilder::generatedVertices() +const std::vector& TubeMeshBuilder::generatedVertices() { return m_generatedVertices; } -const std::vector> &TubeMeshBuilder::generatedFaces() +const std::vector>& TubeMeshBuilder::generatedFaces() { return m_generatedFaces; } @@ -56,7 +55,7 @@ void TubeMeshBuilder::applyRoundEnd() if (m_nodes.size() <= 1) return; - + if (m_buildParameters.frontEndRounded) { auto newNode = m_nodes.front(); newNode.radius *= 0.5; @@ -144,17 +143,16 @@ void TubeMeshBuilder::buildNodePositionAndDirections() m_nodeForwardDirections.front() = rawDirections.front(); for (size_t j = 1; j + 1 < m_nodePositions.size(); ++j) { size_t i = j - 1; - m_nodeForwardDirections[j] = (rawDirections[i] * m_nodeForwardDistances[j] + - rawDirections[j] * m_nodeForwardDistances[i]).normalized(); + m_nodeForwardDirections[j] = (rawDirections[i] * m_nodeForwardDistances[j] + rawDirections[j] * m_nodeForwardDistances[i]).normalized(); } m_nodeForwardDirections.back() = rawDirections.back(); } } } -std::vector TubeMeshBuilder::buildCutFaceVertices(const Vector3 &origin, +std::vector TubeMeshBuilder::buildCutFaceVertices(const Vector3& origin, double radius, - const Vector3 &forwardDirection) + const Vector3& forwardDirection) { std::vector cutFaceVertices(m_buildParameters.cutFace.size()); Vector3 u = m_generatedBaseNormal.rotated(-forwardDirection, m_buildParameters.baseNormalRotation); @@ -171,7 +169,7 @@ std::vector TubeMeshBuilder::buildCutFaceVertices(const Vector3 &origin } } for (size_t i = 0; i < m_buildParameters.cutFace.size(); ++i) { - const auto &t = m_buildParameters.cutFace[i]; + const auto& t = m_buildParameters.cutFace[i]; cutFaceVertices[i] = origin + (uFactor * t.x() + vFactor * t.y()); } return cutFaceVertices; @@ -186,13 +184,11 @@ void TubeMeshBuilder::build() buildNodePositionAndDirections(); - for (const auto &it: m_nodes) + for (const auto& it : m_nodes) m_maxNodeRadius = std::max(m_maxNodeRadius, it.radius); - m_generatedBaseNormal = m_isCircle ? - BaseNormal::calculateCircleBaseNormal(m_nodePositions) : - BaseNormal::calculateTubeBaseNormal(m_nodePositions); - + m_generatedBaseNormal = m_isCircle ? BaseNormal::calculateCircleBaseNormal(m_nodePositions) : BaseNormal::calculateTubeBaseNormal(m_nodePositions); + std::vector> cutFaceIndices(m_nodePositions.size()); for (size_t i = 0; i < m_nodePositions.size(); ++i) { auto cutFaceVertices = buildCutFaceVertices(m_nodePositions[i], @@ -206,8 +202,8 @@ void TubeMeshBuilder::build() } for (size_t j = m_isCircle ? 0 : 1; j < cutFaceIndices.size(); ++j) { size_t i = (j + cutFaceIndices.size() - 1) % cutFaceIndices.size(); - const auto &cutFaceI = cutFaceIndices[i]; - const auto &cutFaceJ = cutFaceIndices[j]; + const auto& cutFaceI = cutFaceIndices[i]; + const auto& cutFaceJ = cutFaceIndices[j]; size_t halfSize = cutFaceI.size() / 2; for (size_t m = 0; m < halfSize; ++m) { size_t n = (m + 1) % cutFaceI.size(); @@ -216,8 +212,7 @@ void TubeMeshBuilder::build() // This will group two points from I, and one point from J as a triangle in the later quad to triangles processing. // If not follow this order, the front triangle and back triangle maybe cross over because of not be parallel. m_generatedFaces.emplace_back(std::vector { - cutFaceI[m], cutFaceI[n], cutFaceJ[n], cutFaceJ[m] - }); + cutFaceI[m], cutFaceI[n], cutFaceJ[n], cutFaceJ[m] }); } for (size_t m = halfSize; m < cutFaceI.size(); ++m) { size_t n = (m + 1) % cutFaceI.size(); @@ -226,8 +221,7 @@ void TubeMeshBuilder::build() // This will group two points from I, and one point from J as a triangle in the later quad to triangles processing. // If not follow this order, the front triangle and back triangle maybe cross over because of not be parallel. m_generatedFaces.emplace_back(std::vector { - cutFaceJ[m], cutFaceI[m], cutFaceI[n], cutFaceJ[n] - }); + cutFaceJ[m], cutFaceI[m], cutFaceI[n], cutFaceJ[n] }); } } if (!m_isCircle) { diff --git a/dust3d/mesh/tube_mesh_builder.h b/dust3d/mesh/tube_mesh_builder.h index d9b03e97..149d61ed 100644 --- a/dust3d/mesh/tube_mesh_builder.h +++ b/dust3d/mesh/tube_mesh_builder.h @@ -28,14 +28,11 @@ #include #include -namespace dust3d -{ +namespace dust3d { -class TubeMeshBuilder -{ +class TubeMeshBuilder { public: - struct BuildParameters - { + struct BuildParameters { std::vector cutFace; double deformThickness = 1.0; double deformWidth = 1.0; @@ -46,11 +43,12 @@ public: bool interpolationEnabled = true; }; - TubeMeshBuilder(const BuildParameters &buildParameters, std::vector &&nodes, bool isCircle); + TubeMeshBuilder(const BuildParameters& buildParameters, std::vector&& nodes, bool isCircle); void build(); - const Vector3 &generatedBaseNormal(); - const std::vector &generatedVertices(); - const std::vector> &generatedFaces(); + const Vector3& generatedBaseNormal(); + const std::vector& generatedVertices(); + const std::vector>& generatedFaces(); + private: BuildParameters m_buildParameters; std::vector m_nodes; @@ -64,9 +62,9 @@ private: double m_maxNodeRadius = 0.0; void preprocessNodes(); void buildNodePositionAndDirections(); - std::vector buildCutFaceVertices(const Vector3 &origin, + std::vector buildCutFaceVertices(const Vector3& origin, double radius, - const Vector3 &forwardDirection); + const Vector3& forwardDirection); void applyRoundEnd(); void applyInterpolation(); }; diff --git a/dust3d/mesh/weld_vertices.cc b/dust3d/mesh/weld_vertices.cc index 8a5b4767..280ce609 100644 --- a/dust3d/mesh/weld_vertices.cc +++ b/dust3d/mesh/weld_vertices.cc @@ -20,17 +20,16 @@ * SOFTWARE. */ -#include -#include -#include #include +#include +#include +#include -namespace dust3d -{ - -size_t weldVertices(const std::vector &sourceVertices, const std::vector> &sourceTriangles, - float allowedSmallestDistance, const std::set &excludePositions, - std::vector &destVertices, std::vector> &destTriangles) +namespace dust3d { + +size_t weldVertices(const std::vector& sourceVertices, const std::vector>& sourceTriangles, + float allowedSmallestDistance, const std::set& excludePositions, + std::vector& destVertices, std::vector>& destTriangles) { std::unordered_set excludeVertices; for (size_t i = 0; i < sourceVertices.size(); ++i) { @@ -44,7 +43,7 @@ size_t weldVertices(const std::vector &sourceVertices, const std::vecto std::map, std::pair> triangleEdgeMap; std::unordered_map vertexAdjFaceCountMap; for (int i = 0; i < (int)sourceTriangles.size(); i++) { - const auto &faceIndices = sourceTriangles[i]; + const auto& faceIndices = sourceTriangles[i]; if (faceIndices.size() == 3) { vertexAdjFaceCountMap[faceIndices[0]]++; vertexAdjFaceCountMap[faceIndices[1]]++; @@ -57,7 +56,7 @@ size_t weldVertices(const std::vector &sourceVertices, const std::vecto for (int i = 0; i < (int)sourceTriangles.size(); i++) { if (processedFaces.find(i) != processedFaces.end()) continue; - const auto &faceIndices = sourceTriangles[i]; + const auto& faceIndices = sourceTriangles[i]; if (faceIndices.size() == 3) { bool indicesSeamCheck[3] = { excludeVertices.find(faceIndices[0]) == excludeVertices.end(), @@ -77,17 +76,13 @@ size_t weldVertices(const std::vector &sourceVertices, const std::vecto continue; } int oppositeFaceIndex = findOppositeFace->second.first; - if (((sourceVertices[edge.first] - sourceVertices[thirdVertexIndex]).lengthSquared() < - (sourceVertices[edge.second] - sourceVertices[thirdVertexIndex]).lengthSquared()) && - vertexAdjFaceCountMap[edge.second] <= 4 && - weldVertexToMap.find(edge.second) == weldVertexToMap.end()) { + if (((sourceVertices[edge.first] - sourceVertices[thirdVertexIndex]).lengthSquared() < (sourceVertices[edge.second] - sourceVertices[thirdVertexIndex]).lengthSquared()) && vertexAdjFaceCountMap[edge.second] <= 4 && weldVertexToMap.find(edge.second) == weldVertexToMap.end()) { weldVertexToMap[edge.second] = edge.first; weldTargetVertices.insert(edge.first); processedFaces.insert(i); processedFaces.insert(oppositeFaceIndex); break; - } else if (vertexAdjFaceCountMap[edge.first] <= 4 && - weldVertexToMap.find(edge.first) == weldVertexToMap.end()) { + } else if (vertexAdjFaceCountMap[edge.first] <= 4 && weldVertexToMap.find(edge.first) == weldVertexToMap.end()) { weldVertexToMap[edge.first] = edge.second; weldTargetVertices.insert(edge.second); processedFaces.insert(i); @@ -103,10 +98,10 @@ size_t weldVertices(const std::vector &sourceVertices, const std::vecto int faceCountAfterWeld = 0; std::map oldToNewVerticesMap; for (int i = 0; i < (int)sourceTriangles.size(); i++) { - const auto &faceIndices = sourceTriangles[i]; + const auto& faceIndices = sourceTriangles[i]; std::vector mappedFaceIndices; bool errored = false; - for (const auto &index: faceIndices) { + for (const auto& index : faceIndices) { int finalIndex = index; int mapTimes = 0; while (mapTimes < 500) { @@ -138,13 +133,13 @@ size_t weldVertices(const std::vector &sourceVertices, const std::vecto } faceCountAfterWeld++; std::vector newFace; - for (const auto &index: mappedFaceIndices) { + for (const auto& index : mappedFaceIndices) { auto findMap = oldToNewVerticesMap.find(index); if (findMap == oldToNewVerticesMap.end()) { size_t newIndex = destVertices.size(); newFace.push_back(newIndex); destVertices.push_back(sourceVertices[index]); - oldToNewVerticesMap.insert({index, newIndex}); + oldToNewVerticesMap.insert({ index, newIndex }); } else { newFace.push_back(findMap->second); } diff --git a/dust3d/mesh/weld_vertices.h b/dust3d/mesh/weld_vertices.h index a5962f9e..c721754d 100644 --- a/dust3d/mesh/weld_vertices.h +++ b/dust3d/mesh/weld_vertices.h @@ -23,17 +23,16 @@ #ifndef DUST3D_MESH_WELD_VERTICES_H_ #define DUST3D_MESH_WELD_VERTICES_H_ -#include -#include #include +#include +#include + +namespace dust3d { + +size_t weldVertices(const std::vector& sourceVertices, const std::vector>& sourceTriangles, + float allowedSmallestDistance, const std::set& excludePositions, + std::vector& destVertices, std::vector>& destTriangles); -namespace dust3d -{ - -size_t weldVertices(const std::vector &sourceVertices, const std::vector> &sourceTriangles, - float allowedSmallestDistance, const std::set &excludePositions, - std::vector &destVertices, std::vector> &destTriangles); - } #endif diff --git a/dust3d/util/obj.cc b/dust3d/util/obj.cc index e660a9a1..d590aa52 100644 --- a/dust3d/util/obj.cc +++ b/dust3d/util/obj.cc @@ -25,73 +25,69 @@ #define TINYOBJLOADER_IMPLEMENTATION #include -namespace dust3d -{ -namespace util -{ +namespace dust3d { +namespace util { -void exportObj(const char *filename, const std::vector &vertices, const std::vector> &faces) -{ - FILE *fp = fopen(filename, "wb"); - for (const auto &it: vertices) { - fprintf(fp, "v %f %f %f\n", it.x(), it.y(), it.z()); - } - for (const auto &it: faces) { - if (it.size() == 2) { - fprintf(fp, "l"); - for (const auto &v: it) + void exportObj(const char* filename, const std::vector& vertices, const std::vector>& faces) + { + FILE* fp = fopen(filename, "wb"); + for (const auto& it : vertices) { + fprintf(fp, "v %f %f %f\n", it.x(), it.y(), it.z()); + } + for (const auto& it : faces) { + if (it.size() == 2) { + fprintf(fp, "l"); + for (const auto& v : it) + fprintf(fp, " %zu", v + 1); + fprintf(fp, "\n"); + continue; + } + fprintf(fp, "f"); + for (const auto& v : it) fprintf(fp, " %zu", v + 1); fprintf(fp, "\n"); - continue; } - fprintf(fp, "f"); - for (const auto &v: it) - fprintf(fp, " %zu", v + 1); - fprintf(fp, "\n"); + fclose(fp); } - fclose(fp); -} -bool loadObj(const std::string &filename, std::vector &outputVertices, std::vector> &outputTriangles) -{ - tinyobj::attrib_t attributes; - std::vector shapes; - std::vector materials; - std::string warn, err; - - bool loadSuccess = tinyobj::LoadObj(&attributes, &shapes, &materials, &warn, &err, filename.c_str()); - if (!warn.empty()) { - std::cout << "WARN:" << warn.c_str() << std::endl; - } - if (!err.empty()) { - std::cout << err.c_str() << std::endl; - } - if (!loadSuccess) { - return false; - } - - outputVertices.resize(attributes.vertices.size() / 3); - for (size_t i = 0, j = 0; i < outputVertices.size(); ++i) { - auto &dest = outputVertices[i]; - dest.setX(attributes.vertices[j++]); - dest.setY(attributes.vertices[j++]); - dest.setZ(attributes.vertices[j++]); - } - - outputTriangles.clear(); - for (const auto &shape: shapes) { - for (size_t i = 0; i < shape.mesh.indices.size(); i += 3) { - outputTriangles.push_back(std::vector { - (size_t)shape.mesh.indices[i + 0].vertex_index, - (size_t)shape.mesh.indices[i + 1].vertex_index, - (size_t)shape.mesh.indices[i + 2].vertex_index - }); + bool loadObj(const std::string& filename, std::vector& outputVertices, std::vector>& outputTriangles) + { + tinyobj::attrib_t attributes; + std::vector shapes; + std::vector materials; + std::string warn, err; + + bool loadSuccess = tinyobj::LoadObj(&attributes, &shapes, &materials, &warn, &err, filename.c_str()); + if (!warn.empty()) { + std::cout << "WARN:" << warn.c_str() << std::endl; } + if (!err.empty()) { + std::cout << err.c_str() << std::endl; + } + if (!loadSuccess) { + return false; + } + + outputVertices.resize(attributes.vertices.size() / 3); + for (size_t i = 0, j = 0; i < outputVertices.size(); ++i) { + auto& dest = outputVertices[i]; + dest.setX(attributes.vertices[j++]); + dest.setY(attributes.vertices[j++]); + dest.setZ(attributes.vertices[j++]); + } + + outputTriangles.clear(); + for (const auto& shape : shapes) { + for (size_t i = 0; i < shape.mesh.indices.size(); i += 3) { + outputTriangles.push_back(std::vector { + (size_t)shape.mesh.indices[i + 0].vertex_index, + (size_t)shape.mesh.indices[i + 1].vertex_index, + (size_t)shape.mesh.indices[i + 2].vertex_index }); + } + } + + return true; } - - return true; -} } } - diff --git a/dust3d/util/obj.h b/dust3d/util/obj.h index 9774cc21..37945bbe 100644 --- a/dust3d/util/obj.h +++ b/dust3d/util/obj.h @@ -19,19 +19,17 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + #ifndef DUST3D_UTIL_OBJ_H_ #define DUST3D_UTIL_OBJ_H_ #include -namespace dust3d -{ -namespace util -{ +namespace dust3d { +namespace util { -void exportObj(const char *filename, const std::vector &vertices, const std::vector> &faces); -bool loadObj(const std::string &filename, std::vector &outputVertices, std::vector> &outputTriangles); + void exportObj(const char* filename, const std::vector& vertices, const std::vector>& faces); + bool loadObj(const std::string& filename, std::vector& outputVertices, std::vector>& outputTriangles); } } diff --git a/dust3d/uv/chart_packer.cc b/dust3d/uv/chart_packer.cc index b604bf33..92c55fb5 100644 --- a/dust3d/uv/chart_packer.cc +++ b/dust3d/uv/chart_packer.cc @@ -24,95 +24,93 @@ #include #include -namespace dust3d -{ -namespace uv -{ - -void ChartPacker::setCharts(const std::vector> &chartSizes) -{ - m_chartSizes = chartSizes; -} +namespace dust3d { +namespace uv { -const std::vector> &ChartPacker::getResult() -{ - return m_result; -} - -double ChartPacker::calculateTotalArea() -{ - double totalArea = 0; - for (const auto &chartSize: m_chartSizes) { - totalArea += chartSize.first * chartSize.second; + void ChartPacker::setCharts(const std::vector>& chartSizes) + { + m_chartSizes = chartSizes; } - return totalArea; -} -bool ChartPacker::tryPack(float textureSize) -{ - std::vector rects; - int width = textureSize * m_floatToIntFactor; - int height = width; - float paddingSize = m_paddingSize * width; - float paddingSize2 = paddingSize + paddingSize; - for (const auto &chartSize: m_chartSizes) { - MaxRectanglesSize r; - r.width = chartSize.first * m_floatToIntFactor + paddingSize2; - r.height = chartSize.second * m_floatToIntFactor + paddingSize2; - rects.push_back(r); + const std::vector>& ChartPacker::getResult() + { + return m_result; } - const MaxRectanglesFreeRectChoiceHeuristic methods[] = { - kMaxRectanglesBestShortSideFit, - kMaxRectanglesBestLongSideFit, - kMaxRectanglesBestAreaFit, - kMaxRectanglesBottomLeftRule, - kMaxRectanglesContactPointRule - }; - float occupancy = 0; - float bestOccupancy = 0; - std::vector bestResult; - for (size_t i = 0; i < sizeof(methods) / sizeof(methods[0]); ++i) { - std::vector result(rects.size()); - if (0 != maxRectangles(width, height, rects.size(), rects.data(), methods[i], true, result.data(), &occupancy)) { - continue; - } - if (occupancy > bestOccupancy) { - bestResult = result; - bestOccupancy = occupancy; + + double ChartPacker::calculateTotalArea() + { + double totalArea = 0; + for (const auto& chartSize : m_chartSizes) { + totalArea += chartSize.first * chartSize.second; } + return totalArea; } - if (bestResult.size() != rects.size()) - return false; - m_result.resize(bestResult.size()); - for (decltype(bestResult.size()) i = 0; i < bestResult.size(); ++i) { - const auto &result = bestResult[i]; - const auto &rect = rects[i]; - auto &dest = m_result[i]; - std::get<0>(dest) = (float)(result.left + paddingSize) / width; - std::get<1>(dest) = (float)(result.top + paddingSize) / height; - std::get<2>(dest) = (float)(rect.width - paddingSize2) / width; - std::get<3>(dest) = (float)(rect.height - paddingSize2) / height; - std::get<4>(dest) = result.rotated; - } - return true; -} -float ChartPacker::pack() -{ - float textureSize = 0; - float initialGuessSize = std::sqrt(calculateTotalArea() * m_initialAreaGuessFactor); - while (true) { - textureSize = initialGuessSize * m_textureSizeFactor; - ++m_tryNum; - if (tryPack(textureSize)) - break; - m_textureSizeFactor += m_textureSizeGrowFactor; - if (m_tryNum >= m_maxTryNum) { - break; + bool ChartPacker::tryPack(float textureSize) + { + std::vector rects; + int width = textureSize * m_floatToIntFactor; + int height = width; + float paddingSize = m_paddingSize * width; + float paddingSize2 = paddingSize + paddingSize; + for (const auto& chartSize : m_chartSizes) { + MaxRectanglesSize r; + r.width = chartSize.first * m_floatToIntFactor + paddingSize2; + r.height = chartSize.second * m_floatToIntFactor + paddingSize2; + rects.push_back(r); } + const MaxRectanglesFreeRectChoiceHeuristic methods[] = { + kMaxRectanglesBestShortSideFit, + kMaxRectanglesBestLongSideFit, + kMaxRectanglesBestAreaFit, + kMaxRectanglesBottomLeftRule, + kMaxRectanglesContactPointRule + }; + float occupancy = 0; + float bestOccupancy = 0; + std::vector bestResult; + for (size_t i = 0; i < sizeof(methods) / sizeof(methods[0]); ++i) { + std::vector result(rects.size()); + if (0 != maxRectangles(width, height, rects.size(), rects.data(), methods[i], true, result.data(), &occupancy)) { + continue; + } + if (occupancy > bestOccupancy) { + bestResult = result; + bestOccupancy = occupancy; + } + } + if (bestResult.size() != rects.size()) + return false; + m_result.resize(bestResult.size()); + for (decltype(bestResult.size()) i = 0; i < bestResult.size(); ++i) { + const auto& result = bestResult[i]; + const auto& rect = rects[i]; + auto& dest = m_result[i]; + std::get<0>(dest) = (float)(result.left + paddingSize) / width; + std::get<1>(dest) = (float)(result.top + paddingSize) / height; + std::get<2>(dest) = (float)(rect.width - paddingSize2) / width; + std::get<3>(dest) = (float)(rect.height - paddingSize2) / height; + std::get<4>(dest) = result.rotated; + } + return true; + } + + float ChartPacker::pack() + { + float textureSize = 0; + float initialGuessSize = std::sqrt(calculateTotalArea() * m_initialAreaGuessFactor); + while (true) { + textureSize = initialGuessSize * m_textureSizeFactor; + ++m_tryNum; + if (tryPack(textureSize)) + break; + m_textureSizeFactor += m_textureSizeGrowFactor; + if (m_tryNum >= m_maxTryNum) { + break; + } + } + return textureSize; } - return textureSize; -} } } diff --git a/dust3d/uv/chart_packer.h b/dust3d/uv/chart_packer.h index c395ff31..522e8d5c 100644 --- a/dust3d/uv/chart_packer.h +++ b/dust3d/uv/chart_packer.h @@ -23,39 +23,35 @@ #ifndef DUST3D_UV_CHART_PACKER_H_ #define DUST3D_UV_CHART_PACKER_H_ -#include #include #include +#include -namespace dust3d -{ -namespace uv -{ - -class ChartPacker -{ -public: - void setCharts(const std::vector> &chartSizes); - const std::vector> &getResult(); - float pack(); - bool tryPack(float textureSize); +namespace dust3d { +namespace uv { -private: - double calculateTotalArea(); + class ChartPacker { + public: + void setCharts(const std::vector>& chartSizes); + const std::vector>& getResult(); + float pack(); + bool tryPack(float textureSize); - std::vector> m_chartSizes; - std::vector> m_result; - float m_initialAreaGuessFactor = 1.1; - float m_textureSizeGrowFactor = 0.05; - float m_floatToIntFactor = 10000; - size_t m_tryNum = 0; - float m_textureSizeFactor = 1.0; - float m_paddingSize = 0.005; - size_t m_maxTryNum = 100; -}; + private: + double calculateTotalArea(); + + std::vector> m_chartSizes; + std::vector> m_result; + float m_initialAreaGuessFactor = 1.1; + float m_textureSizeGrowFactor = 0.05; + float m_floatToIntFactor = 10000; + size_t m_tryNum = 0; + float m_textureSizeFactor = 1.0; + float m_paddingSize = 0.005; + size_t m_maxTryNum = 100; + }; } } #endif - diff --git a/dust3d/uv/max_rectangles.cc b/dust3d/uv/max_rectangles.cc index 6830ca9d..de5f8f88 100644 --- a/dust3d/uv/max_rectangles.cc +++ b/dust3d/uv/max_rectangles.cc @@ -28,472 +28,455 @@ * */ -#include -#include -#include -#include #include #include +#include +#include +#include +#include + +namespace dust3d { +namespace uv { -namespace dust3d -{ -namespace uv -{ - #ifdef MAX -# undef MAX +#undef MAX #endif -#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) #ifdef MIN -# undef MIN +#undef MIN #endif -#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) -typedef struct MaxRectanglesRect -{ - struct MaxRectanglesRect *next; - struct MaxRectanglesRect *prev; - int rectOrder; - int x; - int y; - int width; - int height; - int inFreeRectLink: 1; - int inUsedRectLink: 1; - int inInputRectLink: 1; -} MaxRectanglesRect; + typedef struct MaxRectanglesRect { + struct MaxRectanglesRect* next; + struct MaxRectanglesRect* prev; + int rectOrder; + int x; + int y; + int width; + int height; + int inFreeRectLink : 1; + int inUsedRectLink : 1; + int inInputRectLink : 1; + } MaxRectanglesRect; -typedef struct MaxRectanglesContext -{ - int width; - int height; - int rectCount; - MaxRectanglesSize *rects; - MaxRectanglesPosition *layoutResults; - enum MaxRectanglesFreeRectChoiceHeuristic method; - int allowRotations: 1; - MaxRectanglesRect *freeRectLink; - MaxRectanglesRect *usedRectLink; - MaxRectanglesRect *inputRectLink; -} MaxRectanglesContext; + typedef struct MaxRectanglesContext { + int width; + int height; + int rectCount; + MaxRectanglesSize* rects; + MaxRectanglesPosition* layoutResults; + enum MaxRectanglesFreeRectChoiceHeuristic method; + int allowRotations : 1; + MaxRectanglesRect* freeRectLink; + MaxRectanglesRect* usedRectLink; + MaxRectanglesRect* inputRectLink; + } MaxRectanglesContext; -static void addRectToLink(MaxRectanglesRect *rect, MaxRectanglesRect **link) -{ - rect->prev = 0; - rect->next = *link; - if (*link) { - (*link)->prev = rect; - } - *link = rect; -} - -static void freeRectOnLine(MaxRectanglesRect *rect, long line) -{ - free(rect); -} - -#define freeRect(rect) freeRectOnLine((rect), __LINE__) - -static void removeRectFromLink(MaxRectanglesRect *rect, MaxRectanglesRect **link) -{ - if (rect->prev) { - rect->prev->next = rect->next; - } - if (rect->next) { - rect->next->prev = rect->prev; - } - if (rect == *link) { - *link = rect->next; - } - freeRect(rect); -} - -static void freeLink(MaxRectanglesRect **link) -{ - while (*link) { - MaxRectanglesRect *willDel = *link; - *link = willDel->next; - freeRect(willDel); - } -} - -static void addRectToFreeRectLinkOnLine(MaxRectanglesContext *ctx, - MaxRectanglesRect *rect, long line) -{ - assert(!rect->inInputRectLink && !rect->inFreeRectLink && - !rect->inUsedRectLink); - rect->inFreeRectLink = 1; - addRectToLink(rect, &ctx->freeRectLink); -} - -#define addRectToFreeRectLink(ctx, rect) addRectToFreeRectLinkOnLine((ctx), (rect), __LINE__) - -static void addRectToUsedRectLink(MaxRectanglesContext *ctx, MaxRectanglesRect *rect) -{ - assert(!rect->inInputRectLink && !rect->inFreeRectLink && - !rect->inUsedRectLink); - rect->inUsedRectLink = 1; - addRectToLink(rect, &ctx->usedRectLink); -} - -static void addRectToInputRectLink(MaxRectanglesContext *ctx, MaxRectanglesRect *rect) -{ - assert(!rect->inInputRectLink && !rect->inFreeRectLink && - !rect->inUsedRectLink); - rect->inInputRectLink = 1; - addRectToLink(rect, &ctx->inputRectLink); -} - -static void removeAndFreeRectFromUsedRectLink(MaxRectanglesContext *ctx, - MaxRectanglesRect *rect) -{ - assert(rect->inUsedRectLink); - rect->inUsedRectLink = 0; - removeRectFromLink(rect, &ctx->usedRectLink); -} - -static void removeAndFreeRectFromFreeRectLink(MaxRectanglesContext *ctx, - MaxRectanglesRect *rect) -{ - assert(rect->inFreeRectLink); - rect->inFreeRectLink = 0; - removeRectFromLink(rect, &ctx->freeRectLink); -} - -static void removeAndFreeRectFromInputRectLink(MaxRectanglesContext *ctx, - MaxRectanglesRect *rect) -{ - assert(rect->inInputRectLink); - rect->inInputRectLink = 0; - removeRectFromLink(rect, &ctx->inputRectLink); -} - -static MaxRectanglesRect *createRectOnLine(int x, int y, int width, int height, - int rectOrder, long line) -{ - MaxRectanglesRect *rect = (MaxRectanglesRect*) calloc(1, sizeof(MaxRectanglesRect)); - if (!rect) { - return 0; - } - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; - rect->rectOrder = rectOrder; - return rect; -} - -#define createRect(x, y, width, height, rectOrder) createRectOnLine((x), (y), (width), (height), (rectOrder), __LINE__) - -MaxRectanglesRect *findPositionForNewNodeBottomLeft(MaxRectanglesContext *ctx, - int width, int height, int *bestY, int *bestX) -{ - MaxRectanglesRect * loop; - MaxRectanglesRect *bestNode = createRect(0, 0, 0, 0, 0); - if (!bestNode) { - return 0; - } - - *bestY = INT_MAX; - - for (loop = ctx->freeRectLink; loop; loop = loop->next) { - // Try to place the rectangle in upright (non-flipped) orientation. - if (loop->width >= width && loop->height >= height) { - int topSideY = (int) loop->y + height; - if (topSideY<*bestY || (topSideY == *bestY && loop->x<*bestX)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = width; - bestNode->height = height; - *bestY = topSideY; - *bestX = (int) loop->x; - } + static void addRectToLink(MaxRectanglesRect* rect, MaxRectanglesRect** link) + { + rect->prev = 0; + rect->next = *link; + if (*link) { + (*link)->prev = rect; } - if (ctx->allowRotations && loop->width >= height && loop->height >= width) { - int topSideY = (int) loop->y + width; - if (topSideY<*bestY || (topSideY == *bestY && loop->x<*bestX)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = height; - bestNode->height = width; - *bestY = topSideY; - *bestX = (int) loop->x; - } + *link = rect; + } + + static void freeRectOnLine(MaxRectanglesRect* rect, long line) + { + free(rect); + } + +#define freeRect(rect) freeRectOnLine((rect), __LINE__) + + static void removeRectFromLink(MaxRectanglesRect* rect, MaxRectanglesRect** link) + { + if (rect->prev) { + rect->prev->next = rect->next; + } + if (rect->next) { + rect->next->prev = rect->prev; + } + if (rect == *link) { + *link = rect->next; + } + freeRect(rect); + } + + static void freeLink(MaxRectanglesRect** link) + { + while (*link) { + MaxRectanglesRect* willDel = *link; + *link = willDel->next; + freeRect(willDel); } } - return bestNode; -} -MaxRectanglesRect *findPositionForNewNodeBestShortSideFit(MaxRectanglesContext *ctx, - int width, int height, int *bestShortSideFit, int *bestLongSideFit) -{ - MaxRectanglesRect *loop; - MaxRectanglesRect *bestNode = createRect(0, 0, 0, 0, 0); - if (!bestNode) { - return 0; + static void addRectToFreeRectLinkOnLine(MaxRectanglesContext* ctx, + MaxRectanglesRect* rect, long line) + { + assert(!rect->inInputRectLink && !rect->inFreeRectLink && !rect->inUsedRectLink); + rect->inFreeRectLink = 1; + addRectToLink(rect, &ctx->freeRectLink); } - *bestShortSideFit = INT_MAX; +#define addRectToFreeRectLink(ctx, rect) addRectToFreeRectLinkOnLine((ctx), (rect), __LINE__) - for (loop = ctx->freeRectLink; loop; loop = loop->next) { - // Try to place the rectangle in upright (non-flipped) orientation. - if (loop->width >= width && loop->height >= height) { - int leftoverHoriz = abs((int) loop->width - width); - int leftoverVert = abs((int) loop->height - height); - int shortSideFit = MIN(leftoverHoriz, leftoverVert); - int longSideFit = MAX(leftoverHoriz, leftoverVert); + static void addRectToUsedRectLink(MaxRectanglesContext* ctx, MaxRectanglesRect* rect) + { + assert(!rect->inInputRectLink && !rect->inFreeRectLink && !rect->inUsedRectLink); + rect->inUsedRectLink = 1; + addRectToLink(rect, &ctx->usedRectLink); + } - if (shortSideFit<*bestShortSideFit || - (shortSideFit == *bestShortSideFit && - longSideFit<*bestLongSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = width; - bestNode->height = height; - *bestShortSideFit = shortSideFit; - *bestLongSideFit = longSideFit; - } + static void addRectToInputRectLink(MaxRectanglesContext* ctx, MaxRectanglesRect* rect) + { + assert(!rect->inInputRectLink && !rect->inFreeRectLink && !rect->inUsedRectLink); + rect->inInputRectLink = 1; + addRectToLink(rect, &ctx->inputRectLink); + } + + static void removeAndFreeRectFromUsedRectLink(MaxRectanglesContext* ctx, + MaxRectanglesRect* rect) + { + assert(rect->inUsedRectLink); + rect->inUsedRectLink = 0; + removeRectFromLink(rect, &ctx->usedRectLink); + } + + static void removeAndFreeRectFromFreeRectLink(MaxRectanglesContext* ctx, + MaxRectanglesRect* rect) + { + assert(rect->inFreeRectLink); + rect->inFreeRectLink = 0; + removeRectFromLink(rect, &ctx->freeRectLink); + } + + static void removeAndFreeRectFromInputRectLink(MaxRectanglesContext* ctx, + MaxRectanglesRect* rect) + { + assert(rect->inInputRectLink); + rect->inInputRectLink = 0; + removeRectFromLink(rect, &ctx->inputRectLink); + } + + static MaxRectanglesRect* createRectOnLine(int x, int y, int width, int height, + int rectOrder, long line) + { + MaxRectanglesRect* rect = (MaxRectanglesRect*)calloc(1, sizeof(MaxRectanglesRect)); + if (!rect) { + return 0; + } + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + rect->rectOrder = rectOrder; + return rect; + } + +#define createRect(x, y, width, height, rectOrder) createRectOnLine((x), (y), (width), (height), (rectOrder), __LINE__) + + MaxRectanglesRect* findPositionForNewNodeBottomLeft(MaxRectanglesContext* ctx, + int width, int height, int* bestY, int* bestX) + { + MaxRectanglesRect* loop; + MaxRectanglesRect* bestNode = createRect(0, 0, 0, 0, 0); + if (!bestNode) { + return 0; } - if (ctx->allowRotations && loop->width >= height && loop->height >= width) { - int flippedLeftoverHoriz = abs((int) loop->width - height); - int flippedLeftoverVert = abs((int) loop->height - width); - int flippedShortSideFit = MIN(flippedLeftoverHoriz, flippedLeftoverVert); - int flippedLongSideFit = MAX(flippedLeftoverHoriz, flippedLeftoverVert); + *bestY = INT_MAX; - if (flippedShortSideFit<*bestShortSideFit || - (flippedShortSideFit == *bestShortSideFit && - flippedLongSideFit<*bestLongSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = height; - bestNode->height = width; - *bestShortSideFit = flippedShortSideFit; - *bestLongSideFit = flippedLongSideFit; + for (loop = ctx->freeRectLink; loop; loop = loop->next) { + // Try to place the rectangle in upright (non-flipped) orientation. + if (loop->width >= width && loop->height >= height) { + int topSideY = (int)loop->y + height; + if (topSideY < *bestY || (topSideY == *bestY && loop->x < *bestX)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = width; + bestNode->height = height; + *bestY = topSideY; + *bestX = (int)loop->x; + } + } + if (ctx->allowRotations && loop->width >= height && loop->height >= width) { + int topSideY = (int)loop->y + width; + if (topSideY < *bestY || (topSideY == *bestY && loop->x < *bestX)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = height; + bestNode->height = width; + *bestY = topSideY; + *bestX = (int)loop->x; + } } } - } - return bestNode; -} - -MaxRectanglesRect *findPositionForNewNodeBestLongSideFit(MaxRectanglesContext *ctx, - int width, int height, int *bestShortSideFit, int *bestLongSideFit) -{ - MaxRectanglesRect * loop; - MaxRectanglesRect *bestNode = createRect(0, 0, 0, 0, 0); - if (!bestNode) { - return 0; + return bestNode; } - *bestLongSideFit = INT_MAX; - - for (loop = ctx->freeRectLink; loop; loop = loop->next) { - // Try to place the rectangle in upright (non-flipped) orientation. - if (loop->width >= width && loop->height >= height) { - int leftoverHoriz = abs((int) loop->width - width); - int leftoverVert = abs((int) loop->height - height); - int shortSideFit = MIN(leftoverHoriz, leftoverVert); - int longSideFit = MAX(leftoverHoriz, leftoverVert); - - if (longSideFit<*bestLongSideFit || - (longSideFit == *bestLongSideFit && - shortSideFit<*bestShortSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = width; - bestNode->height = height; - *bestShortSideFit = shortSideFit; - *bestLongSideFit = longSideFit; - } + MaxRectanglesRect* findPositionForNewNodeBestShortSideFit(MaxRectanglesContext* ctx, + int width, int height, int* bestShortSideFit, int* bestLongSideFit) + { + MaxRectanglesRect* loop; + MaxRectanglesRect* bestNode = createRect(0, 0, 0, 0, 0); + if (!bestNode) { + return 0; } - if (ctx->allowRotations && loop->width >= height && loop->height >= width) { - int leftoverHoriz = abs((int) loop->width - height); - int leftoverVert = abs((int) loop->height - width); - int shortSideFit = MIN(leftoverHoriz, leftoverVert); - int longSideFit = MAX(leftoverHoriz, leftoverVert); + *bestShortSideFit = INT_MAX; - if (longSideFit<*bestLongSideFit || - (longSideFit == *bestLongSideFit && - shortSideFit<*bestShortSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = height; - bestNode->height = width; - *bestShortSideFit = shortSideFit; - *bestLongSideFit = longSideFit; + for (loop = ctx->freeRectLink; loop; loop = loop->next) { + // Try to place the rectangle in upright (non-flipped) orientation. + if (loop->width >= width && loop->height >= height) { + int leftoverHoriz = abs((int)loop->width - width); + int leftoverVert = abs((int)loop->height - height); + int shortSideFit = MIN(leftoverHoriz, leftoverVert); + int longSideFit = MAX(leftoverHoriz, leftoverVert); + + if (shortSideFit < *bestShortSideFit || (shortSideFit == *bestShortSideFit && longSideFit < *bestLongSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = width; + bestNode->height = height; + *bestShortSideFit = shortSideFit; + *bestLongSideFit = longSideFit; + } + } + + if (ctx->allowRotations && loop->width >= height && loop->height >= width) { + int flippedLeftoverHoriz = abs((int)loop->width - height); + int flippedLeftoverVert = abs((int)loop->height - width); + int flippedShortSideFit = MIN(flippedLeftoverHoriz, flippedLeftoverVert); + int flippedLongSideFit = MAX(flippedLeftoverHoriz, flippedLeftoverVert); + + if (flippedShortSideFit < *bestShortSideFit || (flippedShortSideFit == *bestShortSideFit && flippedLongSideFit < *bestLongSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = height; + bestNode->height = width; + *bestShortSideFit = flippedShortSideFit; + *bestLongSideFit = flippedLongSideFit; + } } } - } - return bestNode; -} - -MaxRectanglesRect *findPositionForNewNodeBestAreaFit(MaxRectanglesContext *ctx, - int width, int height, int *bestAreaFit, int *bestShortSideFit) -{ - MaxRectanglesRect * loop; - MaxRectanglesRect *bestNode = createRect(0, 0, 0, 0, 0); - if (!bestNode) { - return 0; + return bestNode; } - *bestAreaFit = INT_MAX; - - for (loop = ctx->freeRectLink; loop; loop = loop->next) { - int areaFit = (int) loop->width *(int) loop->height - width * height; - - // Try to place the rectangle in upright (non-flipped) orientation. - if (loop->width >= width && loop->height >= height) { - int leftoverHoriz = abs((int) loop->width - width); - int leftoverVert = abs((int) loop->height - height); - int shortSideFit = MIN(leftoverHoriz, leftoverVert); - - if (areaFit<*bestAreaFit || - (areaFit == *bestAreaFit && shortSideFit<*bestShortSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = width; - bestNode->height = height; - *bestShortSideFit = shortSideFit; - *bestAreaFit = areaFit; - } + MaxRectanglesRect* findPositionForNewNodeBestLongSideFit(MaxRectanglesContext* ctx, + int width, int height, int* bestShortSideFit, int* bestLongSideFit) + { + MaxRectanglesRect* loop; + MaxRectanglesRect* bestNode = createRect(0, 0, 0, 0, 0); + if (!bestNode) { + return 0; } - if (ctx->allowRotations && loop->width >= height && loop->height >= width) { - int leftoverHoriz = abs((int) loop->width - height); - int leftoverVert = abs((int) loop->height - width); - int shortSideFit = MIN(leftoverHoriz, leftoverVert); + *bestLongSideFit = INT_MAX; - if (areaFit<*bestAreaFit || - (areaFit == *bestAreaFit && shortSideFit<*bestShortSideFit)) { - bestNode->x = loop->x; - bestNode->y = loop->y; - bestNode->width = height; - bestNode->height = width; - *bestShortSideFit = shortSideFit; - *bestAreaFit = areaFit; + for (loop = ctx->freeRectLink; loop; loop = loop->next) { + // Try to place the rectangle in upright (non-flipped) orientation. + if (loop->width >= width && loop->height >= height) { + int leftoverHoriz = abs((int)loop->width - width); + int leftoverVert = abs((int)loop->height - height); + int shortSideFit = MIN(leftoverHoriz, leftoverVert); + int longSideFit = MAX(leftoverHoriz, leftoverVert); + + if (longSideFit < *bestLongSideFit || (longSideFit == *bestLongSideFit && shortSideFit < *bestShortSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = width; + bestNode->height = height; + *bestShortSideFit = shortSideFit; + *bestLongSideFit = longSideFit; + } + } + + if (ctx->allowRotations && loop->width >= height && loop->height >= width) { + int leftoverHoriz = abs((int)loop->width - height); + int leftoverVert = abs((int)loop->height - width); + int shortSideFit = MIN(leftoverHoriz, leftoverVert); + int longSideFit = MAX(leftoverHoriz, leftoverVert); + + if (longSideFit < *bestLongSideFit || (longSideFit == *bestLongSideFit && shortSideFit < *bestShortSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = height; + bestNode->height = width; + *bestShortSideFit = shortSideFit; + *bestLongSideFit = longSideFit; + } } } - } - return bestNode; -} - -/// Returns 0 if the two intervals i1 and i2 are disjoint, or the length of their overlap otherwise. -static int commonIntervalLength(int i1start, int i1end, - int i2start, int i2end) -{ - if (i1end < i2start || i2end < i1start) - return 0; - return MIN(i1end, i2end) - MAX(i1start, i2start); -} - -static int contactPointScoreNode(MaxRectanglesContext *ctx, int x, int y, - int width, int height) -{ - MaxRectanglesRect * loop; - int score = 0; - - if (x == 0 || x + width == ctx->width) - score += height; - if (y == 0 || y + height == ctx->height) - score += width; - - for (loop = ctx->usedRectLink; loop; loop = loop->next) { - if (loop->x == x + width || loop->x + loop->width == x) - score += commonIntervalLength((int) loop->y, - (int) loop->y + (int) loop->height, - y, y + height); - if (loop->y == y + height || loop->y + loop->height == y) - score += commonIntervalLength((int) loop->x, - (int) loop->x + (int) loop->width, x, x + width); - } - return score; -} - -MaxRectanglesRect *findPositionForNewNodeContactPoint(MaxRectanglesContext *ctx, - int width, int height, int *bestContactScore) -{ - MaxRectanglesRect * loop; - MaxRectanglesRect *bestNode = createRect(0, 0, 0, 0, 0); - if (!bestNode) { - return 0; + return bestNode; } - *bestContactScore = -1; + MaxRectanglesRect* findPositionForNewNodeBestAreaFit(MaxRectanglesContext* ctx, + int width, int height, int* bestAreaFit, int* bestShortSideFit) + { + MaxRectanglesRect* loop; + MaxRectanglesRect* bestNode = createRect(0, 0, 0, 0, 0); + if (!bestNode) { + return 0; + } - for (loop = ctx->freeRectLink; loop; loop = loop->next) { - // Try to place the rectangle in upright (non-flipped) orientation. - if (loop->width >= width && loop->height >= height) { - int score = contactPointScoreNode(ctx, (int) loop->x, (int) loop->y, - width, height); - if (score > *bestContactScore) { - bestNode->x = (int) loop->x; - bestNode->y = (int) loop->y; - bestNode->width = width; - bestNode->height = height; - *bestContactScore = score; + *bestAreaFit = INT_MAX; + + for (loop = ctx->freeRectLink; loop; loop = loop->next) { + int areaFit = (int)loop->width * (int)loop->height - width * height; + + // Try to place the rectangle in upright (non-flipped) orientation. + if (loop->width >= width && loop->height >= height) { + int leftoverHoriz = abs((int)loop->width - width); + int leftoverVert = abs((int)loop->height - height); + int shortSideFit = MIN(leftoverHoriz, leftoverVert); + + if (areaFit < *bestAreaFit || (areaFit == *bestAreaFit && shortSideFit < *bestShortSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = width; + bestNode->height = height; + *bestShortSideFit = shortSideFit; + *bestAreaFit = areaFit; + } + } + + if (ctx->allowRotations && loop->width >= height && loop->height >= width) { + int leftoverHoriz = abs((int)loop->width - height); + int leftoverVert = abs((int)loop->height - width); + int shortSideFit = MIN(leftoverHoriz, leftoverVert); + + if (areaFit < *bestAreaFit || (areaFit == *bestAreaFit && shortSideFit < *bestShortSideFit)) { + bestNode->x = loop->x; + bestNode->y = loop->y; + bestNode->width = height; + bestNode->height = width; + *bestShortSideFit = shortSideFit; + *bestAreaFit = areaFit; + } } } - if (ctx->allowRotations && loop->width >= height && loop->height >= width) { - int score = contactPointScoreNode(ctx, (int) loop->x, (int) loop->y, - height, width); - if (score > *bestContactScore) { - bestNode->x = (int) loop->x; - bestNode->y = (int) loop->y; - bestNode->width = height; - bestNode->height = width; - *bestContactScore = score; + return bestNode; + } + + /// Returns 0 if the two intervals i1 and i2 are disjoint, or the length of their overlap otherwise. + static int commonIntervalLength(int i1start, int i1end, + int i2start, int i2end) + { + if (i1end < i2start || i2end < i1start) + return 0; + return MIN(i1end, i2end) - MAX(i1start, i2start); + } + + static int contactPointScoreNode(MaxRectanglesContext* ctx, int x, int y, + int width, int height) + { + MaxRectanglesRect* loop; + int score = 0; + + if (x == 0 || x + width == ctx->width) + score += height; + if (y == 0 || y + height == ctx->height) + score += width; + + for (loop = ctx->usedRectLink; loop; loop = loop->next) { + if (loop->x == x + width || loop->x + loop->width == x) + score += commonIntervalLength((int)loop->y, + (int)loop->y + (int)loop->height, + y, y + height); + if (loop->y == y + height || loop->y + loop->height == y) + score += commonIntervalLength((int)loop->x, + (int)loop->x + (int)loop->width, x, x + width); + } + return score; + } + + MaxRectanglesRect* findPositionForNewNodeContactPoint(MaxRectanglesContext* ctx, + int width, int height, int* bestContactScore) + { + MaxRectanglesRect* loop; + MaxRectanglesRect* bestNode = createRect(0, 0, 0, 0, 0); + if (!bestNode) { + return 0; + } + + *bestContactScore = -1; + + for (loop = ctx->freeRectLink; loop; loop = loop->next) { + // Try to place the rectangle in upright (non-flipped) orientation. + if (loop->width >= width && loop->height >= height) { + int score = contactPointScoreNode(ctx, (int)loop->x, (int)loop->y, + width, height); + if (score > *bestContactScore) { + bestNode->x = (int)loop->x; + bestNode->y = (int)loop->y; + bestNode->width = width; + bestNode->height = height; + *bestContactScore = score; + } + } + if (ctx->allowRotations && loop->width >= height && loop->height >= width) { + int score = contactPointScoreNode(ctx, (int)loop->x, (int)loop->y, + height, width); + if (score > *bestContactScore) { + bestNode->x = (int)loop->x; + bestNode->y = (int)loop->y; + bestNode->width = height; + bestNode->height = width; + *bestContactScore = score; + } } } + return bestNode; } - return bestNode; -} -static int initContext(MaxRectanglesContext *ctx) -{ - int i; - MaxRectanglesRect *newRect = createRect(0, 0, ctx->width, ctx->height, 0); - if (!newRect) { - return -1; - } - addRectToFreeRectLink(ctx, newRect); - for (i = 0; i < ctx->rectCount; ++i) { - newRect = createRect(0, 0, ctx->rects[i].width, - ctx->rects[i].height, i + 1); + static int initContext(MaxRectanglesContext* ctx) + { + int i; + MaxRectanglesRect* newRect = createRect(0, 0, ctx->width, ctx->height, 0); if (!newRect) { return -1; } - addRectToInputRectLink(ctx, newRect); + addRectToFreeRectLink(ctx, newRect); + for (i = 0; i < ctx->rectCount; ++i) { + newRect = createRect(0, 0, ctx->rects[i].width, + ctx->rects[i].height, i + 1); + if (!newRect) { + return -1; + } + addRectToInputRectLink(ctx, newRect); + } + return 0; } - return 0; -} -static void releaseContext(MaxRectanglesContext *ctx) -{ - freeLink(&ctx->usedRectLink); - freeLink(&ctx->freeRectLink); - freeLink(&ctx->inputRectLink); -} - -static float getOccupany(MaxRectanglesContext *ctx) -{ - unsigned long long usedSurfaceArea = 0; - MaxRectanglesRect *loop = ctx->usedRectLink; - while (loop) { - usedSurfaceArea += loop->width *loop->height; - loop = loop->next; + static void releaseContext(MaxRectanglesContext* ctx) + { + freeLink(&ctx->usedRectLink); + freeLink(&ctx->freeRectLink); + freeLink(&ctx->inputRectLink); } - return (float) usedSurfaceArea / (ctx->width *ctx->height); -} -MaxRectanglesRect *scoreRect(MaxRectanglesContext *ctx, int width, int height, - enum MaxRectanglesFreeRectChoiceHeuristic method, int *score1, int *score2) -{ - MaxRectanglesRect *newNode = 0; - *score1 = INT_MAX; - *score2 = INT_MAX; - switch (method) { + static float getOccupany(MaxRectanglesContext* ctx) + { + unsigned long long usedSurfaceArea = 0; + MaxRectanglesRect* loop = ctx->usedRectLink; + while (loop) { + usedSurfaceArea += loop->width * loop->height; + loop = loop->next; + } + return (float)usedSurfaceArea / (ctx->width * ctx->height); + } + + MaxRectanglesRect* scoreRect(MaxRectanglesContext* ctx, int width, int height, + enum MaxRectanglesFreeRectChoiceHeuristic method, int* score1, int* score2) + { + MaxRectanglesRect* newNode = 0; + *score1 = INT_MAX; + *score2 = INT_MAX; + switch (method) { case kMaxRectanglesBestShortSideFit: newNode = findPositionForNewNodeBestShortSideFit(ctx, width, height, score1, score2); @@ -504,7 +487,7 @@ MaxRectanglesRect *scoreRect(MaxRectanglesContext *ctx, int width, int height, break; case kMaxRectanglesContactPointRule: newNode = findPositionForNewNodeContactPoint(ctx, width, height, score1); - *score1 = - *score1; // Reverse since we are minimizing, but for contact point score bigger is better. + *score1 = -*score1; // Reverse since we are minimizing, but for contact point score bigger is better. break; case kMaxRectanglesBestLongSideFit: newNode = findPositionForNewNodeBestLongSideFit(ctx, width, height, @@ -514,225 +497,214 @@ MaxRectanglesRect *scoreRect(MaxRectanglesContext *ctx, int width, int height, newNode = findPositionForNewNodeBestAreaFit(ctx, width, height, score1, score2); break; + } + + // Cannot fit the current rectangle. + if (!newNode || 0 == newNode->height) { + *score1 = INT_MAX; + *score2 = INT_MAX; + } + + return newNode; } - // Cannot fit the current rectangle. - if (!newNode || 0 == newNode->height) { - *score1 = INT_MAX; - *score2 = INT_MAX; + int splitFreeNode(MaxRectanglesContext* ctx, MaxRectanglesRect* freeNode, + MaxRectanglesRect* usedNode) + { + // Test with SAT if the rectangles even intersect. + if (usedNode->x >= freeNode->x + freeNode->width || usedNode->x + usedNode->width <= freeNode->x || usedNode->y >= freeNode->y + freeNode->height || usedNode->y + usedNode->height <= freeNode->y) { + return 0; + } + + if (usedNode->x < freeNode->x + freeNode->width && usedNode->x + usedNode->width > freeNode->x) { + // New node at the top side of the used node. + if (usedNode->y > freeNode->y && usedNode->y < freeNode->y + freeNode->height) { + MaxRectanglesRect* newNode = createRect(freeNode->x, freeNode->y, + freeNode->width, freeNode->height, 0); + if (!newNode) { + return -1; + } + newNode->height = usedNode->y - newNode->y; + addRectToFreeRectLink(ctx, newNode); + } + + // New node at the bottom side of the used node. + if (usedNode->y + usedNode->height < freeNode->y + freeNode->height) { + MaxRectanglesRect* newNode = createRect(freeNode->x, freeNode->y, + freeNode->width, freeNode->height, 0); + if (!newNode) { + return -1; + } + newNode->y = usedNode->y + usedNode->height; + newNode->height = freeNode->y + freeNode->height - (usedNode->y + usedNode->height); + addRectToFreeRectLink(ctx, newNode); + } + } + + if (usedNode->y < freeNode->y + freeNode->height && usedNode->y + usedNode->height > freeNode->y) { + // New node at the left side of the used node. + if (usedNode->x > freeNode->x && usedNode->x < freeNode->x + freeNode->width) { + MaxRectanglesRect* newNode = createRect(freeNode->x, freeNode->y, + freeNode->width, freeNode->height, 0); + if (!newNode) { + return -1; + } + newNode->width = usedNode->x - newNode->x; + addRectToFreeRectLink(ctx, newNode); + } + + // New node at the right side of the used node. + if (usedNode->x + usedNode->width < freeNode->x + freeNode->width) { + MaxRectanglesRect* newNode = createRect(freeNode->x, freeNode->y, + freeNode->width, freeNode->height, 0); + if (!newNode) { + return -1; + } + newNode->x = usedNode->x + usedNode->width; + newNode->width = freeNode->x + freeNode->width - (usedNode->x + usedNode->width); + addRectToFreeRectLink(ctx, newNode); + } + } + + return 1; } - return newNode; -} + static int isContainedIn(MaxRectanglesRect* a, MaxRectanglesRect* b) + { + return a->x >= b->x && a->y >= b->y && a->x + a->width <= b->x + b->width && a->y + a->height <= b->y + b->height; + } -int splitFreeNode(MaxRectanglesContext *ctx, MaxRectanglesRect *freeNode, - MaxRectanglesRect *usedNode) -{ - // Test with SAT if the rectangles even intersect. - if (usedNode->x >= freeNode->x + freeNode->width || - usedNode->x + usedNode->width <= freeNode->x || - usedNode->y >= freeNode->y + freeNode->height || - usedNode->y + usedNode->height <= freeNode->y) { + static void pruneFreeList(MaxRectanglesContext* ctx) + { + MaxRectanglesRect* outerLoop = ctx->freeRectLink; + while (outerLoop) { + MaxRectanglesRect* innerLoop; + MaxRectanglesRect* outer = outerLoop; + outerLoop = outerLoop->next; + innerLoop = outerLoop; + while (innerLoop) { + MaxRectanglesRect* inner = innerLoop; + innerLoop = innerLoop->next; + if (isContainedIn(outer, inner)) { + removeAndFreeRectFromFreeRectLink(ctx, outer); + break; + } + if (isContainedIn(inner, outer)) { + if (inner == outerLoop) { + outerLoop = outerLoop->next; + } + removeAndFreeRectFromFreeRectLink(ctx, inner); + } + } + } + } + + static int placeRect(MaxRectanglesContext* ctx, MaxRectanglesRect* rect) + { + MaxRectanglesRect* loop = ctx->freeRectLink; + while (loop) { + MaxRectanglesRect* freeNode = loop; + int splitResult = splitFreeNode(ctx, freeNode, rect); + if (splitResult < 0) { + return -1; + } + loop = loop->next; + if (splitResult) { + removeAndFreeRectFromFreeRectLink(ctx, freeNode); + } + } + pruneFreeList(ctx); + addRectToUsedRectLink(ctx, rect); return 0; } - if (usedNode->x < freeNode->x + freeNode->width && - usedNode->x + usedNode->width > freeNode->x) { - // New node at the top side of the used node. - if (usedNode->y > freeNode->y && usedNode->yy + freeNode->height) { - MaxRectanglesRect *newNode = createRect(freeNode->x, freeNode->y, - freeNode->width, freeNode->height, 0); - if (!newNode) { - return -1; - } - newNode->height = usedNode->y - newNode->y; - addRectToFreeRectLink(ctx, newNode); - } - - // New node at the bottom side of the used node. - if (usedNode->y + usedNode->height < freeNode->y + freeNode->height) { - MaxRectanglesRect *newNode = createRect(freeNode->x, freeNode->y, - freeNode->width, freeNode->height, 0); - if (!newNode) { - return -1; - } - newNode->y = usedNode->y + usedNode->height; - newNode->height = freeNode->y + freeNode->height - - (usedNode->y + usedNode->height); - addRectToFreeRectLink(ctx, newNode); - } - } - - if (usedNode->y < freeNode->y + freeNode->height && - usedNode->y + usedNode->height > freeNode->y) { - // New node at the left side of the used node. - if (usedNode->x > freeNode->x && usedNode->xx + freeNode->width) { - MaxRectanglesRect *newNode = createRect(freeNode->x, freeNode->y, - freeNode->width, freeNode->height, 0); - if (!newNode) { - return -1; - } - newNode->width = usedNode->x - newNode->x; - addRectToFreeRectLink(ctx, newNode); - } - - // New node at the right side of the used node. - if (usedNode->x + usedNode->widthx + freeNode->width) { - MaxRectanglesRect *newNode = createRect(freeNode->x, freeNode->y, - freeNode->width, freeNode->height, 0); - if (!newNode) { - return -1; - } - newNode->x = usedNode->x + usedNode->width; - newNode->width = freeNode->x + freeNode->width - - (usedNode->x + usedNode->width); - addRectToFreeRectLink(ctx, newNode); - } - } - - return 1; -} - -static int isContainedIn(MaxRectanglesRect *a, MaxRectanglesRect *b) -{ - return a->x >= b->x && a->y >= b->y && - a->x + a->width <= b->x + b->width && - a->y + a->height <= b->y + b->height; -} - -static void pruneFreeList(MaxRectanglesContext *ctx) -{ - MaxRectanglesRect *outerLoop = ctx->freeRectLink; - while (outerLoop) { - MaxRectanglesRect * innerLoop; - MaxRectanglesRect *outer = outerLoop; - outerLoop = outerLoop->next; - innerLoop = outerLoop; - while (innerLoop) { - MaxRectanglesRect *inner = innerLoop; - innerLoop = innerLoop->next; - if (isContainedIn(outer, inner)) { - removeAndFreeRectFromFreeRectLink(ctx, outer); - break; - } - if (isContainedIn(inner, outer)) { - if (inner == outerLoop) { - outerLoop = outerLoop->next; + static int startLayout(MaxRectanglesContext* ctx) + { + while (ctx->inputRectLink) { + int bestScore1 = INT_MAX; + int bestScore2 = INT_MAX; + MaxRectanglesRect* bestNode = 0; + MaxRectanglesRect* bestRect = 0; + MaxRectanglesRect* loop = ctx->inputRectLink; + while (loop) { + int score1 = 0; + int score2 = 0; + MaxRectanglesRect* newRect = 0; + newRect = scoreRect(ctx, loop->width, loop->height, ctx->method, &score1, &score2); + if (!newRect) { + return -1; } - removeAndFreeRectFromFreeRectLink(ctx, inner); + if (score1 < bestScore1 || (score1 == bestScore1 && score2 < bestScore2)) { + bestScore1 = score1; + bestScore2 = score2; + if (bestNode) { + freeRect(bestNode); + } + bestRect = loop; + bestNode = newRect; + newRect = 0; + } + if (newRect) { + freeRect(newRect); + } + loop = loop->next; } + if (!bestNode) { + return -1; + } + if (bestNode->width != bestRect->width || bestNode->height != bestRect->height) { + bestNode->rectOrder = -bestRect->rectOrder; + } else { + bestNode->rectOrder = bestRect->rectOrder; + } + placeRect(ctx, bestNode); + removeAndFreeRectFromInputRectLink(ctx, bestRect); } + return 0; } -} -static int placeRect(MaxRectanglesContext *ctx, MaxRectanglesRect *rect) -{ - MaxRectanglesRect *loop = ctx->freeRectLink; - while (loop) { - MaxRectanglesRect *freeNode = loop; - int splitResult = splitFreeNode(ctx, freeNode, rect); - if (splitResult < 0) { - return -1; - } - loop = loop->next; - if (splitResult) { - removeAndFreeRectFromFreeRectLink(ctx, freeNode); - } - } - pruneFreeList(ctx); - addRectToUsedRectLink(ctx, rect); - return 0; -} - -static int startLayout(MaxRectanglesContext *ctx) -{ - while (ctx->inputRectLink) { - int bestScore1 = INT_MAX; - int bestScore2 = INT_MAX; - MaxRectanglesRect *bestNode = 0; - MaxRectanglesRect *bestRect = 0; - MaxRectanglesRect *loop = ctx->inputRectLink; + static void fillResults(MaxRectanglesContext* ctx) + { + MaxRectanglesRect* loop = ctx->usedRectLink; while (loop) { - int score1 = 0; - int score2 = 0; - MaxRectanglesRect *newRect = 0; - newRect = scoreRect(ctx, loop->width, loop->height, ctx->method, &score1, &score2); - if (!newRect) { - return -1; - } - if (score1 < bestScore1 || - (score1 == bestScore1 && score2 < bestScore2)) { - bestScore1 = score1; - bestScore2 = score2; - if (bestNode) { - freeRect(bestNode); - } - bestRect = loop; - bestNode = newRect; - newRect = 0; - } - if (newRect) { - freeRect(newRect); - } + int index = abs(loop->rectOrder) - 1; + MaxRectanglesPosition* result = &ctx->layoutResults[index]; + result->left = loop->x; + result->top = loop->y; + result->rotated = loop->rectOrder < 0; loop = loop->next; } - if (!bestNode) { + } + + int maxRectangles(int width, int height, int rectCount, MaxRectanglesSize* rects, + enum MaxRectanglesFreeRectChoiceHeuristic method, int allowRotations, + MaxRectanglesPosition* layoutResults, float* occupancy) + { + MaxRectanglesContext contextStruct; + MaxRectanglesContext* ctx = &contextStruct; + memset(ctx, 0, sizeof(MaxRectanglesContext)); + ctx->width = width; + ctx->height = height; + ctx->method = method; + ctx->allowRotations = allowRotations; + ctx->rectCount = rectCount; + ctx->rects = rects; + ctx->layoutResults = layoutResults; + if (0 != initContext(ctx)) { + releaseContext(ctx); return -1; } - if (bestNode->width != bestRect->width || - bestNode->height != bestRect->height) { - bestNode->rectOrder = -bestRect->rectOrder; - } else { - bestNode->rectOrder = bestRect->rectOrder; + if (0 != startLayout(ctx)) { + releaseContext(ctx); + return -1; } - placeRect(ctx, bestNode); - removeAndFreeRectFromInputRectLink(ctx, bestRect); - } - return 0; -} - -static void fillResults(MaxRectanglesContext *ctx) -{ - MaxRectanglesRect *loop = ctx->usedRectLink; - while (loop) { - int index = abs(loop->rectOrder) - 1; - MaxRectanglesPosition *result = &ctx->layoutResults[index]; - result->left = loop->x; - result->top = loop->y; - result->rotated = loop->rectOrder < 0; - loop = loop->next; - } -} - -int maxRectangles(int width, int height, int rectCount, MaxRectanglesSize *rects, - enum MaxRectanglesFreeRectChoiceHeuristic method, int allowRotations, - MaxRectanglesPosition *layoutResults, float *occupancy) -{ - MaxRectanglesContext contextStruct; - MaxRectanglesContext *ctx = &contextStruct; - memset(ctx, 0, sizeof(MaxRectanglesContext)); - ctx->width = width; - ctx->height = height; - ctx->method = method; - ctx->allowRotations = allowRotations; - ctx->rectCount = rectCount; - ctx->rects = rects; - ctx->layoutResults = layoutResults; - if (0 != initContext(ctx)) { + if (occupancy) { + *occupancy = getOccupany(ctx); + } + fillResults(ctx); releaseContext(ctx); - return -1; + return 0; } - if (0 != startLayout(ctx)) { - releaseContext(ctx); - return -1; - } - if (occupancy) { - *occupancy = getOccupany(ctx); - } - fillResults(ctx); - releaseContext(ctx); - return 0; -} } } diff --git a/dust3d/uv/max_rectangles.h b/dust3d/uv/max_rectangles.h index 3b43bc59..a374c0d0 100644 --- a/dust3d/uv/max_rectangles.h +++ b/dust3d/uv/max_rectangles.h @@ -31,35 +31,31 @@ #ifndef DUST3D_UV_MAX_RECTANGLES_H_ #define DUST3D_UV_MAX_RECTANGLES_H_ -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -typedef struct MaxRectanglesSize -{ - int width; - int height; -} MaxRectanglesSize; + typedef struct MaxRectanglesSize { + int width; + int height; + } MaxRectanglesSize; -typedef struct MaxRectanglesPosition -{ - int left; - int top; - int rotated:1; -} MaxRectanglesPosition; + typedef struct MaxRectanglesPosition { + int left; + int top; + int rotated : 1; + } MaxRectanglesPosition; -enum MaxRectanglesFreeRectChoiceHeuristic { - kMaxRectanglesBestShortSideFit, ///< -BSSF: Positions the rectangle against the short side of a free rectangle into which it fits the best. - kMaxRectanglesBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best. - kMaxRectanglesBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits. - kMaxRectanglesBottomLeftRule, ///< -BL: Does the Tetris placement. - kMaxRectanglesContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible. -}; + enum MaxRectanglesFreeRectChoiceHeuristic { + kMaxRectanglesBestShortSideFit, ///< -BSSF: Positions the rectangle against the short side of a free rectangle into which it fits the best. + kMaxRectanglesBestLongSideFit, ///< -BLSF: Positions the rectangle against the long side of a free rectangle into which it fits the best. + kMaxRectanglesBestAreaFit, ///< -BAF: Positions the rectangle into the smallest free rect into which it fits. + kMaxRectanglesBottomLeftRule, ///< -BL: Does the Tetris placement. + kMaxRectanglesContactPointRule ///< -CP: Choosest the placement where the rectangle touches other rects as much as possible. + }; -int maxRectangles(int width, int height, int rectCount, MaxRectanglesSize *rects, + int maxRectangles(int width, int height, int rectCount, MaxRectanglesSize* rects, enum MaxRectanglesFreeRectChoiceHeuristic method, int allowRotations, - MaxRectanglesPosition *layoutResults, float *occupancy); + MaxRectanglesPosition* layoutResults, float* occupancy); } } diff --git a/dust3d/uv/parametrize.cc b/dust3d/uv/parametrize.cc index 671febaf..b2576820 100644 --- a/dust3d/uv/parametrize.cc +++ b/dust3d/uv/parametrize.cc @@ -23,121 +23,117 @@ #ifndef NDEBUG #define NDEBUG #endif +#include #include -#include #include #include +#include #include -#include -namespace dust3d -{ -namespace uv -{ - -void parametrizeUsingARAP(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::VectorXi &bnd, Eigen::MatrixXd &V_uv) -{ - Eigen::MatrixXd initial_guess; - Eigen::MatrixXd bnd_uv; - igl::map_vertices_to_circle(V,bnd,bnd_uv); +namespace dust3d { +namespace uv { - igl::harmonic(V,F,bnd,bnd_uv,1,initial_guess); + void parametrizeUsingARAP(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::VectorXi& bnd, Eigen::MatrixXd& V_uv) + { + Eigen::MatrixXd initial_guess; + Eigen::MatrixXd bnd_uv; + igl::map_vertices_to_circle(V, bnd, bnd_uv); - // Add dynamic regularization to avoid to specify boundary conditions - igl::ARAPData arap_data; - arap_data.with_dynamics = true; - Eigen::VectorXi b = Eigen::VectorXi::Zero(0); - Eigen::MatrixXd bc = Eigen::MatrixXd::Zero(0,0); + igl::harmonic(V, F, bnd, bnd_uv, 1, initial_guess); - // Initialize ARAP - arap_data.max_iter = 100; - // 2 means that we're going to *solve* in 2d - arap_precomputation(V,F,2,b,arap_data); + // Add dynamic regularization to avoid to specify boundary conditions + igl::ARAPData arap_data; + arap_data.with_dynamics = true; + Eigen::VectorXi b = Eigen::VectorXi::Zero(0); + Eigen::MatrixXd bc = Eigen::MatrixXd::Zero(0, 0); + // Initialize ARAP + arap_data.max_iter = 100; + // 2 means that we're going to *solve* in 2d + arap_precomputation(V, F, 2, b, arap_data); - // Solve arap using the harmonic map as initial guess - V_uv = initial_guess; + // Solve arap using the harmonic map as initial guess + V_uv = initial_guess; - arap_solve(bc,arap_data,V_uv); -} - -void parametrizeUsingLSCM(const Eigen::MatrixXd &V, const Eigen::MatrixXi &F, const Eigen::VectorXi &bnd, Eigen::MatrixXd &V_uv) -{ - Eigen::VectorXi b(2,1); - b(0) = bnd(0); - b(1) = bnd(round(bnd.size()/2)); - Eigen::MatrixXd bc(2,2); - bc<<0,0,1,0; - - // LSCM parametrization - igl::lscm(V,F,b,bc,V_uv); -} - -bool extractResult(const std::vector &verticies, const Eigen::MatrixXd &V_uv, std::vector &vertexUvs) -{ - vertexUvs.clear(); - auto isCoordValid = [=](float coord) { - if (std::isnan(coord) || std::isinf(coord)) - return false; - return true; - }; - if ((decltype(verticies.size()))V_uv.size() < verticies.size() * 2) { - return false; + arap_solve(bc, arap_data, V_uv); } - for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) { - TextureCoord coord; - coord.uv[0] = V_uv.row(i)[0]; - coord.uv[1] = V_uv.row(i)[1]; - if (isCoordValid(coord.uv[0]) && isCoordValid(coord.uv[1])) { - vertexUvs.push_back(coord); - continue; - } + + void parametrizeUsingLSCM(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::VectorXi& bnd, Eigen::MatrixXd& V_uv) + { + Eigen::VectorXi b(2, 1); + b(0) = bnd(0); + b(1) = bnd(round(bnd.size() / 2)); + Eigen::MatrixXd bc(2, 2); + bc << 0, 0, 1, 0; + + // LSCM parametrization + igl::lscm(V, F, b, bc, V_uv); + } + + bool extractResult(const std::vector& verticies, const Eigen::MatrixXd& V_uv, std::vector& vertexUvs) + { vertexUvs.clear(); + auto isCoordValid = [=](float coord) { + if (std::isnan(coord) || std::isinf(coord)) + return false; + return true; + }; + if ((decltype(verticies.size()))V_uv.size() < verticies.size() * 2) { + return false; + } + for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) { + TextureCoord coord; + coord.uv[0] = V_uv.row(i)[0]; + coord.uv[1] = V_uv.row(i)[1]; + if (isCoordValid(coord.uv[0]) && isCoordValid(coord.uv[1])) { + vertexUvs.push_back(coord); + continue; + } + vertexUvs.clear(); + return false; + } + return true; + } + + bool parametrize(const std::vector& verticies, + const std::vector& faces, + std::vector& vertexUvs) + { + if (verticies.empty() || faces.empty()) + return false; + + Eigen::MatrixXd V(verticies.size(), 3); + Eigen::MatrixXi F(faces.size(), 3); + + for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) { + const auto& vertex = verticies[i]; + V.row(i) << vertex.xyz[0], vertex.xyz[1], vertex.xyz[2]; + } + + for (decltype(faces.size()) i = 0; i < faces.size(); i++) { + const auto& face = faces[i]; + F.row(i) << face.indices[0], face.indices[1], face.indices[2]; + } + + Eigen::VectorXi bnd; + igl::boundary_loop(F, bnd); + + { + Eigen::MatrixXd V_uv; + parametrizeUsingARAP(V, F, bnd, V_uv); + if (extractResult(verticies, V_uv, vertexUvs)) + return true; + } + + { + Eigen::MatrixXd V_uv; + parametrizeUsingLSCM(V, F, bnd, V_uv); + if (extractResult(verticies, V_uv, vertexUvs)) + return true; + } + return false; } - return true; -} - - -bool parametrize(const std::vector &verticies, - const std::vector &faces, - std::vector &vertexUvs) -{ - if (verticies.empty() || faces.empty()) - return false; - - Eigen::MatrixXd V(verticies.size(), 3); - Eigen::MatrixXi F(faces.size(), 3); - - for (decltype(verticies.size()) i = 0; i < verticies.size(); i++) { - const auto &vertex = verticies[i]; - V.row(i) << vertex.xyz[0], vertex.xyz[1], vertex.xyz[2]; - } - - for (decltype(faces.size()) i = 0; i < faces.size(); i++) { - const auto &face = faces[i]; - F.row(i) << face.indices[0], face.indices[1], face.indices[2]; - } - - Eigen::VectorXi bnd; - igl::boundary_loop(F,bnd); - - { - Eigen::MatrixXd V_uv; - parametrizeUsingARAP(V, F, bnd, V_uv); - if (extractResult(verticies, V_uv, vertexUvs)) - return true; - } - - { - Eigen::MatrixXd V_uv; - parametrizeUsingLSCM(V, F, bnd, V_uv); - if (extractResult(verticies, V_uv, vertexUvs)) - return true; - } - - return false; -} } } diff --git a/dust3d/uv/parametrize.h b/dust3d/uv/parametrize.h index 250b72d7..119a1b3b 100644 --- a/dust3d/uv/parametrize.h +++ b/dust3d/uv/parametrize.h @@ -25,14 +25,12 @@ #include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -bool parametrize(const std::vector &verticies, - const std::vector &faces, - std::vector &vertexUvs); + bool parametrize(const std::vector& verticies, + const std::vector& faces, + std::vector& vertexUvs); } } diff --git a/dust3d/uv/triangulate.cc b/dust3d/uv/triangulate.cc index 72720138..1863638a 100644 --- a/dust3d/uv/triangulate.cc +++ b/dust3d/uv/triangulate.cc @@ -24,117 +24,115 @@ #include #include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -static Eigen::Vector3d norm(const Eigen::Vector3d &p1, const Eigen::Vector3d &p2, const Eigen::Vector3d &p3) -{ - auto side1 = p2 - p1; - auto side2 = p3 - p1; - auto perp = side1.cross(side2); - return perp.normalized(); -} - -static float angle360(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &direct) -{ - auto angle = atan2((a.cross(b)).norm(), a.dot(b)) * 180.0 / 3.1415926; - auto c = a.cross(b); - if (c.dot(direct) < 0) { - angle = 360 - angle; + static Eigen::Vector3d norm(const Eigen::Vector3d& p1, const Eigen::Vector3d& p2, const Eigen::Vector3d& p3) + { + auto side1 = p2 - p1; + auto side2 = p3 - p1; + auto perp = side1.cross(side2); + return perp.normalized(); } - return angle; -} -static Eigen::Vector3d vertexToEigenVector3d(const Vertex &vertex) -{ - return Eigen::Vector3d(vertex.xyz[0], vertex.xyz[1], vertex.xyz[2]); -} - -static bool pointInTriangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c, const Eigen::Vector3d &p) -{ - auto u = b - a; - auto v = c - a; - auto w = p - a; - auto vXw = v.cross(w); - auto vXu = v.cross(u); - if (vXw.dot(vXu) < 0.0) { - return false; + static float angle360(const Eigen::Vector3d& a, const Eigen::Vector3d& b, const Eigen::Vector3d& direct) + { + auto angle = atan2((a.cross(b)).norm(), a.dot(b)) * 180.0 / 3.1415926; + auto c = a.cross(b); + if (c.dot(direct) < 0) { + angle = 360 - angle; + } + return angle; } - auto uXw = u.cross(w); - auto uXv = u.cross(v); - if (uXw.dot(uXv) < 0.0) { - return false; - } - auto denom = uXv.norm(); - auto r = vXw.norm() / denom; - auto t = uXw.norm() / denom; - return r + t <= 1.0; -} -static Eigen::Vector3d ringNorm(const std::vector &vertices, const std::vector &ring) -{ - Eigen::Vector3d normal(0.0, 0.0, 0.0); - for (size_t i = 0; i < ring.size(); ++i) { - auto j = (i + 1) % ring.size(); - auto k = (i + 2) % ring.size(); - const auto &enter = vertexToEigenVector3d(vertices[ring[i]]); - const auto &cone = vertexToEigenVector3d(vertices[ring[j]]); - const auto &leave = vertexToEigenVector3d(vertices[ring[k]]); - normal += norm(enter, cone, leave); + static Eigen::Vector3d vertexToEigenVector3d(const Vertex& vertex) + { + return Eigen::Vector3d(vertex.xyz[0], vertex.xyz[1], vertex.xyz[2]); } - return normal.normalized(); -} -void triangulate(const std::vector &vertices, std::vector &faces, const std::vector &ring) -{ - if (ring.size() < 3) - return; - std::vector fillRing = ring; - Eigen::Vector3d direct = ringNorm(vertices, fillRing); - while (fillRing.size() > 3) { - bool newFaceGenerated = false; - for (decltype(fillRing.size()) i = 0; i < fillRing.size(); ++i) { - auto j = (i + 1) % fillRing.size(); - auto k = (i + 2) % fillRing.size(); - const auto &enter = vertexToEigenVector3d(vertices[fillRing[i]]); - const auto &cone = vertexToEigenVector3d(vertices[fillRing[j]]); - const auto &leave = vertexToEigenVector3d(vertices[fillRing[k]]); - auto angle = angle360(cone - enter, leave - cone, direct); - if (angle >= 1.0 && angle <= 179.0) { - bool isEar = true; - for (size_t x = 0; x < fillRing.size() - 3; ++x) { - auto h = (i + 3 + x) % fillRing.size(); - auto fourth = vertexToEigenVector3d(vertices[fillRing[h]]); - if (pointInTriangle(enter, cone, leave, fourth)) { - isEar = false; + static bool pointInTriangle(const Eigen::Vector3d& a, const Eigen::Vector3d& b, const Eigen::Vector3d& c, const Eigen::Vector3d& p) + { + auto u = b - a; + auto v = c - a; + auto w = p - a; + auto vXw = v.cross(w); + auto vXu = v.cross(u); + if (vXw.dot(vXu) < 0.0) { + return false; + } + auto uXw = u.cross(w); + auto uXv = u.cross(v); + if (uXw.dot(uXv) < 0.0) { + return false; + } + auto denom = uXv.norm(); + auto r = vXw.norm() / denom; + auto t = uXw.norm() / denom; + return r + t <= 1.0; + } + + static Eigen::Vector3d ringNorm(const std::vector& vertices, const std::vector& ring) + { + Eigen::Vector3d normal(0.0, 0.0, 0.0); + for (size_t i = 0; i < ring.size(); ++i) { + auto j = (i + 1) % ring.size(); + auto k = (i + 2) % ring.size(); + const auto& enter = vertexToEigenVector3d(vertices[ring[i]]); + const auto& cone = vertexToEigenVector3d(vertices[ring[j]]); + const auto& leave = vertexToEigenVector3d(vertices[ring[k]]); + normal += norm(enter, cone, leave); + } + return normal.normalized(); + } + + void triangulate(const std::vector& vertices, std::vector& faces, const std::vector& ring) + { + if (ring.size() < 3) + return; + std::vector fillRing = ring; + Eigen::Vector3d direct = ringNorm(vertices, fillRing); + while (fillRing.size() > 3) { + bool newFaceGenerated = false; + for (decltype(fillRing.size()) i = 0; i < fillRing.size(); ++i) { + auto j = (i + 1) % fillRing.size(); + auto k = (i + 2) % fillRing.size(); + const auto& enter = vertexToEigenVector3d(vertices[fillRing[i]]); + const auto& cone = vertexToEigenVector3d(vertices[fillRing[j]]); + const auto& leave = vertexToEigenVector3d(vertices[fillRing[k]]); + auto angle = angle360(cone - enter, leave - cone, direct); + if (angle >= 1.0 && angle <= 179.0) { + bool isEar = true; + for (size_t x = 0; x < fillRing.size() - 3; ++x) { + auto h = (i + 3 + x) % fillRing.size(); + auto fourth = vertexToEigenVector3d(vertices[fillRing[h]]); + if (pointInTriangle(enter, cone, leave, fourth)) { + isEar = false; + break; + } + } + if (isEar) { + Face newFace; + newFace.indices[0] = fillRing[i]; + newFace.indices[1] = fillRing[j]; + newFace.indices[2] = fillRing[k]; + faces.push_back(newFace); + fillRing.erase(fillRing.begin() + j); + newFaceGenerated = true; break; } } - if (isEar) { - Face newFace; - newFace.indices[0] = fillRing[i]; - newFace.indices[1] = fillRing[j]; - newFace.indices[2] = fillRing[k]; - faces.push_back(newFace); - fillRing.erase(fillRing.begin() + j); - newFaceGenerated = true; - break; - } } + if (!newFaceGenerated) + break; + } + if (fillRing.size() == 3) { + Face newFace; + newFace.indices[0] = fillRing[0]; + newFace.indices[1] = fillRing[1]; + newFace.indices[2] = fillRing[2]; + faces.push_back(newFace); } - if (!newFaceGenerated) - break; } - if (fillRing.size() == 3) { - Face newFace; - newFace.indices[0] = fillRing[0]; - newFace.indices[1] = fillRing[1]; - newFace.indices[2] = fillRing[2]; - faces.push_back(newFace); - } -} } } diff --git a/dust3d/uv/triangulate.h b/dust3d/uv/triangulate.h index 8a1b90c0..3e8d9c10 100644 --- a/dust3d/uv/triangulate.h +++ b/dust3d/uv/triangulate.h @@ -25,12 +25,10 @@ #include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -void triangulate(const std::vector &vertices, std::vector &faces, const std::vector &ring); + void triangulate(const std::vector& vertices, std::vector& faces, const std::vector& ring); } } diff --git a/dust3d/uv/unwrap_uv.cc b/dust3d/uv/unwrap_uv.cc index fb64b190..cc7bdeb3 100644 --- a/dust3d/uv/unwrap_uv.cc +++ b/dust3d/uv/unwrap_uv.cc @@ -23,28 +23,25 @@ #include #include -namespace dust3d -{ +namespace dust3d { -void unwrapUv(const Object &object, - std::vector> &triangleVertexUvs, - std::set &seamVertices, - std::map> &uvRects) +void unwrapUv(const Object& object, + std::vector>& triangleVertexUvs, + std::set& seamVertices, + std::map>& uvRects) { - const auto &choosenVertices = object.vertices; - const auto &choosenTriangles = object.triangles; - const auto &choosenTriangleNormals = object.triangleNormals; - triangleVertexUvs.resize(choosenTriangles.size(), { - Vector2(), Vector2(), Vector2() - }); - + const auto& choosenVertices = object.vertices; + const auto& choosenTriangles = object.triangles; + const auto& choosenTriangleNormals = object.triangleNormals; + triangleVertexUvs.resize(choosenTriangles.size(), { Vector2(), Vector2(), Vector2() }); + if (nullptr == object.triangleSourceNodes()) return; - - const std::vector> &triangleSourceNodes = *object.triangleSourceNodes(); - + + const std::vector>& triangleSourceNodes = *object.triangleSourceNodes(); + uv::Mesh inputMesh; - for (const auto &vertex: choosenVertices) { + for (const auto& vertex : choosenVertices) { uv::Vertex v; v.xyz[0] = vertex.x(); v.xyz[1] = vertex.y(); @@ -54,9 +51,9 @@ void unwrapUv(const Object &object, std::map partIdToPartitionMap; std::vector partitionPartUuids; for (decltype(choosenTriangles.size()) i = 0; i < choosenTriangles.size(); ++i) { - const auto &triangle = choosenTriangles[i]; - const auto &sourceNode = triangleSourceNodes[i]; - const auto &normal = choosenTriangleNormals[i]; + const auto& triangle = choosenTriangles[i]; + const auto& sourceNode = triangleSourceNodes[i]; + const auto& normal = choosenTriangleNormals[i]; uv::Face f; f.indices[0] = triangle[0]; f.indices[1] = triangle[1]; @@ -70,24 +67,24 @@ void unwrapUv(const Object &object, auto findPartitionResult = partIdToPartitionMap.find(sourceNode.first); if (findPartitionResult == partIdToPartitionMap.end()) { partitionPartUuids.push_back(sourceNode.first); - partIdToPartitionMap.insert({sourceNode.first, (int)partitionPartUuids.size()}); + partIdToPartitionMap.insert({ sourceNode.first, (int)partitionPartUuids.size() }); inputMesh.facePartitions.push_back((int)partitionPartUuids.size()); } else { inputMesh.facePartitions.push_back(findPartitionResult->second); } } - + uv::UvUnwrapper uvUnwrapper; uvUnwrapper.setMesh(inputMesh); uvUnwrapper.unwrap(); - const std::vector &resultFaceUvs = uvUnwrapper.getFaceUvs(); - const std::vector &resultChartRects = uvUnwrapper.getChartRects(); - const std::vector &resultChartSourcePartitions = uvUnwrapper.getChartSourcePartitions(); + const std::vector& resultFaceUvs = uvUnwrapper.getFaceUvs(); + const std::vector& resultChartRects = uvUnwrapper.getChartRects(); + const std::vector& resultChartSourcePartitions = uvUnwrapper.getChartSourcePartitions(); std::map vertexUvMap; for (decltype(choosenTriangles.size()) i = 0; i < choosenTriangles.size(); ++i) { - const auto &triangle = choosenTriangles[i]; - const auto &src = resultFaceUvs[i]; - auto &dest = triangleVertexUvs[i]; + const auto& triangle = choosenTriangles[i]; + const auto& src = resultFaceUvs[i]; + auto& dest = triangleVertexUvs[i]; for (size_t j = 0; j < 3; ++j) { Vector2 uvCoord = Vector2(src.coords[j].uv[0], src.coords[j].uv[1]); dest[j][0] = uvCoord.x(); @@ -95,7 +92,7 @@ void unwrapUv(const Object &object, int vertexIndex = triangle[j]; auto findVertexUvResult = vertexUvMap.find(vertexIndex); if (findVertexUvResult == vertexUvMap.end()) { - vertexUvMap.insert({vertexIndex, uvCoord}); + vertexUvMap.insert({ vertexIndex, uvCoord }); } else { if (findVertexUvResult->second != uvCoord) { seamVertices.insert(vertexIndex); @@ -104,12 +101,12 @@ void unwrapUv(const Object &object, } } for (size_t i = 0; i < resultChartRects.size(); ++i) { - const auto &rect = resultChartRects[i]; - const auto &source = resultChartSourcePartitions[i]; + const auto& rect = resultChartRects[i]; + const auto& source = resultChartSourcePartitions[i]; if (0 == source || source > (int)partitionPartUuids.size()) { continue; } - uvRects[partitionPartUuids[source - 1]].push_back({rect.left, rect.top, rect.width, rect.height}); + uvRects[partitionPartUuids[source - 1]].push_back({ rect.left, rect.top, rect.width, rect.height }); } } diff --git a/dust3d/uv/unwrap_uv.h b/dust3d/uv/unwrap_uv.h index 059a4995..3868f09e 100644 --- a/dust3d/uv/unwrap_uv.h +++ b/dust3d/uv/unwrap_uv.h @@ -23,19 +23,18 @@ #ifndef DUST3D_UV_UNWRAP_UV_H_ #define DUST3D_UV_UNWRAP_UV_H_ -#include +#include #include #include -#include +#include + +namespace dust3d { + +void unwrapUv(const Object& object, + std::vector>& triangleVertexUvs, + std::set& seamVertices, + std::map>& uvRects); -namespace dust3d -{ - -void unwrapUv(const Object &object, - std::vector> &triangleVertexUvs, - std::set &seamVertices, - std::map> &uvRects); - } #endif diff --git a/dust3d/uv/uv_mesh_data_type.cc b/dust3d/uv/uv_mesh_data_type.cc index d2a93461..1d20136d 100644 --- a/dust3d/uv/uv_mesh_data_type.cc +++ b/dust3d/uv/uv_mesh_data_type.cc @@ -23,29 +23,27 @@ #include #include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -float dotProduct(const Vector3 &first, const Vector3 &second) -{ - Eigen::Vector3d v(first.xyz[0], first.xyz[1], first.xyz[2]); - Eigen::Vector3d w(second.xyz[0], second.xyz[1], second.xyz[2]); - return v.dot(w); -} + float dotProduct(const Vector3& first, const Vector3& second) + { + Eigen::Vector3d v(first.xyz[0], first.xyz[1], first.xyz[2]); + Eigen::Vector3d w(second.xyz[0], second.xyz[1], second.xyz[2]); + return v.dot(w); + } -Vector3 crossProduct(const Vector3 &first, const Vector3 &second) -{ - Eigen::Vector3d v(first.xyz[0], first.xyz[1], first.xyz[2]); - Eigen::Vector3d w(second.xyz[0], second.xyz[1], second.xyz[2]); - auto u = v.cross(w); - Vector3 result; - result.xyz[0] = u.x(); - result.xyz[1] = u.y(); - result.xyz[2] = u.z(); - return result; -} + Vector3 crossProduct(const Vector3& first, const Vector3& second) + { + Eigen::Vector3d v(first.xyz[0], first.xyz[1], first.xyz[2]); + Eigen::Vector3d w(second.xyz[0], second.xyz[1], second.xyz[2]); + auto u = v.cross(w); + Vector3 result; + result.xyz[0] = u.x(); + result.xyz[1] = u.y(); + result.xyz[2] = u.z(); + return result; + } } } diff --git a/dust3d/uv/uv_mesh_data_type.h b/dust3d/uv/uv_mesh_data_type.h index 4be0c4a4..49168313 100644 --- a/dust3d/uv/uv_mesh_data_type.h +++ b/dust3d/uv/uv_mesh_data_type.h @@ -23,54 +23,46 @@ #ifndef DUST3D_UV_UV_MESH_DATA_TYPE_H_ #define DUST3D_UV_UV_MESH_DATA_TYPE_H_ -#include #include +#include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -struct Vector3 -{ - float xyz[3]; -}; + struct Vector3 { + float xyz[3]; + }; -typedef Vector3 Vertex; + typedef Vector3 Vertex; -struct Rect -{ - float left; - float top; - float width; - float height; -}; + struct Rect { + float left; + float top; + float width; + float height; + }; -struct Face -{ - size_t indices[3]; -}; + struct Face { + size_t indices[3]; + }; -struct TextureCoord -{ - float uv[2]; -}; + struct TextureCoord { + float uv[2]; + }; -struct FaceTextureCoords -{ - TextureCoord coords[3]; -}; + struct FaceTextureCoords { + TextureCoord coords[3]; + }; -struct Mesh -{ - std::vector vertices; - std::vector faces; - std::vector faceNormals; - std::vector facePartitions; -}; + struct Mesh { + std::vector vertices; + std::vector faces; + std::vector faceNormals; + std::vector facePartitions; + }; -float dotProduct(const Vector3 &first, const Vector3 &second); -Vector3 crossProduct(const Vector3 &first, const Vector3 &second); + float dotProduct(const Vector3& first, const Vector3& second); + Vector3 crossProduct(const Vector3& first, const Vector3& second); } } diff --git a/dust3d/uv/uv_unwrapper.cc b/dust3d/uv/uv_unwrapper.cc index ead41dff..6e47616d 100644 --- a/dust3d/uv/uv_unwrapper.cc +++ b/dust3d/uv/uv_unwrapper.cc @@ -20,599 +20,597 @@ * SOFTWARE. */ -#include -#include -#include -#include -#include #include -#include -#include +#include #include +#include +#include #include +#include +#include +#include +#include -namespace dust3d -{ -namespace uv -{ - -const std::vector UvUnwrapper::m_rotateDegrees = {5, 15, 20, 25, 30, 35, 40, 45}; +namespace dust3d { +namespace uv { -static float areaOf3dTriangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c) -{ - auto ab = b - a; - auto ac = c - a; - return 0.5 * (ab.cross(ac)).norm(); -} + const std::vector UvUnwrapper::m_rotateDegrees = { 5, 15, 20, 25, 30, 35, 40, 45 }; -static float areaOf2dTriangle(const Eigen::Vector2d &a, const Eigen::Vector2d &b, const Eigen::Vector2d &c) -{ - return areaOf3dTriangle(Eigen::Vector3d(a.x(), a.y(), 0), - Eigen::Vector3d(b.x(), b.y(), 0), - Eigen::Vector3d(c.x(), c.y(), 0)); -} - -void UvUnwrapper::setMesh(const Mesh &mesh) -{ - m_mesh = mesh; -} - -void UvUnwrapper::setTexelSize(float texelSize) -{ - m_texelSizePerUnit = texelSize; -} - -const std::vector &UvUnwrapper::getFaceUvs() const -{ - return m_faceUvs; -} - -const std::vector &UvUnwrapper::getChartRects() const -{ - return m_chartRects; -} - -const std::vector &UvUnwrapper::getChartSourcePartitions() const -{ - return m_chartSourcePartitions; -} - -void UvUnwrapper::buildEdgeToFaceMap(const std::vector &faces, std::map, size_t> &edgeToFaceMap) -{ - edgeToFaceMap.clear(); - for (decltype(faces.size()) index = 0; index < faces.size(); ++index) { - const auto &face = faces[index]; - for (size_t i = 0; i < 3; i++) { - size_t j = (i + 1) % 3; - edgeToFaceMap[{face.indices[i], face.indices[j]}] = index; - } + static float areaOf3dTriangle(const Eigen::Vector3d& a, const Eigen::Vector3d& b, const Eigen::Vector3d& c) + { + auto ab = b - a; + auto ac = c - a; + return 0.5 * (ab.cross(ac)).norm(); } -} -void UvUnwrapper::buildEdgeToFaceMap(const std::vector &group, std::map, size_t> &edgeToFaceMap) -{ - edgeToFaceMap.clear(); - for (const auto &index: group) { - const auto &face = m_mesh.faces[index]; - for (size_t i = 0; i < 3; i++) { - size_t j = (i + 1) % 3; - edgeToFaceMap[{face.indices[i], face.indices[j]}] = index; - } + static float areaOf2dTriangle(const Eigen::Vector2d& a, const Eigen::Vector2d& b, const Eigen::Vector2d& c) + { + return areaOf3dTriangle(Eigen::Vector3d(a.x(), a.y(), 0), + Eigen::Vector3d(b.x(), b.y(), 0), + Eigen::Vector3d(c.x(), c.y(), 0)); } -} -void UvUnwrapper::splitPartitionToIslands(const std::vector &group, std::vector> &islands) -{ - std::map, size_t> edgeToFaceMap; - buildEdgeToFaceMap(group, edgeToFaceMap); - bool segmentByNormal = !m_mesh.faceNormals.empty() && m_segmentByNormal; - - std::unordered_set processedFaces; - std::queue waitFaces; - for (const auto &indexInGroup: group) { - if (processedFaces.find(indexInGroup) != processedFaces.end()) - continue; - waitFaces.push(indexInGroup); - std::vector island; - while (!waitFaces.empty()) { - size_t index = waitFaces.front(); - waitFaces.pop(); - if (processedFaces.find(index) != processedFaces.end()) - continue; - const auto &face = m_mesh.faces[index]; + void UvUnwrapper::setMesh(const Mesh& mesh) + { + m_mesh = mesh; + } + + void UvUnwrapper::setTexelSize(float texelSize) + { + m_texelSizePerUnit = texelSize; + } + + const std::vector& UvUnwrapper::getFaceUvs() const + { + return m_faceUvs; + } + + const std::vector& UvUnwrapper::getChartRects() const + { + return m_chartRects; + } + + const std::vector& UvUnwrapper::getChartSourcePartitions() const + { + return m_chartSourcePartitions; + } + + void UvUnwrapper::buildEdgeToFaceMap(const std::vector& faces, std::map, size_t>& edgeToFaceMap) + { + edgeToFaceMap.clear(); + for (decltype(faces.size()) index = 0; index < faces.size(); ++index) { + const auto& face = faces[index]; for (size_t i = 0; i < 3; i++) { size_t j = (i + 1) % 3; - auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]}); - if (findOppositeFaceResult == edgeToFaceMap.end()) - continue; - if (segmentByNormal) { - if (dotProduct(m_mesh.faceNormals[findOppositeFaceResult->second], - m_mesh.faceNormals[m_segmentPreferMorePieces ? indexInGroup : index]) < m_segmentDotProductThreshold) { - continue; - } - } - waitFaces.push(findOppositeFaceResult->second); - } - island.push_back(index); - processedFaces.insert(index); - } - if (island.empty()) - continue; - islands.push_back(island); - } -} - -double UvUnwrapper::distanceBetweenVertices(const Vertex &first, const Vertex &second) -{ - float x = first.xyz[0] - second.xyz[0]; - float y = first.xyz[1] - second.xyz[1]; - float z = first.xyz[2] - second.xyz[2]; - return std::sqrt(x*x + y*y + z*z); -} - -void UvUnwrapper::calculateFaceTextureBoundingBox(const std::vector &faceTextureCoords, - float &left, float &top, float &right, float &bottom) -{ - bool leftFirstTime = true; - bool topFirstTime = true; - bool rightFirstTime = true; - bool bottomFirstTime = true; - for (const auto &item: faceTextureCoords) { - for (int i = 0; i < 3; ++i) { - const auto &x = item.coords[i].uv[0]; - const auto &y = item.coords[i].uv[1]; - if (leftFirstTime || x < left) { - left = x; - leftFirstTime = false; - } - if (rightFirstTime || x > right) { - right = x; - rightFirstTime = false; - } - if (topFirstTime || y < top) { - top = y; - topFirstTime = false; - } - if (bottomFirstTime || y > bottom) { - bottom = y; - bottomFirstTime = false; + edgeToFaceMap[{ face.indices[i], face.indices[j] }] = index; } } } -} -void UvUnwrapper::triangulateRing(const std::vector &verticies, - std::vector &faces, const std::vector &ring) -{ - triangulate(verticies, faces, ring); -} + void UvUnwrapper::buildEdgeToFaceMap(const std::vector& group, std::map, size_t>& edgeToFaceMap) + { + edgeToFaceMap.clear(); + for (const auto& index : group) { + const auto& face = m_mesh.faces[index]; + for (size_t i = 0; i < 3; i++) { + size_t j = (i + 1) % 3; + edgeToFaceMap[{ face.indices[i], face.indices[j] }] = index; + } + } + } -// The hole filling faces should be put in the back of faces vector, so these uv coords of appended faces will be disgarded. -bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector &verticies, std::vector &faces, size_t *remainingHoleNum) -{ - std::map, size_t> edgeToFaceMap; - buildEdgeToFaceMap(faces, edgeToFaceMap); - - std::map> holeVertexLink; - for (const auto &face: faces) { - for (size_t i = 0; i < 3; i++) { - size_t j = (i + 1) % 3; - auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]}); - if (findOppositeFaceResult != edgeToFaceMap.end()) + void UvUnwrapper::splitPartitionToIslands(const std::vector& group, std::vector>& islands) + { + std::map, size_t> edgeToFaceMap; + buildEdgeToFaceMap(group, edgeToFaceMap); + bool segmentByNormal = !m_mesh.faceNormals.empty() && m_segmentByNormal; + + std::unordered_set processedFaces; + std::queue waitFaces; + for (const auto& indexInGroup : group) { + if (processedFaces.find(indexInGroup) != processedFaces.end()) continue; - holeVertexLink[face.indices[j]].push_back(face.indices[i]); + waitFaces.push(indexInGroup); + std::vector island; + while (!waitFaces.empty()) { + size_t index = waitFaces.front(); + waitFaces.pop(); + if (processedFaces.find(index) != processedFaces.end()) + continue; + const auto& face = m_mesh.faces[index]; + for (size_t i = 0; i < 3; i++) { + size_t j = (i + 1) % 3; + auto findOppositeFaceResult = edgeToFaceMap.find({ face.indices[j], face.indices[i] }); + if (findOppositeFaceResult == edgeToFaceMap.end()) + continue; + if (segmentByNormal) { + if (dotProduct(m_mesh.faceNormals[findOppositeFaceResult->second], + m_mesh.faceNormals[m_segmentPreferMorePieces ? indexInGroup : index]) + < m_segmentDotProductThreshold) { + continue; + } + } + waitFaces.push(findOppositeFaceResult->second); + } + island.push_back(index); + processedFaces.insert(index); + } + if (island.empty()) + continue; + islands.push_back(island); } } - - std::vector, double>> holeRings; - while (!holeVertexLink.empty()) { - bool foundRing = false; - std::vector ring; - std::unordered_set visited; - std::set> visitedPath; - double ringLength = 0; - while (!foundRing) { - ring.clear(); - visited.clear(); - ringLength = 0; - auto first = holeVertexLink.begin()->first; - auto index = first; - auto prev = first; - ring.push_back(first); - visited.insert(first); - while (true) { - auto findLinkResult = holeVertexLink.find(index); - if (findLinkResult == holeVertexLink.end()) { - return false; + + double UvUnwrapper::distanceBetweenVertices(const Vertex& first, const Vertex& second) + { + float x = first.xyz[0] - second.xyz[0]; + float y = first.xyz[1] - second.xyz[1]; + float z = first.xyz[2] - second.xyz[2]; + return std::sqrt(x * x + y * y + z * z); + } + + void UvUnwrapper::calculateFaceTextureBoundingBox(const std::vector& faceTextureCoords, + float& left, float& top, float& right, float& bottom) + { + bool leftFirstTime = true; + bool topFirstTime = true; + bool rightFirstTime = true; + bool bottomFirstTime = true; + for (const auto& item : faceTextureCoords) { + for (int i = 0; i < 3; ++i) { + const auto& x = item.coords[i].uv[0]; + const auto& y = item.coords[i].uv[1]; + if (leftFirstTime || x < left) { + left = x; + leftFirstTime = false; } - for (const auto &item: findLinkResult->second) { - if (item == first) { - foundRing = true; - break; + if (rightFirstTime || x > right) { + right = x; + rightFirstTime = false; + } + if (topFirstTime || y < top) { + top = y; + topFirstTime = false; + } + if (bottomFirstTime || y > bottom) { + bottom = y; + bottomFirstTime = false; + } + } + } + } + + void UvUnwrapper::triangulateRing(const std::vector& verticies, + std::vector& faces, const std::vector& ring) + { + triangulate(verticies, faces, ring); + } + + // The hole filling faces should be put in the back of faces vector, so these uv coords of appended faces will be disgarded. + bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector& verticies, std::vector& faces, size_t* remainingHoleNum) + { + std::map, size_t> edgeToFaceMap; + buildEdgeToFaceMap(faces, edgeToFaceMap); + + std::map> holeVertexLink; + for (const auto& face : faces) { + for (size_t i = 0; i < 3; i++) { + size_t j = (i + 1) % 3; + auto findOppositeFaceResult = edgeToFaceMap.find({ face.indices[j], face.indices[i] }); + if (findOppositeFaceResult != edgeToFaceMap.end()) + continue; + holeVertexLink[face.indices[j]].push_back(face.indices[i]); + } + } + + std::vector, double>> holeRings; + while (!holeVertexLink.empty()) { + bool foundRing = false; + std::vector ring; + std::unordered_set visited; + std::set> visitedPath; + double ringLength = 0; + while (!foundRing) { + ring.clear(); + visited.clear(); + ringLength = 0; + auto first = holeVertexLink.begin()->first; + auto index = first; + auto prev = first; + ring.push_back(first); + visited.insert(first); + while (true) { + auto findLinkResult = holeVertexLink.find(index); + if (findLinkResult == holeVertexLink.end()) { + return false; } - } - if (foundRing) - break; - if (findLinkResult->second.size() > 1) { - bool foundNewPath = false; - for (const auto &item: findLinkResult->second) { - if (visitedPath.find({prev, item}) == visitedPath.end()) { - index = item; - foundNewPath = true; + for (const auto& item : findLinkResult->second) { + if (item == first) { + foundRing = true; break; } } - if (!foundNewPath) { - return false; + if (foundRing) + break; + if (findLinkResult->second.size() > 1) { + bool foundNewPath = false; + for (const auto& item : findLinkResult->second) { + if (visitedPath.find({ prev, item }) == visitedPath.end()) { + index = item; + foundNewPath = true; + break; + } + } + if (!foundNewPath) { + return false; + } + visitedPath.insert({ prev, index }); + } else { + index = *findLinkResult->second.begin(); } - visitedPath.insert({prev, index}); - } else { - index = *findLinkResult->second.begin(); + if (visited.find(index) != visited.end()) { + while (index != *ring.begin()) + ring.erase(ring.begin()); + foundRing = true; + break; + } + ring.push_back(index); + visited.insert(index); + ringLength += distanceBetweenVertices(verticies[index], verticies[prev]); + prev = index; } - if (visited.find(index) != visited.end()) { - while (index != *ring.begin()) - ring.erase(ring.begin()); - foundRing = true; - break; - } - ring.push_back(index); - visited.insert(index); - ringLength += distanceBetweenVertices(verticies[index], verticies[prev]); - prev = index; } - } - if (ring.size() < 3) { - return false; - } - holeRings.push_back({ring, ringLength}); - for (size_t i = 0; i < ring.size(); ++i) { - size_t j = (i + 1) % ring.size(); - auto findLinkResult = holeVertexLink.find(ring[i]); - for (auto it = findLinkResult->second.begin(); it != findLinkResult->second.end(); ++it) { - if (*it == ring[j]) { - findLinkResult->second.erase(it); - if (findLinkResult->second.empty()) - holeVertexLink.erase(ring[i]); - break; + if (ring.size() < 3) { + return false; + } + holeRings.push_back({ ring, ringLength }); + for (size_t i = 0; i < ring.size(); ++i) { + size_t j = (i + 1) % ring.size(); + auto findLinkResult = holeVertexLink.find(ring[i]); + for (auto it = findLinkResult->second.begin(); it != findLinkResult->second.end(); ++it) { + if (*it == ring[j]) { + findLinkResult->second.erase(it); + if (findLinkResult->second.empty()) + holeVertexLink.erase(ring[i]); + break; + } } } } - } - - if (holeRings.size() > 1) { - // Sort by ring length, the longer ring sit in the lower array indices - std::sort(holeRings.begin(), holeRings.end(), [](const std::pair, double> &first, const std::pair, double> &second) { - return first.second > second.second; - }); - for (size_t i = 1; i < holeRings.size(); ++i) { - triangulateRing(verticies, faces, holeRings[i].first); - } - holeRings.resize(1); - } - - if (remainingHoleNum) - *remainingHoleNum = holeRings.size(); - return true; -} -void UvUnwrapper::makeSeamAndCut(const std::vector &verticies, - const std::vector &faces, - std::map &localToGlobalFacesMap, - std::vector &firstGroup, std::vector &secondGroup) -{ - // We group the chart by first pick the top(max y) triangle, then join the adjecent traigles until the joint count reach to half of total - - double maxY = 0; - bool firstTime = true; - int choosenIndex = -1; - for (decltype(faces.size()) i = 0; i < faces.size(); ++i) { - const auto &face = faces[i]; - for (int j = 0; j < 3; ++j) { - const auto &vertex = verticies[face.indices[j]]; - if (firstTime || vertex.xyz[2] > maxY) { - maxY = vertex.xyz[2]; - firstTime = false; - choosenIndex = i; + if (holeRings.size() > 1) { + // Sort by ring length, the longer ring sit in the lower array indices + std::sort(holeRings.begin(), holeRings.end(), [](const std::pair, double>& first, const std::pair, double>& second) { + return first.second > second.second; + }); + for (size_t i = 1; i < holeRings.size(); ++i) { + triangulateRing(verticies, faces, holeRings[i].first); + } + holeRings.resize(1); + } + + if (remainingHoleNum) + *remainingHoleNum = holeRings.size(); + return true; + } + + void UvUnwrapper::makeSeamAndCut(const std::vector& verticies, + const std::vector& faces, + std::map& localToGlobalFacesMap, + std::vector& firstGroup, std::vector& secondGroup) + { + // We group the chart by first pick the top(max y) triangle, then join the adjecent traigles until the joint count reach to half of total + + double maxY = 0; + bool firstTime = true; + int choosenIndex = -1; + for (decltype(faces.size()) i = 0; i < faces.size(); ++i) { + const auto& face = faces[i]; + for (int j = 0; j < 3; ++j) { + const auto& vertex = verticies[face.indices[j]]; + if (firstTime || vertex.xyz[2] > maxY) { + maxY = vertex.xyz[2]; + firstTime = false; + choosenIndex = i; + } } } - } - if (-1 == choosenIndex) - return; - - std::map, size_t> edgeToFaceMap; - buildEdgeToFaceMap(faces, edgeToFaceMap); - - std::unordered_set processedFaces; - std::queue waitFaces; - waitFaces.push(choosenIndex); - while (!waitFaces.empty()) { - auto index = waitFaces.front(); - waitFaces.pop(); - if (processedFaces.find(index) != processedFaces.end()) - continue; - const auto &face = faces[index]; - for (size_t i = 0; i < 3; i++) { - size_t j = (i + 1) % 3; - auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]}); - if (findOppositeFaceResult == edgeToFaceMap.end()) + if (-1 == choosenIndex) + return; + + std::map, size_t> edgeToFaceMap; + buildEdgeToFaceMap(faces, edgeToFaceMap); + + std::unordered_set processedFaces; + std::queue waitFaces; + waitFaces.push(choosenIndex); + while (!waitFaces.empty()) { + auto index = waitFaces.front(); + waitFaces.pop(); + if (processedFaces.find(index) != processedFaces.end()) continue; - waitFaces.push(findOppositeFaceResult->second); + const auto& face = faces[index]; + for (size_t i = 0; i < 3; i++) { + size_t j = (i + 1) % 3; + auto findOppositeFaceResult = edgeToFaceMap.find({ face.indices[j], face.indices[i] }); + if (findOppositeFaceResult == edgeToFaceMap.end()) + continue; + waitFaces.push(findOppositeFaceResult->second); + } + processedFaces.insert(index); + firstGroup.push_back(localToGlobalFacesMap[index]); + if (firstGroup.size() * 2 >= faces.size()) + break; + } + for (decltype(faces.size()) index = 0; index < faces.size(); ++index) { + if (processedFaces.find(index) != processedFaces.end()) + continue; + secondGroup.push_back(localToGlobalFacesMap[index]); } - processedFaces.insert(index); - firstGroup.push_back(localToGlobalFacesMap[index]); - if (firstGroup.size() * 2 >= faces.size()) - break; } - for (decltype(faces.size()) index = 0; index < faces.size(); ++index) { - if (processedFaces.find(index) != processedFaces.end()) - continue; - secondGroup.push_back(localToGlobalFacesMap[index]); - } -} -void UvUnwrapper::calculateSizeAndRemoveInvalidCharts() -{ - auto charts = m_charts; - auto chartSourcePartitions = m_chartSourcePartitions; - m_charts.clear(); - m_chartSourcePartitions.clear(); - for (size_t chartIndex = 0; chartIndex < charts.size(); ++chartIndex) { - auto &chart = charts[chartIndex]; - float left, top, right, bottom; - left = top = right = bottom = 0; - calculateFaceTextureBoundingBox(chart.second, left, top, right, bottom); - std::pair size = {right - left, bottom - top}; - if (size.first <= 0 || std::isnan(size.first) || std::isinf(size.first) || - size.second <= 0 || std::isnan(size.second) || std::isinf(size.second)) { - continue; - } - float surfaceArea = 0; - for (const auto &item: chart.first) { - const auto &face = m_mesh.faces[item]; - surfaceArea += areaOf3dTriangle(Eigen::Vector3d(m_mesh.vertices[face.indices[0]].xyz[0], - m_mesh.vertices[face.indices[0]].xyz[1], - m_mesh.vertices[face.indices[0]].xyz[2]), - Eigen::Vector3d(m_mesh.vertices[face.indices[1]].xyz[0], - m_mesh.vertices[face.indices[1]].xyz[1], - m_mesh.vertices[face.indices[1]].xyz[2]), - Eigen::Vector3d(m_mesh.vertices[face.indices[2]].xyz[0], - m_mesh.vertices[face.indices[2]].xyz[1], - m_mesh.vertices[face.indices[2]].xyz[2])); - } - float uvArea = 0; - for (auto &item: chart.second) { - for (int i = 0; i < 3; ++i) { - item.coords[i].uv[0] -= left; - item.coords[i].uv[1] -= top; + void UvUnwrapper::calculateSizeAndRemoveInvalidCharts() + { + auto charts = m_charts; + auto chartSourcePartitions = m_chartSourcePartitions; + m_charts.clear(); + m_chartSourcePartitions.clear(); + for (size_t chartIndex = 0; chartIndex < charts.size(); ++chartIndex) { + auto& chart = charts[chartIndex]; + float left, top, right, bottom; + left = top = right = bottom = 0; + calculateFaceTextureBoundingBox(chart.second, left, top, right, bottom); + std::pair size = { right - left, bottom - top }; + if (size.first <= 0 || std::isnan(size.first) || std::isinf(size.first) || size.second <= 0 || std::isnan(size.second) || std::isinf(size.second)) { + continue; } - uvArea += areaOf2dTriangle(Eigen::Vector2d(item.coords[0].uv[0], item.coords[0].uv[1]), - Eigen::Vector2d(item.coords[1].uv[0], item.coords[1].uv[1]), - Eigen::Vector2d(item.coords[2].uv[0], item.coords[2].uv[1])); - } - if (m_enableRotation) { - Eigen::Vector3d center(size.first * 0.5, size.second * 0.5, 0); - float minRectArea = size.first * size.second; - float minRectLeft = 0; - float minRectTop = 0; - bool rotated = false; - for (const auto °ree: m_rotateDegrees) { - Eigen::Matrix3d matrix; - matrix = Eigen::AngleAxisd(degree * 180.0 / 3.1415926, Eigen::Vector3d::UnitZ()); - std::vector rotatedUvs; - for (auto &item: chart.second) { - FaceTextureCoords rotatedCoords; - for (int i = 0; i < 3; ++i) { - Eigen::Vector3d point(item.coords[i].uv[0], item.coords[i].uv[1], 0); - point -= center; - point = matrix * point; - rotatedCoords.coords[i].uv[0] = point.x(); - rotatedCoords.coords[i].uv[1] = point.y(); + float surfaceArea = 0; + for (const auto& item : chart.first) { + const auto& face = m_mesh.faces[item]; + surfaceArea += areaOf3dTriangle(Eigen::Vector3d(m_mesh.vertices[face.indices[0]].xyz[0], + m_mesh.vertices[face.indices[0]].xyz[1], + m_mesh.vertices[face.indices[0]].xyz[2]), + Eigen::Vector3d(m_mesh.vertices[face.indices[1]].xyz[0], + m_mesh.vertices[face.indices[1]].xyz[1], + m_mesh.vertices[face.indices[1]].xyz[2]), + Eigen::Vector3d(m_mesh.vertices[face.indices[2]].xyz[0], + m_mesh.vertices[face.indices[2]].xyz[1], + m_mesh.vertices[face.indices[2]].xyz[2])); + } + float uvArea = 0; + for (auto& item : chart.second) { + for (int i = 0; i < 3; ++i) { + item.coords[i].uv[0] -= left; + item.coords[i].uv[1] -= top; + } + uvArea += areaOf2dTriangle(Eigen::Vector2d(item.coords[0].uv[0], item.coords[0].uv[1]), + Eigen::Vector2d(item.coords[1].uv[0], item.coords[1].uv[1]), + Eigen::Vector2d(item.coords[2].uv[0], item.coords[2].uv[1])); + } + if (m_enableRotation) { + Eigen::Vector3d center(size.first * 0.5, size.second * 0.5, 0); + float minRectArea = size.first * size.second; + float minRectLeft = 0; + float minRectTop = 0; + bool rotated = false; + for (const auto& degree : m_rotateDegrees) { + Eigen::Matrix3d matrix; + matrix = Eigen::AngleAxisd(degree * 180.0 / 3.1415926, Eigen::Vector3d::UnitZ()); + std::vector rotatedUvs; + for (auto& item : chart.second) { + FaceTextureCoords rotatedCoords; + for (int i = 0; i < 3; ++i) { + Eigen::Vector3d point(item.coords[i].uv[0], item.coords[i].uv[1], 0); + point -= center; + point = matrix * point; + rotatedCoords.coords[i].uv[0] = point.x(); + rotatedCoords.coords[i].uv[1] = point.y(); + } + rotatedUvs.push_back(rotatedCoords); + } + left = top = right = bottom = 0; + calculateFaceTextureBoundingBox(rotatedUvs, left, top, right, bottom); + std::pair newSize = { right - left, bottom - top }; + float newRectArea = newSize.first * newSize.second; + if (newRectArea < minRectArea) { + minRectArea = newRectArea; + size = newSize; + minRectLeft = left; + minRectTop = top; + rotated = true; + chart.second = rotatedUvs; } - rotatedUvs.push_back(rotatedCoords); } - left = top = right = bottom = 0; - calculateFaceTextureBoundingBox(rotatedUvs, left, top, right, bottom); - std::pair newSize = {right - left, bottom - top}; - float newRectArea = newSize.first * newSize.second; - if (newRectArea < minRectArea) { - minRectArea = newRectArea; - size = newSize; - minRectLeft = left; - minRectTop = top; - rotated = true; - chart.second = rotatedUvs; - } - } - if (rotated) { - for (auto &item: chart.second) { - for (int i = 0; i < 3; ++i) { - item.coords[i].uv[0] -= minRectLeft; - item.coords[i].uv[1] -= minRectTop; + if (rotated) { + for (auto& item : chart.second) { + for (int i = 0; i < 3; ++i) { + item.coords[i].uv[0] -= minRectLeft; + item.coords[i].uv[1] -= minRectTop; + } } } } + float ratioOfSurfaceAreaAndUvArea = uvArea > 0 ? surfaceArea / uvArea : 1.0; + float scale = ratioOfSurfaceAreaAndUvArea * m_texelSizePerUnit; + m_chartSizes.push_back(size); + m_scaledChartSizes.push_back(std::make_pair(size.first * scale, size.second * scale)); + m_charts.push_back(chart); + m_chartSourcePartitions.push_back(chartSourcePartitions[chartIndex]); } - float ratioOfSurfaceAreaAndUvArea = uvArea > 0 ? surfaceArea / uvArea : 1.0; - float scale = ratioOfSurfaceAreaAndUvArea * m_texelSizePerUnit; - m_chartSizes.push_back(size); - m_scaledChartSizes.push_back(std::make_pair(size.first * scale, size.second * scale)); - m_charts.push_back(chart); - m_chartSourcePartitions.push_back(chartSourcePartitions[chartIndex]); } -} -void UvUnwrapper::packCharts() -{ - ChartPacker chartPacker; - chartPacker.setCharts(m_scaledChartSizes); - m_resultTextureSize = chartPacker.pack(); - m_chartRects.resize(m_chartSizes.size()); - const std::vector> &packedResult = chartPacker.getResult(); - for (decltype(m_charts.size()) i = 0; i < m_charts.size(); ++i) { - const auto &chartSize = m_chartSizes[i]; - auto &chart = m_charts[i]; - if (i >= packedResult.size()) { - for (auto &item: chart.second) { - for (int i = 0; i < 3; ++i) { - item.coords[i].uv[0] = 0; - item.coords[i].uv[1] = 0; + void UvUnwrapper::packCharts() + { + ChartPacker chartPacker; + chartPacker.setCharts(m_scaledChartSizes); + m_resultTextureSize = chartPacker.pack(); + m_chartRects.resize(m_chartSizes.size()); + const std::vector>& packedResult = chartPacker.getResult(); + for (decltype(m_charts.size()) i = 0; i < m_charts.size(); ++i) { + const auto& chartSize = m_chartSizes[i]; + auto& chart = m_charts[i]; + if (i >= packedResult.size()) { + for (auto& item : chart.second) { + for (int i = 0; i < 3; ++i) { + item.coords[i].uv[0] = 0; + item.coords[i].uv[1] = 0; + } + } + continue; + } + const auto& result = packedResult[i]; + auto& left = std::get<0>(result); + auto& top = std::get<1>(result); + auto& width = std::get<2>(result); + auto& height = std::get<3>(result); + auto& flipped = std::get<4>(result); + if (flipped) + m_chartRects[i] = { left, top, height, width }; + else + m_chartRects[i] = { left, top, width, height }; + if (flipped) { + for (auto& item : chart.second) { + for (int i = 0; i < 3; ++i) { + std::swap(item.coords[i].uv[0], item.coords[i].uv[1]); + } } } - continue; - } - const auto &result = packedResult[i]; - auto &left = std::get<0>(result); - auto &top = std::get<1>(result); - auto &width = std::get<2>(result); - auto &height = std::get<3>(result); - auto &flipped = std::get<4>(result); - if (flipped) - m_chartRects[i] = {left, top, height, width}; - else - m_chartRects[i] = {left, top, width, height}; - if (flipped) { - for (auto &item: chart.second) { + for (auto& item : chart.second) { for (int i = 0; i < 3; ++i) { - std::swap(item.coords[i].uv[0], item.coords[i].uv[1]); + item.coords[i].uv[0] /= chartSize.first; + item.coords[i].uv[1] /= chartSize.second; + item.coords[i].uv[0] *= width; + item.coords[i].uv[1] *= height; + item.coords[i].uv[0] += left; + item.coords[i].uv[1] += top; } } } - for (auto &item: chart.second) { - for (int i = 0; i < 3; ++i) { - item.coords[i].uv[0] /= chartSize.first; - item.coords[i].uv[1] /= chartSize.second; - item.coords[i].uv[0] *= width; - item.coords[i].uv[1] *= height; - item.coords[i].uv[0] += left; - item.coords[i].uv[1] += top; + } + + void UvUnwrapper::finalizeUv() + { + m_faceUvs.resize(m_mesh.faces.size()); + for (const auto& chart : m_charts) { + for (decltype(chart.second.size()) i = 0; i < chart.second.size(); ++i) { + auto& faceUv = m_faceUvs[chart.first[i]]; + faceUv = chart.second[i]; } } } -} -void UvUnwrapper::finalizeUv() -{ - m_faceUvs.resize(m_mesh.faces.size()); - for (const auto &chart: m_charts) { - for (decltype(chart.second.size()) i = 0; i < chart.second.size(); ++i) { - auto &faceUv = m_faceUvs[chart.first[i]]; - faceUv = chart.second[i]; - } - } -} - -void UvUnwrapper::partition() -{ - m_partitions.clear(); - if (m_mesh.facePartitions.empty()) { - for (decltype(m_mesh.faces.size()) i = 0; i < m_mesh.faces.size(); i++) { - m_partitions[0].push_back(i); - } - } else { - for (decltype(m_mesh.faces.size()) i = 0; i < m_mesh.faces.size(); i++) { - int partition = m_mesh.facePartitions[i]; - m_partitions[partition].push_back(i); - } - } -} - -void UvUnwrapper::unwrapSingleIsland(const std::vector &group, int sourcePartition, bool skipCheckHoles) -{ - if (group.empty()) - return; - - std::vector localVertices; - std::vector localFaces; - std::map globalToLocalVerticesMap; - std::map localToGlobalFacesMap; - for (decltype(group.size()) i = 0; i < group.size(); ++i) { - const auto &globalFace = m_mesh.faces[group[i]]; - Face localFace; - for (size_t j = 0; j < 3; j++) { - int globalVertexIndex = globalFace.indices[j]; - if (globalToLocalVerticesMap.find(globalVertexIndex) == globalToLocalVerticesMap.end()) { - localVertices.push_back(m_mesh.vertices[globalVertexIndex]); - globalToLocalVerticesMap[globalVertexIndex] = (int)localVertices.size() - 1; + void UvUnwrapper::partition() + { + m_partitions.clear(); + if (m_mesh.facePartitions.empty()) { + for (decltype(m_mesh.faces.size()) i = 0; i < m_mesh.faces.size(); i++) { + m_partitions[0].push_back(i); + } + } else { + for (decltype(m_mesh.faces.size()) i = 0; i < m_mesh.faces.size(); i++) { + int partition = m_mesh.facePartitions[i]; + m_partitions[partition].push_back(i); } - localFace.indices[j] = globalToLocalVerticesMap[globalVertexIndex]; } - localFaces.push_back(localFace); - localToGlobalFacesMap[localFaces.size() - 1] = group[i]; } - decltype(localFaces.size()) faceNumBeforeFix = localFaces.size(); - size_t remainingHoleNumAfterFix = 0; - if (!fixHolesExceptTheLongestRing(localVertices, localFaces, &remainingHoleNumAfterFix)) { - return; - } - if (1 == remainingHoleNumAfterFix) { - parametrizeSingleGroup(localVertices, localFaces, localToGlobalFacesMap, faceNumBeforeFix, sourcePartition); - return; - } - - if (0 == remainingHoleNumAfterFix) { - std::vector firstGroup; - std::vector secondGroup; - makeSeamAndCut(localVertices, localFaces, localToGlobalFacesMap, firstGroup, secondGroup); - if (firstGroup.empty() || secondGroup.empty()) { + void UvUnwrapper::unwrapSingleIsland(const std::vector& group, int sourcePartition, bool skipCheckHoles) + { + if (group.empty()) + return; + + std::vector localVertices; + std::vector localFaces; + std::map globalToLocalVerticesMap; + std::map localToGlobalFacesMap; + for (decltype(group.size()) i = 0; i < group.size(); ++i) { + const auto& globalFace = m_mesh.faces[group[i]]; + Face localFace; + for (size_t j = 0; j < 3; j++) { + int globalVertexIndex = globalFace.indices[j]; + if (globalToLocalVerticesMap.find(globalVertexIndex) == globalToLocalVerticesMap.end()) { + localVertices.push_back(m_mesh.vertices[globalVertexIndex]); + globalToLocalVerticesMap[globalVertexIndex] = (int)localVertices.size() - 1; + } + localFace.indices[j] = globalToLocalVerticesMap[globalVertexIndex]; + } + localFaces.push_back(localFace); + localToGlobalFacesMap[localFaces.size() - 1] = group[i]; + } + + decltype(localFaces.size()) faceNumBeforeFix = localFaces.size(); + size_t remainingHoleNumAfterFix = 0; + if (!fixHolesExceptTheLongestRing(localVertices, localFaces, &remainingHoleNumAfterFix)) { + return; + } + if (1 == remainingHoleNumAfterFix) { + parametrizeSingleGroup(localVertices, localFaces, localToGlobalFacesMap, faceNumBeforeFix, sourcePartition); return; } - unwrapSingleIsland(firstGroup, sourcePartition, true); - unwrapSingleIsland(secondGroup, sourcePartition, true); - return; - } -} -void UvUnwrapper::parametrizeSingleGroup(const std::vector &verticies, - const std::vector &faces, - std::map &localToGlobalFacesMap, + if (0 == remainingHoleNumAfterFix) { + std::vector firstGroup; + std::vector secondGroup; + makeSeamAndCut(localVertices, localFaces, localToGlobalFacesMap, firstGroup, secondGroup); + if (firstGroup.empty() || secondGroup.empty()) { + return; + } + unwrapSingleIsland(firstGroup, sourcePartition, true); + unwrapSingleIsland(secondGroup, sourcePartition, true); + return; + } + } + + void UvUnwrapper::parametrizeSingleGroup(const std::vector& verticies, + const std::vector& faces, + std::map& localToGlobalFacesMap, size_t faceNumToChart, int sourcePartition) -{ - std::vector localVertexUvs; - if (!parametrize(verticies, faces, localVertexUvs)) - return; - std::pair, std::vector> chart; - for (size_t i = 0; i < faceNumToChart; ++i) { - const auto &localFace = faces[i]; - auto globalFaceIndex = localToGlobalFacesMap[i]; - FaceTextureCoords faceUv; - for (size_t j = 0; j < 3; j++) { - const auto &localVertexIndex = localFace.indices[j]; - const auto &vertexUv = localVertexUvs[localVertexIndex]; - faceUv.coords[j].uv[0] = vertexUv.uv[0]; - faceUv.coords[j].uv[1] = vertexUv.uv[1]; + { + std::vector localVertexUvs; + if (!parametrize(verticies, faces, localVertexUvs)) + return; + std::pair, std::vector> chart; + for (size_t i = 0; i < faceNumToChart; ++i) { + const auto& localFace = faces[i]; + auto globalFaceIndex = localToGlobalFacesMap[i]; + FaceTextureCoords faceUv; + for (size_t j = 0; j < 3; j++) { + const auto& localVertexIndex = localFace.indices[j]; + const auto& vertexUv = localVertexUvs[localVertexIndex]; + faceUv.coords[j].uv[0] = vertexUv.uv[0]; + faceUv.coords[j].uv[1] = vertexUv.uv[1]; + } + chart.first.push_back(globalFaceIndex); + chart.second.push_back(faceUv); } - chart.first.push_back(globalFaceIndex); - chart.second.push_back(faceUv); + if (chart.first.empty()) + return; + m_charts.push_back(chart); + m_chartSourcePartitions.push_back(sourcePartition); } - if (chart.first.empty()) - return; - m_charts.push_back(chart); - m_chartSourcePartitions.push_back(sourcePartition); -} -float UvUnwrapper::getTextureSize() const -{ - return m_resultTextureSize; -} - -void UvUnwrapper::unwrap() -{ - partition(); - - m_faceUvs.resize(m_mesh.faces.size()); - for (const auto &group: m_partitions) { - std::vector> islands; - splitPartitionToIslands(group.second, islands); - for (const auto &island: islands) - unwrapSingleIsland(island, group.first); + float UvUnwrapper::getTextureSize() const + { + return m_resultTextureSize; + } + + void UvUnwrapper::unwrap() + { + partition(); + + m_faceUvs.resize(m_mesh.faces.size()); + for (const auto& group : m_partitions) { + std::vector> islands; + splitPartitionToIslands(group.second, islands); + for (const auto& island : islands) + unwrapSingleIsland(island, group.first); + } + + calculateSizeAndRemoveInvalidCharts(); + packCharts(); + finalizeUv(); } - - calculateSizeAndRemoveInvalidCharts(); - packCharts(); - finalizeUv(); -} } } diff --git a/dust3d/uv/uv_unwrapper.h b/dust3d/uv/uv_unwrapper.h index 9d5d4d13..aeb4366a 100644 --- a/dust3d/uv/uv_unwrapper.h +++ b/dust3d/uv/uv_unwrapper.h @@ -23,68 +23,65 @@ #ifndef DUST3D_UV_UV_UNWRAPPER_H_ #define DUST3D_UV_UV_UNWRAPPER_H_ -#include +#include #include #include -#include +#include -namespace dust3d -{ -namespace uv -{ +namespace dust3d { +namespace uv { -class UvUnwrapper -{ -public: - void setMesh(const Mesh &mesh); - void setTexelSize(float texelSize); - void unwrap(); - const std::vector &getFaceUvs() const; - const std::vector &getChartRects() const; - const std::vector &getChartSourcePartitions() const; - float getTextureSize() const; + class UvUnwrapper { + public: + void setMesh(const Mesh& mesh); + void setTexelSize(float texelSize); + void unwrap(); + const std::vector& getFaceUvs() const; + const std::vector& getChartRects() const; + const std::vector& getChartSourcePartitions() const; + float getTextureSize() const; -private: - void partition(); - void splitPartitionToIslands(const std::vector &group, std::vector> &islands); - void unwrapSingleIsland(const std::vector &group, int sourcePartition, bool skipCheckHoles=false); - void parametrizeSingleGroup(const std::vector &verticies, - const std::vector &faces, - std::map &localToGlobalFacesMap, - size_t faceNumToChart, - int sourcePartition); - bool fixHolesExceptTheLongestRing(const std::vector &verticies, std::vector &faces, size_t *remainingHoleNum=nullptr); - void makeSeamAndCut(const std::vector &verticies, - const std::vector &faces, - std::map &localToGlobalFacesMap, - std::vector &firstGroup, std::vector &secondGroup); - void calculateSizeAndRemoveInvalidCharts(); - void packCharts(); - void finalizeUv(); - void buildEdgeToFaceMap(const std::vector &group, std::map, size_t> &edgeToFaceMap); - void buildEdgeToFaceMap(const std::vector &faces, std::map, size_t> &edgeToFaceMap); - double distanceBetweenVertices(const Vertex &first, const Vertex &second); - void triangulateRing(const std::vector &verticies, - std::vector &faces, const std::vector &ring); - void calculateFaceTextureBoundingBox(const std::vector &faceTextureCoords, - float &left, float &top, float &right, float &bottom); + private: + void partition(); + void splitPartitionToIslands(const std::vector& group, std::vector>& islands); + void unwrapSingleIsland(const std::vector& group, int sourcePartition, bool skipCheckHoles = false); + void parametrizeSingleGroup(const std::vector& verticies, + const std::vector& faces, + std::map& localToGlobalFacesMap, + size_t faceNumToChart, + int sourcePartition); + bool fixHolesExceptTheLongestRing(const std::vector& verticies, std::vector& faces, size_t* remainingHoleNum = nullptr); + void makeSeamAndCut(const std::vector& verticies, + const std::vector& faces, + std::map& localToGlobalFacesMap, + std::vector& firstGroup, std::vector& secondGroup); + void calculateSizeAndRemoveInvalidCharts(); + void packCharts(); + void finalizeUv(); + void buildEdgeToFaceMap(const std::vector& group, std::map, size_t>& edgeToFaceMap); + void buildEdgeToFaceMap(const std::vector& faces, std::map, size_t>& edgeToFaceMap); + double distanceBetweenVertices(const Vertex& first, const Vertex& second); + void triangulateRing(const std::vector& verticies, + std::vector& faces, const std::vector& ring); + void calculateFaceTextureBoundingBox(const std::vector& faceTextureCoords, + float& left, float& top, float& right, float& bottom); - Mesh m_mesh; - std::vector m_faceUvs; - std::map> m_partitions; - std::vector, std::vector>> m_charts; - std::vector> m_chartSizes; - std::vector> m_scaledChartSizes; - std::vector m_chartRects; - std::vector m_chartSourcePartitions; - bool m_segmentByNormal = true; - float m_segmentDotProductThreshold = 0.0; //90 degrees - float m_texelSizePerUnit = 1.0; - float m_resultTextureSize = 0; - bool m_segmentPreferMorePieces = true; - bool m_enableRotation = true; - static const std::vector m_rotateDegrees; -}; + Mesh m_mesh; + std::vector m_faceUvs; + std::map> m_partitions; + std::vector, std::vector>> m_charts; + std::vector> m_chartSizes; + std::vector> m_scaledChartSizes; + std::vector m_chartRects; + std::vector m_chartSourcePartitions; + bool m_segmentByNormal = true; + float m_segmentDotProductThreshold = 0.0; //90 degrees + float m_texelSizePerUnit = 1.0; + float m_resultTextureSize = 0; + bool m_segmentPreferMorePieces = true; + bool m_enableRotation = true; + static const std::vector m_rotateDegrees; + }; } }