ignore duplicate geometry when importing
parent
ab7961df0c
commit
f80535f543
|
@ -203,34 +203,72 @@ VertexData *fetchVertexData(Transform transform, std::ostream &os,
|
||||||
/// For using vertices as keys in an associative structure
|
/// For using vertices as keys in an associative structure
|
||||||
struct vertex_key_order : public
|
struct vertex_key_order : public
|
||||||
std::binary_function<Vertex, Vertex, bool> {
|
std::binary_function<Vertex, Vertex, bool> {
|
||||||
public:
|
static int compare(const Vertex &v1, const Vertex &v2) {
|
||||||
|
if (v1.v.x < v2.v.x) return -1;
|
||||||
|
else if (v1.v.x > v2.v.x) return 1;
|
||||||
|
if (v1.v.y < v2.v.y) return -1;
|
||||||
|
else if (v1.v.y > v2.v.y) return 1;
|
||||||
|
if (v1.v.z < v2.v.z) return -1;
|
||||||
|
else if (v1.v.z > v2.v.z) return 1;
|
||||||
|
if (v1.n.x < v2.n.x) return -1;
|
||||||
|
else if (v1.n.x > v2.n.x) return 1;
|
||||||
|
if (v1.n.y < v2.n.y) return -1;
|
||||||
|
else if (v1.n.y > v2.n.y) return 1;
|
||||||
|
if (v1.n.z < v2.n.z) return -1;
|
||||||
|
else if (v1.n.z > v2.n.z) return 1;
|
||||||
|
if (v1.uv.x < v2.uv.x) return -1;
|
||||||
|
else if (v1.uv.x > v2.uv.x) return 1;
|
||||||
|
if (v1.uv.y < v2.uv.y) return -1;
|
||||||
|
else if (v1.uv.y > v2.uv.y) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator()(const Vertex &v1, const Vertex &v2) const {
|
bool operator()(const Vertex &v1, const Vertex &v2) const {
|
||||||
if (v1.v.x < v2.v.x) return true;
|
return compare(v1, v2) < 0;
|
||||||
else if (v1.v.x > v2.v.x) return false;
|
}
|
||||||
if (v1.v.y < v2.v.y) return true;
|
};
|
||||||
else if (v1.v.y > v2.v.y) return false;
|
|
||||||
if (v1.v.z < v2.v.z) return true;
|
struct SimpleTriangle {
|
||||||
else if (v1.v.z > v2.v.z) return false;
|
Point p0, p1, p2;
|
||||||
if (v1.n.x < v2.n.x) return true;
|
|
||||||
else if (v1.n.x > v2.n.x) return false;
|
inline SimpleTriangle() { }
|
||||||
if (v1.n.y < v2.n.y) return true;
|
inline SimpleTriangle(const Point &p0, const Point &p1, const Point &p2)
|
||||||
else if (v1.n.y > v2.n.y) return false;
|
: p0(p0), p1(p1), p2(p2) { }
|
||||||
if (v1.n.z < v2.n.z) return true;
|
};
|
||||||
else if (v1.n.z > v2.n.z) return false;
|
|
||||||
if (v1.uv.x < v2.uv.x) return true;
|
struct triangle_key_order : public std::binary_function<SimpleTriangle, SimpleTriangle, bool> {
|
||||||
else if (v1.uv.x > v2.uv.x) return false;
|
static int compare(const Point &v1, const Point &v2) {
|
||||||
if (v1.uv.y < v2.uv.y) return true;
|
if (v1.x < v2.x) return -1;
|
||||||
else if (v1.uv.y > v2.uv.y) return false;
|
else if (v1.x > v2.x) return 1;
|
||||||
|
if (v1.y < v2.y) return -1;
|
||||||
|
else if (v1.y > v2.y) return 1;
|
||||||
|
if (v1.z < v2.z) return -1;
|
||||||
|
else if (v1.z > v2.z) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool operator()(const SimpleTriangle &t1, const SimpleTriangle &t2) const {
|
||||||
|
int result;
|
||||||
|
result = compare(t1.p0, t2.p0);
|
||||||
|
if (result == -1) return true;
|
||||||
|
if (result == 1) return false;
|
||||||
|
result = compare(t1.p1, t2.p1);
|
||||||
|
if (result == -1) return true;
|
||||||
|
if (result == 1) return false;
|
||||||
|
result = compare(t1.p2, t2.p2);
|
||||||
|
if (result == -1) return true;
|
||||||
|
if (result == 1) return false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::map<SimpleTriangle, bool, triangle_key_order> TriangleMap;
|
||||||
|
|
||||||
void writeGeometry(std::string prefixName, std::string id, int geomIndex, std::string matID, Transform transform,
|
void writeGeometry(std::string prefixName, std::string id, int geomIndex, std::string matID, Transform transform,
|
||||||
std::ostream &os, VertexData *vData, const std::string &meshesDirectory) {
|
std::ostream &os, VertexData *vData, TriangleMap &triMap, const std::string &meshesDirectory) {
|
||||||
std::vector<Vertex> vertexBuffer;
|
std::vector<Vertex> vertexBuffer;
|
||||||
std::vector<Triangle> triangles;
|
std::vector<Triangle> triangles;
|
||||||
std::map<Vertex, int, vertex_key_order> vertexMap;
|
std::map<Vertex, int, vertex_key_order> vertexMap;
|
||||||
size_t numMerged = 0, triangleIdx = 0;
|
size_t numMerged = 0, triangleIdx = 0, duplicates = 0;
|
||||||
Triangle triangle;
|
Triangle triangle;
|
||||||
if (tess_data.size() == 0)
|
if (tess_data.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -263,11 +301,38 @@ void writeGeometry(std::string prefixName, std::string id, int geomIndex, std::s
|
||||||
}
|
}
|
||||||
triangle.idx[triangleIdx++] = key;
|
triangle.idx[triangleIdx++] = key;
|
||||||
if (triangleIdx == 3) {
|
if (triangleIdx == 3) {
|
||||||
triangles.push_back(triangle);
|
Point p0 = vertexBuffer[triangle.idx[0]].v,
|
||||||
|
p1 = vertexBuffer[triangle.idx[1]].v,
|
||||||
|
p2 = vertexBuffer[triangle.idx[2]].v;
|
||||||
|
if (triMap.find(SimpleTriangle(p0, p1, p2)) != triMap.end() ||
|
||||||
|
triMap.find(SimpleTriangle(p2, p0, p1)) != triMap.end() ||
|
||||||
|
triMap.find(SimpleTriangle(p1, p2, p0)) != triMap.end() ||
|
||||||
|
triMap.find(SimpleTriangle(p1, p0, p2)) != triMap.end() ||
|
||||||
|
triMap.find(SimpleTriangle(p0, p2, p1)) != triMap.end() ||
|
||||||
|
triMap.find(SimpleTriangle(p2, p1, p0)) != triMap.end()) {
|
||||||
|
/* This triangle is a duplicate from another one which exists
|
||||||
|
in the same geometry group -- we may be dealing with SketchUp,
|
||||||
|
which sometimes exports every face TWICE! */
|
||||||
|
duplicates++;
|
||||||
|
} else {
|
||||||
|
triMap[SimpleTriangle(p0, p1, p2)] = true;
|
||||||
|
triangles.push_back(triangle);
|
||||||
|
}
|
||||||
triangleIdx = 0;
|
triangleIdx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (duplicates > 0) {
|
||||||
|
if (triangles.size() == 0) {
|
||||||
|
SLog(EWarn, "%s: Only contains duplicates of already-existing geometry. Ignoring.");
|
||||||
|
os << "\t<!-- Ignored shape \"" << prefixName << "/"
|
||||||
|
<< id << "\" (mat=\"" << matID << "\"), since it only contains duplicate geometry. -->" << endl << endl;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
SLog(EWarn, "Geometry contains %i duplicate triangles!", duplicates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SAssert(triangleIdx == 0);
|
SAssert(triangleIdx == 0);
|
||||||
SLog(EInfo, "%s: Converted " SIZE_T_FMT " triangles, " SIZE_T_FMT
|
SLog(EInfo, "%s: Converted " SIZE_T_FMT " triangles, " SIZE_T_FMT
|
||||||
" vertices (merged " SIZE_T_FMT " vertices).", id.c_str(),
|
" vertices (merged " SIZE_T_FMT " vertices).", id.c_str(),
|
||||||
|
@ -315,8 +380,10 @@ void loadGeometry(std::string prefixName, Transform transform, std::ostream &os,
|
||||||
identifier = formatString("unnamedGeom_%i", unnamedCtr++);
|
identifier = formatString("unnamedGeom_%i", unnamedCtr++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TriangleMap triMap;
|
||||||
|
|
||||||
SLog(EInfo, "Converting geometry \"%s\" (instantiated by %s)..", identifier.c_str(), prefixName.c_str());
|
SLog(EInfo, "Converting geometry \"%s\" (instantiated by %s)..", identifier.c_str(),
|
||||||
|
prefixName == "" ? "/" : prefixName.c_str());
|
||||||
domMesh *mesh = geom.getMesh().cast();
|
domMesh *mesh = geom.getMesh().cast();
|
||||||
if (!mesh)
|
if (!mesh)
|
||||||
SLog(EError, "Invalid geometry type encountered (must be a <mesh>)!");
|
SLog(EError, "Invalid geometry type encountered (must be a <mesh>)!");
|
||||||
|
@ -340,7 +407,7 @@ void loadGeometry(std::string prefixName, Transform transform, std::ostream &os,
|
||||||
SLog(EWarn, "Referenced material could not be found, substituting a lambertian BRDF.");
|
SLog(EWarn, "Referenced material could not be found, substituting a lambertian BRDF.");
|
||||||
else
|
else
|
||||||
matID = matLookupTable[triangles->getMaterial()];
|
matID = matLookupTable[triangles->getMaterial()];
|
||||||
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, meshesDir);
|
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, triMap, meshesDir);
|
||||||
delete data;
|
delete data;
|
||||||
++geomIndex;
|
++geomIndex;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +445,7 @@ void loadGeometry(std::string prefixName, Transform transform, std::ostream &os,
|
||||||
else
|
else
|
||||||
matID = matLookupTable[polygons->getMaterial()];
|
matID = matLookupTable[polygons->getMaterial()];
|
||||||
|
|
||||||
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, meshesDir);
|
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, triMap, meshesDir);
|
||||||
delete data;
|
delete data;
|
||||||
++geomIndex;
|
++geomIndex;
|
||||||
}
|
}
|
||||||
|
@ -418,7 +485,7 @@ void loadGeometry(std::string prefixName, Transform transform, std::ostream &os,
|
||||||
else
|
else
|
||||||
matID = matLookupTable[polylist->getMaterial()];
|
matID = matLookupTable[polylist->getMaterial()];
|
||||||
|
|
||||||
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, meshesDir);
|
writeGeometry(prefixName, identifier, geomIndex, matID, transform, os, data, triMap, meshesDir);
|
||||||
delete data;
|
delete data;
|
||||||
++geomIndex;
|
++geomIndex;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue