Blender V4.3
scene/attribute.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "scene/attribute.h"
6#include "scene/hair.h"
7#include "scene/image.h"
8#include "scene/mesh.h"
9#include "scene/pointcloud.h"
10
11#include "util/foreach.h"
12#include "util/log.h"
13#include "util/transform.h"
14
16
17/* Attribute */
18
22{
23 /* string and matrix not supported! */
24 assert(type == TypeFloat || type == TypeColor || type == TypePoint || type == TypeVector ||
25 type == TypeNormal || type == TypeMatrix || type == TypeFloat2 || type == TypeFloat4 ||
26 type == TypeRGBA);
27
29 buffer.resize(sizeof(ImageHandle));
30 new (buffer.data()) ImageHandle();
31 }
32 else {
33 resize(geom, prim, false);
34 }
35}
36
38{
39 /* For voxel data, we need to free the image handle. */
40 if (element == ATTR_ELEMENT_VOXEL && buffer.size()) {
41 ImageHandle &handle = data_voxel();
42 handle.~ImageHandle();
43 }
44}
45
46void Attribute::resize(Geometry *geom, AttributePrimitive prim, bool reserve_only)
47{
49 if (reserve_only) {
50 buffer.reserve(buffer_size(geom, prim));
51 }
52 else {
53 buffer.resize(buffer_size(geom, prim), 0);
54 }
55 }
56}
57
58void Attribute::resize(size_t num_elements)
59{
61 buffer.resize(num_elements * data_sizeof(), 0);
62 }
63}
64
65void Attribute::add(const float &f)
66{
67 assert(data_sizeof() == sizeof(float));
68
69 char *data = (char *)&f;
70 size_t size = sizeof(f);
71
72 for (size_t i = 0; i < size; i++) {
73 buffer.push_back(data[i]);
74 }
75
76 modified = true;
77}
78
79void Attribute::add(const uchar4 &f)
80{
81 assert(data_sizeof() == sizeof(uchar4));
82
83 char *data = (char *)&f;
84 size_t size = sizeof(f);
85
86 for (size_t i = 0; i < size; i++) {
87 buffer.push_back(data[i]);
88 }
89
90 modified = true;
91}
92
93void Attribute::add(const float2 &f)
94{
95 assert(data_sizeof() == sizeof(float2));
96
97 char *data = (char *)&f;
98 size_t size = sizeof(f);
99
100 for (size_t i = 0; i < size; i++) {
101 buffer.push_back(data[i]);
102 }
103
104 modified = true;
105}
106
107void Attribute::add(const float3 &f)
108{
109 assert(data_sizeof() == sizeof(float3));
110
111 char *data = (char *)&f;
112 size_t size = sizeof(f);
113
114 for (size_t i = 0; i < size; i++) {
115 buffer.push_back(data[i]);
116 }
117
118 modified = true;
119}
120
122{
123 assert(data_sizeof() == sizeof(Transform));
124
125 char *data = (char *)&f;
126 size_t size = sizeof(f);
127
128 for (size_t i = 0; i < size; i++) {
129 buffer.push_back(data[i]);
130 }
131
132 modified = true;
133}
134
135void Attribute::add(const char *data)
136{
137 size_t size = data_sizeof();
138
139 for (size_t i = 0; i < size; i++) {
140 buffer.push_back(data[i]);
141 }
142
143 modified = true;
144}
145
147{
148 assert(other.std == std);
149 assert(other.type == type);
150 assert(other.element == element);
151
152 this->flags = other.flags;
153
154 if (this->buffer.size() != other.buffer.size()) {
155 this->buffer = std::move(other.buffer);
156 modified = true;
157 }
158 else if (memcmp(this->data(), other.data(), other.buffer.size()) != 0) {
159 this->buffer = std::move(other.buffer);
160 modified = true;
161 }
162}
163
165{
167 return sizeof(ImageHandle);
168 }
169 else if (element == ATTR_ELEMENT_CORNER_BYTE) {
170 return sizeof(uchar4);
171 }
172 else if (type == TypeFloat) {
173 return sizeof(float);
174 }
175 else if (type == TypeFloat2) {
176 return sizeof(float2);
177 }
178 else if (type == TypeMatrix) {
179 return sizeof(Transform);
180 // The float3 type is not interchangeable with float4
181 // as it is now a packed type.
182 }
183 else if (type == TypeFloat4) {
184 return sizeof(float4);
185 }
186 else if (type == TypeRGBA) {
187 return sizeof(float4);
188 }
189 else {
190 return sizeof(float3);
191 }
192}
193
195{
196 if (flags & ATTR_FINAL_SIZE) {
197 return buffer.size() / data_sizeof();
198 }
199
200 size_t size = 0;
201
202 switch (element) {
206 size = 1;
207 break;
210 Mesh *mesh = static_cast<Mesh *>(geom);
211 size = mesh->get_verts().size() + mesh->get_num_ngons();
212 if (prim == ATTR_PRIM_SUBD) {
213 size -= mesh->get_num_subd_verts();
214 }
215 }
216 else if (geom->geometry_type == Geometry::POINTCLOUD) {
217 PointCloud *pointcloud = static_cast<PointCloud *>(geom);
218 size = pointcloud->num_points();
219 }
220 break;
222 if (geom->geometry_type == Geometry::MESH) {
223 Mesh *mesh = static_cast<Mesh *>(geom);
224 DCHECK_GT(mesh->get_motion_steps(), 0);
225 size = (mesh->get_verts().size() + mesh->get_num_ngons()) * (mesh->get_motion_steps() - 1);
226 if (prim == ATTR_PRIM_SUBD) {
227 size -= mesh->get_num_subd_verts() * (mesh->get_motion_steps() - 1);
228 }
229 }
230 else if (geom->geometry_type == Geometry::POINTCLOUD) {
231 PointCloud *pointcloud = static_cast<PointCloud *>(geom);
232 size = pointcloud->num_points() * (pointcloud->get_motion_steps() - 1);
233 }
234 break;
237 Mesh *mesh = static_cast<Mesh *>(geom);
238 if (prim == ATTR_PRIM_GEOMETRY) {
239 size = mesh->num_triangles();
240 }
241 else {
242 size = mesh->get_num_subd_faces() + mesh->get_num_ngons();
243 }
244 }
245 break;
248 if (geom->geometry_type == Geometry::MESH) {
249 Mesh *mesh = static_cast<Mesh *>(geom);
250 if (prim == ATTR_PRIM_GEOMETRY) {
251 size = mesh->num_triangles() * 3;
252 }
253 else {
254 size = mesh->get_subd_face_corners().size() + mesh->get_num_ngons();
255 }
256 }
257 break;
259 if (geom->geometry_type == Geometry::HAIR) {
260 Hair *hair = static_cast<Hair *>(geom);
261 size = hair->num_curves();
262 }
263 break;
265 if (geom->geometry_type == Geometry::HAIR) {
266 Hair *hair = static_cast<Hair *>(geom);
267 size = hair->get_curve_keys().size();
268 }
269 break;
271 if (geom->geometry_type == Geometry::HAIR) {
272 Hair *hair = static_cast<Hair *>(geom);
273 DCHECK_GT(hair->get_motion_steps(), 0);
274 size = hair->get_curve_keys().size() * (hair->get_motion_steps() - 1);
275 }
276 break;
277 default:
278 break;
279 }
280
281 return size;
282}
283
285{
286 return element_size(geom, prim) * data_sizeof();
287}
288
290{
291 if (a == b) {
292 return true;
293 }
294
295 if (a == TypeColor || a == TypePoint || a == TypeVector || a == TypeNormal) {
296 if (b == TypeColor || b == TypePoint || b == TypeVector || b == TypeNormal) {
297 return true;
298 }
299 }
300 return false;
301}
302
303void Attribute::zero_data(void *dst)
304{
305 memset(dst, 0, data_sizeof());
306}
307
308void Attribute::add_with_weight(void *dst, void *src, float weight)
309{
311 for (int i = 0; i < 4; i++) {
312 ((uchar *)dst)[i] += uchar(((uchar *)src)[i] * weight);
313 }
314 }
315 else if (same_storage(type, TypeFloat)) {
316 *((float *)dst) += *((float *)src) * weight;
317 }
318 else if (same_storage(type, TypeFloat2)) {
319 *((float2 *)dst) += *((float2 *)src) * weight;
320 }
321 else if (same_storage(type, TypeVector)) {
322 // Points are float3s and not float4s
323 *((float3 *)dst) += *((float3 *)src) * weight;
324 }
325 else {
326 assert(!"not implemented for this type");
327 }
328}
329
331{
332 switch (std) {
334 return "N";
336 return "Ng";
337 case ATTR_STD_UV:
338 return "uv";
340 return "generated";
342 return "generated_transform";
344 return "tangent";
346 return "tangent_sign";
348 return "vertex_color";
350 return "undeformed";
352 return "undisplaced";
354 return "motion_P";
356 return "motion_N";
358 return "particle";
360 return "curve_intercept";
362 return "curve_length";
364 return "curve_random";
366 return "point_random";
368 return "ptex_face_id";
369 case ATTR_STD_PTEX_UV:
370 return "ptex_uv";
372 return "density";
374 return "color";
376 return "flame";
378 return "heat";
380 return "temperature";
382 return "velocity";
384 return "velocity_x";
386 return "velocity_y";
388 return "velocity_z";
390 return "pointiness";
392 return "random_per_island";
394 return "shadow_transparency";
396 case ATTR_STD_NONE:
397 case ATTR_STD_NUM:
398 return "";
399 }
400
401 return "";
402}
403
405{
406 if (name) {
407 for (int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++) {
409 return (AttributeStandard)std;
410 }
411 }
412 }
413
414 return ATTR_STD_NONE;
415}
416
418{
419 if (attr.element == ATTR_ELEMENT_CORNER) {
421 }
422
423 if (attr.type == TypeFloat) {
425 }
426
427 if (attr.type == TypeFloat2) {
429 }
430
431 if (attr.type == TypeFloat4 || attr.type == TypeRGBA || attr.type == TypeMatrix) {
433 }
434
436}
437
440 unordered_set<int> &tiles) const
441{
442 if (type != TypeFloat2) {
443 return;
444 }
445
446 const int num = element_size(geom, prim);
447 const float2 *uv = data_float2();
448 for (int i = 0; i < num; i++, uv++) {
449 float u = uv->x, v = uv->y;
450 int x = (int)u, y = (int)v;
451
452 if (x < 0 || y < 0 || x >= 10) {
453 continue;
454 }
455
456 /* Be conservative in corners - precisely touching the right or upper edge of a tile
457 * should not load its right/upper neighbor as well. */
458 if (x > 0 && (u < x + 1e-6f)) {
459 x--;
460 }
461 if (y > 0 && (v < y + 1e-6f)) {
462 y--;
463 }
464
465 tiles.insert(1001 + 10 * y + x);
466 }
467}
468
469/* Attribute Set */
470
475
477
479{
480 Attribute *attr = find(name);
481
482 if (attr) {
483 /* return if same already exists */
484 if (attr->type == type && attr->element == element) {
485 return attr;
486 }
487
488 /* overwrite attribute with same name but different type/element */
489 remove(name);
490 }
491
492 Attribute new_attr(name, type, element, geometry, prim);
493 attributes.emplace_back(std::move(new_attr));
494 tag_modified(attributes.back());
495 return &attributes.back();
496}
497
498Attribute *AttributeSet::find(ustring name) const
499{
500 foreach (const Attribute &attr, attributes)
501 if (attr.name == name) {
502 return (Attribute *)&attr;
503 }
504
505 return NULL;
506}
507
508void AttributeSet::remove(ustring name)
509{
510 Attribute *attr = find(name);
511
512 if (attr) {
513 list<Attribute>::iterator it;
514
515 for (it = attributes.begin(); it != attributes.end(); it++) {
516 if (&*it == attr) {
517 remove(it);
518 return;
519 }
520 }
521 }
522}
523
525{
526 Attribute *attr = NULL;
527
528 if (name == ustring()) {
529 name = Attribute::standard_name(std);
530 }
531
532 if (geometry->geometry_type == Geometry::MESH) {
533 switch (std) {
535 attr = add(name, TypeNormal, ATTR_ELEMENT_VERTEX);
536 break;
538 attr = add(name, TypeNormal, ATTR_ELEMENT_FACE);
539 break;
540 case ATTR_STD_UV:
541 attr = add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
542 break;
544 attr = add(name, TypeVector, ATTR_ELEMENT_CORNER);
545 break;
547 attr = add(name, TypeFloat, ATTR_ELEMENT_CORNER);
548 break;
551 break;
555 attr = add(name, TypePoint, ATTR_ELEMENT_VERTEX);
556 break;
558 attr = add(name, TypePoint, ATTR_ELEMENT_VERTEX_MOTION);
559 break;
561 attr = add(name, TypeNormal, ATTR_ELEMENT_VERTEX_MOTION);
562 break;
564 attr = add(name, TypeFloat, ATTR_ELEMENT_FACE);
565 break;
566 case ATTR_STD_PTEX_UV:
567 attr = add(name, TypePoint, ATTR_ELEMENT_VERTEX);
568 break;
570 attr = add(name, TypeMatrix, ATTR_ELEMENT_MESH);
571 break;
573 attr = add(name, TypeFloat, ATTR_ELEMENT_VERTEX);
574 break;
576 attr = add(name, TypeFloat, ATTR_ELEMENT_FACE);
577 break;
578 default:
579 assert(0);
580 break;
581 }
582 }
583 else if (geometry->geometry_type == Geometry::POINTCLOUD) {
584 switch (std) {
585 case ATTR_STD_UV:
586 attr = add(name, TypeFloat2, ATTR_ELEMENT_VERTEX);
587 break;
589 attr = add(name, TypePoint, ATTR_ELEMENT_VERTEX);
590 break;
592 attr = add(name, TypeFloat4, ATTR_ELEMENT_VERTEX_MOTION);
593 break;
595 attr = add(name, TypeFloat, ATTR_ELEMENT_VERTEX);
596 break;
598 attr = add(name, TypeMatrix, ATTR_ELEMENT_MESH);
599 break;
600 default:
601 assert(0);
602 break;
603 }
604 }
605 else if (geometry->geometry_type == Geometry::VOLUME) {
606 switch (std) {
608 attr = add(name, TypeNormal, ATTR_ELEMENT_VERTEX);
609 break;
611 attr = add(name, TypeNormal, ATTR_ELEMENT_FACE);
612 break;
620 attr = add(name, TypeFloat, ATTR_ELEMENT_VOXEL);
621 break;
623 attr = add(name, TypeColor, ATTR_ELEMENT_VOXEL);
624 break;
626 attr = add(name, TypeVector, ATTR_ELEMENT_VOXEL);
627 break;
628 default:
629 assert(0);
630 break;
631 }
632 }
633 else if (geometry->geometry_type == Geometry::HAIR) {
634 switch (std) {
636 attr = add(name, TypeNormal, ATTR_ELEMENT_CURVE_KEY);
637 break;
638 case ATTR_STD_UV:
639 attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
640 break;
642 attr = add(name, TypePoint, ATTR_ELEMENT_CURVE);
643 break;
645 attr = add(name, TypeFloat4, ATTR_ELEMENT_CURVE_KEY_MOTION);
646 break;
648 attr = add(name, TypeFloat, ATTR_ELEMENT_CURVE_KEY);
649 break;
651 attr = add(name, TypeFloat, ATTR_ELEMENT_CURVE);
652 break;
654 attr = add(name, TypeFloat, ATTR_ELEMENT_CURVE);
655 break;
657 attr = add(name, TypeMatrix, ATTR_ELEMENT_MESH);
658 break;
660 attr = add(name, TypeFloat, ATTR_ELEMENT_VERTEX);
661 break;
663 attr = add(name, TypeFloat, ATTR_ELEMENT_FACE);
664 break;
666 attr = add(name, TypeFloat, ATTR_ELEMENT_CURVE_KEY);
667 break;
668 default:
669 assert(0);
670 break;
671 }
672 }
673
674 attr->std = std;
675
676 return attr;
677}
678
680{
681 foreach (const Attribute &attr, attributes)
682 if (attr.std == std) {
683 return (Attribute *)&attr;
684 }
685
686 return NULL;
687}
688
690{
691 for (Attribute &attr : attributes) {
692 if (attr.name != other.name) {
693 continue;
694 }
695 if (attr.std != other.std) {
696 continue;
697 }
698 if (attr.type != other.type) {
699 continue;
700 }
701 if (attr.element != other.element) {
702 continue;
703 }
704 return &attr;
705 }
706 return nullptr;
707}
708
710{
711 Attribute *attr = find(std);
712
713 if (attr) {
714 list<Attribute>::iterator it;
715
716 for (it = attributes.begin(); it != attributes.end(); it++) {
717 if (&*it == attr) {
718 remove(it);
719 return;
720 }
721 }
722 }
723}
724
726{
727 if (req.std == ATTR_STD_NONE) {
728 return find(req.name);
729 }
730 else {
731 return find(req.std);
732 }
733}
734
736{
737 if (attribute->std == ATTR_STD_NONE) {
738 remove(attribute->name);
739 }
740 else {
741 remove(attribute->std);
742 }
743}
744
745void AttributeSet::remove(list<Attribute>::iterator it)
746{
747 tag_modified(*it);
748 attributes.erase(it);
749}
750
751void AttributeSet::resize(bool reserve_only)
752{
753 foreach (Attribute &attr, attributes) {
754 attr.resize(geometry, prim, reserve_only);
755 }
756}
757
758void AttributeSet::clear(bool preserve_voxel_data)
759{
760 if (preserve_voxel_data) {
761 list<Attribute>::iterator it;
762
763 for (it = attributes.begin(); it != attributes.end();) {
764 if (it->element == ATTR_ELEMENT_VOXEL || it->std == ATTR_STD_GENERATED_TRANSFORM) {
765 it++;
766 }
767 else {
768 attributes.erase(it++);
769 }
770 }
771 }
772 else {
773 attributes.clear();
774 }
775}
776
777void AttributeSet::update(AttributeSet &&new_attributes)
778{
779 /* Remove any attributes not on new_attributes. */
780 list<Attribute>::iterator it;
781 for (it = attributes.begin(); it != attributes.end();) {
782 const Attribute &old_attr = *it;
783 if (new_attributes.find_matching(old_attr) == nullptr) {
784 remove(it++);
785 continue;
786 }
787 it++;
788 }
789
790 /* Add or update old_attributes based on the new_attributes. */
791 foreach (Attribute &attr, new_attributes.attributes) {
792 Attribute *nattr = add(attr.name, attr.type, attr.element);
793 nattr->std = attr.std;
794 nattr->set_data_from(std::move(attr));
795 }
796
797 /* If all attributes were replaced, transform is no longer applied. */
798 geometry->transform_applied = false;
799}
800
802{
803 foreach (Attribute &attr, attributes) {
804 attr.modified = false;
805 }
806
807 modified_flag = 0;
808}
809
810void AttributeSet::tag_modified(const Attribute &attr)
811{
812 /* Some attributes are not stored in the various kernel attribute arrays
813 * (DeviceScene::attribute_*), so the modified flags are only set if the associated standard
814 * corresponds to an attribute which will be stored in the kernel's attribute arrays. */
815 const bool modifies_device_array = (attr.std != ATTR_STD_FACE_NORMAL &&
817
818 if (modifies_device_array) {
819 AttrKernelDataType kernel_type = Attribute::kernel_type(attr);
820 modified_flag |= (1u << kernel_type);
821 }
822}
823
825{
826 return (modified_flag & (1u << kernel_type)) != 0;
827}
828
829/* AttributeRequest */
830
832{
833 name = name_;
835
836 type = TypeFloat;
837 desc.element = ATTR_ELEMENT_NONE;
838 desc.offset = 0;
839 desc.type = NODE_ATTR_FLOAT;
840
841 subd_type = TypeFloat;
843 subd_desc.offset = 0;
845}
846
848{
849 name = ustring();
850 std = std_;
851
852 type = TypeFloat;
853 desc.element = ATTR_ELEMENT_NONE;
854 desc.offset = 0;
855 desc.type = NODE_ATTR_FLOAT;
856
857 subd_type = TypeFloat;
859 subd_desc.offset = 0;
861}
862
863/* AttributeRequestSet */
864
866
868
870{
871 if (requests.size() != other.requests.size()) {
872 return true;
873 }
874
875 for (size_t i = 0; i < requests.size(); i++) {
876 bool found = false;
877
878 for (size_t j = 0; j < requests.size() && !found; j++) {
879 if (requests[i].name == other.requests[j].name && requests[i].std == other.requests[j].std) {
880 found = true;
881 }
882 }
883
884 if (!found) {
885 return true;
886 }
887 }
888
889 return false;
890}
891
892void AttributeRequestSet::add(ustring name)
893{
894 foreach (AttributeRequest &req, requests) {
895 if (req.name == name) {
896 return;
897 }
898 }
899
900 requests.push_back(AttributeRequest(name));
901}
902
904{
905 foreach (AttributeRequest &req, requests)
906 if (req.std == std) {
907 return;
908 }
909
910 requests.push_back(AttributeRequest(std));
911}
912
914{
915 foreach (AttributeRequest &req, reqs.requests) {
916 if (req.std == ATTR_STD_NONE) {
917 add(req.name);
918 }
919 else {
920 add(req.std);
921 }
922 }
923}
924
926{
927 if (name.empty()) {
928 return;
929 }
930
932
933 if (std) {
934 add(std);
935 }
936 else {
937 add(name);
938 }
939}
940
942{
943 foreach (AttributeRequest &req, requests)
944 if (req.name == name) {
945 return true;
946 }
947
948 return false;
949}
950
952{
953 foreach (AttributeRequest &req, requests)
954 if (req.std == std) {
955 return true;
956 }
957
958 return false;
959}
960
962{
963 return requests.size();
964}
965
967{
968 requests.clear();
969}
970
unsigned char uchar
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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 Retrieve a color attribute
ATTR_WARN_UNUSED_RESULT const void * element
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
vector< AttributeRequest > requests
bool find(ustring name)
void add(ustring name)
bool modified(const AttributeRequestSet &other)
void add_standard(ustring name)
AttributeRequest(ustring name_)
AttributeDescriptor subd_desc
AttributeDescriptor desc
AttributeStandard std
Geometry * geometry
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
void update(AttributeSet &&new_attributes)
list< Attribute > attributes
Attribute * find(ustring name) const
Attribute * find_matching(const Attribute &other)
bool modified(AttrKernelDataType kernel_type) const
void remove(ustring name)
AttributeSet(Geometry *geometry, AttributePrimitive prim)
void resize(bool reserve_only=false)
void clear(bool preserve_voxel_data=false)
AttributePrimitive prim
AttributeElement element
static bool same_storage(TypeDesc a, TypeDesc b)
void add_with_weight(void *dst, void *src, float weight)
static AttrKernelDataType kernel_type(const Attribute &attr)
char * data()
static AttributeStandard name_standard(const char *name)
TypeDesc type
void resize(Geometry *geom, AttributePrimitive prim, bool reserve_only)
size_t element_size(Geometry *geom, AttributePrimitive prim) const
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
vector< char > buffer
void set_data_from(Attribute &&other)
void zero_data(void *dst)
Attribute(ustring name, TypeDesc type, AttributeElement element, Geometry *geom, AttributePrimitive prim)
static const char * standard_name(AttributeStandard std)
size_t buffer_size(Geometry *geom, AttributePrimitive prim) const
AttributeStandard std
ImageHandle & data_voxel()
size_t data_sizeof() const
void add(const float &f)
float2 * data_float2()
Type geometry_type
Definition hair.h:14
size_t num_curves() const
Definition hair.h:126
local_group_size(16, 16) .push_constant(Type b
#define CCL_NAMESPACE_END
#define NULL
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
@ NODE_ATTR_FLOAT
AttributeStandard
@ ATTR_STD_CURVE_INTERCEPT
@ ATTR_STD_GENERATED_TRANSFORM
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_VOLUME_VELOCITY_Y
@ ATTR_STD_VOLUME_TEMPERATURE
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_UV_TANGENT
@ ATTR_STD_NOT_FOUND
@ ATTR_STD_NONE
@ ATTR_STD_VOLUME_VELOCITY_Z
@ ATTR_STD_POINT_RANDOM
@ ATTR_STD_VERTEX_COLOR
@ ATTR_STD_VOLUME_DENSITY
@ ATTR_STD_NUM
@ ATTR_STD_POSITION_UNDISPLACED
@ ATTR_STD_VOLUME_FLAME
@ ATTR_STD_PTEX_FACE_ID
@ ATTR_STD_VOLUME_VELOCITY
@ ATTR_STD_POSITION_UNDEFORMED
@ ATTR_STD_VOLUME_COLOR
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_VOLUME_HEAT
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_CURVE_RANDOM
@ ATTR_STD_SHADOW_TRANSPARENCY
@ ATTR_STD_FACE_NORMAL
@ ATTR_STD_PTEX_UV
@ ATTR_STD_POINTINESS
@ ATTR_STD_GENERATED
@ ATTR_STD_CURVE_LENGTH
@ ATTR_STD_VOLUME_VELOCITY_X
@ ATTR_STD_RANDOM_PER_ISLAND
@ ATTR_STD_PARTICLE
@ ATTR_FINAL_SIZE
AttributeElement
@ ATTR_ELEMENT_NONE
@ ATTR_ELEMENT_CORNER_BYTE
@ ATTR_ELEMENT_CURVE_KEY
@ ATTR_ELEMENT_CURVE_KEY_MOTION
@ ATTR_ELEMENT_VOXEL
@ ATTR_ELEMENT_CORNER
@ ATTR_ELEMENT_OBJECT
@ ATTR_ELEMENT_VERTEX_MOTION
@ ATTR_ELEMENT_VERTEX
@ ATTR_ELEMENT_FACE
@ ATTR_ELEMENT_MESH
@ ATTR_ELEMENT_CURVE
AttributePrimitive
@ ATTR_PRIM_SUBD
@ ATTR_PRIM_GEOMETRY
#define DCHECK_GT(a, b)
Definition log.h:60
static constexpr TypeDesc TypeRGBA(TypeDesc::FLOAT, TypeDesc::VEC4, TypeDesc::COLOR)
CCL_NAMESPACE_BEGIN static OIIO_NAMESPACE_USING constexpr TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2)
AttrKernelDataType
@ FLOAT4
@ FLOAT2
@ UCHAR4
@ FLOAT3
@ FLOAT
long long TypeDesc
size_t get_num_subd_faces() const
Definition scene/mesh.h:233
size_t num_triangles() const
Definition scene/mesh.h:80
size_t get_num_subd_verts()
Definition scene/mesh.h:243
size_t num_points() const
float x
float y
VecBase< float, 4 > float4