Merge with default
commit
bf670cca99
|
@ -92,7 +92,7 @@ and one or more emitters. Here is a more complex example:
|
|||
<shape type="serialized">
|
||||
<string name="filename" value="lightsource.serialized"/>
|
||||
<transform name="toWorld">
|
||||
<translate x="5" x="-3" z="1"/>
|
||||
<translate x="5" y="-3" z="1"/>
|
||||
</transform>
|
||||
|
||||
<!-- This mesh is an area emitter -->
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
* underlying random number generator has been used
|
||||
* outside of this class
|
||||
*/
|
||||
inline void updateSampleIndex(uint64_t index) { m_sampleIndex = index; }
|
||||
inline void updateSampleIndex(size_t index) { m_sampleIndex = index; }
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
|
|
|
@ -250,6 +250,26 @@ public:
|
|||
EAuto
|
||||
};
|
||||
|
||||
/// List of different rotation/flip types that can be passed to \ref rotateFlip()
|
||||
enum ERotateFlipType {
|
||||
ERotateNoneFlipNone = 0,
|
||||
ERotate180FlipXY = ERotateNoneFlipNone,
|
||||
ERotate90FlipNone = 1,
|
||||
ERotate270FlipXY = ERotate90FlipNone,
|
||||
ERotate180FlipNone = 2,
|
||||
ERotateNoneFlipXY = ERotate180FlipNone,
|
||||
ERotate270FlipNone = 3,
|
||||
ERotate90FlipXY = ERotate270FlipNone,
|
||||
ERotateNoneFlipX = 4,
|
||||
ERotate180FlipY = ERotateNoneFlipX,
|
||||
ERotate90FlipX = 5,
|
||||
ERotate270FlipY = ERotate90FlipX,
|
||||
ERotate180FlipX = 6,
|
||||
ERotateNoneFlipY = ERotate180FlipX,
|
||||
ERotate270FlipX = 7,
|
||||
ERotate90FlipY = ERotate270FlipX
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Create a bitmap of the specified type and allocate
|
||||
* the necessary amount of memory
|
||||
|
@ -320,6 +340,15 @@ public:
|
|||
/// Return whether this image has matching width and height
|
||||
inline bool isSquare() const { return m_size.x == m_size.y; }
|
||||
|
||||
/// Return whether this image has an alpha channel
|
||||
inline bool hasAlpha() const {
|
||||
return
|
||||
m_pixelFormat == ELuminanceAlpha ||
|
||||
m_pixelFormat == ERGBA ||
|
||||
m_pixelFormat == EXYZA ||
|
||||
m_pixelFormat == ESpectrumAlpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the number bits per component
|
||||
*
|
||||
|
@ -679,6 +708,9 @@ public:
|
|||
/// Vertically flip the image contents
|
||||
void flipVertically();
|
||||
|
||||
/// Perform the specified rotatation & flip operation
|
||||
ref<Bitmap> rotateFlip(ERotateFlipType type) const;
|
||||
|
||||
/**
|
||||
* \brief Accumulate the contents of another bitmap into the
|
||||
* region of the specified offset
|
||||
|
|
|
@ -662,7 +662,6 @@ template <typename T> struct TVector4 {
|
|||
/// Number of dimensions
|
||||
const static int dim = 4;
|
||||
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
* This construtor is useful when the vector will either not
|
||||
|
|
|
@ -210,8 +210,8 @@ public:
|
|||
void serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Film::serialize(stream, manager);
|
||||
stream->writeBool(m_hasBanner);
|
||||
stream->writeUInt(m_fileFormat);
|
||||
stream->writeUInt(m_pixelFormat);
|
||||
stream->writeUInt(m_fileFormat);
|
||||
stream->writeFloat(m_gamma);
|
||||
stream->writeUInt(m_tonemapMethod);
|
||||
stream->writeFloat(m_exposure);
|
||||
|
|
|
@ -116,21 +116,20 @@ void BeamRadianceEstimator::serialize(Stream *stream, InstanceManager *manager)
|
|||
AABB BeamRadianceEstimator::buildHierarchy(IndexType index) {
|
||||
BRENode &node = m_nodes[index];
|
||||
|
||||
Point center = node.photon.getPosition();
|
||||
Float radius = node.radius;
|
||||
node.aabb = AABB(
|
||||
center - Vector(radius, radius, radius),
|
||||
center + Vector(radius, radius, radius)
|
||||
);
|
||||
|
||||
if (!node.photon.isLeaf()) {
|
||||
IndexType left = node.photon.getLeftIndex(index);
|
||||
IndexType right = node.photon.getRightIndex(index);
|
||||
node.aabb.reset();
|
||||
if (left)
|
||||
node.aabb.expandBy(buildHierarchy(left));
|
||||
if (right)
|
||||
node.aabb.expandBy(buildHierarchy(right));
|
||||
} else {
|
||||
Point center = node.photon.getPosition();
|
||||
Float radius = node.radius;
|
||||
node.aabb = AABB(
|
||||
center - Vector(radius, radius, radius),
|
||||
center + Vector(radius, radius, radius)
|
||||
);
|
||||
}
|
||||
|
||||
return node.aabb;
|
||||
|
|
|
@ -580,7 +580,7 @@ public:
|
|||
RadianceQueryRecord rRec2;
|
||||
Intersection &bsdfIts = rRec2.its;
|
||||
|
||||
DirectSamplingRecord dRec;
|
||||
DirectSamplingRecord dRec(its);
|
||||
for (int i=0; i<numBSDFSamples; ++i) {
|
||||
/* Sample BSDF * cos(theta) */
|
||||
BSDFSamplingRecord bRec(its, rRec.sampler, ERadiance);
|
||||
|
|
|
@ -422,6 +422,60 @@ void Bitmap::flipVertically() {
|
|||
}
|
||||
}
|
||||
|
||||
ref<Bitmap> Bitmap::rotateFlip(ERotateFlipType type) const {
|
||||
/* Based on the GDI+ rotate/flip function in Wine */
|
||||
if (m_componentFormat == EBitmask)
|
||||
Log(EError, "Transformations involving bitmasks are currently not supported!");
|
||||
|
||||
int width = m_size.x, height = m_size.y;
|
||||
bool flip_x = (type & 6) == 2 || (type & 6) == 4;
|
||||
bool flip_y = (type & 3) == 1 || (type & 3) == 2;
|
||||
bool rotate_90 = type & 1;
|
||||
|
||||
if (rotate_90)
|
||||
std::swap(width, height);
|
||||
|
||||
ref<Bitmap> result = new Bitmap(m_pixelFormat, m_componentFormat,
|
||||
Vector2i(width, height), m_channelCount);
|
||||
|
||||
ssize_t bypp = getBytesPerPixel(),
|
||||
src_stride = m_size.x * bypp,
|
||||
dst_stride = width * bypp;
|
||||
|
||||
uint8_t *dst = result->getUInt8Data();
|
||||
uint8_t *dst_row = dst, *src_row = m_data;
|
||||
|
||||
if (flip_x)
|
||||
src_row += bypp * (m_size.x - 1);
|
||||
|
||||
if (flip_y)
|
||||
src_row += src_stride * (m_size.y - 1);
|
||||
|
||||
ssize_t src_x_step, src_y_step;
|
||||
if (rotate_90) {
|
||||
src_x_step = flip_y ? -src_stride : src_stride;
|
||||
src_y_step = flip_x ? -bypp : bypp;
|
||||
} else {
|
||||
src_x_step = flip_x ? -bypp : bypp;
|
||||
src_y_step = flip_y ? -src_stride : src_stride;
|
||||
}
|
||||
|
||||
for (int y=0; y<height; y++) {
|
||||
uint8_t *src_pixel = src_row;
|
||||
uint8_t *dst_pixel = dst_row;
|
||||
|
||||
for (int x=0; x<width; x++) {
|
||||
memcpy(dst_pixel, src_pixel, bypp);
|
||||
dst_pixel += bypp;
|
||||
src_pixel += src_x_step;
|
||||
}
|
||||
|
||||
src_row += src_y_step;
|
||||
dst_row += dst_stride;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Bitmap::accumulate(const Bitmap *bitmap, Point2i sourceOffset,
|
||||
Point2i targetOffset, Vector2i size) {
|
||||
|
@ -906,7 +960,9 @@ ref<Bitmap> Bitmap::separateChannel(int channelIndex) {
|
|||
if (channelIndex == 0 && channelCount == 1)
|
||||
return this;
|
||||
|
||||
Assert(channelIndex > 0 && channelIndex < channelCount);
|
||||
if (channelIndex < 0 || channelIndex >= channelCount)
|
||||
Log(EError, "Bitmap::separateChannel(%i): channel index "
|
||||
"must be between 0 and %i", channelIndex, channelCount-1);
|
||||
|
||||
ref<Bitmap> result = new Bitmap(ELuminance, m_componentFormat, m_size);
|
||||
result->setMetadata(m_metadata);
|
||||
|
|
|
@ -32,7 +32,8 @@ FileResolver::FileResolver() {
|
|||
dladdr((const void *) &dummySymbol, &info);
|
||||
if (info.dli_fname) {
|
||||
/* Try to detect a few default setups */
|
||||
if (boost::starts_with(info.dli_fname, "/usr/lib")) {
|
||||
if (boost::starts_with(info.dli_fname, "/usr/lib") ||
|
||||
boost::starts_with(info.dli_fname, "/lib")) {
|
||||
basePath = fs::path("/usr/share/mitsuba");
|
||||
} else if (boost::starts_with(info.dli_fname, "/usr/local/lib")) {
|
||||
basePath = fs::path("/usr/local/share/mitsuba");
|
||||
|
|
|
@ -477,11 +477,11 @@ Random::Random() : mt(NULL) {
|
|||
seed();
|
||||
#else
|
||||
#if 0
|
||||
uint64_t buf[MT_N];
|
||||
memset(buf, 0, MT_N * sizeof(uint64_t)); /* Make GCC happy */
|
||||
uint64_t buf[N64];
|
||||
memset(buf, 0, N64 * sizeof(uint64_t)); /* Make GCC happy */
|
||||
ref<FileStream> urandom = new FileStream("/dev/urandom", FileStream::EReadOnly);
|
||||
urandom->readULongArray(buf, MT_N);
|
||||
seed(buf, MT_N);
|
||||
urandom->readULongArray(buf, N64);
|
||||
seed(buf, N64);
|
||||
#else
|
||||
seed();
|
||||
#endif
|
||||
|
|
|
@ -375,10 +375,10 @@ public:
|
|||
/* Find the componentwise maxima of the ellipse */
|
||||
for (int i=0; i<2; ++i) {
|
||||
int j = (i==0) ? axis1 : axis2;
|
||||
Float alpha = ellipseAxes[0][j];
|
||||
Float beta = ellipseAxes[1][j];
|
||||
Float ratio = beta/alpha, tmp = std::sqrt(1+ratio*ratio);
|
||||
Float cosTheta = 1/tmp, sinTheta = ratio/tmp;
|
||||
Float alpha = ellipseAxes[0][j], beta = ellipseAxes[1][j];
|
||||
Float tmp = 1 / std::sqrt(alpha*alpha + beta*beta);
|
||||
Float cosTheta = alpha * tmp, sinTheta = beta*tmp;
|
||||
|
||||
Point p1 = ellipseCenter + cosTheta*ellipseAxes[0] + sinTheta*ellipseAxes[1];
|
||||
Point p2 = ellipseCenter - cosTheta*ellipseAxes[0] - sinTheta*ellipseAxes[1];
|
||||
|
||||
|
|
|
@ -350,8 +350,9 @@ public:
|
|||
int j = (i==0) ? axis1 : axis2;
|
||||
Float alpha = ellipseAxes[0][j];
|
||||
Float beta = ellipseAxes[1][j];
|
||||
Float ratio = beta/alpha, tmp = std::sqrt(1+ratio*ratio);
|
||||
Float cosTheta = 1/tmp, sinTheta = ratio/tmp;
|
||||
Float tmp = 1 / std::sqrt(alpha*alpha + beta*beta);
|
||||
Float cosTheta = alpha * tmp, sinTheta = beta*tmp;
|
||||
|
||||
Point p1 = ellipseCenter + cosTheta*ellipseAxes[0] + sinTheta*ellipseAxes[1];
|
||||
Point p2 = ellipseCenter - cosTheta*ellipseAxes[0] - sinTheta*ellipseAxes[1];
|
||||
|
||||
|
|
|
@ -177,6 +177,8 @@ public:
|
|||
fs::path cacheFile;
|
||||
ref<Bitmap> bitmap;
|
||||
|
||||
m_separateAlpha = props.getBoolean("separateAlpha", false);
|
||||
|
||||
if (props.hasProperty("bitmap")) {
|
||||
/* Support initialization via raw data passed from another plugin */
|
||||
bitmap = reinterpret_cast<Bitmap *>(props.getData("bitmap").ptr);
|
||||
|
@ -194,7 +196,12 @@ public:
|
|||
Log(EError, "Could not determine modification time of \"%s\"!", m_filename.string().c_str());
|
||||
|
||||
cacheFile = m_filename;
|
||||
cacheFile.replace_extension(".mip");
|
||||
|
||||
if (!m_separateAlpha)
|
||||
cacheFile.replace_extension(".mip");
|
||||
else
|
||||
cacheFile.replace_extension(".alpha.mip");
|
||||
|
||||
tryReuseCache = fs::exists(cacheFile) && props.getBoolean("cache", true);
|
||||
}
|
||||
|
||||
|
@ -241,18 +248,27 @@ public:
|
|||
}
|
||||
|
||||
Bitmap::EPixelFormat pixelFormat;
|
||||
switch (bitmap->getPixelFormat()) {
|
||||
case Bitmap::ELuminance:
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
case Bitmap::ERGBA:
|
||||
pixelFormat = Bitmap::ERGB;
|
||||
break;
|
||||
default:
|
||||
Log(EError, "The input image has an unsupported pixel format!");
|
||||
return;
|
||||
if (m_separateAlpha) {
|
||||
/* Create a texture from the alpha channel of an image */
|
||||
if (!bitmap->hasAlpha())
|
||||
Log(EError, "separateAlpha specified, but the image contains no alpha channel!");
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
bitmap = bitmap->separateChannel(bitmap->getChannelCount()-1);
|
||||
bitmap->setGamma(1.0f);
|
||||
} else {
|
||||
switch (bitmap->getPixelFormat()) {
|
||||
case Bitmap::ELuminance:
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
case Bitmap::ERGBA:
|
||||
pixelFormat = Bitmap::ERGB;
|
||||
break;
|
||||
default:
|
||||
Log(EError, "The input image has an unsupported pixel format!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* (Re)generate the MIP map hierarchy; downsample using a
|
||||
|
@ -305,6 +321,7 @@ public:
|
|||
m_wrapModeV = (ReconstructionFilter::EBoundaryCondition) stream->readUInt();
|
||||
m_gamma = stream->readFloat();
|
||||
m_maxAnisotropy = stream->readFloat();
|
||||
m_separateAlpha = stream->readBool();
|
||||
|
||||
size_t size = stream->readSize();
|
||||
ref<MemoryStream> mStream = new MemoryStream(size);
|
||||
|
@ -323,18 +340,27 @@ public:
|
|||
rfilter->configure();
|
||||
|
||||
Bitmap::EPixelFormat pixelFormat;
|
||||
switch (bitmap->getPixelFormat()) {
|
||||
case Bitmap::ELuminance:
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
case Bitmap::ERGBA:
|
||||
pixelFormat = Bitmap::ERGB;
|
||||
break;
|
||||
default:
|
||||
Log(EError, "The input image has an unsupported pixel format!");
|
||||
return;
|
||||
if (m_separateAlpha) {
|
||||
/* Create a texture from the alpha channel of an image */
|
||||
if (!bitmap->hasAlpha())
|
||||
Log(EError, "separateAlpha specified, but the image contains no alpha channel!");
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
bitmap = bitmap->separateChannel(bitmap->getChannelCount()-1);
|
||||
bitmap->setGamma(1.0f);
|
||||
} else {
|
||||
switch (bitmap->getPixelFormat()) {
|
||||
case Bitmap::ELuminance:
|
||||
case Bitmap::ELuminanceAlpha:
|
||||
pixelFormat = Bitmap::ELuminance;
|
||||
break;
|
||||
case Bitmap::ERGB:
|
||||
case Bitmap::ERGBA:
|
||||
pixelFormat = Bitmap::ERGB;
|
||||
break;
|
||||
default:
|
||||
Log(EError, "The input image has an unsupported pixel format!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pixelFormat == Bitmap::ELuminance)
|
||||
|
@ -355,6 +381,7 @@ public:
|
|||
stream->writeUInt(m_wrapModeV);
|
||||
stream->writeFloat(m_gamma);
|
||||
stream->writeFloat(m_maxAnisotropy);
|
||||
stream->writeBool(m_separateAlpha);
|
||||
|
||||
if (!m_filename.empty() && fs::exists(m_filename)) {
|
||||
/* We still have access to the original image -- use that, since
|
||||
|
@ -503,6 +530,7 @@ protected:
|
|||
ReconstructionFilter::EBoundaryCondition m_wrapModeU;
|
||||
ReconstructionFilter::EBoundaryCondition m_wrapModeV;
|
||||
Float m_gamma, m_maxAnisotropy;
|
||||
bool m_separateAlpha;
|
||||
fs::path m_filename;
|
||||
};
|
||||
|
||||
|
|
|
@ -237,9 +237,9 @@ public:
|
|||
}
|
||||
|
||||
fs::path inputFile = fileResolver->resolve(argv[i]);
|
||||
Log(EInfo, "Loading EXR image \"%s\" ..", inputFile.string().c_str());
|
||||
Log(EInfo, "Loading image \"%s\" ..", inputFile.string().c_str());
|
||||
ref<FileStream> is = new FileStream(inputFile, FileStream::EReadOnly);
|
||||
ref<Bitmap> input = new Bitmap(Bitmap::EOpenEXR, is);
|
||||
ref<Bitmap> input = new Bitmap(Bitmap::EAuto, is);
|
||||
|
||||
if (crop[2] != -1 && crop[3] != -1)
|
||||
input = input->crop(Point2i(crop[0], crop[1]), Vector2i(crop[2], crop[3]));
|
||||
|
@ -282,9 +282,9 @@ public:
|
|||
} else {
|
||||
for (int i=optind; i<argc; ++i) {
|
||||
fs::path inputFile = fileResolver->resolve(argv[i]);
|
||||
Log(EInfo, "Loading EXR image \"%s\" ..", inputFile.string().c_str());
|
||||
Log(EInfo, "Loading image \"%s\" ..", inputFile.string().c_str());
|
||||
ref<FileStream> is = new FileStream(inputFile, FileStream::EReadOnly);
|
||||
ref<Bitmap> input = new Bitmap(Bitmap::EOpenEXR, is);
|
||||
ref<Bitmap> input = new Bitmap(Bitmap::EAuto, is);
|
||||
|
||||
if (crop[2] != -1 && crop[3] != -1)
|
||||
input = input->crop(Point2i(crop[0], crop[1]), Vector2i(crop[2], crop[3]));
|
||||
|
|
Loading…
Reference in New Issue