Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2014-03-29 16:03:48 +0400
commit691c4c17ad2f4b4e043f0961211ac90ca1656a8f (patch)
tree1e0ab0f0a2987748b1838af18182539eba970656 /intern/cycles/blender/blender_session.cpp
parent27043b8e40f74c8b0917850d1aefbd6315fa46a5 (diff)
Cycles: add "density", "flame" and "color" attributes for smoke domains.
These can currently be accessed by adding an Attribute node and specifying one of those three names. A Smoke/Fire node should be added at some point to make this more convenient. These values might change still before the release, in particular for flame the meaning seems unclear, it's just values in the 0..1 range. This is useful for color ramps, but it might be good if this was also available as temperature in kelvin so it can be plugged into the blackbody node. But I couldn't figure out from the smoke code if or how this corresponds to a physical unit. Here's a (quite poor) example file for a fire + smoke setup: http://www.pasteall.org/blend/27990
Diffstat (limited to 'intern/cycles/blender/blender_session.cpp')
-rw-r--r--intern/cycles/blender/blender_session.cpp165
1 files changed, 123 insertions, 42 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 82434712ca7..f5e696bc582 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -726,85 +726,121 @@ int BlenderSession::builtin_image_frame(const string &builtin_name)
void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels)
{
+ /* empty image */
+ is_float = false;
+ width = 0;
+ height = 0;
+ depth = 0;
+ channels = 0;
+
+ if(!builtin_data)
+ return;
+
+ /* recover ID pointer */
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
+ BL::ID b_id(ptr);
+
+ if(b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
- if(b_image) {
is_float = b_image.is_float();
width = b_image.size()[0];
height = b_image.size()[1];
depth = 1;
channels = b_image.channels();
}
- else {
- is_float = false;
- width = 0;
- height = 0;
- depth = 0;
- channels = 0;
+ else if(b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if(!b_domain)
+ return;
+
+ if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
+ builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME))
+ channels = 1;
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
+ channels = 4;
+ else
+ return;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
+
+ width = resolution.x * amplify;
+ height = resolution.y * amplify;
+ depth = resolution.z * amplify;
+
+ is_float = true;
}
}
bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
{
+ if(!builtin_data)
+ return false;
+
int frame = builtin_image_frame(builtin_name);
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
BL::Image b_image(ptr);
- if(b_image) {
- int width = b_image.size()[0];
- int height = b_image.size()[1];
- int channels = b_image.channels();
+ int width = b_image.size()[0];
+ int height = b_image.size()[1];
+ int channels = b_image.channels();
- unsigned char *image_pixels;
- image_pixels = image_get_pixels_for_frame(b_image, frame);
+ unsigned char *image_pixels;
+ image_pixels = image_get_pixels_for_frame(b_image, frame);
- if(image_pixels) {
- memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
- MEM_freeN(image_pixels);
+ if(image_pixels) {
+ memcpy(pixels, image_pixels, width * height * channels * sizeof(unsigned char));
+ MEM_freeN(image_pixels);
+ }
+ else {
+ if(channels == 1) {
+ memset(pixels, 0, width * height * sizeof(unsigned char));
}
else {
- if(channels == 1) {
- memset(pixels, 0, width * height * sizeof(unsigned char));
- }
- else {
- unsigned char *cp = pixels;
- for(int i = 0; i < width * height; i++, cp += channels) {
- cp[0] = 255;
- cp[1] = 0;
- cp[2] = 255;
- if(channels == 4)
- cp[3] = 255;
- }
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = 255;
+ cp[1] = 0;
+ cp[2] = 255;
+ if(channels == 4)
+ cp[3] = 255;
}
}
+ }
- /* premultiply, byte images are always straight for blender */
- unsigned char *cp = pixels;
- for(int i = 0; i < width * height; i++, cp += channels) {
- cp[0] = (cp[0] * cp[3]) >> 8;
- cp[1] = (cp[1] * cp[3]) >> 8;
- cp[2] = (cp[2] * cp[3]) >> 8;
- }
-
- return true;
+ /* premultiply, byte images are always straight for blender */
+ unsigned char *cp = pixels;
+ for(int i = 0; i < width * height; i++, cp += channels) {
+ cp[0] = (cp[0] * cp[3]) >> 8;
+ cp[1] = (cp[1] * cp[3]) >> 8;
+ cp[2] = (cp[2] * cp[3]) >> 8;
}
- return false;
+ return true;
}
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels)
{
- int frame = builtin_image_frame(builtin_name);
+ if(!builtin_data)
+ return false;
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
- BL::Image b_image(ptr);
+ BL::ID b_id(ptr);
+
+ if(b_id.is_a(&RNA_Image)) {
+ /* image data */
+ BL::Image b_image(b_id);
+ int frame = builtin_image_frame(builtin_name);
- if(b_image) {
int width = b_image.size()[0];
int height = b_image.size()[1];
int channels = b_image.channels();
@@ -834,6 +870,51 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
return true;
}
+ else if(b_id.is_a(&RNA_Object)) {
+ /* smoke volume data */
+ BL::Object b_ob(b_id);
+ BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
+
+ if(!b_domain)
+ return false;
+
+ int3 resolution = get_int3(b_domain.domain_resolution());
+ int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
+
+ int width = resolution.x * amplify;
+ int height = resolution.y * amplify;
+ int depth = resolution.z * amplify;
+
+ if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
+ SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth) {
+ SmokeDomainSettings_density_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
+ /* this is in range 0..1, and interpreted by the OpenGL smoke viewer
+ * as 1500..3000 K with the first part faded to zero density */
+ SmokeDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth) {
+ SmokeDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+ else if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
+ /* the RGB is "premultiplied" by density for better interpolation results */
+ SmokeDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
+
+ if(length == width*height*depth*4) {
+ SmokeDomainSettings_color_grid_get(&b_domain.ptr, pixels);
+ return true;
+ }
+ }
+
+ fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
+ }
return false;
}