Fix cut face base normal.

master
Jeremy Hu 2019-02-26 22:54:58 +09:30
parent 02bb32391e
commit 2b44576f22
4 changed files with 46 additions and 10 deletions

View File

@ -10,6 +10,7 @@
#include "material.h" #include "material.h"
int TextureGenerator::m_textureSize = 1024; int TextureGenerator::m_textureSize = 1024;
QColor TextureGenerator::m_defaultTextureColor = Qt::darkGray;
TextureGenerator::TextureGenerator(const Outcome &outcome, Snapshot *snapshot) : TextureGenerator::TextureGenerator(const Outcome &outcome, Snapshot *snapshot) :
m_resultTextureGuideImage(nullptr), m_resultTextureGuideImage(nullptr),
@ -233,7 +234,7 @@ void TextureGenerator::generate()
auto createImageBeginTime = countTimeConsumed.elapsed(); auto createImageBeginTime = countTimeConsumed.elapsed();
m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureColorImage->fill(Theme::white); m_resultTextureColorImage->fill(m_defaultTextureColor);
m_resultTextureBorderImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureBorderImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureBorderImage->fill(Qt::transparent); m_resultTextureBorderImage->fill(Qt::transparent);
@ -315,7 +316,7 @@ void TextureGenerator::generate()
if (findSourceNodeResult != nodeMap.end() && nullptr != findSourceNodeResult->second) { if (findSourceNodeResult != nodeMap.end() && nullptr != findSourceNodeResult->second) {
texturePainter.fillPath(path, QBrush(findSourceNodeResult->second->color)); texturePainter.fillPath(path, QBrush(findSourceNodeResult->second->color));
} else { } else {
texturePainter.fillPath(path, QBrush(Theme::white)); texturePainter.fillPath(path, QBrush(m_defaultTextureColor));
} }
} }
// Copy normal texture if there is one // Copy normal texture if there is one

View File

@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <vector> #include <vector>
#include <QImage> #include <QImage>
#include <QColor>
#include "outcome.h" #include "outcome.h"
#include "meshloader.h" #include "meshloader.h"
#include "snapshot.h" #include "snapshot.h"
@ -36,6 +37,7 @@ public slots:
void process(); void process();
public: public:
static int m_textureSize; static int m_textureSize;
static QColor m_defaultTextureColor;
private: private:
void prepare(); void prepare();
QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=7); QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=7);

View File

@ -104,6 +104,8 @@ void Builder::prepareNode(size_t nodeIndex)
neighborRadius); neighborRadius);
node.initialBaseNormal = baseNormalResult.first; node.initialBaseNormal = baseNormalResult.first;
node.hasInitialBaseNormal = baseNormalResult.second; node.hasInitialBaseNormal = baseNormalResult.second;
if (node.hasInitialBaseNormal)
node.initialBaseNormal = revisedBaseNormalAcordingToCutNormal(node.initialBaseNormal, node.traverseDirection);
} }
void Builder::resolveBaseNormalRecursively(size_t nodeIndex) void Builder::resolveBaseNormalRecursively(size_t nodeIndex)
@ -260,6 +262,9 @@ bool Builder::build()
for (const auto &nodeIndex: m_sortedNodeIndices) { for (const auto &nodeIndex: m_sortedNodeIndices) {
resolveBaseNormalRecursively(nodeIndex); resolveBaseNormalRecursively(nodeIndex);
} }
unifyBaseNormals();
for (const auto &nodeIndex: m_sortedNodeIndices) { for (const auto &nodeIndex: m_sortedNodeIndices) {
if (!generateCutsForNode(nodeIndex)) if (!generateCutsForNode(nodeIndex))
succeed = false; succeed = false;
@ -555,13 +560,24 @@ bool Builder::swallowEdgeForNode(size_t nodeIndex, size_t edgeOrder)
return true; return true;
} }
void Builder::makeCut(const QVector3D &position, void Builder::unifyBaseNormals()
float radius, {
const std::vector<QVector2D> &cutTemplate, std::vector<size_t> nodeIndices(m_nodes.size());
QVector3D &baseNormal, for (size_t i = 0; i < m_nodes.size(); ++i) {
const QVector3D &cutNormal, const auto &node = m_nodes[i];
const QVector3D &traverseDirection, nodeIndices[node.reversedTraverseOrder] = i;
std::vector<QVector3D> &resultCut) }
for (size_t i = 1; i < nodeIndices.size(); ++i) {
size_t lastIndex = nodeIndices[i - 1];
size_t nodeIndex = nodeIndices[i];
auto &node = m_nodes[nodeIndex];
const auto &last = m_nodes[lastIndex];
if (QVector3D::dotProduct(node.baseNormal, last.baseNormal) <= 0)
node.baseNormal = -node.baseNormal;
}
}
QVector3D Builder::revisedBaseNormalAcordingToCutNormal(const QVector3D &baseNormal, const QVector3D &cutNormal)
{ {
QVector3D orientedBaseNormal = QVector3D::dotProduct(cutNormal, baseNormal) > 0 ? QVector3D orientedBaseNormal = QVector3D::dotProduct(cutNormal, baseNormal) > 0 ?
baseNormal : -baseNormal; baseNormal : -baseNormal;
@ -573,13 +589,28 @@ void Builder::makeCut(const QVector3D &position,
orientedBaseNormal = QVector3D(1, 0, 0); orientedBaseNormal = QVector3D(1, 0, 0);
} }
} }
baseNormal = orientedBaseNormal.normalized(); return orientedBaseNormal.normalized();
}
void Builder::makeCut(const QVector3D &position,
float radius,
const std::vector<QVector2D> &cutTemplate,
QVector3D &baseNormal,
const QVector3D &cutNormal,
const QVector3D &traverseDirection,
std::vector<QVector3D> &resultCut)
{
baseNormal = revisedBaseNormalAcordingToCutNormal(baseNormal, cutNormal);
auto finalCutTemplate = cutTemplate; auto finalCutTemplate = cutTemplate;
auto finalCutNormal = cutNormal; auto finalCutNormal = cutNormal;
if (QVector3D::dotProduct(cutNormal, traverseDirection) <= 0) { if (QVector3D::dotProduct(cutNormal, traverseDirection) <= 0) {
baseNormal = -baseNormal; baseNormal = -baseNormal;
finalCutNormal = -finalCutNormal; finalCutNormal = -finalCutNormal;
std::reverse(finalCutTemplate.begin(), finalCutTemplate.end()); std::reverse(finalCutTemplate.begin(), finalCutTemplate.end());
//for (auto &it: finalCutTemplate) {
// it.setX(-it.x());
// it.setY(-it.y());
//}
} }
QVector3D u = QVector3D::crossProduct(finalCutNormal, baseNormal).normalized(); QVector3D u = QVector3D::crossProduct(finalCutNormal, baseNormal).normalized();
QVector3D v = QVector3D::crossProduct(u, finalCutNormal).normalized(); QVector3D v = QVector3D::crossProduct(u, finalCutNormal).normalized();

View File

@ -102,7 +102,9 @@ private:
void resolveBaseNormalRecursively(size_t nodeIndex); void resolveBaseNormalRecursively(size_t nodeIndex);
void resolveBaseNormalForLeavesRecursively(size_t nodeIndex, const QVector3D &baseNormal); void resolveBaseNormalForLeavesRecursively(size_t nodeIndex, const QVector3D &baseNormal);
std::pair<QVector3D, bool> searchBaseNormalFromNeighborsRecursively(size_t nodeIndex); std::pair<QVector3D, bool> searchBaseNormalFromNeighborsRecursively(size_t nodeIndex);
QVector3D revisedBaseNormalAcordingToCutNormal(const QVector3D &baseNormal, const QVector3D &cutNormal);
void resolveInitialTraverseDirectionRecursively(size_t nodeIndex, const QVector3D *from, std::set<size_t> *visited); void resolveInitialTraverseDirectionRecursively(size_t nodeIndex, const QVector3D *from, std::set<size_t> *visited);
void unifyBaseNormals();
void resolveTraverseDirection(size_t nodeIndex); void resolveTraverseDirection(size_t nodeIndex);
bool generateCutsForNode(size_t nodeIndex); bool generateCutsForNode(size_t nodeIndex);
bool tryWrapMultipleBranchesForNode(size_t nodeIndex, std::vector<float> &offsets, bool &offsetsChanged); bool tryWrapMultipleBranchesForNode(size_t nodeIndex, std::vector<float> &offsets, bool &offsetsChanged);