Fix cut rotation
parent
d866e0147b
commit
b2fdb7f4e8
|
@ -151,6 +151,46 @@ void Builder::resolveBaseNormalForLeavesRecursively(size_t nodeIndex, const QVec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::resolveInitialTraverseDirectionRecursively(size_t nodeIndex, const QVector3D *from, std::set<size_t> *visited)
|
||||||
|
{
|
||||||
|
if (visited->find(nodeIndex) != visited->end())
|
||||||
|
return;
|
||||||
|
auto &node = m_nodes[nodeIndex];
|
||||||
|
node.reversedTraverseOrder = visited->size();
|
||||||
|
visited->insert(nodeIndex);
|
||||||
|
if (nullptr != from) {
|
||||||
|
node.initialTraverseDirection = (node.position - *from).normalized();
|
||||||
|
node.hasInitialTraverseDirection = true;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < node.edges.size(); ++i) {
|
||||||
|
size_t neighborIndex = m_edges[node.edges[i]].neiborOf(nodeIndex);
|
||||||
|
resolveInitialTraverseDirectionRecursively(neighborIndex, &node.position, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::resolveTraverseDirection(size_t nodeIndex)
|
||||||
|
{
|
||||||
|
auto &node = m_nodes[nodeIndex];
|
||||||
|
if (!node.hasInitialTraverseDirection) {
|
||||||
|
if (node.edges.size() > 0) {
|
||||||
|
size_t neighborIndex = m_edges[node.edges[0]].neiborOf(nodeIndex);
|
||||||
|
const auto &neighbor = m_nodes[neighborIndex];
|
||||||
|
node.initialTraverseDirection = neighbor.initialTraverseDirection;
|
||||||
|
node.hasInitialTraverseDirection = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node.edges.size() == 2) {
|
||||||
|
std::vector<size_t> neighborIndices = {m_edges[node.edges[0]].neiborOf(nodeIndex),
|
||||||
|
m_edges[node.edges[1]].neiborOf(nodeIndex)};
|
||||||
|
std::sort(neighborIndices.begin(), neighborIndices.end(), [&](const size_t &firstIndex, const size_t &secondIndex) {
|
||||||
|
return m_nodes[firstIndex].reversedTraverseOrder < m_nodes[secondIndex].reversedTraverseOrder;
|
||||||
|
});
|
||||||
|
node.traverseDirection = (node.initialTraverseDirection + m_nodes[neighborIndices[1]].initialTraverseDirection).normalized();
|
||||||
|
} else {
|
||||||
|
node.traverseDirection = node.initialTraverseDirection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<QVector3D, bool> Builder::searchBaseNormalFromNeighborsRecursively(size_t nodeIndex)
|
std::pair<QVector3D, bool> Builder::searchBaseNormalFromNeighborsRecursively(size_t nodeIndex)
|
||||||
{
|
{
|
||||||
auto &node = m_nodes[nodeIndex];
|
auto &node = m_nodes[nodeIndex];
|
||||||
|
@ -198,6 +238,22 @@ bool Builder::build()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::set<size_t> visited;
|
||||||
|
for (auto nodeIndex = m_sortedNodeIndices.rbegin();
|
||||||
|
nodeIndex != m_sortedNodeIndices.rend();
|
||||||
|
++nodeIndex) {
|
||||||
|
resolveInitialTraverseDirectionRecursively(*nodeIndex, nullptr, &visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
for (auto nodeIndex = m_sortedNodeIndices.rbegin();
|
||||||
|
nodeIndex != m_sortedNodeIndices.rend();
|
||||||
|
++nodeIndex) {
|
||||||
|
resolveTraverseDirection(*nodeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &nodeIndex: m_sortedNodeIndices) {
|
for (const auto &nodeIndex: m_sortedNodeIndices) {
|
||||||
prepareNode(nodeIndex);
|
prepareNode(nodeIndex);
|
||||||
}
|
}
|
||||||
|
@ -295,17 +351,17 @@ bool Builder::generateCutsForNode(size_t nodeIndex)
|
||||||
size_t neighborsCount = node.edges.size();
|
size_t neighborsCount = node.edges.size();
|
||||||
//qDebug() << "Generate cuts for node" << nodeIndex << "with neighbor count" << neighborsCount;
|
//qDebug() << "Generate cuts for node" << nodeIndex << "with neighbor count" << neighborsCount;
|
||||||
if (1 == neighborsCount) {
|
if (1 == neighborsCount) {
|
||||||
QVector3D cutNormal = node.raysToNeibors[0];
|
const QVector3D &cutNormal = node.raysToNeibors[0];
|
||||||
std::vector<QVector3D> cut;
|
std::vector<QVector3D> cut;
|
||||||
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, cut);
|
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut);
|
||||||
std::vector<size_t> vertices;
|
std::vector<size_t> vertices;
|
||||||
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
||||||
m_generatedFaces.push_back(vertices);
|
m_generatedFaces.push_back(vertices);
|
||||||
m_edges[node.edges[0]].cuts.push_back({vertices, -cutNormal});
|
m_edges[node.edges[0]].cuts.push_back({vertices, -cutNormal});
|
||||||
} else if (2 == neighborsCount) {
|
} else if (2 == neighborsCount) {
|
||||||
QVector3D cutNormal = (node.raysToNeibors[0].normalized() - node.raysToNeibors[1].normalized()) / 2;
|
const QVector3D cutNormal = (node.raysToNeibors[0].normalized() - node.raysToNeibors[1].normalized()) / 2;
|
||||||
std::vector<QVector3D> cut;
|
std::vector<QVector3D> cut;
|
||||||
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, cut);
|
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut);
|
||||||
std::vector<size_t> vertices;
|
std::vector<size_t> vertices;
|
||||||
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
||||||
std::vector<size_t> verticesReversed;
|
std::vector<size_t> verticesReversed;
|
||||||
|
@ -344,7 +400,7 @@ bool Builder::tryWrapMultipleBranchesForNode(size_t nodeIndex, std::vector<float
|
||||||
std::vector<std::pair<std::vector<size_t>, QVector3D>> cutsForEdges;
|
std::vector<std::pair<std::vector<size_t>, QVector3D>> cutsForEdges;
|
||||||
bool directSwallowed = false;
|
bool directSwallowed = false;
|
||||||
for (size_t i = 0; i < node.edges.size(); ++i) {
|
for (size_t i = 0; i < node.edges.size(); ++i) {
|
||||||
QVector3D cutNormal = node.raysToNeibors[i];
|
const QVector3D &cutNormal = node.raysToNeibors[i];
|
||||||
size_t edgeIndex = node.edges[i];
|
size_t edgeIndex = node.edges[i];
|
||||||
size_t neighborIndex = m_edges[edgeIndex].neiborOf(nodeIndex);
|
size_t neighborIndex = m_edges[edgeIndex].neiborOf(nodeIndex);
|
||||||
const auto &neighbor = m_nodes[neighborIndex];
|
const auto &neighbor = m_nodes[neighborIndex];
|
||||||
|
@ -368,7 +424,7 @@ bool Builder::tryWrapMultipleBranchesForNode(size_t nodeIndex, std::vector<float
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
makeCut(node.position + cutNormal * finalDistance, radius, node.cutTemplate, node.baseNormal, cutNormal, cut);
|
makeCut(node.position + cutNormal * finalDistance, radius, node.cutTemplate, node.baseNormal, cutNormal, neighbor.traverseDirection, cut);
|
||||||
std::vector<size_t> vertices;
|
std::vector<size_t> vertices;
|
||||||
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
insertCutVertices(cut, vertices, nodeIndex, cutNormal);
|
||||||
cutsForEdges.push_back({vertices, -cutNormal});
|
cutsForEdges.push_back({vertices, -cutNormal});
|
||||||
|
@ -504,6 +560,7 @@ void Builder::makeCut(const QVector3D &position,
|
||||||
const std::vector<QVector2D> &cutTemplate,
|
const std::vector<QVector2D> &cutTemplate,
|
||||||
QVector3D &baseNormal,
|
QVector3D &baseNormal,
|
||||||
const QVector3D &cutNormal,
|
const QVector3D &cutNormal,
|
||||||
|
const QVector3D &traverseDirection,
|
||||||
std::vector<QVector3D> &resultCut)
|
std::vector<QVector3D> &resultCut)
|
||||||
{
|
{
|
||||||
QVector3D orientedBaseNormal = QVector3D::dotProduct(cutNormal, baseNormal) > 0 ?
|
QVector3D orientedBaseNormal = QVector3D::dotProduct(cutNormal, baseNormal) > 0 ?
|
||||||
|
@ -527,7 +584,7 @@ void Builder::makeCut(const QVector3D &position,
|
||||||
if (!qFuzzyIsNull(m_cutRotation)) {
|
if (!qFuzzyIsNull(m_cutRotation)) {
|
||||||
float degree = m_cutRotation * 180;
|
float degree = m_cutRotation * 180;
|
||||||
QMatrix4x4 rotation;
|
QMatrix4x4 rotation;
|
||||||
rotation.rotate(degree, cutNormal);
|
rotation.rotate(degree, traverseDirection);
|
||||||
baseNormal = rotation * baseNormal;
|
baseNormal = rotation * baseNormal;
|
||||||
for (auto &positionOnCut: resultCut) {
|
for (auto &positionOnCut: resultCut) {
|
||||||
positionOnCut = rotation * positionOnCut;
|
positionOnCut = rotation * positionOnCut;
|
||||||
|
|
|
@ -34,12 +34,16 @@ private:
|
||||||
std::vector<size_t> edges;
|
std::vector<size_t> edges;
|
||||||
std::vector<QVector2D> cutTemplate;
|
std::vector<QVector2D> cutTemplate;
|
||||||
std::vector<QVector3D> raysToNeibors;
|
std::vector<QVector3D> raysToNeibors;
|
||||||
|
QVector3D initialTraverseDirection;
|
||||||
|
QVector3D traverseDirection;
|
||||||
QVector3D growthDirection;
|
QVector3D growthDirection;
|
||||||
QVector3D initialBaseNormal;
|
QVector3D initialBaseNormal;
|
||||||
QVector3D baseNormal;
|
QVector3D baseNormal;
|
||||||
|
size_t reversedTraverseOrder;
|
||||||
bool hasInitialBaseNormal = false;
|
bool hasInitialBaseNormal = false;
|
||||||
bool baseNormalResolved = false;
|
bool baseNormalResolved = false;
|
||||||
bool baseNormalSearched = false;
|
bool baseNormalSearched = false;
|
||||||
|
bool hasInitialTraverseDirection = false;
|
||||||
|
|
||||||
size_t anotherEdge(size_t edgeIndex) const
|
size_t anotherEdge(size_t edgeIndex) const
|
||||||
{
|
{
|
||||||
|
@ -98,6 +102,8 @@ 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);
|
||||||
|
void resolveInitialTraverseDirectionRecursively(size_t nodeIndex, const QVector3D *from, std::set<size_t> *visited);
|
||||||
|
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);
|
||||||
void makeCut(const QVector3D &position,
|
void makeCut(const QVector3D &position,
|
||||||
|
@ -105,6 +111,7 @@ private:
|
||||||
const std::vector<QVector2D> &cutTemplate,
|
const std::vector<QVector2D> &cutTemplate,
|
||||||
QVector3D &baseNormal,
|
QVector3D &baseNormal,
|
||||||
const QVector3D &cutNormal,
|
const QVector3D &cutNormal,
|
||||||
|
const QVector3D &traverseDirection,
|
||||||
std::vector<QVector3D> &resultCut);
|
std::vector<QVector3D> &resultCut);
|
||||||
void insertCutVertices(const std::vector<QVector3D> &cut, std::vector<size_t> &vertices, size_t nodeIndex, const QVector3D &cutDirect);
|
void insertCutVertices(const std::vector<QVector3D> &cut, std::vector<size_t> &vertices, size_t nodeIndex, const QVector3D &cutDirect);
|
||||||
void stitchEdgeCuts();
|
void stitchEdgeCuts();
|
||||||
|
|
Loading…
Reference in New Issue