Blender V5.0
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 <algorithm>
6
7#include "bvh/build.h"
8#include "bvh/bvh.h"
9
10#include "device/device.h"
11
12#include "scene/attribute.h"
13#include "scene/mesh.h"
14#include "scene/object.h"
15#include "scene/scene.h"
16#include "scene/shader_graph.h"
17
18#include "subd/split.h"
19
20#include "util/log.h"
21#include "util/set.h"
22
23#include "mikktspace.hh"
24
26
27/* Tangent Space */
28
31 const float3 *normal,
32 const float2 *uv,
34 float *tangent_sign)
36 {
37 }
38
40 {
41 return mesh->num_triangles();
42 }
43
44 int GetNumVerticesOfFace(const int /*face_num*/)
45 {
46 return 3;
47 }
48
49 int CornerIndex(const int face_num, const int vert_num)
50 {
51 return face_num * 3 + vert_num;
52 }
53
54 int VertexIndex(const int face_num, const int vert_num)
55 {
56 const int corner = CornerIndex(face_num, vert_num);
57 return mesh->get_triangles()[corner];
58 }
59
60 mikk::float3 GetPosition(const int face_num, const int vert_num)
61 {
62 const float3 vP = mesh->get_verts()[VertexIndex(face_num, vert_num)];
63 return mikk::float3(vP.x, vP.y, vP.z);
64 }
65
66 mikk::float3 GetTexCoord(const int face_num, const int vert_num)
67 {
68 /* TODO: Check whether introducing a template boolean in order to
69 * turn this into a constexpr is worth it. */
70 if (has_uv()) {
71 const int corner_index = CornerIndex(face_num, vert_num);
72 const float2 tfuv = uv[corner_index];
73 return mikk::float3(tfuv.x, tfuv.y, 1.0f);
74 }
75 /* revert to vertex position */
76 const float3 vP = mesh->get_verts()[VertexIndex(face_num, vert_num)];
77 const float2 uv = map_to_sphere(vP);
78 return mikk::float3(uv.x, uv.y, 1.0f);
79 }
80
81 mikk::float3 GetNormal(const int face_num, const int vert_num)
82 {
83 float3 vN;
84 if (mesh->get_smooth()[face_num]) {
85 const int vertex_index = VertexIndex(face_num, vert_num);
86 vN = normal[vertex_index];
87 }
88 else {
89 const Mesh::Triangle tri = mesh->get_triangle(face_num);
90 vN = tri.compute_normal(mesh->get_verts().data());
91 }
92 return mikk::float3(vN.x, vN.y, vN.z);
93 }
94
95 void SetTangentSpace(const int face_num, const int vert_num, mikk::float3 T, bool orientation)
96 {
97 const int corner_index = CornerIndex(face_num, vert_num);
98 tangent[corner_index] = make_float3(T.x, T.y, T.z);
99 if (tangent_sign != nullptr) {
100 tangent_sign[corner_index] = orientation ? 1.0f : -1.0f;
101 }
102 }
103
104 bool has_uv() const
105 {
106 return uv != nullptr;
107 }
108
109 const Mesh *mesh;
110
112 const float2 *uv;
113
116};
117
118static void mikk_compute_tangents(Attribute *attr_uv,
119 Mesh *mesh,
120 const bool need_sign,
121 const AttributeStandard tangent_std,
122 const AttributeStandard tangent_sign_std,
123 const char *tangent_postfix,
124 const char *tangent_sign_postfix)
125{
126 /* Create tangent attributes. */
127 AttributeSet &attributes = mesh->attributes;
128
129 Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
130 if (attr_vN == nullptr) {
131 /* no normals */
132 return;
133 }
134
135 const float3 *normal = attr_vN->data_float3();
136 const float2 *uv = (attr_uv) ? attr_uv->data_float2() : nullptr;
137
138 const ustring name = ustring((attr_uv) ? attr_uv->name.string() + tangent_postfix :
139 Attribute::standard_name(tangent_std));
140 Attribute *attr;
141 if (attr_uv == nullptr || attr_uv->std == ATTR_STD_UV) {
142 attr = attributes.add(tangent_std, name);
143 }
144 else {
145 attr = attributes.add(name, TypeVector, ATTR_ELEMENT_CORNER);
146 }
147 float3 *tangent = attr->data_float3();
148 /* Create bitangent sign attribute. */
149 float *tangent_sign = nullptr;
150 if (need_sign) {
151 const ustring name_sign = ustring((attr_uv) ? attr_uv->name.string() + tangent_sign_postfix :
152 Attribute::standard_name(tangent_sign_std));
153 Attribute *attr_sign;
154 if (attr_uv == nullptr || attr_uv->std == ATTR_STD_UV) {
155 attr_sign = attributes.add(tangent_sign_std, name_sign);
156 }
157 else {
158 attr_sign = attributes.add(name_sign, TypeFloat, ATTR_ELEMENT_CORNER);
159 }
160 tangent_sign = attr_sign->data_float();
161 }
162
163 MikkMeshWrapper userdata(mesh, normal, uv, tangent, tangent_sign);
164 /* Compute tangents. */
165 mikk::Mikktspace(userdata).genTangSpace();
166}
167
168/* Triangle */
169
171{
172 bounds.grow(verts[v[0]]);
173 bounds.grow(verts[v[1]]);
174 bounds.grow(verts[v[2]]);
175}
176
178 const float3 *vert_steps,
179 const size_t num_verts,
180 const size_t num_steps,
181 const float time,
182 float3 r_verts[3]) const
183{
184 /* Figure out which steps we need to fetch and their interpolation factor. */
185 const size_t max_step = num_steps - 1;
186 const size_t step = min((size_t)(time * max_step), max_step - 1);
187 const float t = time * max_step - step;
188 /* Fetch vertex coordinates. */
189 float3 curr_verts[3];
190 float3 next_verts[3];
191 verts_for_step(verts, vert_steps, num_verts, num_steps, step, curr_verts);
192 verts_for_step(verts, vert_steps, num_verts, num_steps, step + 1, next_verts);
193 /* Interpolate between steps. */
194 r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
195 r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
196 r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
197}
198
200 const float3 *vert_steps,
201 const size_t num_verts,
202 const size_t num_steps,
203 size_t step,
204 float3 r_verts[3]) const
205{
206 const size_t center_step = ((num_steps - 1) / 2);
207 if (step == center_step) {
208 /* Center step: regular vertex location. */
209 r_verts[0] = verts[v[0]];
210 r_verts[1] = verts[v[1]];
211 r_verts[2] = verts[v[2]];
212 }
213 else {
214 /* Center step not stored in the attribute array. */
215 if (step > center_step) {
216 step--;
217 }
218 const size_t offset = step * num_verts;
219 r_verts[0] = vert_steps[offset + v[0]];
220 r_verts[1] = vert_steps[offset + v[1]];
221 r_verts[2] = vert_steps[offset + v[2]];
222 }
223}
224
226{
227 const float3 &v0 = verts[v[0]];
228 const float3 &v1 = verts[v[1]];
229 const float3 &v2 = verts[v[2]];
230 const float3 norm = cross(v1 - v0, v2 - v0);
231 const float normlen = len(norm);
232 if (normlen == 0.0f) {
233 return make_float3(1.0f, 0.0f, 0.0f);
234 }
235 return norm / normlen;
236}
237
239{
240 return isfinite_safe(verts[v[0]]) && isfinite_safe(verts[v[1]]) && isfinite_safe(verts[v[2]]);
241}
242
243/* SubdFace */
244
246{
247 const float3 v0 = mesh->verts[mesh->subd_face_corners[start_corner + 0]];
248 const float3 v1 = mesh->verts[mesh->subd_face_corners[start_corner + 1]];
249 const float3 v2 = mesh->verts[mesh->subd_face_corners[start_corner + 2]];
250
251 return safe_normalize(cross(v1 - v0, v2 - v0));
252}
253
254/* Mesh */
255
257{
258 NodeType *type = NodeType::add("mesh", create, NodeType::NONE, Geometry::get_node_base_type());
259
260 SOCKET_INT_ARRAY(triangles, "Triangles", array<int>());
261 SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>());
262 SOCKET_INT_ARRAY(shader, "Shader", array<int>());
263 SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
264
265 static NodeEnum subdivision_type_enum;
266 subdivision_type_enum.insert("none", SUBDIVISION_NONE);
267 subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR);
268 subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
269 SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
270
271 static NodeEnum subdivision_boundary_interpolation_enum;
272 subdivision_boundary_interpolation_enum.insert("none", SUBDIVISION_BOUNDARY_NONE);
273 subdivision_boundary_interpolation_enum.insert("edge_only", SUBDIVISION_BOUNDARY_EDGE_ONLY);
274 subdivision_boundary_interpolation_enum.insert("edge_and_corner",
276 SOCKET_ENUM(subdivision_boundary_interpolation,
277 "Subdivision Boundary Interpolation",
278 subdivision_boundary_interpolation_enum,
280
281 static NodeEnum subdivision_fvar_interpolation_enum;
282 subdivision_fvar_interpolation_enum.insert("none", SUBDIVISION_FVAR_LINEAR_NONE);
283 subdivision_fvar_interpolation_enum.insert("corners_only", SUBDIVISION_FVAR_LINEAR_CORNERS_ONLY);
284 subdivision_fvar_interpolation_enum.insert("corners_plus1",
286 subdivision_fvar_interpolation_enum.insert("corners_plus2",
288 subdivision_fvar_interpolation_enum.insert("boundaries", SUBDIVISION_FVAR_LINEAR_BOUNDARIES);
289 subdivision_fvar_interpolation_enum.insert("all", SUBDIVISION_FVAR_LINEAR_ALL);
290 SOCKET_ENUM(subdivision_fvar_interpolation,
291 "Subdivision Face-Varying Interpolation",
292 subdivision_fvar_interpolation_enum,
294
295 SOCKET_INT_ARRAY(subd_vert_creases, "Subdivision Vertex Crease", array<int>());
297 subd_vert_creases_weight, "Subdivision Vertex Crease Weights", array<float>());
298 SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
299 SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
300 SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
301 SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>());
302 SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>());
303 SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>());
304 SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>());
305 SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>());
306
307 /* Subdivisions parameters */
308 static NodeEnum subd_adaptive_space_enum;
309 subd_adaptive_space_enum.insert("pixel", SUBDIVISION_ADAPTIVE_SPACE_PIXEL);
310 subd_adaptive_space_enum.insert("object", SUBDIVISION_ADAPTIVE_SPACE_OBJECT);
311
312 SOCKET_ENUM(subd_adaptive_space,
313 "Subdivision Adaptive Space",
314 subd_adaptive_space_enum,
316 SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 1.0f)
317 SOCKET_INT(subd_max_level, "Max Subdivision Level", 1);
318 SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity());
319
320 return type;
321}
322
324{
325 return (subdivision_type != SUBDIVISION_NONE) &&
326 (verts_is_modified() || subd_dicing_rate_is_modified() ||
327 subd_adaptive_space_is_modified() || subd_objecttoworld_is_modified() ||
328 subd_max_level_is_modified());
329}
330
331Mesh::Mesh(const NodeType *node_type, Type geom_type_)
332 : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD)
333{
334 vert_offset = 0;
335
336 face_offset = 0;
337 corner_offset = 0;
338
339 num_subd_added_verts = 0;
340 num_subd_faces = 0;
341
342 subdivision_type = SUBDIVISION_NONE;
343}
344
345Mesh::Mesh() : Mesh(get_node_type(), Geometry::MESH) {}
346
347void Mesh::resize_mesh(const int numverts, const int numtris)
348{
349 verts.resize(numverts);
350 triangles.resize(numtris * 3);
351 shader.resize(numtris);
352 smooth.resize(numtris);
353
354 attributes.resize();
355}
356
357void Mesh::reserve_mesh(const int numverts, const int numtris)
358{
359 /* reserve space to add verts and triangles later */
360 verts.reserve(numverts);
361 triangles.reserve(numtris * 3);
362 shader.reserve(numtris);
363 smooth.reserve(numtris);
364
365 attributes.resize(true);
366}
367
368void Mesh::resize_subd_faces(const int numfaces, const int numcorners)
369{
370 subd_start_corner.resize(numfaces);
371 subd_num_corners.resize(numfaces);
372 subd_shader.resize(numfaces);
373 subd_smooth.resize(numfaces);
374 subd_ptex_offset.resize(numfaces);
375 subd_face_corners.resize(numcorners);
376 num_subd_faces = numfaces;
377
378 subd_attributes.resize();
379}
380
381void Mesh::reserve_subd_faces(const int numfaces, const int numcorners)
382{
383 subd_start_corner.reserve(numfaces);
384 subd_num_corners.reserve(numfaces);
385 subd_shader.reserve(numfaces);
386 subd_smooth.reserve(numfaces);
387 subd_ptex_offset.reserve(numfaces);
388 subd_face_corners.reserve(numcorners);
389 num_subd_faces = numfaces;
390
391 subd_attributes.resize(true);
392}
393
394void Mesh::reserve_subd_creases(const size_t num_creases)
395{
396 subd_creases_edge.reserve(num_creases * 2);
397 subd_creases_weight.reserve(num_creases);
398}
399
401{
402 Geometry::clear(true);
403
404 num_subd_added_verts = 0;
405 num_subd_faces = 0;
406}
407
408void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
409{
410 Geometry::clear(preserve_shaders);
411
412 /* clear all verts and triangles */
413 verts.clear();
414 triangles.clear();
415 shader.clear();
416 smooth.clear();
417
418 subd_start_corner.clear();
419 subd_num_corners.clear();
420 subd_shader.clear();
421 subd_smooth.clear();
422 subd_ptex_offset.clear();
423 subd_face_corners.clear();
424
425 subd_creases_edge.clear();
426 subd_creases_weight.clear();
427
428 subd_attributes.clear();
429 attributes.clear(preserve_voxel_data);
430
431 subdivision_type = SubdivisionType::SUBDIVISION_NONE;
432
434}
435
436void Mesh::clear(bool preserve_shaders)
437{
438 clear(preserve_shaders, false);
439}
440
442{
443 verts.push_back_reserved(P);
444 tag_verts_modified();
445}
446
448{
449 verts.push_back_slow(P);
450 tag_verts_modified();
451}
452
453void Mesh::add_triangle(const int v0, const int v1, const int v2, const int shader_, bool smooth_)
454{
455 triangles.push_back_reserved(v0);
456 triangles.push_back_reserved(v1);
457 triangles.push_back_reserved(v2);
458 shader.push_back_reserved(shader_);
459 smooth.push_back_reserved(smooth_);
460
461 tag_triangles_modified();
462 tag_shader_modified();
463 tag_smooth_modified();
464}
465
466void Mesh::add_subd_face(const int *corners,
467 const int num_corners,
468 const int shader_,
469 bool smooth_)
470{
471 const int start_corner = subd_face_corners.size();
472
473 for (int i = 0; i < num_corners; i++) {
474 subd_face_corners.push_back_reserved(corners[i]);
475 }
476
477 int ptex_offset = 0;
478 // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not
479 // have the total amount of data yet
480 if (subd_shader.size()) {
481 const SubdFace s = get_subd_face(subd_shader.size() - 1);
482 ptex_offset = s.ptex_offset + s.num_ptex_faces();
483 }
484
485 subd_start_corner.push_back_reserved(start_corner);
486 subd_num_corners.push_back_reserved(num_corners);
487 subd_shader.push_back_reserved(shader_);
488 subd_smooth.push_back_reserved(smooth_);
489 subd_ptex_offset.push_back_reserved(ptex_offset);
490
491 tag_subd_face_corners_modified();
492 tag_subd_start_corner_modified();
493 tag_subd_num_corners_modified();
494 tag_subd_shader_modified();
495 tag_subd_smooth_modified();
496 tag_subd_ptex_offset_modified();
497}
498
500{
502 s.shader = subd_shader[index];
503 s.num_corners = subd_num_corners[index];
504 s.smooth = subd_smooth[index];
505 s.ptex_offset = subd_ptex_offset[index];
506 s.start_corner = subd_start_corner[index];
507 return s;
508}
509
510void Mesh::add_edge_crease(const int v0, const int v1, const float weight)
511{
512 subd_creases_edge.push_back_slow(v0);
513 subd_creases_edge.push_back_slow(v1);
514 subd_creases_weight.push_back_slow(weight);
515
516 tag_subd_creases_edge_modified();
517 tag_subd_creases_edge_modified();
518 tag_subd_creases_weight_modified();
519}
520
521void Mesh::add_vertex_crease(const int v, const float weight)
522{
523 subd_vert_creases.push_back_slow(v);
524 subd_vert_creases_weight.push_back_slow(weight);
525
526 tag_subd_vert_creases_modified();
527 tag_subd_vert_creases_weight_modified();
528}
529
531{
533
534 if (attr_mP) {
537 float3 *P = verts.data();
538 float3 *N = (attr_N) ? attr_N->data_float3() : nullptr;
539 const size_t numverts = verts.size();
540
541 std::copy_n(P, numverts, attr_mP->data_float3() + motion_step * numverts);
542 if (attr_mN) {
543 std::copy_n(N, numverts, attr_mN->data_float3() + motion_step * numverts);
544 }
545 }
546}
547
548void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
549{
550 Attribute *attr;
551 Attribute *subd_attr;
552
553 if (map.empty()) {
554 attr = attributes.find(ATTR_STD_UV);
555 subd_attr = subd_attributes.find(ATTR_STD_UV);
556 }
557 else {
558 attr = attributes.find(map);
559 subd_attr = subd_attributes.find(map);
560 }
561
562 if (attr) {
564 }
565 if (subd_attr) {
566 subd_attr->get_uv_tiles(this, ATTR_PRIM_SUBD, tiles);
567 }
568}
569
571{
573 const size_t verts_size = verts.size();
574
575 if (verts_size > 0) {
576 for (size_t i = 0; i < verts_size; i++) {
577 bnds.grow(verts[i]);
578 }
579
581 if (use_motion_blur && attr) {
582 const size_t steps_size = verts.size() * (motion_steps - 1);
583 float3 *vert_steps = attr->data_float3();
584
585 for (size_t i = 0; i < steps_size; i++) {
586 bnds.grow(vert_steps[i]);
587 }
588 }
589
590 if (!bnds.valid()) {
591 bnds = BoundBox::empty;
592
593 /* skip nan or inf coordinates */
594 for (size_t i = 0; i < verts_size; i++) {
595 bnds.grow_safe(verts[i]);
596 }
597
598 if (use_motion_blur && attr) {
599 const size_t steps_size = verts.size() * (motion_steps - 1);
600 float3 *vert_steps = attr->data_float3();
601
602 for (size_t i = 0; i < steps_size; i++) {
603 bnds.grow_safe(vert_steps[i]);
604 }
605 }
606 }
607 }
608
609 if (!bnds.valid()) {
610 /* empty mesh */
611 bnds.grow(zero_float3());
612 }
613
614 bounds = bnds;
615}
616
617void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
618{
620
621 /* apply to mesh vertices */
622 const size_t num_verts = verts.size();
623 for (size_t i = 0; i < num_verts; i++) {
624 verts[i] = transform_point(&tfm, verts[i]);
625 }
626
627 tag_verts_modified();
628
629 if (apply_to_motion) {
631
632 if (attr) {
633 const size_t steps_size = verts.size() * (motion_steps - 1);
634 float3 *vert_steps = attr->data_float3();
635
636 for (size_t i = 0; i < steps_size; i++) {
637 vert_steps[i] = transform_point(&tfm, vert_steps[i]);
638 }
639 }
640
642
643 if (attr_N) {
644 const Transform ntfm = transform_normal;
645 const size_t steps_size = verts.size() * (motion_steps - 1);
646 float3 *normal_steps = attr_N->data_float3();
647
648 for (size_t i = 0; i < steps_size; i++) {
649 normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
650 }
651 }
652 }
653}
654
656{
657 const bool flip = transform_negative_scaled;
658 const size_t verts_size = verts.size();
659 const size_t triangles_size = num_triangles();
660
661 /* static vertex normals */
662 if (!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
663 /* get attributes */
665
666 float3 *verts_ptr = verts.data();
667 float3 *vN = attr_vN->data_float3();
668
669 /* compute vertex normals */
670 std::fill_n(vN, verts.size(), zero_float3());
671
672 for (size_t i = 0; i < triangles_size; i++) {
673 const float3 fN = get_triangle(i).compute_normal(verts_ptr);
674 for (size_t j = 0; j < 3; j++) {
675 vN[get_triangle(i).v[j]] += fN;
676 }
677 }
678
679 if (flip) {
680 for (size_t i = 0; i < verts_size; i++) {
681 vN[i] = -normalize(vN[i]);
682 }
683 }
684 else {
685 for (size_t i = 0; i < verts_size; i++) {
686 vN[i] = normalize(vN[i]);
687 }
688 }
689 }
690
691 /* motion vertex normals */
694
695 if (has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
696 /* create attribute */
698
699 for (int step = 0; step < motion_steps - 1; step++) {
700 float3 *mP = attr_mP->data_float3() + step * verts.size();
701 float3 *mN = attr_mN->data_float3() + step * verts.size();
702
703 /* compute */
704 std::fill_n(mN, verts.size(), zero_float3());
705
706 for (size_t i = 0; i < triangles_size; i++) {
707 const Triangle tri = get_triangle(i);
708 const float3 fN = tri.compute_normal(mP);
709 for (size_t j = 0; j < 3; j++) {
710 mN[tri.v[j]] += fN;
711 }
712 }
713
714 if (flip) {
715 for (size_t i = 0; i < verts_size; i++) {
716 mN[i] = -normalize(mN[i]);
717 }
718 }
719 else {
720 for (size_t i = 0; i < verts_size; i++) {
721 mN[i] = normalize(mN[i]);
722 }
723 }
724 }
725 }
726
727 /* subd vertex normals */
729 /* get attributes */
731 float3 *vN = attr_vN->data_float3();
732
733 /* compute vertex normals */
734 std::fill_n(vN, verts.size(), zero_float3());
735
736 for (size_t i = 0; i < get_num_subd_faces(); i++) {
737 const SubdFace face = get_subd_face(i);
738 const float3 fN = face.normal(this);
739
740 for (size_t j = 0; j < face.num_corners; j++) {
741 const size_t corner = subd_face_corners[face.start_corner + j];
742 vN[corner] += fN;
743 }
744 }
745
746 if (flip) {
747 for (size_t i = 0; i < verts_size; i++) {
748 vN[i] = -normalize(vN[i]);
749 }
750 }
751 else {
752 for (size_t i = 0; i < verts_size; i++) {
753 vN[i] = normalize(vN[i]);
754 }
755 }
756 }
757}
758
760{
763 {
764 /* Copy position to attribute. */
766
767 size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY) / sizeof(float3);
768 std::copy_n(verts.data(), size, attr->data_float3());
769 }
770
773 {
774 /* Copy vertex normal to attribute */
776 if (attr_N) {
778
779 size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY) / sizeof(float3);
780 std::copy_n(attr_N->data_float3(), size, attr->data_float3());
781 }
782 }
783}
784
786{
787 if (!num_triangles()) {
788 return;
789 }
790
791 AttributeSet &attrs = num_subd_faces ? subd_attributes : attributes;
792
793 /* apply generated attributes if needed or missing */
795 const size_t verts_size = verts.size();
796 Attribute *attr_generated = attrs.add(ATTR_STD_GENERATED);
797 float3 *generated = attr_generated->data_float3();
798 for (size_t i = 0; i < verts_size; ++i) {
799 generated[i] = verts[i];
800 }
801 }
802}
803
804void Mesh::update_tangents(Scene *scene, bool undisplaced)
805{
806 if (!num_triangles()) {
807 return;
808 }
809
811
812 ccl::set<ustring> uv_maps;
813 Attribute *attr_std_uv = attributes.find(ATTR_STD_UV);
814
815 AttributeStandard tangent_std = (undisplaced) ? ATTR_STD_UV_TANGENT_UNDISPLACED :
817 AttributeStandard tangent_sign_std = (undisplaced) ? ATTR_STD_UV_TANGENT_SIGN_UNDISPLACED :
819 const char *tangent_postfix = (undisplaced) ? ".undisplaced_tangent" : ".tangent";
820 const char *tangent_sign_postfix = (undisplaced) ? ".undisplaced_tangent_sign" : ".tangent_sign";
821
822 /* standard UVs */
823 if ((need_attribute(scene, tangent_std) || need_attribute(scene, tangent_sign_std)) &&
824 !attributes.find(tangent_std))
825 {
826 mikk_compute_tangents(attr_std_uv,
827 this,
828 true,
829 tangent_std,
830 tangent_sign_std,
831 tangent_postfix,
832 tangent_sign_postfix); /* sign */
833 }
834
835 /* now generate for any other UVs requested */
836 for (Attribute &attr : attributes.attributes) {
837 if (!(attr.type == TypeFloat2 && attr.element == ATTR_ELEMENT_CORNER)) {
838 continue;
839 }
840
841 const ustring tangent_name = ustring(attr.name.string() + tangent_postfix);
842 const ustring tangent_sign_name = ustring(attr.name.string() + tangent_sign_postfix);
843
844 if ((need_attribute(scene, tangent_name) || need_attribute(scene, tangent_sign_name)) &&
845 !attributes.find(tangent_name))
846 {
848 this,
849 true,
850 tangent_std,
851 tangent_sign_std,
852 tangent_postfix,
853 tangent_sign_postfix); /* sign */
854 }
855 }
856}
857
858void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
859{
860 uint shader_id = 0;
861 uint last_shader = -1;
862 bool last_smooth = false;
863
864 const size_t triangles_size = num_triangles();
865 const int *shader_ptr = shader.data();
866 const bool *smooth_ptr = smooth.data();
867
868 for (size_t i = 0; i < triangles_size; i++) {
869 const int new_shader = shader_ptr ? shader_ptr[i] : INT_MAX;
870 const bool new_smooth = smooth_ptr ? smooth_ptr[i] : false;
871
872 if (new_shader != last_shader || last_smooth != new_smooth) {
873 last_shader = new_shader;
874 last_smooth = new_smooth;
875 Shader *shader = (last_shader < used_shaders.size()) ?
876 static_cast<Shader *>(used_shaders[last_shader]) :
877 scene->default_surface;
878 shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
879 }
880
881 tri_shader[i] = shader_id;
882 }
883}
884
886{
888 if (attr_vN == nullptr) {
889 /* Happens on objects with just hair. */
890 return;
891 }
892
893 const bool do_transform = transform_applied;
894 const Transform ntfm = transform_normal;
895
896 float3 *vN = attr_vN->data_float3();
897 const size_t verts_size = verts.size();
898
899 if (do_transform) {
900 for (size_t i = 0; i < verts_size; i++) {
901 vnormal[i] = safe_normalize(transform_direction(&ntfm, vN[i]));
902 }
903 }
904 else {
905 for (size_t i = 0; i < verts_size; i++) {
906 vnormal[i] = vN[i];
907 }
908 }
909}
910
911void Mesh::pack_verts(packed_float3 *tri_verts, packed_uint3 *tri_vindex)
912{
913 const size_t verts_size = verts.size();
914 const size_t triangles_size = num_triangles();
915 const int *p_tris = triangles.data();
916 int off = 0;
917 for (size_t i = 0; i < verts_size; i++) {
918 tri_verts[i] = verts[i];
919 }
920 for (size_t i = 0; i < triangles_size; i++) {
921 tri_vindex[i] = make_packed_uint3(p_tris[off + 0] + vert_offset,
922 p_tris[off + 1] + vert_offset,
923 p_tris[off + 2] + vert_offset);
924 off += 3;
925 }
926}
927
929{
930 return use_motion_blur && (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
931 (get_subdivision_type() != Mesh::SUBDIVISION_NONE &&
933}
934
939
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
unsigned int uint
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
Attribute * find(ustring name) const
Attribute * add(ustring name, const TypeDesc type, AttributeElement element)
Transform transform_normal
int motion_step(const float time) const
BoundBox bounds
bool transform_applied
bool need_attribute(Scene *scene, AttributeStandard std)
AttributeSet attributes
Geometry(const NodeType *node_type, const Type type)
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)
static float verts[][3]
#define assert(assertion)
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
PrimitiveType
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_TRIANGLE
AttributeStandard
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_NORMAL
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_UV_TANGENT
@ ATTR_STD_POSITION_UNDISPLACED
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_NORMAL_UNDISPLACED
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_UV_TANGENT_SIGN_UNDISPLACED
@ ATTR_STD_UV_TANGENT_UNDISPLACED
@ ATTR_STD_GENERATED
@ ATTR_ELEMENT_CORNER
@ ATTR_PRIM_SUBD
@ ATTR_PRIM_GEOMETRY
ccl_device_inline bool isfinite_safe(const float f)
Definition math_base.h:348
ccl_device_inline float2 safe_normalize(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
#define N
#define T
#define SOCKET_BOOLEAN_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:254
#define SOCKET_POINT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:268
#define SOCKET_FLOAT(name, ui_name, default_value,...)
Definition node_type.h:211
#define SOCKET_INT(name, ui_name, default_value,...)
Definition node_type.h:205
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:259
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
Definition node_type.h:225
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:257
#define NODE_DEFINE(structname)
Definition node_type.h:152
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
Definition node_type.h:227
const char * name
static void mikk_compute_tangents(Attribute *attr_uv, Mesh *mesh, const bool need_sign, const AttributeStandard tangent_std, const AttributeStandard tangent_sign_std, const char *tangent_postfix, const char *tangent_sign_postfix)
#define min(a, b)
Definition sort.cc:36
const char * name
AttributeElement element
TypeDesc type
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
static const char * standard_name(AttributeStandard std)
float * data_float()
size_t buffer_size(Geometry *geom, AttributePrimitive prim) const
AttributeStandard std
float3 * data_float3()
float2 * data_float2()
__forceinline bool valid() const
Definition boundbox.h:127
__forceinline void grow_safe(const float3 &pt)
Definition boundbox.h:56
__forceinline void grow(const float3 &pt)
Definition boundbox.h:35
int num_ptex_faces() const
Definition scene/mesh.h:95
float3 normal(const Mesh *mesh) const
bool valid(const float3 *verts) const
void bounds_grow(const float3 *verts, BoundBox &bounds) const
void motion_verts(const float3 *verts, const float3 *vert_steps, const size_t num_verts, const size_t num_steps, const float time, float3 r_verts[3]) const
float3 compute_normal(const float3 *verts) const
void verts_for_step(const float3 *verts, const float3 *vert_steps, const size_t num_verts, const size_t num_steps, const size_t step, float3 r_verts[3]) const
size_t get_num_subd_faces() const
Definition scene/mesh.h:235
void add_undisplaced(Scene *scene)
@ SUBDIVISION_ADAPTIVE_SPACE_OBJECT
Definition scene/mesh.h:140
@ SUBDIVISION_ADAPTIVE_SPACE_PIXEL
Definition scene/mesh.h:139
size_t face_offset
Definition scene/mesh.h:179
void add_triangle(const int v0, const int v1, const int v2, const int shader, bool smooth)
void reserve_subd_creases(const size_t num_creases)
size_t vert_offset
Definition scene/mesh.h:177
void compute_bounds() override
size_t corner_offset
Definition scene/mesh.h:180
void add_vertex_normals()
AttributeSet subd_attributes
Definition scene/mesh.h:174
void copy_center_to_motion_step(const int motion_step)
Mesh(const NodeType *node_type_, Type geom_type_)
void clear(bool preserve_shaders=false) override
void add_vertex_slow(const float3 P)
bool has_motion_blur() const override
void pack_verts(packed_float3 *tri_verts, packed_uint3 *tri_vindex)
@ SUBDIVISION_FVAR_LINEAR_NONE
Definition scene/mesh.h:130
@ SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS2
Definition scene/mesh.h:133
@ SUBDIVISION_FVAR_LINEAR_CORNERS_ONLY
Definition scene/mesh.h:131
@ SUBDIVISION_FVAR_LINEAR_ALL
Definition scene/mesh.h:135
@ SUBDIVISION_FVAR_LINEAR_BOUNDARIES
Definition scene/mesh.h:134
@ SUBDIVISION_FVAR_LINEAR_CORNERS_PLUS1
Definition scene/mesh.h:132
void add_vertex_crease(const int v, const float weight)
SubdFace get_subd_face(const size_t index) const
void reserve_mesh(const int numverts, const int numtris)
bool need_tesselation()
@ SUBDIVISION_NONE
Definition scene/mesh.h:118
@ SUBDIVISION_LINEAR
Definition scene/mesh.h:119
@ SUBDIVISION_CATMULL_CLARK
Definition scene/mesh.h:120
void add_subd_face(const int *corners, const int num_corners, const int shader_, bool smooth_)
size_t num_triangles() const
Definition scene/mesh.h:77
void clear_non_sockets()
void resize_subd_faces(const int numfaces, const int numcorners)
void pack_normals(packed_float3 *vnormal)
void add_vertex(const float3 P)
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
void resize_mesh(const int numverts, const int numtris)
void update_generated(Scene *scene)
Triangle get_triangle(const size_t i) const
Definition scene/mesh.h:71
void pack_shaders(Scene *scene, uint *shader)
PrimitiveType primitive_type() const override
void reserve_subd_faces(const int numfaces, const int numcorners)
void add_edge_crease(const int v0, const int v1, const float weight)
void update_tangents(Scene *scene, bool undisplaced)
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
@ SUBDIVISION_BOUNDARY_EDGE_ONLY
Definition scene/mesh.h:125
@ SUBDIVISION_BOUNDARY_EDGE_AND_CORNER
Definition scene/mesh.h:126
@ SUBDIVISION_BOUNDARY_NONE
Definition scene/mesh.h:124
const float3 * normal
mikk::float3 GetNormal(const int face_num, const int vert_num)
MikkMeshWrapper(const Mesh *mesh, const float3 *normal, const float2 *uv, float3 *tangent, float *tangent_sign)
int VertexIndex(const int face_num, const int vert_num)
const float2 * uv
void SetTangentSpace(const int face_num, const int vert_num, mikk::float3 T, bool orientation)
int CornerIndex(const int face_num, const int vert_num)
int GetNumVerticesOfFace(const int)
const Mesh * mesh
bool has_uv() const
mikk::float3 GetPosition(const int face_num, const int vert_num)
mikk::float3 GetTexCoord(const int face_num, const int vert_num)
void insert(const char *x, const int y)
Definition node_enum.h:21
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
const NodeType * type
Definition graph/node.h:178
Shader * default_surface
Definition scene.h:157
unique_ptr< ShaderManager > shader_manager
Definition scene.h:148
float x
float y
float z
Definition sky_math.h:136
float y
Definition sky_math.h:136
float x
Definition sky_math.h:136
i
Definition text_draw.cc:230
CCL_NAMESPACE_BEGIN Transform transform_transposed_inverse(const Transform &tfm)
Definition transform.cpp:15
ccl_device_inline Transform transform_identity()
Definition transform.h:322
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:127
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56
ccl_device_inline packed_uint3 make_packed_uint3(const uint x, const uint y, uint z)
Definition types_uint3.h:85
uint len