void Path::release(size_t start, size_t end, MemoryPool &pool) { for (size_t i=start; i<end; ++i) { pool.release(m_vertices[i]); if (i+1 < end) pool.release(m_edges[i]); } }
int Path::randomWalk(const Scene *scene, Sampler *sampler, int nSteps, int rrStart, ETransportMode mode, MemoryPool &pool) { /* Determine the relevant edge and vertex to start the random walk */ PathVertex *curVertex = m_vertices[m_vertices.size()-1], *predVertex = m_vertices.size() < 2 ? NULL : m_vertices[m_vertices.size()-2]; PathEdge *predEdge = m_edges.empty() ? NULL : m_edges[m_edges.size()-1]; Spectrum throughput(1.0f); for (int i=0; i<nSteps || nSteps == -1; ++i) { PathVertex *succVertex = pool.allocVertex(); PathEdge *succEdge = pool.allocEdge(); if (!curVertex->sampleNext(scene, sampler, predVertex, predEdge, succEdge, succVertex, mode, rrStart != -1 && i >= rrStart, &throughput)) { pool.release(succVertex); pool.release(succEdge); return i; } append(succEdge, succVertex); predVertex = curVertex; curVertex = succVertex; predEdge = succEdge; } return nSteps; }
void Path::release(MemoryPool &pool) { for (size_t i=0; i<m_vertices.size(); ++i) pool.release(m_vertices[i]); for (size_t i=0; i<m_edges.size(); ++i) pool.release(m_edges[i]); m_vertices.clear(); m_edges.clear(); }
int Path::randomWalkFromPixel(const Scene *scene, Sampler *sampler, int nSteps, const Point2i &pixelPosition, int rrStart, MemoryPool &pool) { PathVertex *v1 = pool.allocVertex(), *v2 = pool.allocVertex(); PathEdge *e0 = pool.allocEdge(), *e1 = pool.allocEdge(); /* Use a special sampling routine for the first two sensor vertices so that the resulting subpath passes through the specified pixel position */ int t = vertex(0)->sampleSensor(scene, sampler, pixelPosition, e0, v1, e1, v2); if (t < 1) { pool.release(e0); pool.release(v1); return 0; } append(e0, v1); if (t < 2) { pool.release(e1); pool.release(v2); return 1; } append(e1, v2); PathVertex *predVertex = v1, *curVertex = v2; PathEdge *predEdge = e1; Spectrum throughput(1.0f); for (; t<nSteps || nSteps == -1; ++t) { PathVertex *succVertex = pool.allocVertex(); PathEdge *succEdge = pool.allocEdge(); if (!curVertex->sampleNext(scene, sampler, predVertex, predEdge, succEdge, succVertex, ERadiance, rrStart != -1 && t >= rrStart, &throughput)) { pool.release(succVertex); pool.release(succEdge); return t; } append(succEdge, succVertex); predVertex = curVertex; curVertex = succVertex; predEdge = succEdge; } return nSteps; }
void PoolAllocator::release(Address addr) { for (Size i = POOL_MIN_POWER - 1; i < POOL_MAX_POWER; i++) { for (MemoryPool *p = pools[i]; p; p = p->next) { if (addr < p->addr + (p->count * p->size) && addr >= p->addr) { p->release(addr); return; } } } }
std::pair<int, int> Path::alternatingRandomWalkFromPixel(const Scene *scene, Sampler *sampler, Path &emitterPath, int nEmitterSteps, Path &sensorPath, int nSensorSteps, const Point2i &pixelPosition, int rrStart, MemoryPool &pool) { /* Determine the relevant edges and vertices to start the random walk */ PathVertex *curVertexS = emitterPath.vertex(0), *curVertexT = sensorPath.vertex(0), *predVertexS = NULL, *predVertexT = NULL; PathEdge *predEdgeS = NULL, *predEdgeT = NULL; PathVertex *v1 = pool.allocVertex(), *v2 = pool.allocVertex(); PathEdge *e0 = pool.allocEdge(), *e1 = pool.allocEdge(); /* Use a special sampling routine for the first two sensor vertices so that the resulting subpath passes through the specified pixel position */ int t = curVertexT->sampleSensor(scene, sampler, pixelPosition, e0, v1, e1, v2); if (t >= 1) { sensorPath.append(e0, v1); } else { pool.release(e0); pool.release(v1); } if (t == 2) { sensorPath.append(e1, v2); predVertexT = v1; curVertexT = v2; predEdgeT = e1; } else { pool.release(e1); pool.release(v2); curVertexT = NULL; } Spectrum throughputS(1.0f), throughputT(1.0f); int s = 0; do { if (curVertexT && (t < nSensorSteps || nSensorSteps == -1)) { PathVertex *succVertexT = pool.allocVertex(); PathEdge *succEdgeT = pool.allocEdge(); if (curVertexT->sampleNext(scene, sampler, predVertexT, predEdgeT, succEdgeT, succVertexT, ERadiance, rrStart != -1 && t >= rrStart, &throughputT)) { sensorPath.append(succEdgeT, succVertexT); predVertexT = curVertexT; curVertexT = succVertexT; predEdgeT = succEdgeT; t++; } else { pool.release(succVertexT); pool.release(succEdgeT); curVertexT = NULL; } } else { curVertexT = NULL; } if (curVertexS && (s < nEmitterSteps || nEmitterSteps == -1)) { PathVertex *succVertexS = pool.allocVertex(); PathEdge *succEdgeS = pool.allocEdge(); if (curVertexS->sampleNext(scene, sampler, predVertexS, predEdgeS, succEdgeS, succVertexS, EImportance, rrStart != -1 && s >= rrStart, &throughputS)) { emitterPath.append(succEdgeS, succVertexS); predVertexS = curVertexS; curVertexS = succVertexS; predEdgeS = succEdgeS; s++; } else { pool.release(succVertexS); pool.release(succEdgeS); curVertexS = NULL; } } else { curVertexS = NULL; } } while (curVertexS || curVertexT); return std::make_pair(s, t); }