coarsen hairs that are too finely tesselated

metadata
Wenzel Jakob 2010-10-26 18:11:59 +02:00
parent 0a611c51dd
commit 48e6b95a90
1 changed files with 35 additions and 4 deletions

View File

@ -495,7 +495,11 @@ public:
Hair(const Properties &props) : Shape(props) { Hair(const Properties &props) : Shape(props) {
fs::path path = Thread::getThread()->getFileResolver()->resolve( fs::path path = Thread::getThread()->getFileResolver()->resolve(
props.getString("filename")); props.getString("filename"));
Float radius = (Float) props.getFloat("radius", 0.05f); Float radius = props.getFloat("radius", 0.05f);
/* Skip segments, whose tangent differs by less than one degree
compared to the previous one */
Float angleThreshold = degToRad(props.getFloat("angleThreshold", 1.0f));
Float dpThresh = std::cos(angleThreshold);
/* Object-space -> World-space transformation */ /* Object-space -> World-space transformation */
Transform objectToWorld = props.getTransform("toWorld", Transform()); Transform objectToWorld = props.getTransform("toWorld", Transform());
@ -511,7 +515,8 @@ public:
Point p, lastP(0.0f); Point p, lastP(0.0f);
std::vector<Point> vertices; std::vector<Point> vertices;
std::vector<bool> vertexStartsFiber; std::vector<bool> vertexStartsFiber;
size_t nDegenerate = 0; Vector tangent(0.0f);
size_t nDegenerate = 0, nSkipped = 0;
while (is.good()) { while (is.good()) {
std::getline(is, line); std::getline(is, line);
@ -522,10 +527,33 @@ public:
std::istringstream iss(line); std::istringstream iss(line);
iss >> p.x >> p.y >> p.z; iss >> p.x >> p.y >> p.z;
if (!iss.fail()) { if (!iss.fail()) {
if (newFiber || p != lastP) { p = objectToWorld(p);
vertices.push_back(objectToWorld(p)); if (newFiber) {
vertices.push_back(p);
vertexStartsFiber.push_back(newFiber); vertexStartsFiber.push_back(newFiber);
lastP = p; lastP = p;
tangent = Vector(0.0f);
} else if (p != lastP) {
if (tangent.isZero()) {
vertices.push_back(p);
vertexStartsFiber.push_back(newFiber);
tangent = normalize(p - lastP);
lastP = p;
} else {
Vector nextTangent = normalize(p - lastP);
if (dot(nextTangent, tangent) > dpThresh) {
/* Too small of a difference in the tangent value,
just overwrite the previous vertex by the current one */
tangent = normalize(p - vertices[vertices.size()-2]);
vertices[vertices.size()-1] = p;
++nSkipped;
} else {
vertices.push_back(p);
vertexStartsFiber.push_back(newFiber);
tangent = nextTangent;
}
lastP = p;
}
} else { } else {
nDegenerate++; nDegenerate++;
} }
@ -538,6 +566,9 @@ public:
if (nDegenerate > 0) if (nDegenerate > 0)
Log(EInfo, "Encountered " SIZE_T_FMT Log(EInfo, "Encountered " SIZE_T_FMT
" degenerate segments!", nDegenerate); " degenerate segments!", nDegenerate);
if (nSkipped > 0)
Log(EInfo, "Skipped " SIZE_T_FMT
" low-curvature segments.", nSkipped);
vertexStartsFiber.push_back(true); vertexStartsFiber.push_back(true);