diff --git a/include/mitsuba/bidir/mut_bidir.h b/include/mitsuba/bidir/mut_bidir.h index 8f480ae6..8a89f0f0 100644 --- a/include/mitsuba/bidir/mut_bidir.h +++ b/include/mitsuba/bidir/mut_bidir.h @@ -64,7 +64,7 @@ public: EMutationType getType() const; Float suitability(const Path &path) const; - bool sampleMutation(Path &source, Path &proposal, MutationRecord &muRec); + bool sampleMutation(Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec); Float Q(const Path &source, const Path &proposal, const MutationRecord &muRec) const; void accept(const MutationRecord &muRec); diff --git a/include/mitsuba/bidir/mut_caustic.h b/include/mitsuba/bidir/mut_caustic.h index d501fe21..7e4899db 100644 --- a/include/mitsuba/bidir/mut_caustic.h +++ b/include/mitsuba/bidir/mut_caustic.h @@ -63,7 +63,7 @@ public: EMutationType getType() const; Float suitability(const Path &path) const; bool sampleMutation(Path &source, Path &proposal, - MutationRecord &muRec); + MutationRecord &muRec, const MutationRecord& sourceMuRec); Float Q(const Path &source, const Path &proposal, const MutationRecord &muRec) const; void accept(const MutationRecord &muRec); diff --git a/include/mitsuba/bidir/mut_lens.h b/include/mitsuba/bidir/mut_lens.h index 0954bee0..35b66acf 100644 --- a/include/mitsuba/bidir/mut_lens.h +++ b/include/mitsuba/bidir/mut_lens.h @@ -63,7 +63,7 @@ public: EMutationType getType() const; Float suitability(const Path &path) const; bool sampleMutation(Path &source, Path &proposal, - MutationRecord &muRec); + MutationRecord &muRec, const MutationRecord& sourceMuRec); Float Q(const Path &source, const Path &proposal, const MutationRecord &muRec) const; void accept(const MutationRecord &muRec); diff --git a/include/mitsuba/bidir/mut_manifold.h b/include/mitsuba/bidir/mut_manifold.h index 784b47c8..d99610fb 100644 --- a/include/mitsuba/bidir/mut_manifold.h +++ b/include/mitsuba/bidir/mut_manifold.h @@ -61,7 +61,7 @@ public: EMutationType getType() const; Float suitability(const Path &path) const; bool sampleMutation(Path &source, Path &proposal, - MutationRecord &muRec); + MutationRecord &muRec, const MutationRecord& sourceMuRec); Float Q(const Path &source, const Path &proposal, const MutationRecord &muRec) const; void accept(const MutationRecord &muRec); diff --git a/include/mitsuba/bidir/mut_mchain.h b/include/mitsuba/bidir/mut_mchain.h index 5bbcb3fb..be100b38 100644 --- a/include/mitsuba/bidir/mut_mchain.h +++ b/include/mitsuba/bidir/mut_mchain.h @@ -63,7 +63,7 @@ public: EMutationType getType() const; Float suitability(const Path &path) const; bool sampleMutation(Path &source, Path &proposal, - MutationRecord &muRec); + MutationRecord &muRec, const MutationRecord& sourceMuRec); Float Q(const Path &source, const Path &proposal, const MutationRecord &muRec) const; void accept(const MutationRecord &muRec); diff --git a/include/mitsuba/bidir/mutator.h b/include/mitsuba/bidir/mutator.h index 2e82054b..ec0cc3cc 100644 --- a/include/mitsuba/bidir/mutator.h +++ b/include/mitsuba/bidir/mutator.h @@ -64,13 +64,17 @@ public: * \param muRec * Data record that describes the sampled mutation strategy * + * \param sourceMuRec + * Data record that describes the last successful mutation strategy + * (for the source path) + * * \return \a true upon success. When the sampling step is * unsuccessful (this could happen due to various * reasons), the function returns false. - */ + */ virtual bool sampleMutation(Path &source, Path &proposal, - MutationRecord &muRec) = 0; + MutationRecord &muRec, const MutationRecord& sourceMuRec) = 0; /** * \brief For a pair of paths, this function computes the inverse diff --git a/src/integrators/erpt/erpt_proc.cpp b/src/integrators/erpt/erpt_proc.cpp index 8237a84d..5ac664a2 100644 --- a/src/integrators/erpt/erpt_proc.cpp +++ b/src/integrators/erpt/erpt_proc.cpp @@ -174,7 +174,7 @@ public: std::ostringstream oss; Spectrum relWeight(0.0f); Float accumulatedWeight = 0; - MutationRecord muRec; + MutationRecord muRec, currentMuRec(Mutator::EMutationTypeCount, 0, 0, 0, Spectrum(0.f)); Path *current = new Path(), *proposed = new Path(); size_t mutations = 0; @@ -211,7 +211,7 @@ public: mutator = m_mutators[mutatorIdx].get(); /* Sample a mutated path */ - success = mutator->sampleMutation(*current, *proposed, muRec); + success = mutator->sampleMutation(*current, *proposed, muRec, currentMuRec); statsAccepted.incrementBase(1); if (success) { @@ -258,6 +258,7 @@ public: std::swap(current, proposed); relWeight = current->getRelativeWeight(); mutator->accept(muRec); + currentMuRec = muRec; accumulatedWeight = a; ++statsAccepted; ++mutations; diff --git a/src/integrators/mlt/mlt_proc.cpp b/src/integrators/mlt/mlt_proc.cpp index 402120c4..4228c0ae 100644 --- a/src/integrators/mlt/mlt_proc.cpp +++ b/src/integrators/mlt/mlt_proc.cpp @@ -127,7 +127,7 @@ public: BDAssert(!relWeight.isZero()); DiscreteDistribution suitabilities(m_mutators.size()); - MutationRecord muRec; + MutationRecord muRec, currentMuRec(Mutator::EMutationTypeCount,0,0,0,Spectrum(0.f)); ref timer = new Timer(); size_t consecRejections = 0; @@ -171,7 +171,7 @@ public: mutator = m_mutators[mutatorIdx].get(); /* Sample a mutated path */ - success = mutator->sampleMutation(*current, *proposed, muRec); + success = mutator->sampleMutation(*current, *proposed, muRec, currentMuRec); #if defined(MTS_BD_DEBUG_HEAVY) if (backup != *current) @@ -263,11 +263,12 @@ public: std::swap(current, proposed); relWeight = current->getRelativeWeight(); mutator->accept(muRec); + currentMuRec = muRec; accumulatedWeight = a; consecRejections = 0; ++statsAccepted; } else { - /* The mutation was rejected */ + /* The mutation was rejected */ proposed->release(muRec.l, muRec.l + muRec.ka + 1, *m_pool); consecRejections++; if (a > 0) { diff --git a/src/libbidir/mut_bidir.cpp b/src/libbidir/mut_bidir.cpp index 7cf67be0..dee4609e 100644 --- a/src/libbidir/mut_bidir.cpp +++ b/src/libbidir/mut_bidir.cpp @@ -44,7 +44,7 @@ Float BidirectionalMutator::suitability(const Path &path) const { } bool BidirectionalMutator::sampleMutation( - Path &source, Path &proposal, MutationRecord &muRec) { + Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec) { TwoTailedGeoDistr desiredLength(2), deletionLength(2); int k = source.length(); diff --git a/src/libbidir/mut_caustic.cpp b/src/libbidir/mut_caustic.cpp index bf351c23..203ebb4e 100644 --- a/src/libbidir/mut_caustic.cpp +++ b/src/libbidir/mut_caustic.cpp @@ -73,7 +73,7 @@ Float CausticPerturbation::suitability(const Path &path) const { } bool CausticPerturbation::sampleMutation( - Path &source, Path &proposal, MutationRecord &muRec) { + Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec) { int k = source.length(), m = k - 1, l = m - 1; if (k < 4 || !source.vertex(l)->isConnectable()) diff --git a/src/libbidir/mut_lens.cpp b/src/libbidir/mut_lens.cpp index e2f938e5..bc8aa971 100644 --- a/src/libbidir/mut_lens.cpp +++ b/src/libbidir/mut_lens.cpp @@ -70,7 +70,7 @@ Float LensPerturbation::suitability(const Path &path) const { } bool LensPerturbation::sampleMutation( - Path &source, Path &proposal, MutationRecord &muRec) { + Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec) { int k = source.length(), m = k-1, l = m-1; while (!source.vertex(l)->isConnectable() && l >= 0) --l; diff --git a/src/libbidir/mut_manifold.cpp b/src/libbidir/mut_manifold.cpp index 0ce9de7b..48af6dee 100644 --- a/src/libbidir/mut_manifold.cpp +++ b/src/libbidir/mut_manifold.cpp @@ -230,7 +230,7 @@ bool ManifoldPerturbation::sampleMutationRecord( } bool ManifoldPerturbation::sampleMutation( - Path &source, Path &proposal, MutationRecord &muRec) { + Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec) { int k = source.length(); int a, b, c, step, tries = 0; diff --git a/src/libbidir/mut_mchain.cpp b/src/libbidir/mut_mchain.cpp index bae1a6f1..1e608cfa 100644 --- a/src/libbidir/mut_mchain.cpp +++ b/src/libbidir/mut_mchain.cpp @@ -66,7 +66,7 @@ Float MultiChainPerturbation::suitability(const Path &path) const { } bool MultiChainPerturbation::sampleMutation( - Path &source, Path &proposal, MutationRecord &muRec) { + Path &source, Path &proposal, MutationRecord &muRec, const MutationRecord& sourceMuRec) { int k = source.length(), m = k - 1, l = m-1, nChains = 1; while (l-1 >= 0 && (!source.vertex(l)->isConnectable()