Blender V4.3
scene/mesh.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/build.h"
6#include "bvh/bvh.h"
7
8#include "device/device.h"
9
10#include "scene/hair.h"
11#include "scene/mesh.h"
12#include "scene/object.h"
13#include "scene/scene.h"
14#include "scene/shader_graph.h"
15
16#include "subd/patch_table.h"
17#include "subd/split.h"
18
19#include "util/foreach.h"
20#include "util/log.h"
21#include "util/progress.h"
22#include "util/set.h"
23
25
26/* Triangle */
27
29{
30 bounds.grow(verts[v[0]]);
31 bounds.grow(verts[v[1]]);
32 bounds.grow(verts[v[2]]);
33}
34
36 const float3 *vert_steps,
37 size_t num_verts,
38 size_t num_steps,
39 float time,
40 float3 r_verts[3]) const
41{
42 /* Figure out which steps we need to fetch and their interpolation factor. */
43 const size_t max_step = num_steps - 1;
44 const size_t step = min((size_t)(time * max_step), max_step - 1);
45 const float t = time * max_step - step;
46 /* Fetch vertex coordinates. */
47 float3 curr_verts[3];
48 float3 next_verts[3];
49 verts_for_step(verts, vert_steps, num_verts, num_steps, step, curr_verts);
50 verts_for_step(verts, vert_steps, num_verts, num_steps, step + 1, next_verts);
51 /* Interpolate between steps. */
52 r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
53 r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
54 r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
55}
56
58 const float3 *vert_steps,
59 size_t num_verts,
60 size_t num_steps,
61 size_t step,
62 float3 r_verts[3]) const
63{
64 const size_t center_step = ((num_steps - 1) / 2);
65 if (step == center_step) {
66 /* Center step: regular vertex location. */
67 r_verts[0] = verts[v[0]];
68 r_verts[1] = verts[v[1]];
69 r_verts[2] = verts[v[2]];
70 }
71 else {
72 /* Center step not stored in the attribute array. */
73 if (step > center_step) {
74 step--;
75 }
76 size_t offset = step * num_verts;
77 r_verts[0] = vert_steps[offset + v[0]];
78 r_verts[1] = vert_steps[offset + v[1]];
79 r_verts[2] = vert_steps[offset + v[2]];
80 }
81}
82
84{
85 const float3 &v0 = verts[v[0]];
86 const float3 &v1 = verts[v[1]];
87 const float3 &v2 = verts[v[2]];
88 const float3 norm = cross(v1 - v0, v2 - v0);
89 const float normlen = len(norm);
90 if (normlen == 0.0f) {
91 return make_float3(1.0f, 0.0f, 0.0f);
92 }
93 return norm / normlen;
94}
95
97{
98 return isfinite_safe(verts[v[0]]) && isfinite_safe(verts[v[1]]) && isfinite_safe(verts[v[2]]);
99}
100
101/* SubdFace */
102
104{
105 float3 v0 = mesh->verts[mesh->subd_face_corners[start_corner + 0]];
106 float3 v1 = mesh->verts[mesh->subd_face_corners[start_corner + 1]];
107 float3 v2 = mesh->verts[mesh->subd_face_corners[start_corner + 2]];
108
109 return safe_normalize(cross(v1 - v0, v2 - v0));
110}
111
112/* Mesh */
113
115{
116 NodeType *type = NodeType::add("mesh", create, NodeType::NONE, Geometry::get_node_base_type());
117
118 SOCKET_INT_ARRAY(triangles, "Triangles", array<int>());
119 SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>());
120 SOCKET_INT_ARRAY(shader, "Shader", array<int>());
121 SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
122
123 SOCKET_INT_ARRAY(triangle_patch, "Triangle Patch", array<int>());
124 SOCKET_POINT2_ARRAY(vert_patch_uv, "Patch UVs", array<float2>());
125
126 static NodeEnum subdivision_type_enum;
127 subdivision_type_enum.insert("none", SUBDIVISION_NONE);
128 subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR);
129 subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
130 SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
131
132 SOCKET_INT_ARRAY(subd_vert_creases, "Subdivision Vertex Crease", array<int>());
134 subd_vert_creases_weight, "Subdivision Vertex Crease Weights", array<float>());
135 SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
136 SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
137 SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
138 SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>());
139 SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>());
140 SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>());
141 SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>());
142 SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>());
143 SOCKET_INT(num_ngons, "NGons Number", 0);
144
145 /* Subdivisions parameters */
146 SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 1.0f)
147 SOCKET_INT(subd_max_level, "Max Subdivision Level", 1);
148 SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity());
149
150 return type;
151}
152
154{
155 if (subdivision_type == SubdivisionType::SUBDIVISION_NONE) {
156 return nullptr;
157 }
158
159 if (!subd_params) {
160 subd_params = new SubdParams(this);
161 }
162
163 subd_params->dicing_rate = subd_dicing_rate;
164 subd_params->max_level = subd_max_level;
165 subd_params->objecttoworld = subd_objecttoworld;
166
167 return subd_params;
168}
169
171{
172 return get_subd_params() && (verts_is_modified() || subd_dicing_rate_is_modified() ||
173 subd_objecttoworld_is_modified() || subd_max_level_is_modified());
174}
175
176Mesh::Mesh(const NodeType *node_type, Type geom_type_)
177 : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD)
178{
179 vert_offset = 0;
180
181 patch_offset = 0;
182 face_offset = 0;
183 corner_offset = 0;
184
185 num_subd_verts = 0;
186 num_subd_faces = 0;
187
188 num_ngons = 0;
189
190 subdivision_type = SUBDIVISION_NONE;
191 subd_params = NULL;
192
193 patch_table = NULL;
194}
195
196Mesh::Mesh() : Mesh(get_node_type(), Geometry::MESH) {}
197
199{
200 delete patch_table;
201 delete subd_params;
202}
203
204void Mesh::resize_mesh(int numverts, int numtris)
205{
206 verts.resize(numverts);
207 triangles.resize(numtris * 3);
208 shader.resize(numtris);
209 smooth.resize(numtris);
210
211 if (get_num_subd_faces()) {
212 triangle_patch.resize(numtris);
213 vert_patch_uv.resize(numverts);
214 }
215
216 attributes.resize();
217}
218
219void Mesh::reserve_mesh(int numverts, int numtris)
220{
221 /* reserve space to add verts and triangles later */
222 verts.reserve(numverts);
223 triangles.reserve(numtris * 3);
224 shader.reserve(numtris);
225 smooth.reserve(numtris);
226
227 if (get_num_subd_faces()) {
228 triangle_patch.reserve(numtris);
229 vert_patch_uv.reserve(numverts);
230 }
231
232 attributes.resize(true);
233}
234
235void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners)
236{
237 subd_start_corner.resize(numfaces);
238 subd_num_corners.resize(numfaces);
239 subd_shader.resize(numfaces);
240 subd_smooth.resize(numfaces);
241 subd_ptex_offset.resize(numfaces);
242 subd_face_corners.resize(numcorners);
243 num_ngons = num_ngons_;
244 num_subd_faces = numfaces;
245
247}
248
249void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners)
250{
251 subd_start_corner.reserve(numfaces);
252 subd_num_corners.reserve(numfaces);
253 subd_shader.reserve(numfaces);
254 subd_smooth.reserve(numfaces);
255 subd_ptex_offset.reserve(numfaces);
256 subd_face_corners.reserve(numcorners);
257 num_ngons = num_ngons_;
258 num_subd_faces = numfaces;
259
261}
262
263void Mesh::reserve_subd_creases(size_t num_creases)
264{
265 subd_creases_edge.reserve(num_creases * 2);
266 subd_creases_weight.reserve(num_creases);
267}
268
270{
271 Geometry::clear(true);
272
273 num_subd_verts = 0;
274 num_subd_faces = 0;
275
276 vert_to_stitching_key_map.clear();
277 vert_stitching_map.clear();
278
279 delete patch_table;
280 patch_table = NULL;
281}
282
283void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
284{
285 Geometry::clear(preserve_shaders);
286
287 /* clear all verts and triangles */
288 verts.clear();
289 triangles.clear();
290 shader.clear();
291 smooth.clear();
292
293 triangle_patch.clear();
294 vert_patch_uv.clear();
295
296 subd_start_corner.clear();
297 subd_num_corners.clear();
298 subd_shader.clear();
299 subd_smooth.clear();
300 subd_ptex_offset.clear();
301 subd_face_corners.clear();
302
303 subd_creases_edge.clear();
304 subd_creases_weight.clear();
305
307 attributes.clear(preserve_voxel_data);
308
309 subdivision_type = SubdivisionType::SUBDIVISION_NONE;
310
312}
313
314void Mesh::clear(bool preserve_shaders)
315{
316 clear(preserve_shaders, false);
317}
318
320{
321 verts.push_back_reserved(P);
322 tag_verts_modified();
323
324 if (get_num_subd_faces()) {
325 vert_patch_uv.push_back_reserved(zero_float2());
326 tag_vert_patch_uv_modified();
327 }
328}
329
331{
332 verts.push_back_slow(P);
333 tag_verts_modified();
334
335 if (get_num_subd_faces()) {
336 vert_patch_uv.push_back_slow(zero_float2());
337 tag_vert_patch_uv_modified();
338 }
339}
340
341void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_)
342{
343 triangles.push_back_reserved(v0);
344 triangles.push_back_reserved(v1);
345 triangles.push_back_reserved(v2);
346 shader.push_back_reserved(shader_);
347 smooth.push_back_reserved(smooth_);
348
349 tag_triangles_modified();
350 tag_shader_modified();
351 tag_smooth_modified();
352
353 if (get_num_subd_faces()) {
354 triangle_patch.push_back_reserved(-1);
355 tag_triangle_patch_modified();
356 }
357}
358
359void Mesh::add_subd_face(const int *corners, int num_corners, int shader_, bool smooth_)
360{
361 int start_corner = subd_face_corners.size();
362
363 for (int i = 0; i < num_corners; i++) {
364 subd_face_corners.push_back_reserved(corners[i]);
365 }
366
367 int ptex_offset = 0;
368 // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not
369 // have the total amount of data yet
370 if (subd_shader.size()) {
371 SubdFace s = get_subd_face(subd_shader.size() - 1);
372 ptex_offset = s.ptex_offset + s.num_ptex_faces();
373 }
374
375 subd_start_corner.push_back_reserved(start_corner);
376 subd_num_corners.push_back_reserved(num_corners);
377 subd_shader.push_back_reserved(shader_);
378 subd_smooth.push_back_reserved(smooth_);
379 subd_ptex_offset.push_back_reserved(ptex_offset);
380
381 tag_subd_face_corners_modified();
382 tag_subd_start_corner_modified();
383 tag_subd_num_corners_modified();
384 tag_subd_shader_modified();
385 tag_subd_smooth_modified();
386 tag_subd_ptex_offset_modified();
387}
388
390{
392 s.shader = subd_shader[index];
393 s.num_corners = subd_num_corners[index];
394 s.smooth = subd_smooth[index];
395 s.ptex_offset = subd_ptex_offset[index];
396 s.start_corner = subd_start_corner[index];
397 return s;
398}
399
400void Mesh::add_edge_crease(int v0, int v1, float weight)
401{
402 subd_creases_edge.push_back_slow(v0);
403 subd_creases_edge.push_back_slow(v1);
404 subd_creases_weight.push_back_slow(weight);
405
406 tag_subd_creases_edge_modified();
407 tag_subd_creases_edge_modified();
408 tag_subd_creases_weight_modified();
409}
410
411void Mesh::add_vertex_crease(int v, float weight)
412{
413 subd_vert_creases.push_back_slow(v);
414 subd_vert_creases_weight.push_back_slow(weight);
415
416 tag_subd_vert_creases_modified();
417 tag_subd_vert_creases_weight_modified();
418}
419
420void Mesh::copy_center_to_motion_step(const int motion_step)
421{
422 Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
423
424 if (attr_mP) {
425 Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
426 Attribute *attr_N = attributes.find(ATTR_STD_VERTEX_NORMAL);
427 float3 *P = &verts[0];
428 float3 *N = (attr_N) ? attr_N->data_float3() : NULL;
429 size_t numverts = verts.size();
430
431 memcpy(attr_mP->data_float3() + motion_step * numverts, P, sizeof(float3) * numverts);
432 if (attr_mN) {
433 memcpy(attr_mN->data_float3() + motion_step * numverts, N, sizeof(float3) * numverts);
434 }
435 }
436}
437
438void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
439{
440 Attribute *attr, *subd_attr;
441
442 if (map.empty()) {
443 attr = attributes.find(ATTR_STD_UV);
444 subd_attr = subd_attributes.find(ATTR_STD_UV);
445 }
446 else {
447 attr = attributes.find(map);
448 subd_attr = subd_attributes.find(map);
449 }
450
451 if (attr) {
453 }
454 if (subd_attr) {
455 subd_attr->get_uv_tiles(this, ATTR_PRIM_SUBD, tiles);
456 }
457}
458
460{
462 size_t verts_size = verts.size();
463
464 if (verts_size > 0) {
465 for (size_t i = 0; i < verts_size; i++) {
466 bnds.grow(verts[i]);
467 }
468
469 Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
470 if (use_motion_blur && attr) {
471 size_t steps_size = verts.size() * (motion_steps - 1);
472 float3 *vert_steps = attr->data_float3();
473
474 for (size_t i = 0; i < steps_size; i++) {
475 bnds.grow(vert_steps[i]);
476 }
477 }
478
479 if (!bnds.valid()) {
480 bnds = BoundBox::empty;
481
482 /* skip nan or inf coordinates */
483 for (size_t i = 0; i < verts_size; i++) {
484 bnds.grow_safe(verts[i]);
485 }
486
487 if (use_motion_blur && attr) {
488 size_t steps_size = verts.size() * (motion_steps - 1);
489 float3 *vert_steps = attr->data_float3();
490
491 for (size_t i = 0; i < steps_size; i++) {
492 bnds.grow_safe(vert_steps[i]);
493 }
494 }
495 }
496 }
497
498 if (!bnds.valid()) {
499 /* empty mesh */
500 bnds.grow(zero_float3());
501 }
502
503 bounds = bnds;
504}
505
506void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
507{
509
510 /* apply to mesh vertices */
511 for (size_t i = 0; i < verts.size(); i++) {
512 verts[i] = transform_point(&tfm, verts[i]);
513 }
514
515 tag_verts_modified();
516
517 if (apply_to_motion) {
518 Attribute *attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
519
520 if (attr) {
521 size_t steps_size = verts.size() * (motion_steps - 1);
522 float3 *vert_steps = attr->data_float3();
523
524 for (size_t i = 0; i < steps_size; i++) {
525 vert_steps[i] = transform_point(&tfm, vert_steps[i]);
526 }
527 }
528
529 Attribute *attr_N = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
530
531 if (attr_N) {
533 size_t steps_size = verts.size() * (motion_steps - 1);
534 float3 *normal_steps = attr_N->data_float3();
535
536 for (size_t i = 0; i < steps_size; i++) {
537 normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
538 }
539 }
540 }
541}
542
544{
545 /* don't compute if already there */
546 if (attributes.find(ATTR_STD_FACE_NORMAL)) {
547 return;
548 }
549
550 /* get attributes */
551 Attribute *attr_fN = attributes.add(ATTR_STD_FACE_NORMAL);
552 float3 *fN = attr_fN->data_float3();
553
554 /* compute face normals */
555 size_t triangles_size = num_triangles();
556
557 if (triangles_size) {
558 float3 *verts_ptr = verts.data();
559
560 for (size_t i = 0; i < triangles_size; i++) {
561 fN[i] = get_triangle(i).compute_normal(verts_ptr);
562 }
563 }
564
565 /* expected to be in local space */
566 if (transform_applied) {
568
569 for (size_t i = 0; i < triangles_size; i++) {
570 fN[i] = normalize(transform_direction(&ntfm, fN[i]));
571 }
572 }
573}
574
576{
577 bool flip = transform_negative_scaled;
578 size_t verts_size = verts.size();
579 size_t triangles_size = num_triangles();
580
581 /* static vertex normals */
582 if (!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
583 /* get attributes */
584 Attribute *attr_fN = attributes.find(ATTR_STD_FACE_NORMAL);
585 Attribute *attr_vN = attributes.add(ATTR_STD_VERTEX_NORMAL);
586
587 float3 *fN = attr_fN->data_float3();
588 float3 *vN = attr_vN->data_float3();
589
590 /* compute vertex normals */
591 memset(vN, 0, verts.size() * sizeof(float3));
592
593 for (size_t i = 0; i < triangles_size; i++) {
594 for (size_t j = 0; j < 3; j++) {
595 vN[get_triangle(i).v[j]] += fN[i];
596 }
597 }
598
599 if (flip) {
600 for (size_t i = 0; i < verts_size; i++) {
601 vN[i] = -normalize(vN[i]);
602 }
603 }
604 else {
605 for (size_t i = 0; i < verts_size; i++) {
606 vN[i] = normalize(vN[i]);
607 }
608 }
609 }
610
611 /* motion vertex normals */
612 Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
613 Attribute *attr_mN = attributes.find(ATTR_STD_MOTION_VERTEX_NORMAL);
614
615 if (has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
616 /* create attribute */
617 attr_mN = attributes.add(ATTR_STD_MOTION_VERTEX_NORMAL);
618
619 for (int step = 0; step < motion_steps - 1; step++) {
620 float3 *mP = attr_mP->data_float3() + step * verts.size();
621 float3 *mN = attr_mN->data_float3() + step * verts.size();
622
623 /* compute */
624 memset(mN, 0, verts.size() * sizeof(float3));
625
626 for (size_t i = 0; i < triangles_size; i++) {
627 Triangle tri = get_triangle(i);
628 float3 fN = tri.compute_normal(mP);
629 for (size_t j = 0; j < 3; j++) {
630 mN[tri.v[j]] += fN;
631 }
632 }
633
634 if (flip) {
635 for (size_t i = 0; i < verts_size; i++) {
636 mN[i] = -normalize(mN[i]);
637 }
638 }
639 else {
640 for (size_t i = 0; i < verts_size; i++) {
641 mN[i] = normalize(mN[i]);
642 }
643 }
644 }
645 }
646
647 /* subd vertex normals */
649 /* get attributes */
651 float3 *vN = attr_vN->data_float3();
652
653 /* compute vertex normals */
654 memset(vN, 0, verts.size() * sizeof(float3));
655
656 for (size_t i = 0; i < get_num_subd_faces(); i++) {
657 SubdFace face = get_subd_face(i);
658 float3 fN = face.normal(this);
659
660 for (size_t j = 0; j < face.num_corners; j++) {
661 size_t corner = subd_face_corners[face.start_corner + j];
662 vN[corner] += fN;
663 }
664 }
665
666 if (flip) {
667 for (size_t i = 0; i < verts_size; i++) {
668 vN[i] = -normalize(vN[i]);
669 }
670 }
671 else {
672 for (size_t i = 0; i < verts_size; i++) {
673 vN[i] = normalize(vN[i]);
674 }
675 }
676 }
677}
678
680{
681 AttributeSet &attrs = (subdivision_type == SUBDIVISION_NONE) ? attributes : subd_attributes;
682
683 /* don't compute if already there */
685 return;
686 }
687
688 /* get attribute */
690 attr->flags |= ATTR_SUBDIVIDED;
691
692 float3 *data = attr->data_float3();
693
694 /* copy verts */
695 size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY);
696
697 /* Center points for ngons aren't stored in Mesh::verts but are included in size since they will
698 * be calculated later, we subtract them from size here so we don't have an overflow while
699 * copying.
700 */
701 size -= num_ngons * attr->data_sizeof();
702
703 if (size) {
704 memcpy(data, verts.data(), size);
705 }
706}
707
708void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
709{
710 uint shader_id = 0;
711 uint last_shader = -1;
712 bool last_smooth = false;
713
714 size_t triangles_size = num_triangles();
715 const int *shader_ptr = shader.data();
716 const bool *smooth_ptr = smooth.data();
717
718 for (size_t i = 0; i < triangles_size; i++) {
719 const int new_shader = shader_ptr ? shader_ptr[i] : INT_MAX;
720 const bool new_smooth = smooth_ptr ? smooth_ptr[i] : false;
721
722 if (new_shader != last_shader || last_smooth != new_smooth) {
723 last_shader = new_shader;
724 last_smooth = new_smooth;
725 Shader *shader = (last_shader < used_shaders.size()) ?
726 static_cast<Shader *>(used_shaders[last_shader]) :
727 scene->default_surface;
728 shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
729 }
730
731 tri_shader[i] = shader_id;
732 }
733}
734
736{
737 Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
738 if (attr_vN == NULL) {
739 /* Happens on objects with just hair. */
740 return;
741 }
742
743 bool do_transform = transform_applied;
745
746 float3 *vN = attr_vN->data_float3();
747 size_t verts_size = verts.size();
748
749 if (do_transform) {
750 for (size_t i = 0; i < verts_size; i++) {
751 vnormal[i] = safe_normalize(transform_direction(&ntfm, vN[i]));
752 }
753 }
754 else {
755 for (size_t i = 0; i < verts_size; i++) {
756 vnormal[i] = vN[i];
757 }
758 }
759}
760
762 packed_uint3 *tri_vindex,
763 uint *tri_patch,
764 float2 *tri_patch_uv)
765{
766 size_t verts_size = verts.size();
767 size_t triangles_size = num_triangles();
768 const int *p_tris = triangles.data();
769 int off = 0;
770 if (verts_size && get_num_subd_faces()) {
771 float2 *vert_patch_uv_ptr = vert_patch_uv.data();
772
773 for (size_t i = 0; i < verts_size; i++) {
774 tri_verts[i] = verts[i];
775 tri_patch_uv[i] = vert_patch_uv_ptr[i];
776 }
777 for (size_t i = 0; i < triangles_size; i++) {
778 tri_vindex[i] = make_packed_uint3(p_tris[off + 0] + vert_offset,
779 p_tris[off + 1] + vert_offset,
780 p_tris[off + 2] + vert_offset);
781 tri_patch[i] = triangle_patch[i] * 8 + patch_offset;
782 off += 3;
783 }
784 }
785 else {
786 for (size_t i = 0; i < verts_size; i++) {
787 tri_verts[i] = verts[i];
788 }
789 for (size_t i = 0; i < triangles_size; i++) {
790 tri_vindex[i] = make_packed_uint3(p_tris[off + 0] + vert_offset,
791 p_tris[off + 1] + vert_offset,
792 p_tris[off + 2] + vert_offset);
793 tri_patch[i] = -1;
794 off += 3;
795 }
796 }
797}
798
799void Mesh::pack_patches(uint *patch_data)
800{
801 size_t num_faces = get_num_subd_faces();
802 int ngons = 0;
803
804 for (size_t f = 0; f < num_faces; f++) {
805 SubdFace face = get_subd_face(f);
806
807 if (face.is_quad()) {
808 int c[4];
809 memcpy(c, &subd_face_corners[face.start_corner], sizeof(int) * 4);
810
811 *(patch_data++) = c[0] + vert_offset;
812 *(patch_data++) = c[1] + vert_offset;
813 *(patch_data++) = c[2] + vert_offset;
814 *(patch_data++) = c[3] + vert_offset;
815
816 *(patch_data++) = f + face_offset;
817 *(patch_data++) = face.num_corners;
818 *(patch_data++) = face.start_corner + corner_offset;
819 *(patch_data++) = 0;
820 }
821 else {
822 for (int i = 0; i < face.num_corners; i++) {
823 int c[4];
824 c[0] = subd_face_corners[face.start_corner + mod(i + 0, face.num_corners)];
825 c[1] = subd_face_corners[face.start_corner + mod(i + 1, face.num_corners)];
826 c[2] = verts.size() - num_subd_verts + ngons;
827 c[3] = subd_face_corners[face.start_corner + mod(i - 1, face.num_corners)];
828
829 *(patch_data++) = c[0] + vert_offset;
830 *(patch_data++) = c[1] + vert_offset;
831 *(patch_data++) = c[2] + vert_offset;
832 *(patch_data++) = c[3] + vert_offset;
833
834 *(patch_data++) = f + face_offset;
835 *(patch_data++) = face.num_corners | (i << 16);
836 *(patch_data++) = face.start_corner + corner_offset;
837 *(patch_data++) = subd_face_corners.size() + ngons + corner_offset;
838 }
839
840 ngons++;
841 }
842 }
843}
844
849
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
Attribute * add(ustring name, TypeDesc type, AttributeElement element)
Attribute * find(ustring name) const
void resize(bool reserve_only=false)
void clear(bool preserve_voxel_data=false)
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
size_t buffer_size(Geometry *geom, AttributePrimitive prim) const
size_t data_sizeof() const
float3 * data_float3()
void add(const float &f)
Transform transform_normal
BoundBox bounds
bool transform_applied
int motion_step(float time) const
bool has_motion_blur() const
bool transform_negative_scaled
virtual void clear(bool preserve_shaders=false)
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
int len
static float verts[][3]
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
PrimitiveType
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_TRIANGLE
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_POSITION_UNDISPLACED
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_FACE_NORMAL
@ ATTR_SUBDIVIDED
@ ATTR_PRIM_SUBD
@ ATTR_PRIM_GEOMETRY
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
Definition math_float2.h:14
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float cross(const float2 a, const float2 b)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
#define N
#define SOCKET_BOOLEAN_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:243
#define SOCKET_POINT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:257
#define SOCKET_POINT2_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:263
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:200
#define SOCKET_INT(name, ui_name, default_value,...)
Definition node_type.h:194
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:248
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition node_type.h:214
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:246
#define NODE_DEFINE(structname)
Definition node_type.h:148
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:216
#define min(a, b)
Definition sort.c:32
__forceinline bool valid() const
Definition boundbox.h:128
__forceinline float3 size() const
Definition boundbox.h:123
__forceinline void grow_safe(const float3 &pt)
Definition boundbox.h:57
__forceinline void grow(const float3 &pt)
Definition boundbox.h:36
float3 normal(const Mesh *mesh) const
bool valid(const float3 *verts) const
void motion_verts(const float3 *verts, const float3 *vert_steps, size_t num_verts, size_t num_steps, float time, float3 r_verts[3]) const
void verts_for_step(const float3 *verts, const float3 *vert_steps, size_t num_verts, size_t num_steps, size_t step, float3 r_verts[3]) const
void bounds_grow(const float3 *verts, BoundBox &bounds) const
float3 compute_normal(const float3 *verts) const
SubdParams * get_subd_params()
void reserve_subd_faces(int numfaces, int num_ngons, int numcorners)
size_t get_num_subd_faces() const
Definition scene/mesh.h:233
void add_edge_crease(int v0, int v1, float weight)
void reserve_subd_creases(size_t num_creases)
void add_undisplaced()
void compute_bounds() override
void add_vertex_normals()
AttributeSet subd_attributes
Definition scene/mesh.h:159
Triangle get_triangle(size_t i) const
Definition scene/mesh.h:74
void copy_center_to_motion_step(const int motion_step)
void clear(bool preserve_shaders=false) override
void resize_subd_faces(int numfaces, int num_ngons, int numcorners)
void pack_patches(uint *patch_data)
void pack_verts(packed_float3 *tri_verts, packed_uint3 *tri_vindex, uint *tri_patch, float2 *tri_patch_uv)
void reserve_mesh(int numverts, int numfaces)
void add_vertex_slow(float3 P)
bool need_tesselation()
@ SUBDIVISION_NONE
Definition scene/mesh.h:121
@ SUBDIVISION_LINEAR
Definition scene/mesh.h:122
@ SUBDIVISION_CATMULL_CLARK
Definition scene/mesh.h:123
size_t num_triangles() const
Definition scene/mesh.h:80
void clear_non_sockets()
void pack_normals(packed_float3 *vnormal)
void add_vertex(float3 P)
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
void add_vertex_crease(int v, float weight)
void add_triangle(int v0, int v1, int v2, int shader, bool smooth)
SubdFace get_subd_face(size_t index) const
void pack_shaders(Scene *scene, uint *shader)
PrimitiveType primitive_type() const override
void resize_mesh(int numverts, int numfaces)
void add_subd_face(const int *corners, int num_corners, int shader_, bool smooth_)
void add_face_normals()
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
void insert(const char *x, int y)
Definition node_enum.h:21
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition graph/node.h:178
int max_level
Definition dice.h:31
Transform objecttoworld
Definition dice.h:33
float dicing_rate
Definition dice.h:30
Transform transform_transposed_inverse(const Transform &tfm)
ccl_device_inline Transform transform_identity()
Definition transform.h:296
ccl_device_inline Transform transform_inverse(const Transform tfm)
Definition transform.h:423
ccl_device_inline float3 transform_direction(ccl_private const Transform *t, const float3 a)
Definition transform.h:94
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 packed_uint3 make_packed_uint3(uint x, uint y, uint z)
ccl_device_inline int mod(int x, int m)
Definition util/math.h:520
ccl_device_inline bool isfinite_safe(float f)
Definition util/math.h:365