Skip to content

Commit

Permalink
Improved fix for issue that causes hair builder to be non-deterministic.
Browse files Browse the repository at this point in the history
  • Loading branch information
svenwoop committed Jan 16, 2018
1 parent e4c2588 commit f998ab2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
29 changes: 19 additions & 10 deletions kernels/builders/heuristic_binning_array_unaligned.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ namespace embree

const LinearSpace3fa computeAlignedSpace(const range<size_t>& set)
{
/*! find first curve that defines valid direction */
Vec3fa axis(0,0,1);
uint64_t bestGeomPrimID = -1;

/*! find curve with minimal ID that defines valid direction */
for (size_t i=set.begin(); i<set.end(); i++)
{
NativeCurves* mesh = (NativeCurves*) scene->get(prims[i].geomID());
const unsigned vtxID = mesh->curve(prims[i].primID());
const unsigned int geomID = prims[i].geomID();
const unsigned int primID = prims[i].primID();
const uint64_t geomprimID = prims[i].ID64();
if (geomprimID >= bestGeomPrimID) continue;
NativeCurves* mesh = (NativeCurves*) scene->get(geomID);
const unsigned vtxID = mesh->curve(primID);
const Vec3fa v0 = mesh->vertex(vtxID+0);
const Vec3fa v1 = mesh->vertex(vtxID+1);
const Vec3fa v2 = mesh->vertex(vtxID+2);
Expand All @@ -55,12 +61,12 @@ namespace embree
const Vec3fa axis1 = normalize(p3 - p0);
if (sqr_length(p3-p0) > 1E-18f) {
axis = axis1;
break;
bestGeomPrimID = geomprimID;
}
}
return frame(axis).transposed();
}

const PrimInfo computePrimInfo(const range<size_t>& set, const LinearSpace3fa& space)
{
auto computeBounds = [&](const range<size_t>& r) -> CentGeomBBox3fa
Expand Down Expand Up @@ -216,15 +222,18 @@ namespace embree
const LinearSpace3fa computeAlignedSpaceMB(Scene* scene, const SetMB& set)
{
Vec3fa axis0(0,0,1);
uint64_t bestGeomPrimID = -1;

/*! find first curve that defines valid direction */
/*! find curve with minimal ID that defines valid direction */
for (size_t i=set.object_range.begin(); i<set.object_range.end(); i++)
{
const PrimRefMB& prim = (*set.prims)[i];
const size_t geomID = prim.geomID();
const size_t primID = prim.primID();
const unsigned int geomID = prim.geomID();
const unsigned int primID = prim.primID();
const uint64_t geomprimID = prim.ID64();
if (geomprimID >= bestGeomPrimID) continue;

const NativeCurves* mesh = scene->get<NativeCurves>(geomID);

const unsigned num_time_segments = mesh->numTimeSegments();
const range<int> tbounds = getTimeSegmentRange(set.time_range, (float)num_time_segments);
if (tbounds.size() == 0) continue;
Expand All @@ -236,7 +245,7 @@ namespace embree

if (sqr_length(a3 - a0) > 1E-18f) {
axis0 = normalize(a3 - a0);
break;
bestGeomPrimID = geomprimID;
}
}

Expand Down
25 changes: 21 additions & 4 deletions kernels/builders/heuristic_strand_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,37 @@ namespace embree
/*! finds the best split */
const Split find(const range<size_t>& set)
{
/* first curve determines first axis */
Vec3fa axis0 = normalize(direction(prims[set.begin()]));
Vec3fa axis0(0,0,1);
uint64_t bestGeomPrimID = -1;

/* curve with minimal ID determines first axis */
for (size_t i=set.begin(); i<set.end(); i++)
{
const uint64_t geomprimID = prims[i].ID64();
if (geomprimID >= bestGeomPrimID) continue;
const Vec3fa axis = direction(prims[i]);
if (sqr_length(axis) > 1E-18f) {
axis0 = normalize(axis);
bestGeomPrimID = geomprimID;
}
}

/* find 2nd axis that is most misaligned with first axis */
/* find 2nd axis that is most misaligned with first axis and has minimal ID */
float bestCos = 1.0f;
Vec3fa axis1 = axis0;
bestGeomPrimID = -1;
for (size_t i=set.begin(); i<set.end(); i++)
{
const uint64_t geomprimID = prims[i].ID64();
Vec3fa axisi = direction(prims[i]);
float leni = length(axisi);
if (leni == 0.0f) continue;
axisi /= leni;
float cos = abs(dot(axisi,axis0));
if (cos < bestCos) { bestCos = cos; axis1 = axisi; }
if ((cos == bestCos && (geomprimID < bestGeomPrimID)) || cos < bestCos) {
bestCos = cos; axis1 = axisi;
bestGeomPrimID = geomprimID;
}
}

/* partition the two strands */
Expand Down

0 comments on commit f998ab2

Please sign in to comment.