#CUDA
WITH_BF_CYCLES_CUDA_BINARIES = False
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21'] # don't build sm_13 until the compile can fit in 32bit process again :)
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
##
CC = 'gcc'
WITH_BF_CYCLES = True
WITH_BF_CYCLES_CUDA_BINARIES = False
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
-BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21']
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
WITH_BF_OIIO = True
BF_OIIO = LIBDIR + '/openimageio'
elif value_type in (bool, int, float, str, tuple):
# constant, not much fun we can do here except to list it.
# TODO, figure out some way to document these!
- #fw(".. data:: %s\n\n" % attribute)
+ fw(".. data:: %s\n\n" % attribute)
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
fw("\n")
else:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
endif()
-# for OSL, not needed yet
-# set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
+# for OSL
+set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
# set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
# Definitions and Includes
else if(string_iequals(node.name(), "mix")) {
MixNode *mix = new MixNode();
xml_read_enum(&mix->type, MixNode::type_enum, node, "type");
+ xml_read_bool(&mix->use_clamp, node, "use_clamp");
snode = mix;
}
else if(string_iequals(node.name(), "gamma")) {
else if(string_iequals(node.name(), "math")) {
MathNode *math = new MathNode();
xml_read_enum(&math->type, MathNode::type_enum, node, "type");
+ xml_read_bool(&math->use_clamp, node, "use_clamp");
snode = math;
}
else if(string_iequals(node.name(), "vector_math")) {
layout.prop(cscene, "device")
elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL':
layout.prop(cscene, "device")
+
+ if cscene.feature_set == 'EXPERIMENTAL' and cscene.device == 'CPU' and engine.with_osl():
+ layout.prop(cscene, "shading_system")
def draw_pause(self, context):
scene->object_manager->tag_update(scene);
}
- /* updated dupli objects require particle sync */
- bool need_particle_update = object_need_particle_update(b_ob);
-
/* object sync */
- if(object_updated || (object->mesh && object->mesh->need_update) || need_particle_update) {
+ /* transform comparison should not be needed, but duplis don't work perfect
+ * in the depsgraph and may not signal changes, so this is a workaround */
+ if(object_updated || (object->mesh && object->mesh->need_update) || tfm != object->tfm) {
object->name = b_ob.name().c_str();
object->pass_id = b_ob.pass_index();
object->tfm = tfm;
object->particle_id = particle_id;
- /* particle sync */
- if (need_particle_update)
- sync_particles(object, b_ob);
-
object->tag_update(scene);
}
}
/* object loop */
BL::Scene::objects_iterator b_ob;
BL::Scene b_sce = b_scene;
- int particle_offset = 0;
+ int particle_offset = 1; /* first particle is dummy for regular, non-instanced objects */
bool cancel = false;
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "object.h"
-
#include "mesh.h"
+#include "particles.h"
+
#include "blender_sync.h"
#include "blender_util.h"
/* Particles Sync */
-bool BlenderSync::object_need_particle_update(BL::Object b_ob)
+bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys)
{
/* Particle data is only needed for
* a) Billboard render mode if object's own material uses particle info
*/
bool need_update = false;
- BL::Object::particle_systems_iterator b_psys;
- for (b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
- switch (b_psys->settings().render_type()) {
+ switch (b_psys.settings().render_type()) {
/* XXX not implemented yet!
* billboards/strands would become part of the mesh data (?),
* so the mesh attributes would store whether particle info is required.
#endif
case BL::ParticleSettings::render_type_OBJECT: {
- BL::Object b_dupli_ob = b_psys->settings().dupli_object();
+ BL::Object b_dupli_ob = b_psys.settings().dupli_object();
if (b_dupli_ob) {
BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data();
Mesh *mesh = mesh_map.find(key);
}
case BL::ParticleSettings::render_type_GROUP: {
- BL::Group b_dupli_group = b_psys->settings().dupli_group();
+ BL::Group b_dupli_group = b_psys.settings().dupli_group();
if (b_dupli_group) {
BL::Group::objects_iterator b_gob;
for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) {
default:
/* avoid compiler warning */
break;
- }
}
return need_update;
static bool use_particle(BL::Particle b_pa)
{
- return b_pa.is_exist() && b_pa.is_visible() && b_pa.alive_state()==BL::Particle::alive_state_ALIVE;
+ return b_pa.is_exist() && b_pa.is_visible() &&
+ (b_pa.alive_state()==BL::Particle::alive_state_ALIVE || b_pa.alive_state()==BL::Particle::alive_state_DYING);
+}
+
+static int psys_count_particles(BL::ParticleSystem b_psys)
+{
+ int tot = 0;
+ BL::ParticleSystem::particles_iterator b_pa;
+ for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
+ if(use_particle(*b_pa))
+ ++tot;
+ }
+ return tot;
}
int BlenderSync::object_count_particles(BL::Object b_ob)
int tot = 0;
BL::Object::particle_systems_iterator b_psys;
for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
- if (use_particle_system(*b_psys)) {
- BL::ParticleSystem::particles_iterator b_pa;
- for(b_psys->particles.begin(b_pa); b_pa != b_psys->particles.end(); ++b_pa) {
- if(use_particle(*b_pa))
- ++tot;
- }
- }
+ if (use_particle_system(*b_psys))
+ tot += psys_count_particles(*b_psys);
}
return tot;
}
-void BlenderSync::sync_particles(Object *ob, BL::Object b_ob)
+void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys)
{
- int tot = object_count_particles(b_ob);
+ /* depending on settings the psys may not even be rendered */
+ if (!use_particle_system(b_psys))
+ return;
- ob->particles.clear();
- ob->particles.reserve(tot);
+ /* key to lookup particle system */
+ ParticleSystemKey key(b_ob, b_psys);
+ ParticleSystem *psys;
- int index;
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
- if (use_particle_system(*b_psys)) {
- int pa_index = 0;
- BL::ParticleSystem::particles_iterator b_pa;
- for(b_psys->particles.begin(b_pa), index = 0; b_pa != b_psys->particles.end(); ++b_pa, ++index) {
- if(use_particle(*b_pa)) {
- Particle pa;
-
- pa.index = pa_index;
- pa.age = b_scene.frame_current() - b_pa->birth_time();
- pa.lifetime = b_pa->lifetime();
-
- ob->particles.push_back(pa);
- }
+ /* test if we need to sync */
+ bool object_updated = false;
+
+ if(particle_system_map.sync(&psys, b_ob, b_ob, key))
+ object_updated = true;
+
+ bool need_update = psys_need_update(b_psys);
+
+ if (object_updated || need_update) {
+ int tot = psys_count_particles(b_psys);
+ psys->particles.clear();
+ psys->particles.reserve(tot);
+
+ int index = 0;
+ BL::ParticleSystem::particles_iterator b_pa;
+ for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
+ if(use_particle(*b_pa)) {
+ Particle pa;
+
+ pa.index = index;
+ pa.age = b_scene.frame_current() - b_pa->birth_time();
+ pa.lifetime = b_pa->lifetime();
+ pa.location = get_float3(b_pa->location());
+ pa.rotation = get_float4(b_pa->rotation());
+ pa.size = b_pa->size();
+ pa.velocity = get_float3(b_pa->velocity());
+ pa.angular_velocity = get_float3(b_pa->angular_velocity());
- ++pa_index;
+ psys->particles.push_back(pa);
+ }
+
+ ++index;
+ }
+
+ psys->tag_update(scene);
+ }
+}
+
+void BlenderSync::sync_particle_systems()
+{
+ /* layer data */
+ uint scene_layer = render_layer.scene_layer;
+
+ particle_system_map.pre_sync();
+
+ /* object loop */
+ BL::Scene::objects_iterator b_ob;
+ BL::Scene b_sce = b_scene;
+
+ for(; b_sce; b_sce = b_sce.background_set()) {
+ for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) {
+ bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
+ uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), object_is_light(*b_ob));
+ CYCLES_LOCAL_LAYER_HACK(render_layer.use_localview, ob_layer);
+ hide = hide || !(ob_layer & scene_layer);
+
+ if(!hide) {
+ BL::Object::particle_systems_iterator b_psys;
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
+ sync_particles(*b_ob, *b_psys);
}
}
}
+
+ /* handle removed data and modified pointers */
+ if(particle_system_map.post_sync())
+ scene->particle_system_manager->tag_update(scene);
}
CCL_NAMESPACE_END
BL::ShaderNodeMixRGB b_mix_node(b_node);
MixNode *mix = new MixNode();
mix->type = MixNode::type_enum[b_mix_node.blend_type()];
+ mix->use_clamp = b_mix_node.use_clamp();
node = mix;
break;
}
BL::ShaderNodeMath b_math_node(b_node);
MathNode *math = new MathNode();
math->type = MathNode::type_enum[b_math_node.operation()];
+ math->use_clamp = b_math_node.use_clamp();
node = math;
break;
}
object_map(&scene_->objects),
mesh_map(&scene_->meshes),
light_map(&scene_->lights),
+ particle_system_map(&scene_->particle_systems),
world_map(NULL),
world_recalc(false),
experimental(false),
if(b_ob->is_updated_data() || b_ob->data().is_updated())
light_map.set_recalc(*b_ob);
}
+
+ if(b_ob->is_updated_data()) {
+ BL::Object::particle_systems_iterator b_psys;
+ for (b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
+ particle_system_map.set_recalc(*b_ob);
+ }
}
BL::BlendData::meshes_iterator b_mesh;
object_map.has_recalc() ||
light_map.has_recalc() ||
mesh_map.has_recalc() ||
+ particle_system_map.has_recalc() ||
BlendDataObjects_is_updated_get(&b_data.ptr) ||
world_recalc;
sync_film();
sync_shaders();
sync_objects(b_v3d);
+ sync_particle_systems();
sync_motion(b_v3d, b_override);
}
void sync_world();
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_shaders();
+ void sync_particle_systems();
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
void sync_background_light();
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
void sync_camera_motion(BL::Object b_ob, int motion);
- void sync_particles(Object *ob, BL::Object b_ob);
+ void sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys);
/* util */
void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
bool BKE_object_is_modified(BL::Object b_ob);
bool object_is_mesh(BL::Object b_ob);
bool object_is_light(BL::Object b_ob);
- bool object_need_particle_update(BL::Object b_ob);
+ bool psys_need_update(BL::ParticleSystem b_psys);
int object_count_particles(BL::Object b_ob);
/* variables */
id_map<ObjectKey, Object> object_map;
id_map<void*, Mesh> mesh_map;
id_map<ObjectKey, Light> light_map;
+ id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
set<Mesh*> mesh_synced;
void *world_map;
bool world_recalc;
return make_float3(array[0], array[1], array[2]);
}
+static inline float4 get_float4(BL::Array<float, 4> array)
+{
+ return make_float4(array[0], array[1], array[2], array[3]);
+}
+
static inline int4 get_int4(BL::Array<int, 4> array)
{
return make_int4(array[0], array[1], array[2], array[3]);
{ return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
};
+struct ParticleSystemKey {
+ void *ob;
+ void *psys;
+
+ ParticleSystemKey(void *ob_, void *psys_)
+ : ob(ob_), psys(psys_) {}
+
+ bool operator<(const ParticleSystemKey& k) const
+ { return (ob < k.ob && psys < k.psys); }
+};
+
CCL_NAMESPACE_END
#endif /* __BLENDER_UTIL_H__ */
if(WITH_CYCLES_OSL)
- set(CYCLES_OSL "" CACHE PATH "Path to OpenShadingLanguage installation")
+ set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
__device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float clamp)
{
+ #ifdef WITH_OSL
+ using std::isfinite;
+ #endif
+
float sum = fabsf((*L_sum).x) + fabsf((*L_sum).y) + fabsf((*L_sum).z);
if(!isfinite(sum)) {
__device_inline float particle_index(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.x;
}
__device float particle_age(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.y;
}
__device float particle_lifetime(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.z;
}
+__device float particle_size(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
+ return f.w;
+}
+
+__device float4 particle_rotation(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 1);
+ return f;
+}
+
+__device float3 particle_location(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 2);
+ return make_float3(f.x, f.y, f.z);
+}
+
+__device float3 particle_velocity(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f2 = kernel_tex_fetch(__particles, offset + 2);
+ float4 f3 = kernel_tex_fetch(__particles, offset + 3);
+ return make_float3(f2.w, f3.x, f3.y);
+}
+
+__device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f3 = kernel_tex_fetch(__particles, offset + 3);
+ float4 f4 = kernel_tex_fetch(__particles, offset + 4);
+ return make_float3(f3.z, f3.w, f4.x);
+}
+
CCL_NAMESPACE_END
path_state_next(kg, &ps, label);
/* setup ray */
- ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
- ray.D = bsdf_omega_in;
- ray.t = FLT_MAX;
+ Ray bsdf_ray;
+
+ bsdf_ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng);
+ bsdf_ray.D = bsdf_omega_in;
+ bsdf_ray.t = FLT_MAX;
#ifdef __RAY_DIFFERENTIALS__
- ray.dP = sd.dP;
- ray.dD = bsdf_domega_in;
+ bsdf_ray.dP = sd.dP;
+ bsdf_ray.dD = bsdf_domega_in;
+#endif
+#ifdef __MOTION__
+ bsdf_ray.time = sd.time;
#endif
- kernel_path_indirect(kg, rng, sample*num_samples, ray, buffer,
+ kernel_path_indirect(kg, rng, sample*num_samples, bsdf_ray, buffer,
tp*num_samples_inv, min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, &L);
}
}
#include "osl_shader.h"
-#else
+#endif
#include "svm/bsdf.h"
#include "svm/emissive.h"
#include "svm/svm_bsdf.h"
#include "svm/svm.h"
-#endif
CCL_NAMESPACE_BEGIN
#ifdef __MULTI_CLOSURE__
-__device_inline void _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
+#ifdef __OSL__
+__device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
{
for(int i = 0; i< sd->num_closure; i++) {
if(CLOSURE_IS_BSDF(sc->type)) {
float bsdf_pdf = 0.0f;
-#ifdef __OSL__
+
float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
-#else
- float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
+
+ if(bsdf_pdf != 0.0f) {
+ bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
+ sum_pdf += bsdf_pdf*sc->sample_weight;
+ }
+
+ sum_sample_weight += sc->sample_weight;
+ }
+ }
+
+ *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
+}
#endif
+__device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
+ int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
+{
+ for(int i = 0; i< sd->num_closure; i++) {
+ if(i == skip_bsdf)
+ continue;
+
+ const ShaderClosure *sc = &sd->closure[i];
+
+ if(CLOSURE_IS_BSDF(sc->type)) {
+ float bsdf_pdf = 0.0f;
+
+ float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
+
if(bsdf_pdf != 0.0f) {
bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
sum_pdf += bsdf_pdf*sc->sample_weight;
#ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
- return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+#ifdef __OSL__
+ if (kernel_osl_use(kg))
+ return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
+ else
+#endif
+ return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
#else
const ShaderClosure *sc = &sd->closure;
*pdf = 0.0f;
#ifdef __OSL__
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
-#else
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ if (kernel_osl_use(kg))
+ label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
+ else
#endif
+ label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+
if(*pdf != 0.0f) {
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
if(sd->num_closure > 1) {
float sweight = sc->sample_weight;
- _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
+#ifdef __OSL__
+ if (kernel_osl_use(kg))
+ _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
+ else
+#endif
+ _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
}
}
*pdf = 0.0f;
#ifdef __OSL__
- label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
-#else
- label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+ if (kernel_osl_use(kg))
+ label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
+ else
#endif
+ label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
+
if(*pdf != 0.0f)
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
if(CLOSURE_IS_EMISSION(sc->type)) {
#ifdef __OSL__
- eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
-#else
- eval += svm_emissive_eval(sd, sc)*sc->weight;
+ if (kernel_osl_use(kg))
+ eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
+ else
#endif
+ eval += svm_emissive_eval(sd, sc)*sc->weight;
+
}
}
#else
float randb, int path_flag)
{
#ifdef __OSL__
- OSLShader::eval_surface(kg, sd, randb, path_flag);
-#else
-
+ if (kernel_osl_use(kg))
+ OSLShader::eval_surface(kg, sd, randb, path_flag);
+ else
+#endif
+ {
#ifdef __SVM__
- svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
+ svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
#else
- bsdf_diffuse_setup(sd, &sd->closure);
- sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
-#endif
-
+ bsdf_diffuse_setup(sd, &sd->closure);
+ sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
#endif
+ }
}
/* Background Evaluation */
__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
{
#ifdef __OSL__
- return OSLShader::eval_background(kg, sd, path_flag);
-#else
+ if (kernel_osl_use(kg))
+ return OSLShader::eval_background(kg, sd, path_flag);
+ else
+#endif
+ {
#ifdef __SVM__
- svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
+ svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
#ifdef __MULTI_CLOSURE__
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ float3 eval = make_float3(0.0f, 0.0f, 0.0f);
- for(int i = 0; i< sd->num_closure; i++) {
- const ShaderClosure *sc = &sd->closure[i];
+ for(int i = 0; i< sd->num_closure; i++) {
+ const ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BACKGROUND(sc->type))
- eval += sc->weight;
- }
+ if(CLOSURE_IS_BACKGROUND(sc->type))
+ eval += sc->weight;
+ }
- return eval;
+ return eval;
#else
- if(sd->closure.type == CLOSURE_BACKGROUND_ID)
- return sd->closure.weight;
- else
- return make_float3(0.0f, 0.0f, 0.0f);
+ if(sd->closure.type == CLOSURE_BACKGROUND_ID)
+ return sd->closure.weight;
+ else
+ return make_float3(0.0f, 0.0f, 0.0f);
#endif
#else
- return make_float3(0.8f, 0.8f, 0.8f);
-#endif
-
+ return make_float3(0.8f, 0.8f, 0.8f);
#endif
+ }
}
/* Volume */
if(CLOSURE_IS_VOLUME(sc->type)) {
#ifdef __OSL__
- eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out);
-#else
- eval += volume_eval_phase(sd, sc, omega_in, omega_out);
+ if (kernel_osl_use(kg))
+ eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out);
+ else
#endif
+ eval += volume_eval_phase(sd, sc, omega_in, omega_out);
}
}
{
#ifdef __SVM__
#ifdef __OSL__
- OSLShader::eval_volume(kg, sd, randb, path_flag);
-#else
- svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
+ if (kernel_osl_use(kg))
+ OSLShader::eval_volume(kg, sd, randb, path_flag);
+ else
#endif
+ svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
#endif
}
/* this will modify sd->P */
#ifdef __SVM__
#ifdef __OSL__
- OSLShader::eval_displacement(kg, sd);
-#else
- svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
+ if (kernel_osl_use(kg))
+ OSLShader::eval_displacement(kg, sd);
+ else
#endif
+ svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
#endif
}
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __OSL__
- OSLShader::release(kg, sd);
+ if (kernel_osl_use(kg))
+ OSLShader::release(kg, sd);
#endif
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
+#include "kernel_projection.h"
CCL_NAMESPACE_BEGIN
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
-#define PARTICLE_SIZE 1
+#define PARTICLE_SIZE 5
#define TIME_INVALID FLT_MAX
/* device capabilities */
#ifdef __OSL__
void *prim;
-#else
+#endif
float data0;
float data1;
-#endif
} ShaderClosure;
add_library(cycles_kernel_osl ${SRC} ${HEADER_SRC})
add_subdirectory(nodes)
+
+if(WITH_CYCLES_OSL)
+ target_link_libraries(cycles_kernel_osl ${OSL_LIBRARIES})
+endif()
node_bump.osl
node_camera.osl
node_checker_texture.osl
+ node_combine_rgb.osl
node_convert_from_color.osl
node_convert_from_float.osl
node_convert_from_normal.osl
node_geometry.osl
node_glass_bsdf.osl
node_glossy_bsdf.osl
+ node_holdout.osl
node_hsv.osl
node_image_texture.osl
node_invert.osl
node_mix_closure.osl
node_musgrave_texture.osl
node_normal.osl
- node_blend_weight_texture.osl
node_noise_texture.osl
node_output_displacement.osl
node_output_surface.osl
node_output_volume.osl
- node_sepcomb_rgb.osl
+ node_separate_rgb.osl
node_sky_texture.osl
node_texture_coordinate.osl
node_translucent_bsdf.osl
node_color.h
node_fresnel.h
stdosl.h
+ oslutil.h
)
set(SRC_OSO
add_custom_target(shader ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS})
-delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader)
+# CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths
+delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader)
shader node_brightness(
color ColorIn = color(0.8, 0.8, 0.8),
- float Bright = 0.0,
+ float Brightness = 0.0,
float Contrast = 0.0,
- output ColorOut = color(0.8, 0.8, 0.8)
+ output color ColorOut = color(0.8, 0.8, 0.8))
{
float delta = Contrast * (1.0/200.0);
float a = 1.0 - delta * 2.0;
float b;
- Bright *= 1.0/100.0;
+ /* input value is a percentage */
+ float bright_factor = Brightness / 100.0;
/*
* The algorithm is by Werner D. Streidt
if (Contrast > 0.0) {
a = (a < 0.0 ? 1.0/a : 0.0);
- b = a * (Brightness - delta);
+ b = a * (bright_factor - delta);
}
else {
delta *= -1.0;
- b = a * (Brightness + delta);
+ b = a * (bright_factor + delta);
}
ColorOut = a * ColorIn + b;
{
Fac = checker(Vector*Scale);
if(Fac == 1.0) {
- Color = color(Color1, Color1, Color1);
+ Color = Color1;
}
else {
- Color = color(Color2, Color2, Color2);
+ Color = Color2;
}
}
--- /dev/null
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_combine_rgb(
+ float R = 0.0,
+ float G = 0.0,
+ float B = 0.0,
+ output color Image = color(0.8, 0.8, 0.8))
+{
+ Image = color(R, G, B);
+}
+
shader node_gamma(
color ColorIn = color(0.8, 0.8, 0.8),
float Gamma = 1.0,
- output ColorOut = color(0.8, 0.8, 0.8)
+ output color ColorOut = color(0.0, 0.0, 0.0))
{
- int i;
- for (i=0;i<3;i++) {
- if (ColorIn[i] > 0.0)
- ColorIn[i] = powf(ColorIn[i], Gamma);
- }
-
- ColorOut = ColorIn;
+ ColorOut = pow(ColorIn, Gamma);
}
if(distribution == "Sharp")
BSDF = Color*(Fr*reflection(Normal) + (1.0-Fr)*refraction(Normal, eta));
else if(distribution == "Beckmann")
- BSDF = Color*(Fr*microfacet_beckmann(Normal, Roughness) + (1.0-Fr)*microfacet_beckmann_refraction(Normal, Roughness, eta));
+ BSDF = Color*(Fr*microfacet_beckmann(Normal, Roughness, eta) + (1.0-Fr)*microfacet_beckmann_refraction(Normal, Roughness, eta));
else if(distribution == "GGX")
- BSDF = Color*(Fr*microfacet_ggx(Normal, Roughness) + (1.0-Fr)*microfacet_ggx_refraction(Normal, Roughness, eta));
+ BSDF = Color*(Fr*microfacet_ggx(Normal, Roughness, eta) + (1.0-Fr)*microfacet_ggx_refraction(Normal, Roughness, eta));
}
if(distribution == "Sharp")
BSDF = Color*reflection(Normal);
else if(distribution == "Beckmann")
- BSDF = Color*microfacet_beckmann(Normal, Roughness);
+ BSDF = Color*microfacet_beckmann(Normal, Roughness, 1.0);
else if(distribution == "GGX")
- BSDF = Color*microfacet_ggx(Normal, Roughness);
+ BSDF = Color*microfacet_ggx(Normal, Roughness, 1.0);
}
shader node_invert(
float Fac = 1.0,
color ColorIn = color(0.8, 0.8, 0.8),
- output ColorOut = color(0.8, 0.8, 0.8)
+ output color ColorOut = color(0.8, 0.8, 0.8))
{
color ColorInv = color(1.0) - ColorIn;
ColorOut = mix(ColorIn, ColorInv, Fac);
shader node_math(
string type = "Add",
+ int Clamp = 0,
float Value1 = 0.0,
float Value2 = 0.0,
output float Value = 0.0)
Value = Value1 < Value2;
if(type == "Greater Than")
Value = Value1 > Value2;
+
+ if(Clamp)
+ Value = clamp(Value1, 0.0, 1.0);
}
return outcol;
}
+color node_mix_clamp(color col)
+{
+ color outcol = col;
+
+ outcol[0] = clamp(col[0], 0.0, 1.0);
+ outcol[1] = clamp(col[2], 0.0, 1.0);
+ outcol[2] = clamp(col[2], 0.0, 1.0);
+
+ return outcol;
+}
+
shader node_mix(
string type = "Mix",
+ int Clamp = 0,
float Fac = 0.5,
color Color1 = color(0.0, 0.0, 0.0),
color Color2 = color(0.0, 0.0, 0.0),
Color = node_mix_soft(t, Color1, Color2);
if(type == "Linear Light")
Color = node_mix_linear(t, Color1, Color2);
+
+ if(Clamp)
+ Color = node_mix_clamp(Color);
}
int hard = 0;
float fac = 0.0;
- if(distortion != 0.0( {
+ if(distortion != 0.0) {
r[0] = noise_basis(p + point(13.5), basis) * distortion;
r[1] = noise_basis(p, basis) * distortion;
r[2] = noise_basis(p - point(13.5), basis) * distortion;
normal Direction = normal(0.0, 0.0, 0.0),
normal NormalIn = normal(0.0, 0.0, 0.0),
output normal NormalOut = normal(0.0, 0.0, 0.0),
- output float Dot = 1.0
+ output float Dot = 1.0)
{
- Direction = normalize(Direction);
- NormalOut = Direction;
- Dot = dot(Direction, NormalIn);
+ NormalOut = normalize(Direction);
+ Dot = dot(NormalOut, NormalIn);
}
output float G = 0.0,
output float B = 0.0)
{
- R = Image[0];
- G = Image[1];
- B = Image[2];
+ R = Image[0];
+ G = Image[1];
+ B = Image[2];
}
-
-shader node_combine_rgb(
- float R = 0.0,
- float G = 0.0,
- float B = 0.0,
- output color Image = color(0.8, 0.8, 0.8)
-{
- Image = color(R, G, B)
-}
-
/* Turbulence */
-float noise_turbulence(point p, string basis, int octaves, int hard)
+float noise_turbulence(point p, string basis, float details, int hard)
{
float fscale = 1.0;
float amp = 1.0;
float sum = 0.0;
- int i;
+ int i, n;
+
+ float octaves = clamp(details, 0.0, 16.0);
+ n = (int)octaves;
- for (i = 0; i <= octaves; i++) {
+ for (i = 0; i <= n; i++) {
float t = noise_basis(fscale * p, basis);
if (hard)
amp *= 0.5;
fscale *= 2.0;
}
+
+ float rmd = octaves - floor(octaves);
+
+ if(rmd != 0.0) {
+ float t = noise_basis(fscale*p, basis);
+
+ if(hard)
+ t = fabs(2.0*t - 1.0);
- sum *= ((float)(1 << octaves) / (float)((1 << (octaves + 1)) - 1));
+ float sum2 = sum + t*amp;
- return sum;
+ sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
+ sum2 *= ((float)(1 << (n+1))/(float)((1 << (n+2)) - 1));
+
+ return (1.0 - rmd)*sum + rmd*sum2;
+ }
+ else {
+ sum *= ((float)(1 << n)/(float)((1 << (n+1)) - 1));
+ return sum;
+ }
}
/* Utility */
{
float sigma = clamp(Sigma, 0.0, 1.0);
- BSDF = Color*ashikhmin_velvet(Normal, sigma);
+ BSDF = Color*ashikhmin_velvet(Normal, sigma, 1.0);
}
float n = 0.0;
if(type == "Bands") {
- n = (x + y + z)*10.0);
+ n = (x + y + z)*10.0;
}
else if(type == "Rings") {
n = (sqrt(x*x + y*y + z*z)*20.0);
}
if(distortion != 0.0) {
- n = n +(distortion * noise_turbulence(p*dscale, "Perlin", detail, 0);
+ n = n +(distortion * noise_turbulence(p*dscale, "Perlin", detail, 0));
}
result = noise_wave("Sine", n);
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of Sony Pictures Imageworks nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef CCL_OSLUTIL_H
+#define CCL_OSLUTIL_H
+
+// Return wireframe opacity factor [0, 1] given a geometry type in
+// ("triangles", "polygons" or "patches"), and a line_width in raster
+// or world space depending on the last (raster) boolean argument.
+//
+float wireframe(string edge_type, float line_width, int raster)
+{
+ // ray differentials are so big in diffuse context that this function would always return "wire"
+ if (raytype("path:diffuse")) return 0.0;
+
+ int np = 0;
+ point p[64];
+ float pixelWidth = 1;
+
+ if (edge_type == "triangles")
+ {
+ np = 3;
+ if (!getattribute("geom:trianglevertices", p))
+ return 0.0;
+ }
+ else if (edge_type == "polygons" || edge_type == "patches")
+ {
+ getattribute("geom:numpolyvertices", np);
+ if (np < 3 || !getattribute("geom:polyvertices", p))
+ return 0.0;
+ }
+
+ if (raster)
+ {
+ // Project the derivatives of P to the viewing plane defined
+ // by I so we have a measure of how big is a pixel at this point
+ float pixelWidthX = length(Dx(P) - dot(Dx(P), I) * I);
+ float pixelWidthY = length(Dy(P) - dot(Dy(P), I) * I);
+ // Take the average of both axis' length
+ pixelWidth = (pixelWidthX + pixelWidthY) / 2;
+ }
+
+ // Use half the width as the neighbor face will render the
+ // other half. And take the square for fast comparison
+ pixelWidth *= 0.5 * line_width;
+ pixelWidth *= pixelWidth;
+ for (int i = 0; i < np; i++)
+ {
+ int i2 = i ? i - 1 : np - 1;
+ vector dir = P - p[i];
+ vector edge = p[i] - p[i2];
+ vector crs = cross(edge, dir);
+ // At this point dot(crs, crs) / dot(edge, edge) is
+ // the square of area / length(edge) == square of the
+ // distance to the edge.
+ if (dot(crs, crs) < (dot(edge, edge) * pixelWidth))
+ return 1;
+ }
+ return 0;
+}
+
+float wireframe(string edge_type, float line_width) { return wireframe(edge_type, line_width, 1); }
+float wireframe(string edge_type) { return wireframe(edge_type, 1.0, 1); }
+float wireframe() { return wireframe("polygons", 1.0, 1); }
+
+#endif /* CCL_OSLUTIL_H */
#define M_PI_2 1.5707963267948966 /* pi/2 */
#define M_PI_4 0.7853981633974483 /* pi/4 */
#define M_2_PI 0.6366197723675813 /* 2/pi */
+#define M_2PI 6.2831853071795865 /* 2*pi */
+#define M_4PI 12.566370614359173 /* 4*pi */
#define M_2_SQRTPI 1.1283791670955126 /* 2/sqrt(pi) */
#define M_E 2.7182818284590452 /* e (Euler's number) */
#define M_LN2 0.6931471805599453 /* ln(2) */
PERCOMP1 (trunc)
PERCOMP2 (fmod)
PERCOMP2F (fmod)
-PERCOMP2 (mod)
-PERCOMP2F (mod)
-int mod (int x, int y) BUILTIN;
+int mod (int a, int b) { return a - b*(int)floor(a/b); }
+point mod (point a, point b) { return a - b*floor(a/b); }
+vector mod (vector a, vector b) { return a - b*floor(a/b); }
+normal mod (normal a, normal b) { return a - b*floor(a/b); }
+color mod (color a, color b) { return a - b*floor(a/b); }
+point mod (point a, float b) { return a - b*floor(a/b); }
+vector mod (vector a, float b) { return a - b*floor(a/b); }
+normal mod (normal a, float b) { return a - b*floor(a/b); }
+color mod (color a, float b) { return a - b*floor(a/b); }
+float mod (float a, float b) { return a - b*floor(a/b); }
PERCOMP2 (min)
PERCOMP2 (max)
normal clamp (normal x, normal minval, normal maxval) { return max(min(x,maxval),minval); }
point clamp (point x, point minval, point maxval) { return max(min(x,maxval),minval); }
color clamp (color x, color minval, color maxval) { return max(min(x,maxval),minval); }
float clamp (float x, float minval, float maxval) { return max(min(x,maxval),minval); }
-//normal clamp (normal x, normal minval, normal maxval) BUILTIN;
-//vector clamp (vector x, vector minval, vector maxval) BUILTIN;
-//point clamp (point x, point minval, point maxval) BUILTIN;
-//color clamp (color x, color minval, color maxval) BUILTIN;
-//float clamp (float x, float minval, float maxval) BUILTIN;
normal mix (normal x, normal y, normal a) { return x*(1-a) + y*a; }
normal mix (normal x, normal y, float a) { return x*(1-a) + y*a; }
vector mix (vector x, vector y, vector a) { return x*(1-a) + y*a; }
vector faceforward (vector N, vector I, vector Nref) BUILTIN;
vector faceforward (vector N, vector I) BUILTIN;
vector reflect (vector I, vector N) { return I - 2*dot(N,I)*N; }
-vector refract(vector I, vector N, float eta) {
- float IdotN = dot(I, N);
- float k = 1 - eta * eta * (1 - IdotN * IdotN);
- return (k < 0) ? vector(0, 0, 0) : (eta * I - N * (eta * IdotN + sqrt(k)));
+vector refract (vector I, vector N, float eta) {
+ float IdotN = dot (I, N);
+ float k = 1 - eta*eta * (1 - IdotN*IdotN);
+ return (k < 0) ? vector(0,0,0) : (eta*I - N * (eta*IdotN + sqrt(k)));
}
-void fresnel(vector I, normal N, float eta,
- output float Kr, output float Kt,
- output vector R, output vector T)
+void fresnel (vector I, normal N, float eta,
+ output float Kr, output float Kt,
+ output vector R, output vector T)
{
- float sqr(float x) {
- return x * x;
- }
- float c = dot(I, N);
- if (c < 0)
- c = -c;
- R = reflect(I, N);
- float g = 1.0 / sqr(eta) - 1.0 + c * c;
- if (g >= 0.0) {
- g = sqrt(g);
- float beta = g - c;
- float F = (c * (g + c) - 1.0) / (c * beta + 1.0);
- F = 0.5 * (1.0 + sqr(F));
- F *= sqr(beta / (g + c));
- Kr = F;
- Kt = (1.0 - Kr) * eta * eta;
- // OPT: the following recomputes some of the above values, but it
- // gives us the same result as if the shader-writer called refract()
- T = refract(I, N, eta);
- }
- else {
- // total internal reflection
- Kr = 1.0;
- Kt = 0.0;
- T = vector(0, 0, 0);
- }
-#undef sqr
+ float sqr(float x) { return x*x; }
+ float c = dot(I, N);
+ if (c < 0)
+ c = -c;
+ R = reflect(I, N);
+ float g = 1.0 / sqr(eta) - 1.0 + c * c;
+ if (g >= 0.0) {
+ g = sqrt (g);
+ float beta = g - c;
+ float F = (c * (g+c) - 1.0) / (c * beta + 1.0);
+ F = 0.5 * (1.0 + sqr(F));
+ F *= sqr (beta / (g+c));
+ Kr = F;
+ Kt = (1.0 - Kr) * eta*eta;
+ // OPT: the following recomputes some of the above values, but it
+ // gives us the same result as if the shader-writer called refract()
+ T = refract(I, N, eta);
+ } else {
+ // total internal reflection
+ Kr = 1.0;
+ Kt = 0.0;
+ T = vector (0,0,0);
+ }
}
-void fresnel(vector I, normal N, float eta,
- output float Kr, output float Kt)
+void fresnel (vector I, normal N, float eta,
+ output float Kr, output float Kt)
{
- vector R, T;
- fresnel(I, N, eta, Kr, Kt, R, T);
+ vector R, T;
+ fresnel(I, N, eta, Kr, Kt, R, T);
}
-point rotate(point q, float angle, point a, point b) BUILTIN;
-normal transform(matrix Mto, normal p) BUILTIN;
-vector transform(matrix Mto, vector p) BUILTIN;
-point transform(matrix Mto, point p) BUILTIN;
+normal transform (matrix Mto, normal p) BUILTIN;
+vector transform (matrix Mto, vector p) BUILTIN;
+point transform (matrix Mto, point p) BUILTIN;
+normal transform (string from, string to, normal p) BUILTIN;
+vector transform (string from, string to, vector p) BUILTIN;
+point transform (string from, string to, point p) BUILTIN;
+normal transform (string to, normal p) { return transform("common",to,p); }
+vector transform (string to, vector p) { return transform("common",to,p); }
+point transform (string to, point p) { return transform("common",to,p); }
-// Implementation of transform-with-named-space in terms of matrices:
+float transformu (string tounits, float x) BUILTIN;
+float transformu (string fromunits, string tounits, float x) BUILTIN;
-point transform(string tospace, point x)
+point rotate (point p, float angle, point a, point b)
{
- return transform(matrix("common", tospace), x);
+ vector axis = normalize (b - a);
+ float cosang, sinang;
+ sincos (angle, sinang, cosang);
+ float cosang1 = 1.0 - cosang;
+ float x = axis[0], y = axis[1], z = axis[2];
+ matrix M = matrix (x * x + (1.0 - x * x) * cosang,
+ x * y * cosang1 + z * sinang,
+ x * z * cosang1 - y * sinang,
+ 0.0,
+ x * y * cosang1 - z * sinang,
+ y * y + (1.0 - y * y) * cosang,
+ y * z * cosang1 + x * sinang,
+ 0.0,
+ x * z * cosang1 + y * sinang,
+ y * z * cosang1 - x * sinang,
+ z * z + (1.0 - z * z) * cosang,
+ 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+ return transform (M, p-a) + a;
}
-point transform(string fromspace, string tospace, point x)
-{
- return transform(matrix(fromspace, tospace), x);
-}
-
-
-vector transform(string tospace, vector x)
-{
- return transform(matrix("common", tospace), x);
-}
-
-vector transform(string fromspace, string tospace, vector x)
-{
- return transform(matrix(fromspace, tospace), x);
-}
-
-
-normal transform(string tospace, normal x)
-{
- return transform(matrix("common", tospace), x);
-}
-
-normal transform(string fromspace, string tospace, normal x)
-{
- return transform(matrix(fromspace, tospace), x);
-}
-
-float transformu(string tounits, float x) BUILTIN;
-float transformu(string fromunits, string tounits, float x) BUILTIN;
// Color functions
-float luminance(color c) {
- return dot((vector)c, vector(0.2126, 0.7152, 0.0722));
-}
-
+float luminance (color c) BUILTIN;
+color blackbody (float temperatureK) BUILTIN;
+color wavelength_color (float wavelength_nm) BUILTIN;
-color transformc(string to, color x)
+color transformc (string to, color x)
{
- color rgb_to_hsv(color rgb) { // See Foley & van Dam
- float r = rgb[0], g = rgb[1], b = rgb[2];
- float mincomp = min(r, min(g, b));
- float maxcomp = max(r, max(g, b));
- float delta = maxcomp - mincomp; // chroma
- float h, s, v;
- v = maxcomp;
- if (maxcomp > 0)
- s = delta / maxcomp;
- else s = 0;
- if (s <= 0)
- h = 0;
- else {
- if (r >= maxcomp) h = (g - b) / delta;
- else if (g >= maxcomp) h = 2 + (b - r) / delta;
- else h = 4 + (r - g) / delta;
- h /= 6;
- if (h < 0)
- h += 1;
- }
- return color(h, s, v);
- }
-
- color rgb_to_hsl(color rgb) { // See Foley & van Dam
- // First convert rgb to hsv, then to hsl
- float minval = min(rgb[0], min(rgb[1], rgb[2]));
- color hsv = rgb_to_hsv(rgb);
- float maxval = hsv[2]; // v == maxval
- float h = hsv[0], s, l = (minval + maxval) / 2;
- if (minval == maxval)
- s = 0; // special 'achromatic' case, hue is 0
- else if (l <= 0.5)
- s = (maxval - minval) / (maxval + minval);
- else
- s = (maxval - minval) / (2 - maxval - minval);
- return color(h, s, l);
- }
-
- color r;
- if (to == "rgb" || to == "RGB")
- r = x;
- else if (to == "hsv")
- r = rgb_to_hsv(x);
- else if (to == "hsl")
- r = rgb_to_hsl(x);
- else if (to == "YIQ")
- r = color(dot(vector(0.299, 0.587, 0.114), (vector)x),
- dot(vector(0.596, -0.275, -0.321), (vector)x),
- dot(vector(0.212, -0.523, 0.311), (vector)x));
- else if (to == "xyz")
- r = color(dot(vector(0.412453, 0.357580, 0.180423), (vector)x),
- dot(vector(0.212671, 0.715160, 0.072169), (vector)x),
- dot(vector(0.019334, 0.119193, 0.950227), (vector)x));
- else {
- error("Unknown color space \"%s\"", to);
- r = x;
- }
- return r;
+ color rgb_to_hsv (color rgb) { // See Foley & van Dam
+ float r = rgb[0], g = rgb[1], b = rgb[2];
+ float mincomp = min (r, min (g, b));
+ float maxcomp = max (r, max (g, b));
+ float delta = maxcomp - mincomp; // chroma
+ float h, s, v;
+ v = maxcomp;
+ if (maxcomp > 0)
+ s = delta / maxcomp;
+ else s = 0;
+ if (s <= 0)
+ h = 0;
+ else {
+ if (r >= maxcomp) h = (g-b) / delta;
+ else if (g >= maxcomp) h = 2 + (b-r) / delta;
+ else h = 4 + (r-g) / delta;
+ h /= 6;
+ if (h < 0)
+ h += 1;
+ }
+ return color (h, s, v);
+ }
+
+ color rgb_to_hsl (color rgb) { // See Foley & van Dam
+ // First convert rgb to hsv, then to hsl
+ float minval = min (rgb[0], min (rgb[1], rgb[2]));
+ color hsv = rgb_to_hsv (rgb);
+ float maxval = hsv[2]; // v == maxval
+ float h = hsv[0], s, l = (minval+maxval) / 2;
+ if (minval == maxval)
+ s = 0; // special 'achromatic' case, hue is 0
+ else if (l <= 0.5)
+ s = (maxval - minval) / (maxval + minval);
+ else
+ s = (maxval - minval) / (2 - maxval - minval);
+ return color (h, s, l);
+ }
+
+ color r;
+ if (to == "rgb" || to == "RGB")
+ r = x;
+ else if (to == "hsv")
+ r = rgb_to_hsv (x);
+ else if (to == "hsl")
+ r = rgb_to_hsl (x);
+ else if (to == "YIQ")
+ r = color (dot (vector(0.299, 0.587, 0.114), (vector)x),
+ dot (vector(0.596, -0.275, -0.321), (vector)x),
+ dot (vector(0.212, -0.523, 0.311), (vector)x));
+ else if (to == "xyz")
+ r = color (dot (vector(0.412453, 0.357580, 0.180423), (vector)x),
+ dot (vector(0.212671, 0.715160, 0.072169), (vector)x),
+ dot (vector(0.019334, 0.119193, 0.950227), (vector)x));
+ else {
+ error ("Unknown color space \"%s\"", to);
+ r = x;
+ }
+ return r;
}
-color transformc(string from, string to, color x)
+color transformc (string from, string to, color x)
{
- color hsv_to_rgb(color c) { // Reference: Foley & van Dam
- float h = c[0], s = c[1], v = c[2];
- color r;
- if (s < 0.0001) {
- r = v;
- }
- else {
- h = 6 * (h - floor(h)); // expand to [0..6)
- int hi = (int)h;
- float f = h - hi;
- float p = v * (1 - s);
- float q = v * (1 - s * f);
- float t = v * (1 - s * (1 - f));
- if (hi == 0) r = color(v, t, p);
- else if (hi == 1) r = color(q, v, p);
- else if (hi == 2) r = color(p, v, t);
- else if (hi == 3) r = color(p, q, v);
- else if (hi == 4) r = color(t, p, v);
- else r = color(v, p, q);
- }
- return r;
- }
-
- color hsl_to_rgb(color c) {
- float h = c[0], s = c[1], l = c[2];
- // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
- float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
- color r;
- if (v <= 0) {
- r = 0;
- }
- else {
- float min = 2 * l - v;
- s = (v - min) / v;
- r = hsv_to_rgb(color(h, s, v));
- }
- return r;
- }
-
- color r;
- if (from == "rgb" || from == "RGB")
- r = x;
- else if (from == "hsv")
- r = hsv_to_rgb(x);
- else if (from == "hsl")
- r = hsl_to_rgb(x);
- else if (from == "YIQ")
- r = color(dot(vector(1, 0.9557, 0.6199), (vector)x),
- dot(vector(1, -0.2716, -0.6469), (vector)x),
- dot(vector(1, -1.1082, 1.7051), (vector)x));
- else if (from == "xyz")
- r = color(dot(vector(3.240479, -1.537150, -0.498535), (vector)x),
- dot(vector(-0.969256, 1.875991, 0.041556), (vector)x),
- dot(vector(0.055648, -0.204043, 1.057311), (vector)x));
- else {
- error("Unknown color space \"%s\"", to);
- r = x;
- }
- return transformc(to, r);
+ color hsv_to_rgb (color c) { // Reference: Foley & van Dam
+ float h = c[0], s = c[1], v = c[2];
+ color r;
+ if (s < 0.0001) {
+ r = v;
+ } else {
+ h = 6 * (h - floor(h)); // expand to [0..6)
+ int hi = (int)h;
+ float f = h - hi;
+ float p = v * (1-s);
+ float q = v * (1-s*f);
+ float t = v * (1-s*(1-f));
+ if (hi == 0) r = color (v, t, p);
+ else if (hi == 1) r = color (q, v, p);
+ else if (hi == 2) r = color (p, v, t);
+ else if (hi == 3) r = color (p, q, v);
+ else if (hi == 4) r = color (t, p, v);
+ else r = color (v, p, q);
+ }
+ return r;
+ }
+
+ color hsl_to_rgb (color c) {
+ float h = c[0], s = c[1], l = c[2];
+ // Easiest to convert hsl -> hsv, then hsv -> RGB (per Foley & van Dam)
+ float v = (l <= 0.5) ? (l * (1 + s)) : (l * (1 - s) + s);
+ color r;
+ if (v <= 0) {
+ r = 0;
+ } else {
+ float min = 2 * l - v;
+ s = (v - min) / v;
+ r = hsv_to_rgb (color (h, s, v));
+ }
+ return r;
+ }
+
+ color r;
+ if (from == "rgb" || from == "RGB")
+ r = x;
+ else if (from == "hsv")
+ r = hsv_to_rgb (x);
+ else if (from == "hsl")
+ r = hsl_to_rgb (x);
+ else if (from == "YIQ")
+ r = color (dot (vector(1, 0.9557, 0.6199), (vector)x),
+ dot (vector(1, -0.2716, -0.6469), (vector)x),
+ dot (vector(1, -1.1082, 1.7051), (vector)x));
+ else if (from == "xyz")
+ r = color (dot (vector( 3.240479, -1.537150, -0.498535), (vector)x),
+ dot (vector(-0.969256, 1.875991, 0.041556), (vector)x),
+ dot (vector( 0.055648, -0.204043, 1.057311), (vector)x));
+ else {
+ error ("Unknown color space \"%s\"", to);
+ r = x;
+ }
+ return transformc (to, r);
}
// Matrix functions
-float determinant(matrix m) BUILTIN;
-matrix transpose(matrix m) BUILTIN;
+float determinant (matrix m) BUILTIN;
+matrix transpose (matrix m) BUILTIN;
// Pattern generation
-float step(float edge, float x) BUILTIN;
-color step(color edge, color x) BUILTIN;
-point step(point edge, point x) BUILTIN;
-vector step(vector edge, vector x) BUILTIN;
-normal step(normal edge, normal x) BUILTIN;
-float smoothstep(float edge0, float edge1, float x) BUILTIN;
+float step (float edge, float x) BUILTIN;
+color step (color edge, color x) BUILTIN;
+point step (point edge, point x) BUILTIN;
+vector step (vector edge, vector x) BUILTIN;
+normal step (normal edge, normal x) BUILTIN;
+float smoothstep (float edge0, float edge1, float x) BUILTIN;
// Derivatives and area operators
// String functions
-int strlen(string s) BUILTIN;
-int startswith(string s, string prefix) BUILTIN;
-int endswith(string s, string suffix) BUILTIN;
-string substr(string s, int start, int len) BUILTIN;
-string substr(string s, int start) {
- return substr(s, start, strlen(s));
-}
+int strlen (string s) BUILTIN;
+int startswith (string s, string prefix) BUILTIN;
+int endswith (string s, string suffix) BUILTIN;
+string substr (string s, int start, int len) BUILTIN;
+string substr (string s, int start) { return substr (s, start, strlen(s)); }
// Define concat in terms of shorter concat
-string concat(string a, string b, string c) {
- return concat(concat(a, b), c);
+string concat (string a, string b, string c) {
+ return concat(concat(a,b), c);
}
-string concat(string a, string b, string c, string d) {
- return concat(concat(a, b, c), d);
+string concat (string a, string b, string c, string d) {
+ return concat(concat(a,b,c), d);
}
-string concat(string a, string b, string c, string d, string e) {
- return concat(concat(a, b, c, d), e);
+string concat (string a, string b, string c, string d, string e) {
+ return concat(concat(a,b,c,d), e);
}
-string concat(string a, string b, string c, string d, string e, string f) {
- return concat(concat(a, b, c, d, e), f);
+string concat (string a, string b, string c, string d, string e, string f) {
+ return concat(concat(a,b,c,d,e), f);
}
closure color oren_nayar(normal N, float sigma) BUILTIN;
closure color translucent(normal N) BUILTIN;
closure color reflection(normal N, float eta) BUILTIN;
-closure color reflection(normal N) { return reflection(N, 0.0); }
+closure color reflection(normal N) { return reflection (N, 0.0); }
closure color refraction(normal N, float eta) BUILTIN;
closure color dielectric(normal N, float eta) BUILTIN;
closure color transparent() BUILTIN;
-closure color microfacet_ggx(normal N, float ag) BUILTIN;
+closure color microfacet_ggx(normal N, float ag, float eta) BUILTIN;
closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
-closure color microfacet_beckmann(normal N, float ab) BUILTIN;
+closure color microfacet_beckmann(normal N, float ab, float eta) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
-closure color ward(normal N, vector T, float ax, float ay) BUILTIN;
-closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
+closure color ward(normal N, vector T,float ax, float ay) BUILTIN;
+closure color phong(normal N, float exponent) BUILTIN;
+closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
+closure color hair_diffuse(vector T) BUILTIN;
+closure color hair_specular(vector T, float offset, float exponent) BUILTIN;
+closure color ashikhmin_velvet(normal N, float sigma, float eta) BUILTIN;
closure color westin_backscatter(normal N, float roughness) BUILTIN;
closure color westin_sheen(normal N, float edginess) BUILTIN;
closure color bssrdf_cubic(color radius) BUILTIN;
closure color debug(string tag) BUILTIN;
closure color background() BUILTIN;
closure color holdout() BUILTIN;
-closure color subsurface(float eta, float g, float mfp, float albedo) BUILTIN;
+closure color subsurface(float eta, float g, color mfp, color albedo) BUILTIN;
+
+closure color cloth(normal N, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy,
+ float area_scaled, vector dPdu, color diff_warp_col, color diff_weft_col,
+ color spec_warp_col, color spec_weft_col, float fresnel_warp, float fresnel_weft,
+ float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
+ float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
+ float thread_count_mult_v) BUILTIN;
+closure color cloth_specular(normal N, color spec_col[4], float eta[4], int thread_pattern[4],
+ float pattern_weight[4], int current_thread, float brdf_interp,
+ float btf_interp, float uux, float vvx, float area_scaled, vector dPdu,
+ float eccentricity[4], float angle[4], float Kx[4], float Ky[4],
+ float Sx[4], float Sy[4]) BUILTIN;
+closure color fakefur_diffuse(normal N, vector T, float fur_reflectivity, float fur_transmission,
+ float shadow_start, float shadow_end, float fur_attenuation, float fur_density,
+ float fur_avg_radius, float fur_length, float fur_shadow_fraction) BUILTIN;
+closure color fakefur_specular(normal N, vector T, float offset, float exp, float fur_reflectivity,
+ float fur_transmission, float shadow_start, float shadow_end,
+ float fur_attenuation, float fur_density, float fur_avg_radius,
+ float fur_length, float fur_shadow_fraction) BUILTIN;
+
+closure color fakefur_skin(vector N, vector T, float fur_reflectivity, float fur_transmission,
+ float shadow_start, float shadow_end, float fur_attenuation, float fur_density,
+ float fur_avg_radius, float fur_length) BUILTIN;
+
+
+closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft,
+ color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft,
+ float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
+ float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
+ float thread_count_mult_v)
+{
+
+ return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft,
+ fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle,
+ warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v);
+}
+
+closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft,
+ color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft,
+ float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
+ float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
+ float thread_count_mult_v, string tok, string val)
+{
+
+ return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft,
+ fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle,
+ warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v, tok, val);
+}
+
+
// Renderer state
-int raytype(string typename) BUILTIN;
+int raytype (string typename) BUILTIN;
+// the individual 'isFOOray' functions are deprecated
+int iscameraray () { return raytype("camera"); }
+int isdiffuseray () { return raytype("diffuse"); }
+int isglossyray () { return raytype("glossy"); }
+int isshadowray () { return raytype("shadow"); }
+int getmatrix (string fromspace, string tospace, output matrix M) BUILTIN;
+int getmatrix (string fromspace, output matrix M) {
+ return getmatrix (fromspace, "common", M);
+}
+
+
+// Miscellaneous
+
+
+
#undef BUILTIN
#undef BUILTIN_DERIV
#undef PERCOMP2F
#endif /* CCL_STDOSL_H */
-
CCL_NAMESPACE_BEGIN
+class OSLRenderServices;
+
struct OSLGlobals {
/* use */
bool use;
/* shading system */
OSL::ShadingSystem *ss;
+ OSLRenderServices *services;
/* shader states */
vector<OSL::ShadingAttribStateRef> surface_state;
/* thread key for thread specific data lookup */
struct ThreadData {
OSL::ShaderGlobals globals;
- void *thread_info;
+ OSL::PerThreadInfo *thread_info;
};
static tls_ptr(ThreadData, thread_data);
return false;
}
+bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform)
+{
+ // XXX implementation
+ return true;
+}
+
+bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
+{
+ // XXX implementation
+ return true;
+}
+
bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives,
ustring object, TypeDesc type, ustring name,
int index, void *val)
return false; /* never called by OSL */
}
-void *OSLRenderServices::get_pointcloud_attr_query(ustring *attr_names,
- TypeDesc *attr_types, int nattrs)
+int OSLRenderServices::pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 ¢er,
+ float radius, int max_points, bool sort, size_t *out_indices, float *out_distances, int derivs_offset)
{
-#ifdef WITH_PARTIO
- m_attr_queries.push_back(AttrQuery());
- AttrQuery &query = m_attr_queries.back();
-
- /* make space for what we need. the only reason to use
- * std::vector is to skip the delete */
- query.attr_names.resize(nattrs);
- query.attr_partio_types.resize(nattrs);
- /* capacity will keep the length of the smallest array passed
- * to the query. Just to prevent buffer overruns */
- query.capacity = -1;
-
- for (int i = 0; i < nattrs; ++i) {
- query.attr_names[i] = attr_names[i];
-
- TypeDesc element_type = attr_types[i].elementtype();
-
- if (query.capacity < 0)
- query.capacity = attr_types[i].numelements();
- else
- query.capacity = min(query.capacity, (int)attr_types[i].numelements());
-
- /* convert the OSL (OIIO) type to the equivalent Partio type so
- * we can do a fast check at query time. */
- if (element_type == TypeDesc::TypeFloat) {
- query.attr_partio_types[i] = Partio::FLOAT;
- }
- else if (element_type == TypeDesc::TypeInt) {
- query.attr_partio_types[i] = Partio::INT;
- }
- else if (element_type == TypeDesc::TypeColor || element_type == TypeDesc::TypePoint ||
- element_type == TypeDesc::TypeVector || element_type == TypeDesc::TypeNormal)
- {
- query.attr_partio_types[i] = Partio::VECTOR;
- }
- else {
- return NULL; /* report some error of unknown type */
- }
- }
-
- /* this is valid until the end of RenderServices */
- return &query;
-#else
- return NULL;
-#endif
+ return 0;
}
-#ifdef WITH_PARTIO
-Partio::ParticlesData *OSLRenderServices::get_pointcloud(ustring filename)
+int OSLRenderServices::pointcloud_get(ustring filename, size_t *indices, int count,
+ ustring attr_name, TypeDesc attr_type, void *out_data)
{
- return Partio::readCached(filename.c_str(), true);
-}
-
-#endif
-
-int OSLRenderServices::pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius,
- int max_points, void *_attr_query, void **attr_outdata)
-{
- /* todo: this code has never been tested, and most likely does not
- * work. it's based on the example code in OSL */
-
-#ifdef WITH_PARTIO
- /* query Partio for this pointcloud lookup using cached attr_query */
- if (!_attr_query)
- return 0;
-
- AttrQuery *attr_query = (AttrQuery *)_attr_query;
- if (attr_query->capacity < max_points)
- return 0;
-
- /* get the pointcloud entry for the given filename */
- Partio::ParticlesData *cloud = get_pointcloud(filename);
-
- /* now we have to look up all the attributes in the file. we can't do this
- * before hand cause we never know what we are going to load. */
- int nattrs = attr_query->attr_names.size();
- Partio::ParticleAttribute *attr = (Partio::ParticleAttribute *)alloca(sizeof(Partio::ParticleAttribute) * nattrs);
-
- for (int i = 0; i < nattrs; ++i) {
- /* special case attributes */
- if (attr_query->attr_names[i] == u_distance || attr_query->attr_names[i] == u_index)
- continue;
-
- /* lookup the attribute by name*/
- if (!cloud->attributeInfo(attr_query->attr_names[i].c_str(), attr[i])) {
- /* issue an error here and return, types don't match */
- Partio::endCachedAccess(cloud);
- cloud->release();
- return 0;
- }
- }
-
- std::vector<Partio::ParticleIndex> indices;
- std::vector<float> dist2;
-
- Partio::beginCachedAccess(cloud);
-
- /* finally, do the lookup */
- cloud->findNPoints((const float *)¢er, max_points, radius, indices, dist2);
- int count = indices.size();
-
- /* retrieve the attributes directly to user space */
- for (int j = 0; j < nattrs; ++j) {
- /* special cases */
- if (attr_query->attr_names[j] == u_distance) {
- for (int i = 0; i < count; ++i)
- ((float *)attr_outdata[j])[i] = sqrtf(dist2[i]);
- }
- else if (attr_query->attr_names[j] == u_index) {
- for (int i = 0; i < count; ++i)
- ((int *)attr_outdata[j])[i] = indices[i];
- }
- else {
- /* note we make a single call per attribute, we don't loop over the
- * points. Partio does it, so it is there that we have to care about
- * performance */
- cloud->data(attr[j], count, &indices[0], true, attr_outdata[j]);
- }
- }
-
- Partio::endCachedAccess(cloud);
- cloud->release();
-
- return count;
-#else
- return 0;
-#endif
+ return 0;
}
CCL_NAMESPACE_END
-
#include <OSL/oslexec.h>
#include <OSL/oslclosure.h>
-#ifdef WITH_PARTIO
-#include <Partio.h>
-#endif
-
CCL_NAMESPACE_BEGIN
class Object;
bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time);
bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform, float time);
+
bool get_matrix(OSL::Matrix44 &result, ustring from, float time);
bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time);
+
+ bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform);
+ bool get_matrix(OSL::Matrix44 &result, ustring from);
bool get_array_attribute(void *renderstate, bool derivatives,
ustring object, TypeDesc type, ustring name,
bool get_userdata(bool derivatives, ustring name, TypeDesc type,
void *renderstate, void *val);
bool has_userdata(ustring name, TypeDesc type, void *renderstate);
+
+ int pointcloud_search(OSL::ShaderGlobals *sg, ustring filename, const OSL::Vec3 ¢er,
+ float radius, int max_points, bool sort, size_t *out_indices,
+ float *out_distances, int derivs_offset);
- void *get_pointcloud_attr_query(ustring *attr_names,
- TypeDesc *attr_types, int nattrs);
- int pointcloud(ustring filename, const OSL::Vec3 ¢er, float radius,
- int max_points, void *attr_query, void **attr_outdata);
+ int pointcloud_get(ustring filename, size_t *indices, int count, ustring attr_name,
+ TypeDesc attr_type, void *out_data);
private:
KernelGlobals *kernel_globals;
-#ifdef WITH_PARTIO
- /* OSL gets pointers to this but its definition is private.
- * right now it only caches the types already converted to
- * Partio constants. this is what get_pointcloud_attr_query
- * returns */
- struct AttrQuery {
- /* names of the attributes to query */
- std::vector<ustring> attr_names;
- /* types as (enum Partio::ParticleAttributeType) of the
- * attributes in the query */
- std::vector<int> attr_partio_types;
- /* for sanity checks, capacity of the output arrays */
- int capacity;
- };
-
- Partio::ParticlesData *get_pointcloud(ustring filename);
-
- /* keep a list so adding elements doesn't invalidate pointers */
- std::list<AttrQuery> m_attr_queries;
-#endif
-
static ustring u_distance;
static ustring u_index;
static ustring u_camera;
void OSLShader::thread_init(KernelGlobals *kg)
{
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = new OSLGlobals::ThreadData();
memset(&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
- tdata->thread_info = ssi->create_thread_info();
+ tdata->thread_info = ss->create_thread_info();
tls_set(kg->osl.thread_data, tdata);
- ((OSLRenderServices *)ssi->renderer())->thread_init(kg);
+ kg->osl.services->thread_init(kg);
}
void OSLShader::thread_free(KernelGlobals *kg)
{
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
- ssi->destroy_thread_info(tdata->thread_info);
+ ss->destroy_thread_info(tdata->thread_info);
delete tdata;
}
sc.weight = weight;
switch (prim->category()) {
- case ClosurePrimitive::BSDF: {
+ case OSL::ClosurePrimitive::BSDF: {
if (sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */
float albedo = bsdf->albedo(TO_VEC3(sd->I));
float sample_weight = fabsf(average(weight)) * albedo;
- float sample_sum = sd->osl_closure.bsdf_sample_sum + sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_BSDF_ID;
- sd->osl_closure.bsdf_sample_sum = sample_sum;
/* scattering flags */
if (scattering == OSL::Labels::DIFFUSE)
sd->closure[sd->num_closure++] = sc;
break;
}
- case ClosurePrimitive::Emissive: {
+ case OSL::ClosurePrimitive::Emissive: {
if (sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */
float sample_weight = fabsf(average(weight));
- float sample_sum = sd->osl_closure.emissive_sample_sum + sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_EMISSION_ID;
- sd->osl_closure.emissive_sample_sum = sample_sum;
/* flag */
sd->flag |= SD_EMISSION;
sd->closure[sd->num_closure++] = sc;
break;
}
- case ClosurePrimitive::Holdout:
+ case OSL::ClosurePrimitive::Holdout:
if (sd->num_closure == MAX_CLOSURE)
return;
sd->flag |= SD_HOLDOUT;
sd->closure[sd->num_closure++] = sc;
break;
- case ClosurePrimitive::BSSRDF:
- case ClosurePrimitive::Debug:
+ case OSL::ClosurePrimitive::BSSRDF:
+ case OSL::ClosurePrimitive::Debug:
break; /* not implemented */
- case ClosurePrimitive::Background:
- case ClosurePrimitive::Volume:
+ case OSL::ClosurePrimitive::Background:
+ case OSL::ClosurePrimitive::Volume:
break; /* not relevant */
}
}
void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{
/* gather pointers */
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);
+ OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
/* setup shader globals from shader data */
sd->osl_ctx = ctx;
int shader = sd->shader & SHADER_MASK;
if (kg->osl.surface_state[shader])
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals);
+ ss->execute(*ctx, *(kg->osl.surface_state[shader]), *globals);
/* flatten closure tree */
sd->num_closure = 0;
float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
{
/* gather pointers */
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);
+ OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
/* setup shader globals from shader data */
sd->osl_ctx = ctx;
/* execute shader for this point */
if (kg->osl.background_state)
- ctx->execute(OSL::pvt::ShadUseSurface, *kg->osl.background_state, *globals);
+ ss->execute(*ctx, *(kg->osl.background_state), *globals);
/* return background color immediately */
if (globals->Ci)
sc.weight = weight;
switch (prim->category()) {
- case ClosurePrimitive::Volume: {
+ case OSL::ClosurePrimitive::Volume: {
if (sd->num_closure == MAX_CLOSURE)
return;
/* sample weight */
float sample_weight = fabsf(average(weight));
- float sample_sum = sd->osl_closure.volume_sample_sum + sample_weight;
sc.sample_weight = sample_weight;
sc.type = CLOSURE_VOLUME_ID;
- sd->osl_closure.volume_sample_sum = sample_sum;
/* add */
sd->closure[sd->num_closure++] = sc;
break;
}
- case ClosurePrimitive::Holdout:
- case ClosurePrimitive::Debug:
+ case OSL::ClosurePrimitive::Holdout:
+ case OSL::ClosurePrimitive::Debug:
break; /* not implemented */
- case ClosurePrimitive::Background:
- case ClosurePrimitive::BSDF:
- case ClosurePrimitive::Emissive:
- case ClosurePrimitive::BSSRDF:
+ case OSL::ClosurePrimitive::Background:
+ case OSL::ClosurePrimitive::BSDF:
+ case OSL::ClosurePrimitive::Emissive:
+ case OSL::ClosurePrimitive::BSSRDF:
break; /* not relevant */
}
}
void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int path_flag)
{
/* gather pointers */
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);
+ OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
/* setup shader globals from shader data */
sd->osl_ctx = ctx;
int shader = sd->shader & SHADER_MASK;
if (kg->osl.volume_state[shader])
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals);
-
- /* retrieve resulting closures */
- sd->osl_closure.volume_sample_sum = 0.0f;
- sd->osl_closure.num_volume = 0;
- sd->osl_closure.randb = randb;
+ ss->execute(*ctx, *(kg->osl.volume_state[shader]), *globals);
if (globals->Ci)
flatten_volume_closure_tree(sd, globals->Ci);
void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
{
/* gather pointers */
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
OSL::ShaderGlobals *globals = &tdata->globals;
- OSL::pvt::ShadingContext *ctx = ssi->get_context(tdata->thread_info);
+ OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
/* setup shader globals from shader data */
sd->osl_ctx = ctx;
int shader = sd->shader & SHADER_MASK;
if (kg->osl.displacement_state[shader])
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[shader]), *globals);
+ ss->execute(*ctx, *(kg->osl.displacement_state[shader]), *globals);
/* get back position */
sd->P = TO_FLOAT3(globals->P);
void OSLShader::release(KernelGlobals *kg, const ShaderData *sd)
{
- OSL::pvt::ShadingSystemImpl *ssi = (OSL::pvt::ShadingSystemImpl *)kg->osl.ss;
+ OSL::ShadingSystem *ss = kg->osl.ss;
OSLGlobals::ThreadData *tdata = tls_get(OSLGlobals::ThreadData, kg->osl.thread_data);
+ OSL::ShadingContext *ctx = ss->get_context(tdata->thread_info);
- ssi->release_context((OSL::pvt::ShadingContext *)sd->osl_ctx, tdata->thread_info);
+ ss->release_context(ctx);
}
/* BSDF Closure */
{
OSL::EmissiveClosure *emissive = (OSL::EmissiveClosure *)sc->prim;
OSL::Color3 emissive_eval = emissive->eval(TO_VEC3(sd->Ng), TO_VEC3(sd->I));
- eval += TO_FLOAT3(emissive_eval);
- return eval;
+ return TO_FLOAT3(emissive_eval);
}
/* Volume Closure */
__device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- float data;
-
switch(type) {
case NODE_INFO_PAR_INDEX: {
uint particle_id = object_particle_id(kg, sd->object);
- data = particle_index(kg, particle_id);
- stack_store_float(stack, out_offset, data);
+ stack_store_float(stack, out_offset, particle_index(kg, particle_id));
break;
}
case NODE_INFO_PAR_AGE: {
uint particle_id = object_particle_id(kg, sd->object);
- data = particle_age(kg, particle_id);
- stack_store_float(stack, out_offset, data);
+ stack_store_float(stack, out_offset, particle_age(kg, particle_id));
break;
}
case NODE_INFO_PAR_LIFETIME: {
uint particle_id = object_particle_id(kg, sd->object);
- data = particle_lifetime(kg, particle_id);
- stack_store_float(stack, out_offset, data);
+ stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_LOCATION: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
+ break;
+ }
+ #if 0 /* XXX float4 currently not supported in SVM stack */
+ case NODE_INFO_PAR_ROTATION: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
+ break;
+ }
+ #endif
+ case NODE_INFO_PAR_SIZE: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_size(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_VELOCITY: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_ANGULAR_VELOCITY: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
break;
}
}
Fac = Fac1 < Fac2;
else if(type == NODE_MATH_GREATER_THAN)
Fac = Fac1 > Fac2;
+ else if(type == NODE_MATH_CLAMP)
+ Fac = clamp(Fac1, 0.0f, 1.0f);
else
Fac = 0.0f;
return outcol;
}
+__device float3 svm_mix_clamp(float3 col)
+{
+ float3 outcol = col;
+
+ outcol.x = clamp(col.x, 0.0f, 1.0f);
+ outcol.y = clamp(col.y, 0.0f, 1.0f);
+ outcol.z = clamp(col.z, 0.0f, 1.0f);
+
+ return outcol;
+}
+
__device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2)
{
float t = clamp(fac, 0.0f, 1.0f);
case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2);
case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2);
case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2);
+ case NODE_MIX_CLAMP: return svm_mix_clamp(c1);
}
return make_float3(0.0f, 0.0f, 0.0f);
__device_inline float3 svm_world_to_ndc(KernelGlobals *kg, ShaderData *sd, float3 P)
{
if(kernel_data.cam.type != CAMERA_PANORAMA) {
- if(sd->object != ~0)
+ if(sd->object == ~0)
P += svm_background_offset(kg);
Transform tfm = kernel_data.cam.worldtondc;
typedef enum NodeParticleInfo {
NODE_INFO_PAR_INDEX,
NODE_INFO_PAR_AGE,
- NODE_INFO_PAR_LIFETIME
+ NODE_INFO_PAR_LIFETIME,
+ NODE_INFO_PAR_LOCATION,
+ NODE_INFO_PAR_ROTATION,
+ NODE_INFO_PAR_SIZE,
+ NODE_INFO_PAR_VELOCITY,
+ NODE_INFO_PAR_ANGULAR_VELOCITY
} NodeParticleInfo;
typedef enum NodeLightPath {
NODE_MIX_VAL,
NODE_MIX_COLOR,
NODE_MIX_SOFT,
- NODE_MIX_LINEAR
+ NODE_MIX_LINEAR,
+ NODE_MIX_CLAMP /* used for the clamp UI option */
} NodeMix;
typedef enum NodeMath {
NODE_MATH_MAXIMUM,
NODE_MATH_ROUND,
NODE_MATH_LESS_THAN,
- NODE_MATH_GREATER_THAN
+ NODE_MATH_GREATER_THAN,
+ NODE_MATH_CLAMP /* used for the clamp UI option */
} NodeMath;
typedef enum NodeVectorMath {
nodes.cpp
object.cpp
osl.cpp
+ particles.cpp
scene.cpp
session.cpp
shader.cpp
nodes.h
object.h
osl.h
+ particles.h
scene.h
session.h
shader.h
name = name_;
id = -1;
bump = SHADER_BUMP_NONE;
+ special_type = SHADER_SPECIAL_TYPE_NONE;
}
ShaderNode::~ShaderNode()
void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
{
foreach(ShaderNode *node, nodes) {
- ProxyNode *proxy = dynamic_cast<ProxyNode*>(node);
- if (proxy) {
+ if (node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
+ ProxyNode *proxy = static_cast<ProxyNode*>(node);
ShaderInput *input = proxy->inputs[0];
ShaderOutput *output = proxy->outputs[0];
}
/* remove useless mix closures nodes */
- MixClosureNode *mix = dynamic_cast<MixClosureNode*>(node);
-
- if(mix) {
+ if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) {
+ MixClosureNode *mix = static_cast<MixClosureNode*>(node);
if(mix->outputs[0]->links.size() && mix->inputs[1]->link == mix->inputs[2]->link) {
ShaderOutput *output = mix->inputs[1]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
SHADER_BUMP_DY
};
+/* Identifiers for some special node types.
+ *
+ * The graph needs to identify these in the clean function.
+ * Cannot use dynamic_cast, as this is disabled for OSL. */
+
+enum ShaderNodeSpecialType {
+ SHADER_SPECIAL_TYPE_NONE,
+ SHADER_SPECIAL_TYPE_PROXY,
+ SHADER_SPECIAL_TYPE_MIX_CLOSURE
+};
+
/* Enum
*
* Utility class for enum values. */
ustring name; /* name, not required to be unique */
int id; /* index in graph node array */
ShaderBump bump; /* for bump mapping utility */
+
+ ShaderNodeSpecialType special_type; /* special node type */
};
device->tex_alloc("__light_distribution", dscene->light_distribution);
}
else {
+ dscene->light_distribution.clear();
+
kintegrator->num_distribution = 0;
+ kintegrator->num_all_lights = 0;
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
- kintegrator->num_all_lights = 0;
-
- dscene->light_distribution.clear();
}
}
{
from = from_;
to = to_;
+ special_type = SHADER_SPECIAL_TYPE_PROXY;
add_input("Input", from);
add_output("Output", to);
add_output("Index", SHADER_SOCKET_FLOAT);
add_output("Age", SHADER_SOCKET_FLOAT);
add_output("Lifetime", SHADER_SOCKET_FLOAT);
+ add_output("Location", SHADER_SOCKET_POINT);
+ #if 0 /* not yet supported */
+ add_output("Rotation", SHADER_SOCKET_QUATERNION);
+ #endif
+ add_output("Size", SHADER_SOCKET_FLOAT);
+ add_output("Velocity", SHADER_SOCKET_VECTOR);
+ add_output("Angular Velocity", SHADER_SOCKET_VECTOR);
}
void ParticleInfoNode::attributes(AttributeRequestSet *attributes)
attributes->add(ATTR_STD_PARTICLE);
if(!output("Lifetime")->links.empty())
attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Location")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ #if 0 /* not yet supported */
+ if(!output("Rotation")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ #endif
+ if(!output("Size")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Angular Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
ShaderNode::attributes(attributes);
}
compiler.stack_assign(out);
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, out->stack_offset);
}
+
+ out = output("Location");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, out->stack_offset);
+ }
+
+ #if 0 /* XXX Quaternion data is not yet supported by Cycles */
+ out = output("Rotation");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, out->stack_offset);
+ }
+ #endif
+
+ out = output("Size");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, out->stack_offset);
+ }
+
+ out = output("Velocity");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, out->stack_offset);
+ }
+
+ out = output("Angular Velocity");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, out->stack_offset);
+ }
}
void ParticleInfoNode::compile(OSLCompiler& compiler)
MixClosureNode::MixClosureNode()
: ShaderNode("mix_closure")
{
+ special_type = SHADER_SPECIAL_TYPE_MIX_CLOSURE;
+
add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
add_input("Closure1", SHADER_SOCKET_CLOSURE);
add_input("Closure2", SHADER_SOCKET_CLOSURE);
{
type = ustring("Mix");
+ use_clamp = false;
+
add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f);
add_input("Color1", SHADER_SOCKET_COLOR);
add_input("Color2", SHADER_SOCKET_COLOR);
compiler.add_node(NODE_MIX, fac_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset);
compiler.add_node(NODE_MIX, type_enum[type], color_out->stack_offset);
+
+ if(use_clamp) {
+ compiler.add_node(NODE_MIX, 0, color_out->stack_offset);
+ compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, color_out->stack_offset);
+ }
}
void MixNode::compile(OSLCompiler& compiler)
{
compiler.parameter("type", type);
+ compiler.parameter("Clamp", use_clamp);
compiler.add(this, "node_mix");
}
void LayerWeightNode::compile(OSLCompiler& compiler)
{
- compiler.add(this, "node_layer_height");
+ compiler.add(this, "node_blend_weight");
}
/* Output */
{
type = ustring("Add");
+ use_clamp = false;
+
add_input("Value1", SHADER_SOCKET_FLOAT);
add_input("Value2", SHADER_SOCKET_FLOAT);
add_output("Value", SHADER_SOCKET_FLOAT);
compiler.add_node(NODE_MATH, type_enum[type], value1_in->stack_offset, value2_in->stack_offset);
compiler.add_node(NODE_MATH, value_out->stack_offset);
+
+ if(use_clamp) {
+ compiler.add_node(NODE_MATH, NODE_MATH_CLAMP, value_out->stack_offset);
+ compiler.add_node(NODE_MATH, value_out->stack_offset);
+ }
}
void MathNode::compile(OSLCompiler& compiler)
{
compiler.parameter("type", type);
+ compiler.parameter("Clamp", use_clamp);
compiler.add(this, "node_math");
}
public:
SHADER_NODE_CLASS(MixNode)
+ bool use_clamp;
+
ustring type;
static ShaderEnum type_enum;
};
public:
SHADER_NODE_CLASS(MathNode)
+ bool use_clamp;
+
ustring type;
static ShaderEnum type_enum;
};
device->tex_alloc("__object_flag", dscene->object_flag);
}
-void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
-{
- /* count particles.
- * adds one dummy particle at the beginning to avoid invalid lookups,
- * in case a shader uses particle info without actual particle data.
- */
- int num_particles = 1;
- foreach(Object *ob, scene->objects)
- num_particles += ob->particles.size();
-
- float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles);
-
- /* dummy particle */
- particles[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-
- int i = 1;
- foreach(Object *ob, scene->objects) {
- foreach(Particle &pa, ob->particles) {
- /* pack in texture */
- int offset = i*PARTICLE_SIZE;
-
- particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f);
-
- i++;
-
- if(progress.get_cancel()) return;
- }
- }
-
- device->tex_alloc("__particles", dscene->particles);
-}
-
void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
if(!need_update)
if(progress.get_cancel()) return;
- progress.set_status("Updating Objects", "Copying Particles to device");
- device_update_particles(device, dscene, scene, progress);
-
- if(progress.get_cancel()) return;
-
need_update = false;
}
device->tex_free(dscene->object_flag);
dscene->object_flag.clear();
-
- device->tex_free(dscene->particles);
- dscene->particles.clear();
}
void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
/* Object */
-struct Particle {
- int index;
- float age;
- float lifetime;
-};
-
class Object {
public:
Mesh *mesh;
bool use_holdout;
int particle_id;
- vector<Particle> particles;
Object();
~Object();
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
/* setup shader engine */
og->ss = ss;
+ og->services = services;
int background_id = scene->shader_manager->get_shader_id(scene->default_background);
- og->background_state = og->surface_state[background_id];
+ og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true;
tls_create(OSLGlobals::ThreadData, og->thread_data);
--- /dev/null
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "device.h"
+#include "particles.h"
+#include "scene.h"
+
+#include "util_foreach.h"
+#include "util_map.h"
+#include "util_progress.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Particle System */
+
+ParticleSystem::ParticleSystem()
+{
+}
+
+ParticleSystem::~ParticleSystem()
+{
+}
+
+void ParticleSystem::tag_update(Scene *scene)
+{
+ scene->particle_system_manager->need_update = true;
+}
+
+/* Particle System Manager */
+
+ParticleSystemManager::ParticleSystemManager()
+{
+ need_update = true;
+}
+
+ParticleSystemManager::~ParticleSystemManager()
+{
+}
+
+void ParticleSystemManager::device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ /* count particles.
+ * adds one dummy particle at the beginning to avoid invalid lookups,
+ * in case a shader uses particle info without actual particle data.
+ */
+ int num_particles = 1;
+ foreach(ParticleSystem *psys, scene->particle_systems)
+ num_particles += psys->particles.size();
+
+ float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles);
+
+ /* dummy particle */
+ particles[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ particles[1] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ particles[2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ particles[3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ particles[4] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ int i = 1;
+ foreach(ParticleSystem *psys, scene->particle_systems) {
+ foreach(Particle &pa, psys->particles) {
+ /* pack in texture */
+ int offset = i*PARTICLE_SIZE;
+
+ particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size);
+ particles[offset+1] = pa.rotation;
+ particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x);
+ particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y);
+ particles[offset+4] = make_float4(pa.angular_velocity.z, 0.0f, 0.0f, 0.0f);
+
+ i++;
+
+ if(progress.get_cancel()) return;
+ }
+ }
+
+ device->tex_alloc("__particles", dscene->particles);
+}
+
+void ParticleSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ if(!need_update)
+ return;
+
+ device_free(device, dscene);
+
+ progress.set_status("Updating Particle Systems", "Copying Particles to device");
+ device_update_particles(device, dscene, scene, progress);
+
+ if(progress.get_cancel()) return;
+
+ need_update = false;
+}
+
+void ParticleSystemManager::device_free(Device *device, DeviceScene *dscene)
+{
+ device->tex_free(dscene->particles);
+ dscene->particles.clear();
+}
+
+void ParticleSystemManager::tag_update(Scene *scene)
+{
+ need_update = true;
+}
+
+CCL_NAMESPACE_END
+
--- /dev/null
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __PARTICLES_H__
+#define __PARTICLES_H__
+
+#include "util_types.h"
+#include "util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+class Device;
+class DeviceScene;
+class Progress;
+class Scene;
+
+/* Particle System */
+
+struct Particle {
+ int index;
+ float age;
+ float lifetime;
+ float3 location;
+ float4 rotation;
+ float size;
+ float3 velocity;
+ float3 angular_velocity;
+};
+
+class ParticleSystem {
+public:
+ ParticleSystem();
+ ~ParticleSystem();
+
+ void tag_update(Scene *scene);
+
+ vector<Particle> particles;
+};
+
+/* ParticleSystem Manager */
+
+class ParticleSystemManager {
+public:
+ bool need_update;
+
+ ParticleSystemManager();
+ ~ParticleSystemManager();
+
+ void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_free(Device *device, DeviceScene *dscene);
+
+ void tag_update(Scene *scene);
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __PARTICLES_H__ */
+
#include "shader.h"
#include "mesh.h"
#include "object.h"
+#include "particles.h"
#include "scene.h"
#include "svm.h"
#include "osl.h"
integrator = new Integrator();
image_manager = new ImageManager();
shader_manager = ShaderManager::create(this);
+ particle_system_manager = new ParticleSystemManager();
if (device_info_.type == DEVICE_CPU)
image_manager->set_extended_image_limits();
delete o;
foreach(Light *l, lights)
delete l;
+ foreach(ParticleSystem *p, particle_systems)
+ delete p;
if(device) image_manager->device_free(device, &dscene);
delete image_manager;
+
+ if(device) particle_system_manager->device_free(device, &dscene);
+ delete particle_system_manager;
}
void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
+ progress.set_status("Updating Particle Systems");
+ particle_system_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel()) return;
+
progress.set_status("Updating Filter");
filter->device_update(device, &dscene);
|| light_manager->need_update
|| filter->need_update
|| integrator->need_update
- || shader_manager->need_update);
+ || shader_manager->need_update
+ || particle_system_manager->need_update);
}
CCL_NAMESPACE_END
class MeshManager;
class Object;
class ObjectManager;
+class ParticleSystemManager;
+class ParticleSystem;
class Shader;
class ShaderManager;
class Progress;
vector<Mesh*> meshes;
vector<Shader*> shaders;
vector<Light*> lights;
+ vector<ParticleSystem*> particle_systems;
/* data managers */
ImageManager *image_manager;
ShaderManager *shader_manager;
MeshManager *mesh_manager;
ObjectManager *object_manager;
+ ParticleSystemManager *particle_system_manager;
/* default shaders */
int default_surface;
m_cRef = 1;
m_hWnd = window->getHWND();
m_draggedObjectType = GHOST_kDragnDropTypeUnknown;
-
- // register our window as drop target
- ::RegisterDragDrop(m_hWnd, this);
}
GHOST_DropTargetWin32::~GHOST_DropTargetWin32()
{
- ::RevokeDragDrop(m_hWnd);
}
int r;
GetKeyboardState((PBYTE)state);
- if (r = ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) {
+ if ((r = ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout))) {
if ((r > 0 && r < 3)) {
utf16[r] = 0;
conv_utf_16_to_8(utf16, utf8_char, 6);
// Register this window as a droptarget. Requires m_hWnd to be valid.
// Note that OleInitialize(0) has to be called prior to this. Done in GHOST_SystemWin32.
m_dropTarget = new GHOST_DropTargetWin32(this, m_system);
+ if (m_dropTarget) {
+ ::RegisterDragDrop(m_hWnd, m_dropTarget);
+ }
+
// Store a pointer to this class in the window structure
::SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG_PTR) this);
m_hDC = 0;
}
if (m_hWnd) {
- m_dropTarget->Release(); // frees itself.
+ if (m_dropTarget) {
+ // Disable DragDrop
+ RevokeDragDrop(m_hWnd);
+ // Release our reference of the DropTarget and it will delete itself eventually.
+ m_dropTarget->Release();
+ }
+
::DestroyWindow(m_hWnd);
m_hWnd = 0;
}
#define FILE_MAP_EXECUTE 0x0020
#endif
-/* copied from BKE_utildefines.h ugh */
+/* copied from BLI_utildefines.h, ugh */
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
__NL_DELETE(context->variable[i].a);
}
}
+
+ __NL_DELETE_ARRAY(context->variable);
}
if(context->alloc_b) {
__NL_DELETE_ARRAY(context->b);
mat.raytrace_transparency.depth = 4
if self.start_baking:
- bpy.ops.fluid.bake()
+ bpy.ops.fluid.bake('INVOKE_DEFAULT')
return {'FINISHED'}
#include "DNA_vec_types.h"
-#include "BKE_utildefines.h"
-
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#ifndef NDEBUG
char *DM_debug_info(DerivedMesh *dm);
void DM_debug_print(DerivedMesh *dm);
+void DM_debug_print_cdlayers(CustomData *cdata);
#endif
#endif
void free_path(struct Path *path);
void calc_curvepath(struct Object *ob);
-int interval_test(int min, int max, int p1, int cycl);
int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight);
/* ---------------------------------------------------- */
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
* ***** END GPL LICENSE BLOCK *****
*/
extern "C" {
#endif
-/* these values need to be hardcoded in structs, dna does not recognize defines */
-/* also defined in DNA_space_types.h */
-#ifndef FILE_MAXDIR
-#define FILE_MAXDIR 768
-#define FILE_MAXFILE 256
-#define FILE_MAX 1024
-#endif
-
-/* this weirdo pops up in two places ... */
-#if !defined(WIN32)
-# ifndef O_BINARY
-# define O_BINARY 0
-# endif
-#endif
-
-/* INTEGER CODES */
-#ifdef __BIG_ENDIAN__
-/* Big Endian */
-# define MAKE_ID(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
-#else
-/* Little Endian */
-# define MAKE_ID(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) )
-#endif
-
-#define DATA MAKE_ID('D', 'A', 'T', 'A')
-#define GLOB MAKE_ID('G', 'L', 'O', 'B')
-
-#define DNA1 MAKE_ID('D', 'N', 'A', '1')
-#define TEST MAKE_ID('T', 'E', 'S', 'T') /* used as preview between 'REND' and 'GLOB' */
-#define REND MAKE_ID('R', 'E', 'N', 'D')
-#define USER MAKE_ID('U', 'S', 'E', 'R')
-
-#define ENDB MAKE_ID('E', 'N', 'D', 'B')
-
-/* Bit operations */
-#define BTST(a, b) ( ( (a) & 1 << (b) ) != 0)
-#define BNTST(a, b) ( ( (a) & 1 << (b) ) == 0)
-#define BTST2(a, b, c) (BTST( (a), (b) ) || BTST( (a), (c) ) )
-#define BSET(a, b) ( (a) | 1 << (b) )
-#define BCLR(a, b) ( (a) & ~(1 << (b)) )
-/* bit-row */
-#define BROW(min, max) (((max) >= 31 ? 0xFFFFFFFF : (1 << (max + 1)) - 1) - ((min) ? ((1 << (min)) - 1) : 0) )
+/* currently unused but we may want to add macros here for BKE later */
#ifdef __cplusplus
}
MEM_freeN(str);
}
+void DM_debug_print_cdlayers(CustomData *data)
+{
+ int i;
+ CustomDataLayer *layer;
+
+ printf("{\n");
+
+ for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
+
+ const char *name = CustomData_layertype_name(layer->type);
+ const int size = CustomData_sizeof(layer->type);
+ const char *structname;
+ int structnum;
+ CustomData_file_write_info(layer->type, &structname, &structnum);
+ printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
+ name, structname, layer->type, (void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size));
+ }
+
+ printf("}\n");
+}
+
#endif /* NDEBUG */
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
#include "BKE_depsgraph.h"
#include "BKE_anim.h"
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
- if (ob == NULL || ob->type != OB_CURVE) return;
+ if (ob == NULL || ob->type != OB_CURVE) {
+ return;
+ }
cu = ob->data;
- nurbs = BKE_curve_nurbs_get(cu);
- nu = nurbs->first;
-
if (cu->path) free_path(cu->path);
cu->path = NULL;
+ /* weak! can only use first curve */
bl = cu->bev.first;
- if (bl == NULL || !bl->nr) return;
+ if (bl == NULL || !bl->nr) {
+ return;
+ }
+
+ nurbs = BKE_curve_nurbs_get(cu);
+ nu = nurbs->first;
cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
/* if POLY: last vertice != first vertice */
cycl = (bl->poly != -1);
- if (cycl) tot = bl->nr;
- else tot = bl->nr - 1;
+ tot = cycl ? bl->nr : bl->nr - 1;
path->len = tot + 1;
/* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */
- if (path->len < nu->resolu * SEGMENTSU(nu)) path->len = nu->resolu * SEGMENTSU(nu);
+ if (path->len < nu->resolu * SEGMENTSU(nu)) {
+ path->len = nu->resolu * SEGMENTSU(nu);
+ }
dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist");
/* all lengths in *dist */
bevp = bevpfirst = (BevPoint *)(bl + 1);
fp = dist;
- *fp = 0;
+ *fp = 0.0f;
for (a = 0; a < tot; a++) {
fp++;
if (cycl && a == tot - 1)
fp++;
if (bevp < bevplast) bevp++;
bevpn = bevp + 1;
- if (bevpn > bevplast) {
- if (cycl) bevpn = bevpfirst;
- else bevpn = bevplast;
+ if (UNLIKELY(bevpn > bevplast)) {
+ bevpn = cycl ? bevpfirst : bevplast;
}
}
- fac1 = *(fp) - *(fp - 1);
- fac2 = *(fp) - d;
- fac1 = fac2 / fac1;
+ fac1 = (*(fp) - d) / (*(fp) - *(fp - 1));
fac2 = 1.0f - fac1;
-
+
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
- pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa;
+ pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa;
pp->radius = fac1 * bevp->radius + fac2 * bevpn->radius;
pp->weight = fac1 * bevp->weight + fac2 * bevpn->weight;
interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
MEM_freeN(dist);
}
-
-/* is this only used internally?*/
-int interval_test(int min, int max, int p1, int cycl)
+static int interval_test(const int min, const int max, int p1, const int cycl)
{
if (cycl) {
- if (p1 < min)
- p1 = ((p1 - min) % (max - min + 1)) + max + 1;
- else if (p1 > max)
- p1 = ((p1 - min) % (max - min + 1)) + min;
+ if (p1 < min) p1 = ((p1 - min) % (max - min + 1)) + max + 1;
+ else if (p1 > max) p1 = ((p1 - min) % (max - min + 1)) + min;
}
else {
- if (p1 < min) p1 = min;
+ if (p1 < min) p1 = min;
else if (p1 > max) p1 = max;
}
return p1;
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_report.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
}
/* Check RNA-Paths for a list of F-Curves */
-static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *curves, int verify_paths)
+static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+ const char *oldKey, const char *newKey, ListBase *curves, int verify_paths)
{
FCurve *fcu;
/* we need to check every curve... */
for (fcu = curves->first; fcu; fcu = fcu->next) {
- /* firstly, handle the F-Curve's own path */
- if (fcu->rna_path)
- fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path, verify_paths);
+ if (fcu->rna_path) {
+ char *old_path = fcu->rna_path;
+
+ /* firstly, handle the F-Curve's own path */
+ fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
+
+ /* if path changed and the F-Curve is grouped, check if its group also needs renaming
+ * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename)
+ */
+ if (fcu->rna_path != old_path) {
+ bActionGroup *agrp = fcu->grp;
+
+ if ((agrp) && strcmp(oldName, agrp->name)==0) {
+ BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
+ }
+ }
+ }
}
}
}
/* Fix all RNA-Paths for Actions linked to NLA Strips */
-static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *strips, int verify_paths)
+static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+ const char *oldKey, const char *newKey, ListBase *strips, int verify_paths)
{
NlaStrip *strip;
for (strip = strips->first; strip; strip = strip->next) {
/* fix strip's action */
if (strip->act)
- fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
/* ignore own F-Curves, since those are local... */
/* check sub-strips (if metas) */
- nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips, verify_paths);
+ nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
}
}
/* Active action and temp action */
if (adt->action)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths);
if (adt->tmpact)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths);
/* Drivers - Drivers are really F-Curves */
drivers_path_rename_fix(owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
/* NLA Data - Animation Data for Strips */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next)
- nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips, verify_paths);
+ nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
/* free the temp names */
MEM_freeN(oldN);
static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected)
{
bPose *pose = ob->pose, *frompose = from->pose;
- bPoseChannel *pchan, *pchanp, pchanw;
+ bPoseChannel *pchan, *pchanp;
bConstraint *con;
int error = 0;
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
pchanp = BKE_pose_channel_find_name(frompose, pchan->name);
-
+
if (UNLIKELY(pchanp == NULL)) {
/* happens for proxies that become invalid because of a missing link
* for regulat cases it shouldn't happen at all */
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
-
+ bPoseChannel pchanw = {NULL};
+
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
pchanw.prev = pchan->prev;
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
-
+
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
-
+
/* use the values from the the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
}
-
+
/* constraints - proxy constraints are flushed... local ones are added after
* 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
* 2. copy proxy-pchan's constraints on-to new
extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
-
+
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == from)
ct->tar = ob;
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
}
-
+
/* free stuff from current channel */
BKE_pose_channel_free(pchan);
-
- /* the final copy */
+
+ /* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
}
else {
#include "BKE_sound.h"
#include "RE_pipeline.h"
-
#include "BLO_undofile.h"
#include "BLO_readfile.h"
#include "BLO_writefile.h"
-#include "BKE_utildefines.h"
-
#include "RNA_access.h"
#include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_paint.h"
-#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
#include "BKE_curve.h"
* since we've got the actual ID block, let's just inline this
* code.
*
- * See ID_NEW(a) in BKE_utildefines.h
+ * See ID_NEW(a) in DNA_ID.h
*/
if ((*idpoin) && (*idpoin)->newid)
(*idpoin) = (void *)(*idpoin)->newid;
#include "BLI_mempool.h"
#include "BLI_utildefines.h"
-#include "BKE_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_customdata_file.h"
#include "BKE_global.h"
#include "BLI_fileops.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
#include "BKE_customdata_file.h"
#include "BKE_global.h"
header->endian = cdf_endian();
if (cdf->switchendian) {
- SWITCH_INT(header->type);
- SWITCH_INT(header->totlayer);
- SWITCH_INT(header->structbytes);
+ BLI_endian_switch_int32(&header->type);
+ BLI_endian_switch_int32(&header->totlayer);
+ BLI_endian_switch_int32(&header->structbytes);
}
if (!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH))
return 0;
if (cdf->switchendian) {
- SWITCH_INT(image->width);
- SWITCH_INT(image->height);
- SWITCH_INT(image->tile_size);
- SWITCH_INT(image->structbytes);
+ BLI_endian_switch_int32(&image->width);
+ BLI_endian_switch_int32(&image->height);
+ BLI_endian_switch_int32(&image->tile_size);
+ BLI_endian_switch_int32(&image->structbytes);
}
offset += image->structbytes;
return 0;
if (cdf->switchendian)
- SWITCH_INT(mesh->structbytes);
+ BLI_endian_switch_int32(&mesh->structbytes);
offset += mesh->structbytes;
mesh->structbytes = sizeof(CDataFileMeshHeader);
return 0;
if (cdf->switchendian) {
- SWITCH_INT(layer->type);
- SWITCH_INT(layer->datatype);
- SWITCH_INT64(layer->datasize);
- SWITCH_INT(layer->structbytes);
+ BLI_endian_switch_int32(&layer->type);
+ BLI_endian_switch_int32(&layer->datatype);
+ BLI_endian_switch_uint64(&layer->datasize);
+ BLI_endian_switch_int32(&layer->structbytes);
}
if (layer->datatype != CDF_DATA_FLOAT)
int cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
{
- float *fdata;
- unsigned int a;
-
/* read data */
if (!fread(data, size, 1, cdf->readf))
return 0;
/* switch endian if necessary */
if (cdf->switchendian) {
- fdata = data;
-
- for (a = 0; a < size / sizeof(float); a++) {
- SWITCH_INT(fdata[a]);
- }
+ BLI_endian_switch_float_array(data, size / sizeof(float));
}
return 1;
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
-#include "BKE_utildefines.h"
#include "depsgraph_private.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "BKE_utildefines.h"
#include "BKE_packedFile.h"
#include "BKE_library.h"
#include "BKE_font.h"
return newp;
}
-/*taken from readfile.c*/
-#define SWITCH_LONGINT(a) { \
- char s_i, *p_i; \
- p_i = (char *)& (a); \
- s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; \
- s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; \
- s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; \
- s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; \
- } (void)0
-
-
-
/* ---------- String Type ------------ */
IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
{
#include "BKE_scene.h"
#include "BKE_node.h"
#include "BKE_sequencer.h" /* seq_foreground_frame_get() */
-#include "BKE_utildefines.h"
#include "BLF_api.h"
#include "BKE_gpencil.h"
#include "BKE_fcurve.h"
#include "BKE_speaker.h"
-#include "BKE_utildefines.h"
#include "BKE_movieclip.h"
#include "BKE_mask.h"
#include "BKE_sequencer.h"
#include "BKE_tracking.h"
#include "BKE_movieclip.h"
-#include "BKE_utildefines.h"
unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
/* Forward declarations */
static int vertid(const CORNER *c1, const CORNER *c2, PROCESS *p, MetaBall *mb);
-static int setcenter(CENTERLIST *table[], int i, int j, int k);
+static int setcenter(CENTERLIST *table[], const int i, const int j, const int k);
static CORNER *setcorner(PROCESS *p, int i, int j, int k);
static void converge(const float p1[3], const float p2[3], float v1, float v2,
float (*function)(float, float, float), float p[3], MetaBall *mb, int f);
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_utildefines.h"
#include "BKE_movieclip.h"
#include "BKE_image.h" /* openanim */
#include "BKE_tracking.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_utildefines.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "BKE_image.h"
#include "BKE_ocean.h"
-#include "BKE_utildefines.h"
-
#include "BKE_global.h" // XXX TESTING
#include "BLI_math_base.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_sound.h"
-#include "BKE_utildefines.h"
#ifdef _WIN32
#define open _open
#include "BKE_scene.h"
#include "BKE_smoke.h"
#include "BKE_softbody.h"
-#include "BKE_utildefines.h"
#include "BIK_api.h"
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_texture.h"
-#include "BKE_utildefines.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "BKE_colortools.h"
#include "BKE_sequencer.h"
-#include "BKE_utildefines.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "BKE_fcurve.h"
#include "BKE_scene.h"
#include "BKE_mask.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
# include "AUD_C-API.h"
#endif
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
#include "IMB_imbuf.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_ocean.h"
track = next_track;
}
+
+ tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL;
}
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
--- /dev/null
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_ENDIAN_SWITCH_H__
+#define __BLI_ENDIAN_SWITCH_H__
+
+/** \file BLI_endian_switch.h
+ * \ingroup bli
+ */
+
+#include "BLI_endian_switch_inline.h"
+
+/* endian_switch.c */
+void BLI_endian_switch_int16_array(short *val, const int size);
+void BLI_endian_switch_uint16_array(unsigned short *val, const int size);
+void BLI_endian_switch_int32_array(int *val, const int size);
+void BLI_endian_switch_uint32_array(unsigned int *val, const int size);
+void BLI_endian_switch_float_array(float *val, const int size);
+void BLI_endian_switch_int64_array(int64_t *val, const int size);
+void BLI_endian_switch_uint64_array(uint64_t *val, const int size);
+void BLI_endian_switch_double_array(double *val, const int size);
+
+#endif /* __BLI_ENDIAN_SWITCH_H__ */
--- /dev/null
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* only include from header */
+#ifndef __BLI_ENDIAN_SWITCH_H__
+# error "this file isnt to be directly included"
+#endif
+
+#ifndef __BLI_ENDIAN_SWITCH_INLINE_H__
+#define __BLI_ENDIAN_SWITCH_INLINE_H__
+
+/** \file blender/blenlib/BLI_endian_switch_inline.h
+ * \ingroup bli
+ */
+
+
+BLI_INLINE void BLI_endian_switch_int16(short *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0];
+ p_i[0] = p_i[1];
+ p_i[1] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0];
+ p_i[0] = p_i[1];
+ p_i[1] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_int32(int *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_float(float *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_int64(int64_t *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i;
+ s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i;
+ s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i;
+ s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i;
+ s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i;
+}
+
+BLI_INLINE void BLI_endian_switch_double(double *val)
+{
+ char *p_i = (char *)val;
+ char s_i;
+
+ s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i;
+ s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i;
+ s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i;
+ s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i;
+}
+
+#endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */
struct LinkNode *BLI_file_read_as_lines(const char *file);
void BLI_file_free_lines(struct LinkNode *lines);
+/* this weirdo pops up in two places ... */
+#if !defined(WIN32)
+# ifndef O_BINARY
+# define O_BINARY 0
+# endif
+#endif
+
#ifdef __cplusplus
}
#endif
void BLI_string_to_utf8(char *original, char *utf_8, const char *code);
#endif
+/* these values need to be hardcoded in structs, dna does not recognize defines */
+/* also defined in DNA_space_types.h */
+#ifndef FILE_MAXDIR
+# define FILE_MAXDIR 768
+# define FILE_MAXFILE 256
+# define FILE_MAX 1024
+#endif
+
#ifdef __cplusplus
}
#endif
(item <= ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot)) \
)
-/* This one rotates the bytes in an int64, int (32) and short (16) */
-#define SWITCH_INT64(a) { \
- char s_i, *p_i; \
- p_i = (char *)&(a); \
- s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; \
- s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; \
- s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; \
- s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; \
- } (void)0
-
-#define SWITCH_INT(a) { \
- char s_i, *p_i; \
- p_i = (char *)&(a); \
- s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; \
- s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; \
- } (void)0
-
-#define SWITCH_SHORT(a) { \
- char s_i, *p_i; \
- p_i = (char *)&(a); \
- s_i = p_i[0]; p_i[0] = p_i[1]; p_i[1] = s_i; \
- } (void)0
-
-
/* Warning-free macros for storing ints in pointers. Use these _only_
* for storing an int in a pointer, not a pointer in an int (64bit)! */
#define SET_INT_IN_POINTER(i) ((void *)(intptr_t)(i))
intern/cpu.c
intern/dynlib.c
intern/edgehash.c
+ intern/endian_switch.c
intern/fileops.c
intern/fnmatch.c
intern/freetypefont.c
BLI_dynlib.h
BLI_dynstr.h
BLI_edgehash.h
+ BLI_endian_switch.h
+ BLI_endian_switch_inline.h
BLI_fileops.h
BLI_fileops_types.h
BLI_fnmatch.h
LinkNode *bufs;
};
-MemArena *BLI_memarena_new(int bufsize, const char *name)
+MemArena *BLI_memarena_new(const int bufsize, const char *name)
{
MemArena *ma = MEM_callocN(sizeof(*ma), "memarena");
ma->bufsize = bufsize;
ma->use_calloc = 0;
}
-void BLI_memarena_use_align(struct MemArena *ma, int align)
+void BLI_memarena_use_align(struct MemArena *ma, const int align)
{
/* align should be a power of two */
ma->align = align;
#include <string.h>
#include <stdlib.h>
-/* note: copied from BKE_utildefines.h, don't use here because we're in BLI */
+/* note: copied from BLO_blend_defs.h, don't use here because we're in BLI */
#ifdef __BIG_ENDIAN__
/* Big Endian */
# define MAKE_ID(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_sequencer.h"
-#include "BKE_utildefines.h"
#include "BKE_image.h" /* so we can check the image's type */
static int checkMissingFiles_visit_cb(void *userdata, char *UNUSED(path_dst), const char *path_src)
--- /dev/null
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenlib/intern/endian_switch.c
+ * \ingroup bli
+ */
+
+#include "BLO_sys_types.h"
+#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
+
+void BLI_endian_switch_int16_array(short *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_int16(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_uint16_array(unsigned short *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_uint16(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_int32_array(int *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_int32(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_uint32_array(unsigned int *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_uint32(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_float_array(float *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_float(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_int64_array(int64_t *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_int64(val--);
+ }
+ }
+}
+
+void BLI_endian_switch_uint64_array(uint64_t *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_uint64(val--);
+ }
+ }
+}
+
+
+void BLI_endian_switch_double_array(double *val, const int size)
+{
+ if (size > 0) {
+ int i = size;
+ val = val + (size - 1);
+ while (i--) {
+ BLI_endian_switch_double(val--);
+ }
+ }
+}
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BKE_utildefines.h"
-
#include "BLO_sys_types.h" // for intptr_t support
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
-#include "BKE_utildefines.h"
#include "BKE_blender.h" // BLENDER_VERSION
#include "GHOST_Path-api.h"
#include "BLI_listbase.h"
#include "BLI_linklist.h"
-#include "BLI_fileops.h"
-
-#include "BLI_fileops_types.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
-
-#include "BKE_utildefines.h"
+#include "BLI_fileops_types.h"
+#include "BLI_path_util.h"
/* vars: */
static int totnum, actnum;
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
#include "BLI_winstuff.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "utf_winfunc.h"
#include "utfconv.h"
--- /dev/null
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BLO_BLEND_DEFS_H__
+#define __BLO_BLEND_DEFS_H__
+
+/** \file BLO_blend_defs.h
+ * \ingroup blenloader
+ * \brief defines for blendfile codes
+ */
+
+/* INTEGER CODES */
+#ifdef __BIG_ENDIAN__
+/* Big Endian */
+# define BLEND_MAKE_ID(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
+#else
+/* Little Endian */
+# define BLEND_MAKE_ID(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) )
+#endif
+
+#define DATA BLEND_MAKE_ID('D', 'A', 'T', 'A')
+#define GLOB BLEND_MAKE_ID('G', 'L', 'O', 'B')
+
+#define DNA1 BLEND_MAKE_ID('D', 'N', 'A', '1')
+#define TEST BLEND_MAKE_ID('T', 'E', 'S', 'T') /* used as preview between 'REND' and 'GLOB' */
+#define REND BLEND_MAKE_ID('R', 'E', 'N', 'D')
+#define USER BLEND_MAKE_ID('U', 'S', 'E', 'R')
+
+#define ENDB BLEND_MAKE_ID('E', 'N', 'D', 'B')
+
+#endif /* __BLO_BLEND_DEFS_H__ */
intern/versioning_legacy.c
intern/writefile.c
+ BLO_blend_defs.h
BLO_readfile.h
BLO_runtime.h
BLO_soundfile.h
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "DNA_genfile.h"
#include "DNA_sdna_types.h"
#include "BKE_library.h" // for free_main
#include "BKE_idcode.h"
#include "BKE_report.h"
-#include "BKE_utildefines.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
+#include "BLO_blend_defs.h"
#include "readfile.h"
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_edgehash.h"
#include "BKE_sequencer.h"
#include "BKE_text.h" // for txt_extended_ascii_as_utf8
#include "BKE_tracking.h"
-#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
#include "BKE_sound.h"
#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
#include "BLO_readfile.h"
#include "BLO_undofile.h"
+#include "BLO_blend_defs.h"
#include "RE_engine.h"
/* from misc_util: flip the bytes from x */
/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-// only used here in readfile.c
-#define SWITCH_LONGINT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
- s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
- s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
- s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; \
-} (void)0
-
/***/
typedef struct OldNew {
if ((bhead->code & 0xFFFF)==0) bhead->code >>= 16;
if (bhead->code != ENDB) {
- SWITCH_INT(bhead->len);
- SWITCH_INT(bhead->SDNAnr);
- SWITCH_INT(bhead->nr);
+ BLI_endian_switch_int32(&bhead->len);
+ BLI_endian_switch_int32(&bhead->SDNAnr);
+ BLI_endian_switch_int32(&bhead->nr);
}
}
if ((bhead->code & 0xFFFF)==0) bhead->code >>= 16;
if (bhead->code != ENDB) {
- SWITCH_INT(bhead->len);
- SWITCH_INT(bhead->SDNAnr);
- SWITCH_INT(bhead->nr);
+ BLI_endian_switch_int32(&bhead->len);
+ BLI_endian_switch_int32(&bhead->SDNAnr);
+ BLI_endian_switch_int32(&bhead->nr);
}
}
* 0x0000000000000000000012345678 would become 0x12345678000000000000000000000000
*/
if (do_endian_swap) {
- SWITCH_LONGINT(bhead8->old);
+ BLI_endian_switch_int64(&bhead8->old);
}
/* this patch is to avoid a long long being read from not-eight aligned positions
static void test_pointer_array(FileData *fd, void **mat)
{
-#if defined(WIN32) && !defined(FREE_WINDOWS)
- __int64 *lpoin, *lmat;
-#else
- long long *lpoin, *lmat;
-#endif
+ int64_t *lpoin, *lmat;
int *ipoin, *imat;
size_t len;
while (len-- > 0) {
if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN))
- SWITCH_LONGINT(*lpoin);
+ BLI_endian_switch_int64(lpoin);
*ipoin = (int)((*lpoin) >> 3);
ipoin++;
lpoin++;
}
else if (prop->subtype == IDP_DOUBLE) {
if (switch_endian) {
- for (i = 0; i < prop->len; i++) {
- SWITCH_LONGINT(((double *)prop->data.pointer)[i]);
- }
+ BLI_endian_switch_double_array(prop->data.pointer, prop->len);
}
}
else {
if (switch_endian) {
- for (i = 0; i < prop->len; i++) {
- SWITCH_INT(((int *)prop->data.pointer)[i]);
- }
+ /* also used for floats */
+ BLI_endian_switch_int32_array(prop->data.pointer, prop->len);
}
}
}
*/
if (switch_endian) {
- SWITCH_INT(prop->data.val);
- SWITCH_INT(prop->data.val2);
- SWITCH_LONGINT(prop->data.val);
+ BLI_endian_switch_int32(&prop->data.val);
+ BLI_endian_switch_int32(&prop->data.val2);
+ BLI_endian_switch_int64((int64_t *)&prop->data.val);
}
break;
data->coefficients = newdataadr(fd, data->coefficients);
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- unsigned int a;
- for (a = 0; a < data->arraysize; a++)
- SWITCH_INT(data->coefficients[a]);
+ BLI_endian_switch_float_array(data->coefficients, data->arraysize);
}
}
break;
case IPO_BPOINT:
case IPO_BEZTRIPLE:
b = cp[0];
-
- while (b--) {
- SWITCH_INT((*poin));
- poin += 4;
- }
+ BLI_endian_switch_float_array((float *)poin, b);
+ poin += sizeof(float) * b;
break;
}
static void switch_endian_knots(Nurb *nu)
{
- int len;
-
if (nu->knotsu) {
- len = KNOTSU(nu);
- while (len--) {
- SWITCH_INT(nu->knotsu[len]);
- }
+ BLI_endian_switch_float_array(nu->knotsu, KNOTSU(nu));
}
if (nu->knotsv) {
- len = KNOTSV(nu);
- while (len--) {
- SWITCH_INT(nu->knotsv[len]);
- }
+ BLI_endian_switch_float_array(nu->knotsv, KNOTSV(nu));
}
}
/* the cache saves non-struct data without DNA */
if (pm->data[i] && ptcache_data_struct[i][0]=='\0' && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
- int j, tot = (BKE_ptcache_data_size (i) * pm->totpoint)/4; /* data_size returns bytes */
+ int tot = (BKE_ptcache_data_size (i) * pm->totpoint) / sizeof(int); /* data_size returns bytes */
int *poin = pm->data[i];
- for (j = 0; j < tot; j++)
- SWITCH_INT(poin[j]);
+ BLI_endian_switch_int32_array(poin, tot);
}
}
if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN) && (mdisps[i].disps)) {
/* DNA_struct_switch_endian doesn't do endian swap for (*disps)[] */
/* this does swap for data written at write_mdisps() - readfile.c */
- int x;
- float *tmpdisps = *mdisps[i].disps;
- for (x = 0; x < mdisps[i].totdisp * 3; x++) {
- SWITCH_INT(*tmpdisps);
- tmpdisps++;
- }
+ BLI_endian_switch_float_array(*mdisps[i].disps, mdisps[i].totdisp * 3);
}
if (!external && !mdisps[i].disps)
mdisps[i].totdisp = 0;
TFace *tf = mesh->tface;
int i;
- for (i = 0; i < (mesh->totface); i++, tf++) {
- SWITCH_INT(tf->col[0]);
- SWITCH_INT(tf->col[1]);
- SWITCH_INT(tf->col[2]);
- SWITCH_INT(tf->col[3]);
+ for (i = 0; i < mesh->totface; i++, tf++) {
+ BLI_endian_switch_uint32_array(tf->col, 4);
}
}
}
hmd->indexar = newdataadr(fd, hmd->indexar);
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- int a;
- for (a = 0; a < hmd->totindex; a++) {
- SWITCH_INT(hmd->indexar[a]);
- }
+ BLI_endian_switch_int32_array(hmd->indexar, hmd->totindex);
}
}
else if (md->type == eModifierType_ParticleSystem) {
mmd->bindcos = newdataadr(fd, mmd->bindcos);
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- int a;
-
- if (mmd->bindoffsets)
- for (a=0; a<mmd->totvert+1; a++)
- SWITCH_INT(mmd->bindoffsets[a]);
- if (mmd->bindcagecos)
- for (a=0; a<mmd->totcagevert*3; a++)
- SWITCH_INT(mmd->bindcagecos[a]);
- if (mmd->dynverts)
- for (a=0; a<mmd->totvert; a++)
- SWITCH_INT(mmd->dynverts[a]);
-
- if (mmd->bindweights)
- for (a=0; a<mmd->totcagevert*mmd->totvert; a++)
- SWITCH_INT(mmd->bindweights[a]);
- if (mmd->bindcos)
- for (a=0; a<mmd->totcagevert*3; a++)
- SWITCH_INT(mmd->bindcos[a]);
+ if (mmd->bindoffsets) BLI_endian_switch_int32_array(mmd->bindoffsets, mmd->totvert + 1);
+ if (mmd->bindcagecos) BLI_endian_switch_float_array(mmd->bindcagecos, mmd->totcagevert * 3);
+ if (mmd->dynverts) BLI_endian_switch_int32_array(mmd->dynverts, mmd->totvert);
+ if (mmd->bindweights) BLI_endian_switch_float_array(mmd->bindweights, mmd->totvert);
+ if (mmd->bindcos) BLI_endian_switch_float_array(mmd->bindcos, mmd->totcagevert * 3);
}
}
else if (md->type == eModifierType_Ocean) {
hook->indexar= newdataadr(fd, hook->indexar);
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
- int a;
- for (a = 0; a < hook->totindex; a++) {
- SWITCH_INT(hook->indexar[a]);
- }
+ BLI_endian_switch_int32_array(hook->indexar, hook->totindex);
}
/* Do conversion here because if we have loaded
if (node->storage == NULL) {
NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__);
/* move settings into own struct */
- data->size_x = node->custom3;
- data->size_y = node->custom4;
+ data->size_x = (int)node->custom3;
+ data->size_y = (int)node->custom4;
node->custom3 = 0.5f; /* default shutter */
node->storage = data;
}
#include "BKE_blender.h"
#include "BKE_report.h"
-#include "BKE_utildefines.h"
#include "BLI_blenlib.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BKE_texture.h"
-#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
#include "BKE_sound.h"
#include "NOD_socket.h"
#include "BKE_property.h" // for get_ob_property
#include "BKE_scene.h"
#include "BKE_sequencer.h"
-#include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND
#include "IMB_imbuf.h" // for proxy / timecode versioning stuff
#include "BKE_report.h"
#include "BKE_sequencer.h"
#include "BKE_subsurf.h"
-#include "BKE_utildefines.h"
#include "BKE_modifier.h"
#include "BKE_fcurve.h"
#include "BKE_pointcache.h"
#include "BLO_writefile.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
+#include "BLO_blend_defs.h"
#include "readfile.h"
bm->act_face = efa;
}
-BMFace *BM_active_face_get(BMesh *bm, int sloppy)
+BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected)
{
- if (bm->act_face) {
+ if (bm->act_face && (!selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) {
return bm->act_face;
}
else if (sloppy) {
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
f = NULL;
}
+ else if (selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ f = NULL;
+ }
&nbs