Add subdivide face
parent
96282fea08
commit
bb2734ba33
|
@ -89,7 +89,7 @@ Vector3 BaseNormal::calculateTubeBaseNormal(const std::vector<Vector3> &vertices
|
||||||
size_t h = i - 1;
|
size_t h = i - 1;
|
||||||
// >15 degrees && < 165 degrees
|
// >15 degrees && < 165 degrees
|
||||||
if (std::abs(Vector3::dotProduct(edgeDirections[h], edgeDirections[i])) < 0.966)
|
if (std::abs(Vector3::dotProduct(edgeDirections[h], edgeDirections[i])) < 0.966)
|
||||||
baseNormal += Vector3::crossProduct(edgeDirections[h], edgeDirections[i]);
|
baseNormal += Vector3::crossProduct(-edgeDirections[h], edgeDirections[i]);
|
||||||
}
|
}
|
||||||
if (baseNormal.isZero()) {
|
if (baseNormal.isZero()) {
|
||||||
for (size_t h = 0; h + 1 < edgeDirections.size(); ++h) {
|
for (size_t h = 0; h + 1 < edgeDirections.size(); ++h) {
|
||||||
|
|
|
@ -93,6 +93,18 @@ void MeshGenerator::chamferFace(std::vector<Vector2> *face)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshGenerator::subdivideFace(std::vector<Vector2> *face)
|
||||||
|
{
|
||||||
|
auto oldFace = *face;
|
||||||
|
face->resize(oldFace.size() * 2);
|
||||||
|
for (size_t i = 0, n = 0; i < oldFace.size(); ++i) {
|
||||||
|
size_t h = (i + oldFace.size() - 1) % oldFace.size();
|
||||||
|
size_t j = (i + 1) % oldFace.size();
|
||||||
|
(*face)[n++] = oldFace[h] * 0.125 + oldFace[i] * 0.75 + oldFace[j] * 0.125;
|
||||||
|
(*face)[n++] = (oldFace[i] + oldFace[j]) * 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MeshGenerator::isWatertight(const std::vector<std::vector<size_t>> &faces)
|
bool MeshGenerator::isWatertight(const std::vector<std::vector<size_t>> &faces)
|
||||||
{
|
{
|
||||||
std::set<std::pair<size_t, size_t>> halfEdges;
|
std::set<std::pair<size_t, size_t>> halfEdges;
|
||||||
|
@ -596,6 +608,8 @@ std::unique_ptr<MeshCombiner::Mesh> MeshGenerator::combinePartMesh(const std::st
|
||||||
cutFaceStringToCutTemplate(cutFaceString, cutTemplate);
|
cutFaceStringToCutTemplate(cutFaceString, cutTemplate);
|
||||||
if (chamfered)
|
if (chamfered)
|
||||||
chamferFace(&cutTemplate);
|
chamferFace(&cutTemplate);
|
||||||
|
if (subdived)
|
||||||
|
subdivideFace(&cutTemplate);
|
||||||
|
|
||||||
std::string cutRotationString = String::valueOrEmpty(part, "cutRotation");
|
std::string cutRotationString = String::valueOrEmpty(part, "cutRotation");
|
||||||
if (!cutRotationString.empty()) {
|
if (!cutRotationString.empty()) {
|
||||||
|
|
|
@ -163,6 +163,7 @@ private:
|
||||||
bool fetchPartOrderedNodes(const std::string &partIdString, std::vector<MeshNode> *meshNodes, bool *isCircle);
|
bool fetchPartOrderedNodes(const std::string &partIdString, std::vector<MeshNode> *meshNodes, bool *isCircle);
|
||||||
|
|
||||||
static void chamferFace(std::vector<Vector2> *face);
|
static void chamferFace(std::vector<Vector2> *face);
|
||||||
|
static void subdivideFace(std::vector<Vector2> *face);
|
||||||
static bool isWatertight(const std::vector<std::vector<size_t>> &faces);
|
static bool isWatertight(const std::vector<std::vector<size_t>> &faces);
|
||||||
static void flattenLinks(const std::unordered_map<size_t, size_t> &links,
|
static void flattenLinks(const std::unordered_map<size_t, size_t> &links,
|
||||||
std::vector<size_t> *array,
|
std::vector<size_t> *array,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <dust3d/mesh/base_normal.h>
|
#include <dust3d/mesh/base_normal.h>
|
||||||
#include <dust3d/mesh/tube_mesh_builder.h>
|
#include <dust3d/mesh/tube_mesh_builder.h>
|
||||||
|
|
||||||
|
@ -139,6 +140,11 @@ void TubeMeshBuilder::build()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!m_isCircle) {
|
||||||
|
m_generatedFaces.emplace_back(cutFaceIndices.back());
|
||||||
|
m_generatedFaces.emplace_back(cutFaceIndices.front());
|
||||||
|
std::reverse(m_generatedFaces.back().begin(), m_generatedFaces.back().end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue