bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels) { 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(); 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); } 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; } } } /* 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; } return false; }
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels) { 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(); float *image_pixels; image_pixels = image_get_float_pixels_for_frame(b_image, frame); if(image_pixels) { memcpy(pixels, image_pixels, width * height * channels * sizeof(float)); MEM_freeN(image_pixels); } else { if(channels == 1) { memset(pixels, 0, width * height * sizeof(float)); } else { float *fp = pixels; for(int i = 0; i < width * height; i++, fp += channels) { fp[0] = 1.0f; fp[1] = 0.0f; fp[2] = 1.0f; if(channels == 4) fp[3] = 1.0f; } } } return true; } return false; }
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels) { if(!builtin_data) return false; PointerRNA ptr; RNA_id_pointer_create((ID*)builtin_data, &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); int width = b_image.size()[0]; int height = b_image.size()[1]; int channels = b_image.channels(); float *image_pixels; image_pixels = image_get_float_pixels_for_frame(b_image, frame); if(image_pixels) { memcpy(pixels, image_pixels, width * height * channels * sizeof(float)); MEM_freeN(image_pixels); } else { if(channels == 1) { memset(pixels, 0, width * height * sizeof(float)); } else { float *fp = pixels; for(int i = 0; i < width * height; i++, fp += channels) { fp[0] = 1.0f; fp[1] = 0.0f; fp[2] = 1.0f; if(channels == 4) fp[3] = 1.0f; } } } 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; }