Skip to content

Commit ec9d73e

Browse files
committed
mesh,uv: remove vertices welding, add component color to broken triangles
1 parent 63a1a58 commit ec9d73e

File tree

12 files changed

+75
-217
lines changed

12 files changed

+75
-217
lines changed

application/application.pro

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,6 @@ HEADERS += ../dust3d/mesh/trim_vertices.h
285285
SOURCES += ../dust3d/mesh/trim_vertices.cc
286286
HEADERS += ../dust3d/mesh/tube_mesh_builder.h
287287
SOURCES += ../dust3d/mesh/tube_mesh_builder.cc
288-
HEADERS += ../dust3d/mesh/weld_vertices.h
289-
SOURCES += ../dust3d/mesh/weld_vertices.cc
290288
HEADERS += ../dust3d/uv/chart_packer.h
291289
SOURCES += ../dust3d/uv/chart_packer.cc
292290
HEADERS += ../dust3d/uv/max_rectangles.h

application/sources/uv_map_generator.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,31 @@ void UvMapGenerator::packUvs()
127127
m_mapPacker->addPart(part);
128128
}
129129

130+
// The following is to make a component colored UV for those broken triangles which generated by mesh boolean algorithm
131+
std::map<dust3d::Uuid, dust3d::UvMapPacker::Part> partWithBrokenTriangles;
132+
const auto zeroUv = std::array<dust3d::Vector2, 3> {
133+
dust3d::Vector2(0.0, 0.0), dust3d::Vector2(0.0, 0.0), dust3d::Vector2(0.0, 0.0)
134+
};
135+
for (const auto& brokenTrianglesToComponentIdIt : m_object->brokenTrianglesToComponentIdMap) {
136+
partWithBrokenTriangles[brokenTrianglesToComponentIdIt.second].localUv.insert({ brokenTrianglesToComponentIdIt.first, zeroUv });
137+
}
138+
for (auto& partIt : partWithBrokenTriangles) {
139+
auto componentIt = m_snapshot->components.find(partIt.first.toString());
140+
if (componentIt == m_snapshot->components.end())
141+
continue;
142+
dust3d::Color color(1.0, 1.0, 1.0);
143+
double width = 1.0;
144+
double height = 1.0;
145+
const auto& colorIt = componentIt->second.find("color");
146+
if (colorIt != componentIt->second.end()) {
147+
color = dust3d::Color(colorIt->second);
148+
}
149+
partIt.second.color = color;
150+
partIt.second.width = width;
151+
partIt.second.height = height;
152+
m_mapPacker->addPart(partIt.second);
153+
}
154+
130155
m_mapPacker->addSeams(m_object->seamTriangleUvs);
131156

132157
m_mapPacker->pack();

ci/lint.sh

100644100755
File mode changed.

dust3d/base/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Object {
6565
std::vector<Vector3> triangleNormals;
6666
std::vector<Color> vertexColors;
6767
std::vector<float> vertexSmoothCutoffDegrees;
68+
std::map<std::array<PositionKey, 3>, Uuid> brokenTrianglesToComponentIdMap;
6869
bool alphaEnabled = false;
6970
uint64_t meshId = 0;
7071

dust3d/mesh/mesh_generator.cc

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
#include <dust3d/mesh/triangulate.h>
3333
#include <dust3d/mesh/trim_vertices.h>
3434
#include <dust3d/mesh/tube_mesh_builder.h>
35-
#include <dust3d/mesh/weld_vertices.h>
3635
#include <functional>
3736
#include <memory>
3837

@@ -902,7 +901,7 @@ std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string
902901
}
903902
std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>> groupMeshes;
904903
for (const auto& group : combineGroups) {
905-
auto childMesh = combineComponentChildGroupMesh(group.second, componentCache);
904+
auto childMesh = combineComponentChildGroupMesh(group.second, componentCache, &componentCache.brokenTriangles);
906905
if (nullptr == childMesh || childMesh->isNull())
907906
continue;
908907
groupMeshes.emplace_back(std::make_tuple(std::move(childMesh), group.first, String::join(group.second, "|")));
@@ -922,7 +921,7 @@ std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string
922921
groupMeshes.emplace_back(std::make_tuple(std::move(stitchingMesh), CombineMode::Normal, String::join(stitchingComponents, ":")));
923922
}
924923
}
925-
mesh = combineMultipleMeshes(std::move(groupMeshes));
924+
mesh = combineMultipleMeshes(std::move(groupMeshes), &componentCache.brokenTriangles);
926925
ComponentPreview preview;
927926
if (mesh) {
928927
mesh->fetch(preview.vertices, preview.triangles);
@@ -947,7 +946,8 @@ std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string
947946
return mesh;
948947
}
949948

950-
std::unique_ptr<MeshState> MeshGenerator::combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes)
949+
std::unique_ptr<MeshState> MeshGenerator::combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes,
950+
std::set<std::array<PositionKey, 3>>* brokenTriangles)
951951
{
952952
std::unique_ptr<MeshState> mesh;
953953
std::string meshIdStrings;
@@ -982,6 +982,10 @@ std::unique_ptr<MeshState> MeshGenerator::combineMultipleMeshes(std::vector<std:
982982
m_cacheContext->cachedCombination.insert({ meshIdStrings, nullptr });
983983
}
984984
if (newMesh && !newMesh->isNull()) {
985+
if (nullptr != brokenTriangles) {
986+
for (const auto& brokenTriangle : newMesh->brokenTriangles)
987+
brokenTriangles->insert(brokenTriangle);
988+
}
985989
mesh = std::move(newMesh);
986990
} else {
987991
m_isSuccessful = false;
@@ -993,7 +997,9 @@ std::unique_ptr<MeshState> MeshGenerator::combineMultipleMeshes(std::vector<std:
993997
return mesh;
994998
}
995999

996-
std::unique_ptr<MeshState> MeshGenerator::combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings, GeneratedComponent& componentCache)
1000+
std::unique_ptr<MeshState> MeshGenerator::combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings,
1001+
GeneratedComponent& componentCache,
1002+
std::set<std::array<PositionKey, 3>>* brokenTriangles)
9971003
{
9981004
std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>> multipleMeshes;
9991005
for (const auto& childIdString : componentIdStrings) {
@@ -1022,7 +1028,7 @@ std::unique_ptr<MeshState> MeshGenerator::combineComponentChildGroupMesh(const s
10221028

10231029
multipleMeshes.emplace_back(std::make_tuple(std::move(subMesh), childCombineMode, childIdString));
10241030
}
1025-
return combineMultipleMeshes(std::move(multipleMeshes));
1031+
return combineMultipleMeshes(std::move(multipleMeshes), brokenTriangles);
10261032
}
10271033

10281034
void MeshGenerator::collectSharedQuadEdges(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces,
@@ -1139,6 +1145,20 @@ void MeshGenerator::collectUncombinedComponent(const std::string& componentIdStr
11391145
}
11401146
}
11411147

1148+
void MeshGenerator::collectBrokenTriangles(const std::string& componentIdString)
1149+
{
1150+
const auto& component = findComponent(componentIdString);
1151+
for (const auto& childIdString : String::split(String::valueOrEmpty(*component, "children"), ',')) {
1152+
if (childIdString.empty())
1153+
continue;
1154+
collectBrokenTriangles(childIdString);
1155+
}
1156+
const auto& componentCache = m_cacheContext->components[componentIdString];
1157+
for (const auto& triangle : componentCache.brokenTriangles) {
1158+
m_object->brokenTrianglesToComponentIdMap.insert({ triangle, Uuid(componentIdString) });
1159+
}
1160+
}
1161+
11421162
void MeshGenerator::setDefaultPartColor(const Color& color)
11431163
{
11441164
m_defaultPartColor = color;
@@ -1310,27 +1330,14 @@ void MeshGenerator::generate()
13101330
if (nullptr != combinedMesh) {
13111331
combinedMesh->fetch(combinedVertices, combinedFaces);
13121332
m_object->seamTriangleUvs = combinedMesh->seamTriangleUvs;
1313-
if (m_weldEnabled) {
1314-
size_t totalAffectedNum = 0;
1315-
size_t affectedNum = 0;
1316-
do {
1317-
std::vector<Vector3> weldedVertices;
1318-
std::vector<std::vector<size_t>> weldedFaces;
1319-
affectedNum = weldVertices(combinedVertices, combinedFaces,
1320-
m_minimalRadius, componentCache.noneSeamVertices,
1321-
weldedVertices, weldedFaces);
1322-
combinedVertices = weldedVertices;
1323-
combinedFaces = weldedFaces;
1324-
totalAffectedNum += affectedNum;
1325-
} while (affectedNum > 0);
1326-
}
13271333
recoverQuads(combinedVertices, combinedFaces, componentCache.sharedQuadEdges, m_object->triangleAndQuads);
13281334
m_object->vertices = combinedVertices;
13291335
m_object->triangles = combinedFaces;
13301336
}
13311337

13321338
// Recursively check uncombined components
13331339
collectUncombinedComponent(to_string(Uuid()));
1340+
collectBrokenTriangles(to_string(Uuid()));
13341341

13351342
postprocessObject(m_object);
13361343

dust3d/mesh/mesh_generator.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class MeshGenerator {
7272
std::unique_ptr<MeshState> mesh;
7373
std::set<std::pair<PositionKey, PositionKey>> sharedQuadEdges;
7474
std::unordered_map<Uuid, std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> componentTriangleUvs;
75-
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
75+
std::set<std::array<PositionKey, 3>> brokenTriangles;
7676
std::set<PositionKey> noneSeamVertices;
7777
std::map<PositionKey, Uuid> positionToNodeIdMap;
7878
std::map<Uuid, ObjectNode> nodeMap;
@@ -81,7 +81,7 @@ class MeshGenerator {
8181
mesh.reset();
8282
sharedQuadEdges.clear();
8383
componentTriangleUvs.clear();
84-
seamTriangleUvs.clear();
84+
brokenTriangles.clear();
8585
noneSeamVertices.clear();
8686
positionToNodeIdMap.clear();
8787
nodeMap.clear();
@@ -141,7 +141,7 @@ class MeshGenerator {
141141
bool m_cacheEnabled = false;
142142
float m_smoothShadingThresholdAngleDegrees = 60;
143143
uint64_t m_id = 0;
144-
bool m_weldEnabled = true;
144+
bool m_weldEnabled = false;
145145

146146
void collectParts();
147147
void collectIncombinableMesh(const MeshState* mesh, const GeneratedComponent& componentCache);
@@ -160,8 +160,10 @@ class MeshGenerator {
160160
const std::map<std::string, std::string>* findComponent(const std::string& componentIdString);
161161
CombineMode componentCombineMode(const std::map<std::string, std::string>* component);
162162
std::unique_ptr<MeshState> combineComponentChildGroupMesh(const std::vector<std::string>& componentIdStrings,
163-
GeneratedComponent& componentCache);
164-
std::unique_ptr<MeshState> combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes);
163+
GeneratedComponent& componentCache,
164+
std::set<std::array<PositionKey, 3>>* brokenTriangles);
165+
std::unique_ptr<MeshState> combineMultipleMeshes(std::vector<std::tuple<std::unique_ptr<MeshState>, CombineMode, std::string>>&& multipleMeshes,
166+
std::set<std::array<PositionKey, 3>>* brokenTriangles);
165167
std::unique_ptr<MeshState> combineStitchingMesh(const std::string& componentIdString,
166168
const std::vector<std::string>& partIdStrings,
167169
const std::vector<std::string>& componentIdStrings,
@@ -173,6 +175,7 @@ class MeshGenerator {
173175
float smoothCutoffDegrees,
174176
GeneratedComponent& componentCache);
175177
void collectUncombinedComponent(const std::string& componentIdString);
178+
void collectBrokenTriangles(const std::string& componentIdString);
176179
void cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector<Vector2>& cutTemplate);
177180
void postprocessObject(Object* object);
178181
void preprocessMirror();

dust3d/mesh/mesh_recombiner.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ bool MeshRecombiner::recombine()
228228
return true;
229229
}
230230

231+
const std::map<size_t, size_t>& MeshRecombiner::inputFacesInSeamArea() const
232+
{
233+
return m_facesInSeamArea;
234+
}
235+
231236
size_t MeshRecombiner::adjustTrianglesFromSeam(std::vector<size_t>& edgeLoop, size_t seamIndex)
232237
{
233238
if (edgeLoop.size() <= 3)

dust3d/mesh/mesh_recombiner.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class MeshRecombiner {
4141
const std::vector<std::vector<size_t>>& regeneratedFaces();
4242
const std::vector<std::vector<std::pair<std::array<Vector3, 3>, std::array<Vector2, 3>>>>& generatedBridgingTriangleUvs();
4343
bool recombine();
44+
const std::map<size_t, size_t>& inputFacesInSeamArea() const;
4445

4546
private:
4647
const std::vector<Vector3>* m_vertices = nullptr;

dust3d/mesh/mesh_state.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ std::unique_ptr<MeshState> MeshState::combine(const MeshState& first, const Mesh
9393
newMesh = std::move(reMesh);
9494
}
9595
}
96+
for (const auto& faceIt : recombiner.inputFacesInSeamArea()) {
97+
const auto& face = combinedFaces[faceIt.first];
98+
newMeshState->brokenTriangles.push_back(std::array<PositionKey, 3> {
99+
PositionKey(combinedVertices[face[0]]),
100+
PositionKey(combinedVertices[face[1]]),
101+
PositionKey(combinedVertices[face[2]]) });
102+
}
96103
}
97104
}
98105
if (newMesh->isNull()) {

dust3d/mesh/mesh_state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class MeshState {
3333
public:
3434
std::unique_ptr<MeshCombiner::Mesh> mesh;
3535
std::vector<std::map<std::array<PositionKey, 3>, std::array<Vector2, 3>>> seamTriangleUvs;
36+
std::vector<std::array<PositionKey, 3>> brokenTriangles;
3637

3738
MeshState() = default;
3839
MeshState(const std::vector<Vector3>& vertices, const std::vector<std::vector<size_t>>& faces);

0 commit comments

Comments
 (0)