16 #include "util/color.h"
35 float radius = 1.0f -
time;
39 radius =
powf(radius, 1.0f + shape);
41 radius =
powf(radius, 1.0f / (1.0f - shape));
43 return (radius * (root - tip)) + tip;
54 if (!(hair && b_mesh && b_ob && CData))
60 for (BL::Modifier &b_mod : b_ob->modifiers) {
61 if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
62 (background ? b_mod.show_render() : b_mod.show_viewport())) {
63 BL::ParticleSystemModifier psmd((
const PointerRNA)b_mod.ptr);
67 if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
68 (b_part.type() == BL::ParticleSettings::type_HAIR)) {
69 int shader =
clamp(b_part.material() - 1, 0, hair->get_used_shaders().size() - 1);
70 int display_step = background ? b_part.render_step() : b_part.display_step();
71 int totparts = b_psys.particles.length();
72 int totchild = background ? b_psys.child_particles.length() :
73 (int)((
float)b_psys.child_particles.length() *
74 (
float)b_part.display_percentage() / 100.0f);
75 int totcurves = totchild;
77 if (b_part.child_type() == 0 || totchild == 0)
78 totcurves += totparts;
83 int ren_step = (1 << display_step) + 1;
84 if (b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
85 ren_step += b_part.kink_extra_steps();
91 float radius = b_part.radius_scale() * 0.5f;
99 if (!(b_part.child_type() == 0) && totchild != 0)
102 int num_add = (totparts + totchild - pa_no);
109 for (; pa_no < totparts + totchild; pa_no++) {
113 float curve_length = 0.0f;
116 for (
int step_no = 0; step_no < ren_step; step_no++) {
117 float3 co_world = prev_co_world;
118 b_psys.co_hair(*b_ob, pa_no, step_no, &co_world.
x);
121 const float step_length =
len(co_object - prev_co_object);
122 curve_length += step_length;
126 prev_co_object = co_object;
127 prev_co_world = co_world;
150 if (!(hair && b_mesh && b_ob && CData))
155 for (BL::Modifier &b_mod : b_ob->modifiers) {
156 if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
157 (background ? b_mod.show_render() : b_mod.show_viewport())) {
158 BL::ParticleSystemModifier psmd((
const PointerRNA)b_mod.ptr);
162 if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
163 (b_part.type() == BL::ParticleSettings::type_HAIR)) {
164 int totparts = b_psys.particles.length();
165 int totchild = background ? b_psys.child_particles.length() :
166 (int)((
float)b_psys.child_particles.length() *
167 (
float)b_part.display_percentage() / 100.0f);
168 int totcurves = totchild;
170 if (b_part.child_type() == 0 || totchild == 0)
171 totcurves += totparts;
177 if (!(b_part.child_type() == 0) && totchild != 0)
180 int num_add = (totparts + totchild - pa_no);
183 BL::ParticleSystem::particles_iterator b_pa;
184 b_psys.particles.begin(b_pa);
185 for (; pa_no < totparts + totchild; pa_no++) {
187 BL::Mesh::uv_layers_iterator
l;
188 b_mesh->uv_layers.begin(
l);
191 if (!b_mesh->uv_layers.empty())
192 b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.
x);
195 if (pa_no < totparts && b_pa != b_psys.particles.end())
212 if (!(hair && b_mesh && b_ob && CData))
217 for (BL::Modifier &b_mod : b_ob->modifiers) {
218 if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
219 (background ? b_mod.show_render() : b_mod.show_viewport())) {
220 BL::ParticleSystemModifier psmd((
const PointerRNA)b_mod.ptr);
224 if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
225 (b_part.type() == BL::ParticleSettings::type_HAIR)) {
226 int totparts = b_psys.particles.length();
227 int totchild = background ? b_psys.child_particles.length() :
228 (int)((
float)b_psys.child_particles.length() *
229 (
float)b_part.display_percentage() / 100.0f);
230 int totcurves = totchild;
232 if (b_part.child_type() == 0 || totchild == 0)
233 totcurves += totparts;
239 if (!(b_part.child_type() == 0) && totchild != 0)
242 int num_add = (totparts + totchild - pa_no);
245 BL::ParticleSystem::particles_iterator b_pa;
246 b_psys.particles.begin(b_pa);
247 for (; pa_no < totparts + totchild; pa_no++) {
249 BL::Mesh::vertex_colors_iterator
l;
250 b_mesh->vertex_colors.begin(
l);
253 if (!b_mesh->vertex_colors.empty())
254 b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
257 if (pa_no < totparts && b_pa != b_psys.particles.end())
289 curve < CData->psys_firstcurve[sys] + CData->
psys_curvenum[sys];
304 curve < CData->psys_firstcurve[sys] + CData->
psys_curvenum[sys];
306 size_t num_curve_keys = 0;
314 const float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
328 if (attr_length !=
NULL) {
332 if (attr_random !=
NULL) {
337 num_keys += num_curve_keys;
343 if ((hair->get_curve_keys().size() != num_keys) || (hair->
num_curves() != num_curves)) {
344 VLOG_WARNING <<
"Hair memory allocation failed, clearing data.";
354 float time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
370 assert(step >= 0.0f);
371 assert(step <= 1.0f);
374 int curvekey = (int)
floorf(curve_key_f);
375 const float remainder = curve_key_f - curvekey;
376 if (remainder == 0.0f) {
379 int curvekey2 = curvekey + 1;
382 curvekey = curvekey2 - 1;
386 return lerp(mP, mP2, remainder);
395 const int num_keys = hair->get_curve_keys().size();
397 if (num_motion_keys != num_keys || !have_motion) {
399 if (num_motion_keys != num_keys) {
400 VLOG_WORK <<
"Hair topology changed, removing motion attribute.";
404 else if (motion_step > 0) {
407 for (
int step = 0; step < motion_step; step++) {
410 for (
int key = 0; key < num_keys; key++) {
412 mP[key].w = hair->get_curve_radius()[key];
422 bool new_attribute =
false;
427 new_attribute =
true;
431 size_t numkeys = hair->get_curve_keys().size();
433 bool have_motion =
false;
439 curve < CData->psys_firstcurve[sys] + CData->
psys_curvenum[sys];
442 int curve_key_end = (num_curves + 1 < (int)hair->get_curve_first_key().size() ?
443 hair->get_curve_first_key()[num_curves + 1] :
444 (int)hair->get_curve_keys().size());
445 const int num_center_curve_keys = curve_key_end - hair->get_curve_first_key()[num_curves];
446 const int is_num_keys_different = CData->
curve_keynum[
curve] - num_center_curve_keys;
448 if (!is_num_keys_different) {
452 if (i < hair->get_curve_keys().size()) {
459 curve_key.w = hair->get_curve_radius()[i];
460 if (
len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f)
470 const float step_size = num_center_curve_keys > 1 ? 1.0f / (num_center_curve_keys - 1) :
472 for (
int step_index = 0; step_index < num_center_curve_keys; ++step_index) {
473 const float step = step_index * step_size;
491 bool BlenderSync::object_has_particle_hair(
BL::Object b_ob)
494 for (BL::Modifier &b_mod : b_ob.modifiers) {
495 if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
496 (preview ? b_mod.show_viewport() : b_mod.show_render())) {
497 BL::ParticleSystemModifier psmd((
const PointerRNA)b_mod.ptr);
501 if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) &&
502 (b_part.type() == BL::ParticleSettings::type_HAIR)) {
512 void BlenderSync::sync_particle_hair(
521 if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) {
547 for (
size_t i = 0; i < hair->
num_curves(); i++) {
549 generated[i] = co *
size - loc;
556 BL::Mesh::vertex_colors_iterator
l;
559 for (b_mesh.vertex_colors.begin(
l);
l != b_mesh.vertex_colors.end(); ++
l, vcol_num++) {
583 BL::Mesh::uv_layers_iterator
l;
586 for (b_mesh.uv_layers.begin(
l);
l != b_mesh.uv_layers.end(); ++
l, uv_num++) {
587 bool active_render =
l->active_render();
589 ustring name = ustring(
l->name().c_str());
619 if (b_attribute.name() !=
"radius") {
622 if (b_attribute.domain() != BL::Attribute::domain_POINT) {
625 if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
628 return BL::FloatAttribute{b_attribute};
636 if (b_attribute.name() !=
"position") {
639 if (b_attribute.domain() != BL::Attribute::domain_POINT) {
642 if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT_VECTOR) {
645 return BL::FloatVectorAttribute{b_attribute};
649 return BL::FloatVectorAttribute{b_curves.attributes[0]};
652 template<
typename TypeInCycles,
typename GetValueAtIndex>
656 const GetValueAtIndex &get_value_at_index)
660 const int num_points = b_curves.points.length();
661 for (
int i = 0; i < num_points; i++) {
662 data[i] = get_value_at_index(i);
667 const int num_verts = b_curves.curves.length();
668 for (
int i = 0; i < num_verts; i++) {
669 data[i] = get_value_at_index(i);
682 if (!(b_attribute.domain() == BL::Attribute::domain_POINT) &&
683 (b_attribute.data_type() == BL::Attribute::data_type_FLOAT_VECTOR)) {
687 BL::FloatVectorAttribute b_vector_attribute(b_attribute);
688 const int num_curve_keys = hair->get_curve_keys().size();
691 float3 *
P = &hair->get_curve_keys()[0];
699 float motion_times[2] = {-1.0f, 1.0f};
700 for (
int step = 0; step < 2; step++) {
701 const float relative_time = motion_times[step] * 0.5f * motion_scale;
704 for (
int i = 0; i < num_curve_keys; i++) {
705 mP[i] =
P[i] +
get_float3(b_vector_attribute.data[i].vector()) * relative_time;
715 BL::Float2Attribute b_float2_attribute{b_attribute};
720 BL::Array<float, 2>
v = b_float2_attribute.data[i].vector();
728 const bool need_motion,
729 const float motion_scale)
732 static const ustring u_velocity(
"velocity");
734 bool have_uv =
false;
737 const ustring name{b_attribute.name().c_str()};
739 const BL::Attribute::domain_enum b_domain = b_attribute.domain();
740 const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
742 if (need_motion && name == u_velocity) {
748 if (need_uv && !have_uv && b_data_type == BL::Attribute::data_type_FLOAT2 &&
749 b_domain == BL::Attribute::domain_CURVE) {
758 if (attributes.
find(name)) {
764 case BL::Attribute::domain_POINT:
767 case BL::Attribute::domain_CURVE:
777 switch (b_data_type) {
778 case BL::Attribute::data_type_FLOAT: {
779 BL::FloatAttribute b_float_attribute{b_attribute};
783 b_curves,
data,
element, [&](
int i) {
return b_float_attribute.data[i].value(); });
786 case BL::Attribute::data_type_BOOLEAN: {
787 BL::BoolAttribute b_bool_attribute{b_attribute};
791 return (
float)b_bool_attribute.data[i].value();
795 case BL::Attribute::data_type_INT: {
796 BL::IntAttribute b_int_attribute{b_attribute};
800 return (
float)b_int_attribute.data[i].value();
804 case BL::Attribute::data_type_FLOAT_VECTOR: {
805 BL::FloatVectorAttribute b_vector_attribute{b_attribute};
809 BL::Array<float, 3>
v = b_vector_attribute.data[i].vector();
814 case BL::Attribute::data_type_FLOAT_COLOR: {
815 BL::FloatColorAttribute b_color_attribute{b_attribute};
819 BL::Array<float, 4>
v = b_color_attribute.data[i].color();
824 case BL::Attribute::data_type_FLOAT2: {
825 BL::Float2Attribute b_float2_attribute{b_attribute};
829 BL::Array<float, 2>
v = b_float2_attribute.data[i].vector();
842 std::optional<BL::FloatAttribute> b_attr_radius,
846 mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.005f;
851 std::optional<BL::FloatAttribute> b_attr_radius,
852 const int first_point_index,
853 const int num_points,
856 const float curve_t = step * (num_points - 1);
857 const int point_a =
clamp((
int)curve_t, 0, num_points - 1);
858 const int point_b =
min(point_a + 1, num_points - 1);
859 const float t = curve_t - (
float)point_a;
868 const bool need_motion,
869 const float motion_scale)
873 const int num_keys = b_curves.points.length();
874 const int num_curves = b_curves.curves.length();
878 float3 *curve_keys = hair->get_curve_keys().data();
879 float *curve_radius = hair->get_curve_radius().data();
880 int *curve_first_key = hair->get_curve_first_key().data();
881 int *curve_shader = hair->get_curve_shader().data();
884 float *attr_intercept =
NULL;
885 float *attr_length =
NULL;
886 float *attr_random =
NULL;
902 for (
int i = 0; i < num_curves; i++) {
903 const int first_point_index = b_curves.curve_offset_data[i].value();
904 const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
910 for (
int j = 0; j < num_points; j++) {
911 const int point_offset = first_point_index + j;
913 const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f;
915 curve_keys[point_offset] = co;
916 curve_radius[point_offset] = radius;
918 if (attr_length || attr_intercept) {
924 if (attr_intercept) {
925 attr_intercept[point_offset] =
length;
931 if (attr_intercept &&
length > 0.0f) {
932 for (
int j = 1; j < num_points; j++) {
933 const int point_offset = first_point_index + j;
934 attr_intercept[point_offset] /=
length;
944 if (attr_random !=
NULL) {
950 curve_first_key[i] = first_point_index;
960 bool new_attribute =
false;
964 new_attribute =
true;
968 const int num_keys = hair->
num_keys();
969 const int num_motion_curves = b_curves.curves.length();
972 bool have_motion =
false;
973 int num_motion_keys = 0;
979 for (
int i = 0; i < num_motion_curves; i++) {
980 if (curve_index >= num_curves) {
984 const int first_point_index = b_curves.curve_offset_data[i].value();
985 const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
990 if (num_points ==
curve.num_keys) {
992 for (
int i = 0; i < num_points; i++) {
1003 curve_key.w = hair->get_curve_radius()[i];
1004 have_motion = !(mP[i] == curve_key);
1012 const float step_size =
curve.num_keys > 1 ? 1.0f / (
curve.num_keys - 1) : 0.0f;
1013 for (
int i = 0; i <
curve.num_keys; i++) {
1014 const float step = i * step_size;
1016 b_attr_position, b_attr_radius, first_point_index, num_points, step);
1024 if (new_attribute) {
1030 void BlenderSync::sync_hair(
Hair *hair,
BObjectInfo &b_ob_info,
bool motion,
int motion_step)
1034 const float motion_scale = (need_motion) ?
1036 (b_scene.render().fps() / b_scene.render().fps_base()) :
1056 new_hair.set_used_shaders(used_shaders);
1058 if (view_layer.use_hair) {
1061 sync_hair(&new_hair, b_ob_info,
false);
1070 sync_particle_hair(&new_hair, b_mesh, b_ob_info,
false);
1080 if (socket.
name ==
"use_motion_blur" || socket.
name ==
"motion_steps" ||
1081 socket.
name ==
"used_shaders") {
1084 hair->
set_value(socket, new_hair, socket);
1093 const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified());
1098 void BlenderSync::sync_hair_motion(
BL::Depsgraph b_depsgraph,
1112 sync_hair(hair, b_ob_info,
true, motion_step);
1120 sync_particle_hair(hair, b_mesh, b_ob_info,
true, motion_step);
typedef float(TangentPoint)[2]
int BKE_object_is_deform_modified(struct Scene *scene, struct Object *ob)
struct Depsgraph Depsgraph
struct ParticleSettings ParticleSettings
struct ParticleSystem ParticleSystem
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Attribute
static bool ObtainCacheParticleData(Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background)
static void attr_create_uv(AttributeSet &attributes, BL::Curves &b_curves, BL::Attribute &b_attribute, const ustring name)
static float4 hair_point_as_float4(BL::FloatVectorAttribute b_attr_position, std::optional< BL::FloatAttribute > b_attr_radius, const int index)
static std::optional< BL::FloatAttribute > find_curves_radius_attribute(BL::Curves b_curves)
static float4 interpolate_hair_points(BL::FloatVectorAttribute b_attr_position, std::optional< BL::FloatAttribute > b_attr_radius, const int first_point_index, const int num_points, const float step)
static void export_hair_curves_motion(Hair *hair, BL::Curves b_curves, int motion_step)
static BL::FloatVectorAttribute find_curves_position_attribute(BL::Curves b_curves)
static float4 CurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, int curvekey)
static void export_hair_motion_validate_attribute(Hair *hair, int motion_step, int num_motion_keys, bool have_motion)
static bool ObtainCacheParticleUV(Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int uv_num)
static bool ObtainCacheParticleVcol(Hair *hair, BL::Mesh *b_mesh, BL::Object *b_ob, ParticleCurveData *CData, bool background, int vcol_num)
static void fill_generic_attribute(BL::Curves &b_curves, TypeInCycles *data, const AttributeElement element, const GetValueAtIndex &get_value_at_index)
static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData)
static void attr_create_generic(Scene *scene, Hair *hair, BL::Curves &b_curves, const bool need_motion, const float motion_scale)
static float shaperadius(float shape, float root, float tip, float time)
static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step)
static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int curve, float step)
static void attr_create_motion(Hair *hair, BL::Attribute &b_attribute, const float motion_scale)
static void export_hair_curves(Scene *scene, Hair *hair, BL::Curves b_curves, const bool need_motion, const float motion_scale)
ATTR_WARN_UNUSED_RESULT const void * element
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
void update(AttributeSet &&new_attributes)
Attribute * find(ustring name) const
void remove(ustring name)
bool need_attribute(Scene *scene, AttributeStandard std)
void tag_update(Scene *scene, bool rebuild)
void resize_curves(int numcurves, int numkeys)
void add_curve(int first_key, int shader)
Curve get_curve(size_t i) const
void reserve_curves(int numcurves, int numkeys)
size_t num_curves() const
void copy_center_to_motion_step(const int motion_step)
void clear(bool preserve_shaders=false) override
void add_curve_key(float3 loc, float radius)
array< int > curve_firstkey
array< bool > psys_closetip
array< float > psys_tipradius
array< float > curve_length
array< float4 > curve_vcol
array< float > curvekey_time
array< float > psys_rootradius
array< int > psys_firstcurve
array< int > psys_curvenum
array< float > psys_shape
array< int > curve_keynum
array< float3 > curvekey_co
void reserve(size_t newcapacity)
void push_back_slow(const T &t)
#define CCL_NAMESPACE_END
static void free_object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Mesh &mesh)
static BL::Mesh object_to_mesh(BL::BlendData &, BObjectInfo &b_ob_info, BL::Depsgraph &, bool, Mesh::SubdivisionType subdivision_type)
static float3 get_float3(const BL::Array< float, 2 > &array)
static bool object_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene)
static Transform get_transform(const BL::Array< float, 16 > &array)
static void mesh_texture_space(BL::Mesh &b_mesh, float3 &loc, float3 &size)
ccl_device_inline float hash_uint2_to_float(uint kx, uint ky)
@ ATTR_STD_CURVE_INTERCEPT
@ ATTR_STD_MOTION_VERTEX_POSITION
ccl_device_inline float2 zero_float2()
ccl_device_inline float3 zero_float3()
ccl_device_inline float len_squared(const float3 a)
static float lerp(float t, float a, float b)
T clamp(const T &a, const T &min, const T &max)
T length(const vec_base< T, Size > &a)
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static constexpr OIIO_NAMESPACE_USING TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
bool is_real_object_data() const
vector< SocketType, std::allocator< SocketType > > inputs
void set_value(const SocketType &input, const Node &other, const SocketType &other_input)
float motion_shutter_time()
ccl_device float4 color_srgb_to_linear_v4(float4 c)
ccl_device_inline float4 float3_to_float4(const float3 a)