Blender V4.3
scene/pointcloud.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 "bvh/bvh.h"
6
7#include "scene/pointcloud.h"
8#include "scene/scene.h"
9
11
12/* PointCloud Point */
13
15 const float *radius,
16 BoundBox &bounds) const
17{
18 bounds.grow(points[index], radius[index]);
19}
20
22 const float *radius,
23 const Transform &aligned_space,
24 BoundBox &bounds) const
25{
26 float3 P = transform_point(&aligned_space, points[index]);
27 bounds.grow(P, radius[index]);
28}
29
34
36 const float *radius,
37 const float4 *point_steps,
38 size_t num_points,
39 size_t num_steps,
40 float time,
41 size_t p) const
42{
43 /* Figure out which steps we need to fetch and their
44 * interpolation factor. */
45 const size_t max_step = num_steps - 1;
46 const size_t step = min((size_t)(time * max_step), max_step - 1);
47 const float t = time * max_step - step;
48 /* Fetch vertex coordinates. */
49 const float4 curr_key = point_for_step(
50 points, radius, point_steps, num_points, num_steps, step, p);
51 const float4 next_key = point_for_step(
52 points, radius, point_steps, num_points, num_steps, step + 1, p);
53 /* Interpolate between steps. */
54 return (1.0f - t) * curr_key + t * next_key;
55}
56
58 const float *radius,
59 const float4 *point_steps,
60 size_t num_points,
61 size_t num_steps,
62 size_t step,
63 size_t p) const
64{
65 const size_t center_step = ((num_steps - 1) / 2);
66 if (step == center_step) {
67 /* Center step: regular key location. */
68 return make_float4(points[p].x, points[p].y, points[p].z, radius[p]);
69 }
70 else {
71 /* Center step is not stored in this array. */
72 if (step > center_step) {
73 step--;
74 }
75 const size_t offset = step * num_points;
76 return point_steps[offset + p];
77 }
78}
79
80/* PointCloud */
81
83{
85 "pointcloud", create, NodeType::NONE, Geometry::get_node_base_type());
86
87 SOCKET_POINT_ARRAY(points, "Points", array<float3>());
88 SOCKET_FLOAT_ARRAY(radius, "Radius", array<float>());
89 SOCKET_INT_ARRAY(shader, "Shader", array<int>());
90
91 return type;
92}
93
95
97
98void PointCloud::resize(int numpoints)
99{
100 points.resize(numpoints);
101 radius.resize(numpoints);
102 shader.resize(numpoints);
103 attributes.resize();
104
105 tag_points_modified();
106 tag_radius_modified();
107 tag_shader_modified();
108}
109
110void PointCloud::reserve(int numpoints)
111{
112 points.reserve(numpoints);
113 radius.reserve(numpoints);
114 shader.reserve(numpoints);
115 attributes.resize(true);
116}
117
118void PointCloud::clear(const bool preserve_shaders)
119{
120 Geometry::clear(preserve_shaders);
121
122 points.clear();
123 radius.clear();
124 shader.clear();
125 attributes.clear();
126
127 tag_points_modified();
128 tag_radius_modified();
129 tag_shader_modified();
130}
131
132void PointCloud::add_point(float3 co, float r, int shader_index)
133{
134 points.push_back_reserved(co);
135 radius.push_back_reserved(r);
136 shader.push_back_reserved(shader_index);
137
138 tag_points_modified();
139 tag_radius_modified();
140 tag_shader_modified();
141}
142
144{
146 if (attr_mP) {
147 float3 *points_data = points.data();
148 size_t numpoints = points.size();
149 float *radius_data = radius.data();
150
151 float4 *attrib_P = attr_mP->data_float4() + motion_step * numpoints;
152 for (int i = 0; i < numpoints; i++) {
153 float3 P = points_data[i];
154 float r = radius_data[i];
155 attrib_P[i] = make_float4(P.x, P.y, P.z, r);
156 }
157 }
158}
159
160void PointCloud::get_uv_tiles(ustring map, unordered_set<int> &tiles)
161{
162 Attribute *attr;
163
164 if (map.empty()) {
165 attr = attributes.find(ATTR_STD_UV);
166 }
167 else {
168 attr = attributes.find(map);
169 }
170
171 if (attr) {
173 }
174}
175
177{
179 size_t numpoints = points.size();
180
181 if (numpoints > 0) {
182 for (size_t i = 0; i < numpoints; i++) {
183 bnds.grow(points[i], radius[i]);
184 }
185
187 if (use_motion_blur && attr) {
188 size_t steps_size = points.size() * (motion_steps - 1);
189 float4 *point_steps = attr->data_float4();
190
191 for (size_t i = 0; i < steps_size; i++) {
192 bnds.grow(float4_to_float3(point_steps[i]), point_steps[i].w);
193 }
194 }
195
196 if (!bnds.valid()) {
197 bnds = BoundBox::empty;
198
199 /* skip nan or inf coordinates */
200 for (size_t i = 0; i < numpoints; i++) {
201 bnds.grow_safe(points[i], radius[i]);
202 }
203
204 if (use_motion_blur && attr) {
205 size_t steps_size = points.size() * (motion_steps - 1);
206 float4 *point_steps = attr->data_float4();
207
208 for (size_t i = 0; i < steps_size; i++) {
209 bnds.grow_safe(float4_to_float3(point_steps[i]), point_steps[i].w);
210 }
211 }
212 }
213 }
214
215 if (!bnds.valid()) {
216 /* empty mesh */
217 bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
218 }
219
220 bounds = bnds;
221}
222
223void PointCloud::apply_transform(const Transform &tfm, const bool apply_to_motion)
224{
225 /* compute uniform scale */
226 float3 c0 = transform_get_column(&tfm, 0);
227 float3 c1 = transform_get_column(&tfm, 1);
228 float3 c2 = transform_get_column(&tfm, 2);
229 float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f);
230
231 /* apply transform to curve keys */
232 for (size_t i = 0; i < points.size(); i++) {
233 float3 co = transform_point(&tfm, points[i]);
234 float r = radius[i] * scalar;
235
236 /* scale for curve radius is only correct for uniform scale
237 */
238 points[i] = co;
239 radius[i] = r;
240 }
241
242 if (apply_to_motion) {
244
245 if (attr) {
246 /* apply transform to motion curve keys */
247 size_t steps_size = points.size() * (motion_steps - 1);
248 float4 *point_steps = attr->data_float4();
249
250 for (size_t i = 0; i < steps_size; i++) {
251 float3 co = transform_point(&tfm, float4_to_float3(point_steps[i]));
252 float radius = point_steps[i].w * scalar;
253
254 /* scale for curve radius is only correct for uniform
255 * scale */
256 point_steps[i] = float3_to_float4(co);
257 point_steps[i].w = radius;
258 }
259 }
260 }
261}
262
263void PointCloud::pack(Scene *scene, float4 *packed_points, uint *packed_shader)
264{
265 size_t numpoints = points.size();
266 float3 *points_data = points.data();
267 float *radius_data = radius.data();
268 int *shader_data = shader.data();
269
270 for (size_t i = 0; i < numpoints; i++) {
271 packed_points[i] = make_float4(
272 points_data[i].x, points_data[i].y, points_data[i].z, radius_data[i]);
273 }
274
275 uint shader_id = 0;
276 uint last_shader = -1;
277 for (size_t i = 0; i < numpoints; i++) {
278 if (last_shader != shader_data[i]) {
279 last_shader = shader_data[i];
280 Shader *shader = (last_shader < used_shaders.size()) ?
281 static_cast<Shader *>(used_shaders[last_shader]) :
282 scene->default_surface;
283 shader_id = scene->shader_manager->get_shader_id(shader);
284 }
285 packed_shader[i] = shader_id;
286 }
287}
288
293
unsigned int uint
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 point
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
float4 * data_float4()
BoundBox bounds
int motion_step(float time) const
bool has_motion_blur() const
AttributeSet attributes
Geometry(const NodeType *node_type, const Type type)
virtual void clear(bool preserve_shaders=false)
int get_shader_id(Shader *shader, bool smooth=false)
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define fabsf(x)
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
PrimitiveType
@ PRIMITIVE_MOTION_POINT
@ PRIMITIVE_POINT
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_PRIM_GEOMETRY
ccl_device_inline float cross(const float2 a, const float2 b)
#define SOCKET_POINT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:257
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:248
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:246
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define min(a, b)
Definition sort.c:32
__forceinline bool valid() const
Definition boundbox.h:128
__forceinline void grow_safe(const float3 &pt)
Definition boundbox.h:57
__forceinline void grow(const float3 &pt)
Definition boundbox.h:36
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition graph/node.h:178
float4 motion_key(const float3 *points, const float *radius, const float4 *point_steps, size_t num_points, size_t num_steps, float time, size_t p) const
void bounds_grow(const float3 *points, const float *radius, BoundBox &bounds) const
float4 point_for_step(const float3 *points, const float *radius, const float4 *point_steps, size_t num_points, size_t num_steps, size_t step, size_t p) const
void pack(Scene *scene, float4 *packed_points, uint *packed_shader)
void reserve(int numpoints)
void clear(const bool preserver_shaders=false) override
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
size_t num_points() const
void resize(int numpoints)
void copy_center_to_motion_step(const int motion_step)
void compute_bounds() override
PrimitiveType primitive_type() const override
void add_point(float3 loc, float radius, int shader=0)
Shader * default_surface
Definition scene.h:150
ShaderManager * shader_manager
Definition scene.h:142
VecBase< float, 4 > float4
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
Definition transform.h:326
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition util/math.h:540
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition util/math.h:535