Improve the quality of mesh parts bridging
First, split parts by combine mode, then sub group by color name, those parts which following in the same sub group will be bridged together.master
parent
3e1fde4260
commit
8053d3c3fb
|
@ -6,7 +6,6 @@ enum class CombineMode
|
||||||
{
|
{
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
Inversion,
|
Inversion,
|
||||||
Inflation,
|
|
||||||
Count
|
Count
|
||||||
};
|
};
|
||||||
CombineMode CombineModeFromString(const char *modeString);
|
CombineMode CombineModeFromString(const char *modeString);
|
||||||
|
@ -18,8 +17,6 @@ CombineMode CombineModeFromString(const char *modeString) \
|
||||||
return CombineMode::Normal; \
|
return CombineMode::Normal; \
|
||||||
if (mode == "Inversion") \
|
if (mode == "Inversion") \
|
||||||
return CombineMode::Inversion; \
|
return CombineMode::Inversion; \
|
||||||
if (mode == "Inflation") \
|
|
||||||
return CombineMode::Inflation; \
|
|
||||||
return CombineMode::Normal; \
|
return CombineMode::Normal; \
|
||||||
}
|
}
|
||||||
const char *CombineModeToString(CombineMode mode);
|
const char *CombineModeToString(CombineMode mode);
|
||||||
|
@ -31,8 +28,6 @@ const char *CombineModeToString(CombineMode mode) \
|
||||||
return "Normal"; \
|
return "Normal"; \
|
||||||
case CombineMode::Inversion: \
|
case CombineMode::Inversion: \
|
||||||
return "Inversion"; \
|
return "Inversion"; \
|
||||||
case CombineMode::Inflation: \
|
|
||||||
return "Inflation"; \
|
|
||||||
default: \
|
default: \
|
||||||
return "Normal"; \
|
return "Normal"; \
|
||||||
} \
|
} \
|
||||||
|
@ -46,8 +41,6 @@ QString CombineModeToDispName(CombineMode mode) \
|
||||||
return QObject::tr("Normal"); \
|
return QObject::tr("Normal"); \
|
||||||
case CombineMode::Inversion: \
|
case CombineMode::Inversion: \
|
||||||
return QObject::tr("Inversion"); \
|
return QObject::tr("Inversion"); \
|
||||||
case CombineMode::Inflation: \
|
|
||||||
return QObject::tr("Inflation"); \
|
|
||||||
default: \
|
default: \
|
||||||
return QObject::tr("Normal"); \
|
return QObject::tr("Normal"); \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -409,6 +409,53 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<QString, QString> *MeshGenerator::findComponent(const QString &componentIdString)
|
||||||
|
{
|
||||||
|
const std::map<QString, QString> *component = &m_snapshot->rootComponent;
|
||||||
|
if (componentIdString != QUuid().toString()) {
|
||||||
|
auto findComponent = m_snapshot->components.find(componentIdString);
|
||||||
|
if (findComponent == m_snapshot->components.end()) {
|
||||||
|
qDebug() << "Component not found:" << componentIdString;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &findComponent->second;
|
||||||
|
}
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
CombineMode MeshGenerator::componentCombineMode(const std::map<QString, QString> *component)
|
||||||
|
{
|
||||||
|
if (nullptr == component)
|
||||||
|
return CombineMode::Normal;
|
||||||
|
CombineMode combineMode = CombineModeFromString(valueOfKeyInMapOrEmpty(*component, "combineMode").toUtf8().constData());
|
||||||
|
if (combineMode == CombineMode::Normal) {
|
||||||
|
if (isTrueValueString(valueOfKeyInMapOrEmpty(*component, "inverse")))
|
||||||
|
combineMode = CombineMode::Inversion;
|
||||||
|
}
|
||||||
|
return combineMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MeshGenerator::componentColorName(const std::map<QString, QString> *component)
|
||||||
|
{
|
||||||
|
if (nullptr == component)
|
||||||
|
return QString();
|
||||||
|
QString linkDataType = valueOfKeyInMapOrEmpty(*component, "linkDataType");
|
||||||
|
if ("partId" == linkDataType) {
|
||||||
|
QString partIdString = valueOfKeyInMapOrEmpty(*component, "linkData");
|
||||||
|
auto findPart = m_snapshot->parts.find(partIdString);
|
||||||
|
if (findPart == m_snapshot->parts.end()) {
|
||||||
|
qDebug() << "Find part failed:" << partIdString;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
auto &part = findPart->second;
|
||||||
|
QString colorName = valueOfKeyInMapOrEmpty(part, "color");
|
||||||
|
if (colorName.isEmpty())
|
||||||
|
return QString("-");
|
||||||
|
return colorName;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &componentIdString, CombineMode *combineMode)
|
nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &componentIdString, CombineMode *combineMode)
|
||||||
{
|
{
|
||||||
nodemesh::Combiner::Mesh *mesh = nullptr;
|
nodemesh::Combiner::Mesh *mesh = nullptr;
|
||||||
|
@ -425,11 +472,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &com
|
||||||
component = &findComponent->second;
|
component = &findComponent->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
*combineMode = CombineModeFromString(valueOfKeyInMapOrEmpty(*component, "combineMode").toUtf8().constData());
|
*combineMode = componentCombineMode(component);
|
||||||
if (*combineMode == CombineMode::Normal) {
|
|
||||||
if (isTrueValueString(valueOfKeyInMapOrEmpty(*component, "inverse")))
|
|
||||||
*combineMode = CombineMode::Inversion;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto &componentCache = m_cacheContext->components[componentIdString];
|
auto &componentCache = m_cacheContext->components[componentIdString];
|
||||||
|
|
||||||
|
@ -462,56 +505,74 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &com
|
||||||
for (const auto &it: partCache.outcomeNodeVertices)
|
for (const auto &it: partCache.outcomeNodeVertices)
|
||||||
componentCache.outcomeNodeVertices.push_back(it);
|
componentCache.outcomeNodeVertices.push_back(it);
|
||||||
} else {
|
} else {
|
||||||
|
std::vector<std::pair<CombineMode, std::vector<std::pair<QString, QString>>>> combineGroups;
|
||||||
|
// Firstly, group by combine mode
|
||||||
|
int currentGroupIndex = -1;
|
||||||
|
auto lastCombineMode = CombineMode::Count;
|
||||||
for (const auto &childIdString: valueOfKeyInMapOrEmpty(*component, "children").split(",")) {
|
for (const auto &childIdString: valueOfKeyInMapOrEmpty(*component, "children").split(",")) {
|
||||||
if (childIdString.isEmpty())
|
if (childIdString.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
CombineMode childCombineMode = CombineMode::Normal;
|
const auto &child = findComponent(childIdString);
|
||||||
nodemesh::Combiner::Mesh *subMesh = combineComponentMesh(childIdString, &childCombineMode);
|
QString colorName = componentColorName(child);
|
||||||
|
auto combineMode = componentCombineMode(child);
|
||||||
const auto &childComponentCache = m_cacheContext->components[childIdString];
|
if (lastCombineMode != combineMode || lastCombineMode == CombineMode::Inversion) {
|
||||||
for (const auto &vertex: childComponentCache.noneSeamVertices)
|
qDebug() << "New group[" << currentGroupIndex << "] for combine mode[" << CombineModeToString(combineMode) << "]";
|
||||||
componentCache.noneSeamVertices.insert(vertex);
|
combineGroups.push_back({combineMode, {}});
|
||||||
for (const auto &it: childComponentCache.sharedQuadEdges)
|
++currentGroupIndex;
|
||||||
componentCache.sharedQuadEdges.insert(it);
|
lastCombineMode = combineMode;
|
||||||
for (const auto &it: childComponentCache.outcomeNodes)
|
}
|
||||||
componentCache.outcomeNodes.push_back(it);
|
if (-1 == currentGroupIndex) {
|
||||||
for (const auto &it: childComponentCache.outcomeNodeVertices)
|
qDebug() << "Should not happen: -1 == currentGroupIndex";
|
||||||
componentCache.outcomeNodeVertices.push_back(it);
|
|
||||||
|
|
||||||
qDebug() << "Combine mode:" << CombineModeToString(childCombineMode);
|
|
||||||
if (nullptr == subMesh) {
|
|
||||||
m_isSucceed = false;
|
|
||||||
qDebug() << "Child mesh is null";
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (subMesh->isNull()) {
|
combineGroups[currentGroupIndex].second.push_back({childIdString, colorName});
|
||||||
m_isSucceed = false;
|
}
|
||||||
qDebug() << "Child mesh is uncombinable";
|
// Secondly, sub group by color
|
||||||
delete subMesh;
|
std::vector<std::pair<nodemesh::Combiner::Mesh *, CombineMode>> groupMeshes;
|
||||||
|
for (const auto &group: combineGroups) {
|
||||||
|
std::set<size_t> used;
|
||||||
|
std::vector<std::vector<QString>> componentIdStrings;
|
||||||
|
int currentSubGroupIndex = -1;
|
||||||
|
auto lastColorName = QString();
|
||||||
|
for (size_t i = 0; i < group.second.size(); ++i) {
|
||||||
|
if (used.find(i) != used.end())
|
||||||
|
continue;
|
||||||
|
const auto &colorName = group.second[i].second;
|
||||||
|
if (lastColorName != colorName || lastColorName.isEmpty()) {
|
||||||
|
qDebug() << "New sub group[" << currentSubGroupIndex << "] for color[" << colorName << "]";
|
||||||
|
componentIdStrings.push_back({});
|
||||||
|
++currentSubGroupIndex;
|
||||||
|
lastColorName = colorName;
|
||||||
|
}
|
||||||
|
if (-1 == currentSubGroupIndex) {
|
||||||
|
qDebug() << "Should not happen: -1 == currentSubGroupIndex";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (nullptr == mesh) {
|
used.insert(i);
|
||||||
if (childCombineMode == CombineMode::Inversion) {
|
componentIdStrings[currentSubGroupIndex].push_back(group.second[i].first);
|
||||||
delete subMesh;
|
if (colorName.isEmpty())
|
||||||
} else {
|
continue;
|
||||||
mesh = subMesh;
|
for (size_t j = i + 1; j < group.second.size(); ++j) {
|
||||||
}
|
if (used.find(j) != used.end())
|
||||||
} else {
|
continue;
|
||||||
nodemesh::Combiner::Mesh *newMesh = combineTwoMeshes(*mesh,
|
const auto &otherColorName = group.second[j].second;
|
||||||
*subMesh,
|
if (otherColorName.isEmpty())
|
||||||
childCombineMode == CombineMode::Inversion ?
|
continue;
|
||||||
nodemesh::Combiner::Method::Diff : nodemesh::Combiner::Method::Union);
|
if (otherColorName != colorName)
|
||||||
delete subMesh;
|
continue;
|
||||||
if (newMesh && !newMesh->isNull()) {
|
used.insert(j);
|
||||||
delete mesh;
|
componentIdStrings[currentSubGroupIndex].push_back(group.second[j].first);
|
||||||
mesh = newMesh;
|
|
||||||
} else {
|
|
||||||
m_isSucceed = false;
|
|
||||||
qDebug() << "Mesh combine failed";
|
|
||||||
delete newMesh;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::vector<std::pair<nodemesh::Combiner::Mesh *, CombineMode>> multipleMeshes;
|
||||||
|
for (const auto &it: componentIdStrings) {
|
||||||
|
nodemesh::Combiner::Mesh *childMesh = combineComponentChildGroupMesh(it, componentCache);
|
||||||
|
multipleMeshes.push_back({childMesh, CombineMode::Normal});
|
||||||
}
|
}
|
||||||
|
nodemesh::Combiner::Mesh *subGroupMesh = combineMultipleMeshes(multipleMeshes, false);
|
||||||
|
groupMeshes.push_back({subGroupMesh, group.first});
|
||||||
|
}
|
||||||
|
mesh = combineMultipleMeshes(groupMeshes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr != mesh)
|
if (nullptr != mesh)
|
||||||
|
@ -525,8 +586,75 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &com
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodemesh::Combiner::Mesh *MeshGenerator::combineMultipleMeshes(const std::vector<std::pair<nodemesh::Combiner::Mesh *, CombineMode>> &multipleMeshes, bool recombine)
|
||||||
|
{
|
||||||
|
nodemesh::Combiner::Mesh *mesh = nullptr;
|
||||||
|
for (const auto &it: multipleMeshes) {
|
||||||
|
const auto &childCombineMode = it.second;
|
||||||
|
nodemesh::Combiner::Mesh *subMesh = it.first;
|
||||||
|
qDebug() << "Combine mode:" << CombineModeToString(childCombineMode);
|
||||||
|
if (nullptr == subMesh) {
|
||||||
|
m_isSucceed = false;
|
||||||
|
qDebug() << "Child mesh is null";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (subMesh->isNull()) {
|
||||||
|
m_isSucceed = false;
|
||||||
|
qDebug() << "Child mesh is uncombinable";
|
||||||
|
delete subMesh;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nullptr == mesh) {
|
||||||
|
//if (childCombineMode == CombineMode::Inversion) {
|
||||||
|
// delete subMesh;
|
||||||
|
//} else {
|
||||||
|
mesh = subMesh;
|
||||||
|
//}
|
||||||
|
} else {
|
||||||
|
nodemesh::Combiner::Mesh *newMesh = combineTwoMeshes(*mesh,
|
||||||
|
*subMesh,
|
||||||
|
childCombineMode == CombineMode::Inversion ?
|
||||||
|
nodemesh::Combiner::Method::Diff : nodemesh::Combiner::Method::Union,
|
||||||
|
recombine);
|
||||||
|
delete subMesh;
|
||||||
|
if (newMesh && !newMesh->isNull()) {
|
||||||
|
delete mesh;
|
||||||
|
mesh = newMesh;
|
||||||
|
} else {
|
||||||
|
m_isSucceed = false;
|
||||||
|
qDebug() << "Mesh combine failed";
|
||||||
|
delete newMesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodemesh::Combiner::Mesh *MeshGenerator::combineComponentChildGroupMesh(const std::vector<QString> &componentIdStrings, GeneratedComponent &componentCache)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<nodemesh::Combiner::Mesh *, CombineMode>> multipleMeshes;
|
||||||
|
for (const auto &childIdString: componentIdStrings) {
|
||||||
|
CombineMode childCombineMode = CombineMode::Normal;
|
||||||
|
nodemesh::Combiner::Mesh *subMesh = combineComponentMesh(childIdString, &childCombineMode);
|
||||||
|
|
||||||
|
const auto &childComponentCache = m_cacheContext->components[childIdString];
|
||||||
|
for (const auto &vertex: childComponentCache.noneSeamVertices)
|
||||||
|
componentCache.noneSeamVertices.insert(vertex);
|
||||||
|
for (const auto &it: childComponentCache.sharedQuadEdges)
|
||||||
|
componentCache.sharedQuadEdges.insert(it);
|
||||||
|
for (const auto &it: childComponentCache.outcomeNodes)
|
||||||
|
componentCache.outcomeNodes.push_back(it);
|
||||||
|
for (const auto &it: childComponentCache.outcomeNodeVertices)
|
||||||
|
componentCache.outcomeNodeVertices.push_back(it);
|
||||||
|
|
||||||
|
multipleMeshes.push_back({subMesh, childCombineMode});
|
||||||
|
}
|
||||||
|
return combineMultipleMeshes(multipleMeshes);
|
||||||
|
}
|
||||||
|
|
||||||
nodemesh::Combiner::Mesh *MeshGenerator::combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
nodemesh::Combiner::Mesh *MeshGenerator::combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
||||||
nodemesh::Combiner::Method method)
|
nodemesh::Combiner::Method method,
|
||||||
|
bool recombine)
|
||||||
{
|
{
|
||||||
if (first.isNull() || second.isNull())
|
if (first.isNull() || second.isNull())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -537,7 +665,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineTwoMeshes(const nodemesh::Combin
|
||||||
&combinedVerticesSources);
|
&combinedVerticesSources);
|
||||||
if (nullptr == newMesh)
|
if (nullptr == newMesh)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!newMesh->isNull()) {
|
if (!newMesh->isNull() && recombine) {
|
||||||
nodemesh::Recombiner recombiner;
|
nodemesh::Recombiner recombiner;
|
||||||
std::vector<QVector3D> combinedVertices;
|
std::vector<QVector3D> combinedVertices;
|
||||||
std::vector<std::vector<size_t>> combinedFaces;
|
std::vector<std::vector<size_t>> combinedFaces;
|
||||||
|
@ -699,6 +827,19 @@ void MeshGenerator::generate()
|
||||||
triangleSourceNodeResolve(*m_outcome, sourceNodes);
|
triangleSourceNodeResolve(*m_outcome, sourceNodes);
|
||||||
m_outcome->setTriangleSourceNodes(sourceNodes);
|
m_outcome->setTriangleSourceNodes(sourceNodes);
|
||||||
|
|
||||||
|
std::map<std::pair<QUuid, QUuid>, QColor> sourceNodeToColorMap;
|
||||||
|
for (const auto &node: m_outcome->nodes)
|
||||||
|
sourceNodeToColorMap.insert({{node.partId, node.nodeId}, node.color});
|
||||||
|
|
||||||
|
m_outcome->triangleColors.resize(m_outcome->triangles.size(), Qt::white);
|
||||||
|
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes = m_outcome->triangleSourceNodes();
|
||||||
|
if (nullptr != triangleSourceNodes) {
|
||||||
|
for (size_t triangleIndex = 0; triangleIndex < m_outcome->triangles.size(); triangleIndex++) {
|
||||||
|
const auto &source = (*triangleSourceNodes)[triangleIndex];
|
||||||
|
m_outcome->triangleColors[triangleIndex] = sourceNodeToColorMap[source];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::vector<QVector3D>> triangleVertexNormals;
|
std::vector<std::vector<QVector3D>> triangleVertexNormals;
|
||||||
generateSmoothTriangleVertexNormals(combinedVertices,
|
generateSmoothTriangleVertexNormals(combinedVertices,
|
||||||
combinedFaces,
|
combinedFaces,
|
||||||
|
|
|
@ -93,10 +93,17 @@ private:
|
||||||
void collectSharedQuadEdges(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces,
|
void collectSharedQuadEdges(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces,
|
||||||
std::set<std::pair<nodemesh::PositionKey, nodemesh::PositionKey>> *sharedQuadEdges);
|
std::set<std::pair<nodemesh::PositionKey, nodemesh::PositionKey>> *sharedQuadEdges);
|
||||||
nodemesh::Combiner::Mesh *combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
nodemesh::Combiner::Mesh *combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
||||||
nodemesh::Combiner::Method method);
|
nodemesh::Combiner::Method method,
|
||||||
|
bool recombine=true);
|
||||||
void generateSmoothTriangleVertexNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
|
void generateSmoothTriangleVertexNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
|
||||||
const std::vector<QVector3D> &triangleNormals,
|
const std::vector<QVector3D> &triangleNormals,
|
||||||
std::vector<std::vector<QVector3D>> *triangleVertexNormals);
|
std::vector<std::vector<QVector3D>> *triangleVertexNormals);
|
||||||
|
const std::map<QString, QString> *findComponent(const QString &componentIdString);
|
||||||
|
CombineMode componentCombineMode(const std::map<QString, QString> *component);
|
||||||
|
nodemesh::Combiner::Mesh *combineComponentChildGroupMesh(const std::vector<QString> &componentIdStrings,
|
||||||
|
GeneratedComponent &componentCache);
|
||||||
|
nodemesh::Combiner::Mesh *combineMultipleMeshes(const std::vector<std::pair<nodemesh::Combiner::Mesh *, CombineMode>> &multipleMeshes, bool recombine=true);
|
||||||
|
QString componentColorName(const std::map<QString, QString> *component);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,6 +112,7 @@ MeshLoader::MeshLoader(Outcome &outcome) :
|
||||||
const QVector2D defaultUv = QVector2D(0, 0);
|
const QVector2D defaultUv = QVector2D(0, 0);
|
||||||
const QVector3D defaultTangent = QVector3D(0, 0, 0);
|
const QVector3D defaultTangent = QVector3D(0, 0, 0);
|
||||||
for (size_t i = 0; i < outcome.triangles.size(); ++i) {
|
for (size_t i = 0; i < outcome.triangles.size(); ++i) {
|
||||||
|
const auto &triangleColor = &outcome.triangleColors[i];
|
||||||
for (auto j = 0; j < 3; j++) {
|
for (auto j = 0; j < 3; j++) {
|
||||||
int vertexIndex = outcome.triangles[i][j];
|
int vertexIndex = outcome.triangles[i][j];
|
||||||
const QVector3D *srcVert = &outcome.vertices[vertexIndex];
|
const QVector3D *srcVert = &outcome.vertices[vertexIndex];
|
||||||
|
@ -125,9 +126,9 @@ MeshLoader::MeshLoader(Outcome &outcome) :
|
||||||
if (triangleTangents)
|
if (triangleTangents)
|
||||||
srcTangent = &(*triangleTangents)[i];
|
srcTangent = &(*triangleTangents)[i];
|
||||||
Vertex *dest = &m_triangleVertices[destIndex];
|
Vertex *dest = &m_triangleVertices[destIndex];
|
||||||
dest->colorR = 0;
|
dest->colorR = triangleColor->redF();
|
||||||
dest->colorG = 0;
|
dest->colorG = triangleColor->greenF();
|
||||||
dest->colorB = 0;
|
dest->colorB = triangleColor->blueF();
|
||||||
dest->posX = srcVert->x();
|
dest->posX = srcVert->x();
|
||||||
dest->posY = srcVert->y();
|
dest->posY = srcVert->y();
|
||||||
dest->posZ = srcVert->z();
|
dest->posZ = srcVert->z();
|
||||||
|
@ -144,6 +145,37 @@ MeshLoader::MeshLoader(Outcome &outcome) :
|
||||||
destIndex++;
|
destIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uncomment out to show wireframes
|
||||||
|
/*
|
||||||
|
size_t edgeCount = 0;
|
||||||
|
for (const auto &face: outcome.triangleAndQuads) {
|
||||||
|
edgeCount += face.size();
|
||||||
|
}
|
||||||
|
m_edgeVertexCount = edgeCount * 2;
|
||||||
|
m_edgeVertices = new Vertex[m_edgeVertexCount];
|
||||||
|
size_t edgeVertexIndex = 0;
|
||||||
|
for (size_t faceIndex = 0; faceIndex < outcome.triangleAndQuads.size(); ++faceIndex) {
|
||||||
|
const auto &face = outcome.triangleAndQuads[faceIndex];
|
||||||
|
for (size_t i = 0; i < face.size(); ++i) {
|
||||||
|
for (size_t x = 0; x < 2; ++x) {
|
||||||
|
size_t sourceIndex = face[(i + x) % face.size()];
|
||||||
|
const QVector3D *srcVert = &outcome.vertices[sourceIndex];
|
||||||
|
Vertex *dest = &m_edgeVertices[edgeVertexIndex];
|
||||||
|
memset(dest, 0, sizeof(Vertex));
|
||||||
|
dest->colorR = 0.0;
|
||||||
|
dest->colorG = 0.0;
|
||||||
|
dest->colorB = 0.0;
|
||||||
|
dest->posX = srcVert->x();
|
||||||
|
dest->posY = srcVert->y();
|
||||||
|
dest->posZ = srcVert->z();
|
||||||
|
dest->metalness = m_defaultMetalness;
|
||||||
|
dest->roughness = m_defaultRoughness;
|
||||||
|
edgeVertexIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshLoader::MeshLoader() :
|
MeshLoader::MeshLoader() :
|
||||||
|
|
|
@ -14,7 +14,7 @@ ModelMeshBinder::ModelMeshBinder() :
|
||||||
m_renderTriangleVertexCount(0),
|
m_renderTriangleVertexCount(0),
|
||||||
m_renderEdgeVertexCount(0),
|
m_renderEdgeVertexCount(0),
|
||||||
m_newMeshComing(false),
|
m_newMeshComing(false),
|
||||||
m_showWireframes(false),
|
m_showWireframes(true),
|
||||||
m_hasTexture(false),
|
m_hasTexture(false),
|
||||||
m_texture(nullptr),
|
m_texture(nullptr),
|
||||||
m_hasNormalMap(false),
|
m_hasNormalMap(false),
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
std::vector<std::vector<size_t>> triangleAndQuads;
|
std::vector<std::vector<size_t>> triangleAndQuads;
|
||||||
std::vector<std::vector<size_t>> triangles;
|
std::vector<std::vector<size_t>> triangles;
|
||||||
std::vector<QVector3D> triangleNormals;
|
std::vector<QVector3D> triangleNormals;
|
||||||
|
std::vector<QColor> triangleColors;
|
||||||
|
|
||||||
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes() const
|
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -320,7 +320,7 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
|
||||||
QPushButton *pickButton = new QPushButton();
|
QPushButton *pickButton = new QPushButton();
|
||||||
initToolButtonWithoutFont(pickButton);
|
initToolButtonWithoutFont(pickButton);
|
||||||
QPalette palette = pickButton->palette();
|
QPalette palette = pickButton->palette();
|
||||||
QColor choosenColor = part->hasColor ? part->color : Theme::white;
|
QColor choosenColor = part->hasColor ? part->color : Qt::white;
|
||||||
palette.setColor(QPalette::Window, choosenColor);
|
palette.setColor(QPalette::Window, choosenColor);
|
||||||
palette.setColor(QPalette::Button, choosenColor);
|
palette.setColor(QPalette::Button, choosenColor);
|
||||||
pickButton->setPalette(palette);
|
pickButton->setPalette(palette);
|
||||||
|
@ -331,7 +331,7 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
|
||||||
colorLayout->addStretch();
|
colorLayout->addStretch();
|
||||||
|
|
||||||
connect(colorEraser, &QPushButton::clicked, [=]() {
|
connect(colorEraser, &QPushButton::clicked, [=]() {
|
||||||
emit setPartColorState(m_partId, false, Theme::white);
|
emit setPartColorState(m_partId, false, Qt::white);
|
||||||
emit groupOperationAdded();
|
emit groupOperationAdded();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue