Blender V4.5
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 (uv != nullptr) {
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 const Mesh *mesh;
105
107 const float2 *uv;
108
111};
112
113static void mikk_compute_tangents(Attribute *attr_uv, Mesh *mesh, const bool need_sign)
114{
115 /* Create tangent attributes. */
116 AttributeSet &attributes = mesh->attributes;
117
118 Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
119 if (attr_vN == nullptr) {
120 /* no normals */
121 return;
122 }
123
124 const float3 *normal = attr_vN->data_float3();
125 const float2 *uv = (attr_uv) ? attr_uv->data_float2() : nullptr;
126
127 const ustring name = ustring((attr_uv) ? attr_uv->name.string() + ".tangent" :
129 Attribute *attr;
130 if (attr_uv == nullptr || attr_uv->std == ATTR_STD_UV) {
131 attr = attributes.add(ATTR_STD_UV_TANGENT, name);
132 }
133 else {
134 attr = attributes.add(name, TypeVector, ATTR_ELEMENT_CORNER);
135 }
136 float3 *tangent = attr->data_float3();
137 /* Create bitangent sign attribute. */
138 float *tangent_sign = nullptr;
139 if (need_sign) {
140 const ustring name_sign = ustring((attr_uv) ?
141 attr_uv->name.string() + ".tangent_sign" :
143 Attribute *attr_sign;
144 if (attr_uv == nullptr || attr_uv->std == ATTR_STD_UV) {
145 attr_sign = attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
146 }
147 else {
148 attr_sign = attributes.add(name_sign, TypeFloat, ATTR_ELEMENT_CORNER);
149 }
150 tangent_sign = attr_sign->data_float();
151 }
152
153 MikkMeshWrapper userdata(mesh, normal, uv, tangent, tangent_sign);
154 /* Compute tangents. */
155 mikk::Mikktspace(userdata).genTangSpace();
156}
157
158/* Triangle */
159
161{
162 bounds.grow(verts[v[0]]);
163 bounds.grow(verts[v[1]]);
164 bounds.grow(verts[v[2]]);
165}
166
168 const float3 *vert_steps,
169 const size_t num_verts,
170 const size_t num_steps,
171 const float time,
172 float3 r_verts[3]) const
173{
174 /* Figure out which steps we need to fetch and their interpolation factor. */
175 const size_t max_step = num_steps - 1;
176 const size_t step = min((size_t)(time * max_step), max_step - 1);
177 const float t = time * max_step - step;
178 /* Fetch vertex coordinates. */
179 float3 curr_verts[3];
180 float3 next_verts[3];
181 verts_for_step(verts, vert_steps, num_verts, num_steps, step, curr_verts);
182 verts_for_step(verts, vert_steps, num_verts, num_steps, step + 1, next_verts);
183 /* Interpolate between steps. */
184 r_verts[0] = (1.0f - t) * curr_verts[0] + t * next_verts[0];
185 r_verts[1] = (1.0f - t) * curr_verts[1] + t * next_verts[1];
186 r_verts[2] = (1.0f - t) * curr_verts[2] + t * next_verts[2];
187}
188
190 const float3 *vert_steps,
191 const size_t num_verts,
192 const size_t num_steps,
193 size_t step,
194 float3 r_verts[3]) const
195{
196 const size_t center_step = ((num_steps - 1) / 2);
197 if (step == center_step) {
198 /* Center step: regular vertex location. */
199 r_verts[0] = verts[v[0]];
200 r_verts[1] = verts[v[1]];
201 r_verts[2] = verts[v[2]];
202 }
203 else {
204 /* Center step not stored in the attribute array. */
205 if (step > center_step) {
206 step--;
207 }
208 const size_t offset = step * num_verts;
209 r_verts[0] = vert_steps[offset + v[0]];
210 r_verts[1] = vert_steps[offset + v[1]];
211 r_verts[2] = vert_steps[offset + v[2]];
212 }
213}
214
216{
217 const float3 &v0 = verts[v[0]];
218 const float3 &v1 = verts[v[1]];
219 const float3 &v2 = verts[v[2]];
220 const float3 norm = cross(v1 - v0, v2 - v0);
221 const float normlen = len(norm);
222 if (normlen == 0.0f) {
223 return make_float3(1.0f, 0.0f, 0.0f);
224 }
225 return norm / normlen;
226}
227
229{
230 return isfinite_safe(verts[v[0]]) && isfinite_safe(verts[v[1]]) && isfinite_safe(verts[v[2]]);
231}
232
233/* SubdFace */
234
236{
237 const float3 v0 = mesh->verts[mesh->subd_face_corners[start_corner + 0]];
238 const float3 v1 = mesh->verts[mesh->subd_face_corners[start_corner + 1]];
239 const float3 v2 = mesh->verts[mesh->subd_face_corners[start_corner + 2]];
240
241 return safe_normalize(cross(v1 - v0, v2 - v0));
242}
243
244/* Mesh */
245
247{
248 NodeType *type = NodeType::add("mesh", create, NodeType::NONE, Geometry::get_node_base_type());
249
250 SOCKET_INT_ARRAY(triangles, "Triangles", array<int>());
251 SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>());
252 SOCKET_INT_ARRAY(shader, "Shader", array<int>());
253 SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>());
254
255 static NodeEnum subdivision_type_enum;
256 subdivision_type_enum.insert("none", SUBDIVISION_NONE);
257 subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR);
258 subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
259 SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
260
261 static NodeEnum subdivision_boundary_interpolation_enum;
262 subdivision_boundary_interpolation_enum.insert("none", SUBDIVISION_BOUNDARY_NONE);
263 subdivision_boundary_interpolation_enum.insert("edge_only", SUBDIVISION_BOUNDARY_EDGE_ONLY);
264 subdivision_boundary_interpolation_enum.insert("edge_and_corner",
266 SOCKET_ENUM(subdivision_boundary_interpolation,
267 "Subdivision Boundary Interpolation",
268 subdivision_boundary_interpolation_enum,
270
271 static NodeEnum subdivision_fvar_interpolation_enum;
272 subdivision_fvar_interpolation_enum.insert("none", SUBDIVISION_FVAR_LINEAR_NONE);
273 subdivision_fvar_interpolation_enum.insert("corners_only", SUBDIVISION_FVAR_LINEAR_CORNERS_ONLY);
274 subdivision_fvar_interpolation_enum.insert("corners_plus1",
276 subdivision_fvar_interpolation_enum.insert("corners_plus2",
278 subdivision_fvar_interpolation_enum.insert("boundaries", SUBDIVISION_FVAR_LINEAR_BOUNDARIES);
279 subdivision_fvar_interpolation_enum.insert("all", SUBDIVISION_FVAR_LINEAR_ALL);
280 SOCKET_ENUM(subdivision_fvar_interpolation,
281 "Subdivision Face-Varying Interpolation",
282 subdivision_fvar_interpolation_enum,
284
285 SOCKET_INT_ARRAY(subd_vert_creases, "Subdivision Vertex Crease", array<int>());
287 subd_vert_creases_weight, "Subdivision Vertex Crease Weights", array<float>());
288 SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
289 SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
290 SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
291 SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>());
292 SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>());
293 SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>());
294 SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>());
295 SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>());
296
297 /* Subdivisions parameters */
298 SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 1.0f)
299 SOCKET_INT(subd_max_level, "Max Subdivision Level", 1);
300 SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity());
301
302 return type;
303}
304
306{
307 return (subdivision_type != SUBDIVISION_NONE) &&
308 (verts_is_modified() || subd_dicing_rate_is_modified() ||
309 subd_objecttoworld_is_modified() || subd_max_level_is_modified());
310}
311
312Mesh::Mesh(const NodeType *node_type, Type geom_type_)
313 : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD)
314{
315 vert_offset = 0;
316
317 face_offset = 0;
318 corner_offset = 0;
319
320 num_subd_added_verts = 0;
321 num_subd_faces = 0;
322
323 subdivision_type = SUBDIVISION_NONE;
324}
325
326Mesh::Mesh() : Mesh(get_node_type(), Geometry::MESH) {}
327
328void Mesh::resize_mesh(const int numverts, const int numtris)
329{
330 verts.resize(numverts);
331 triangles.resize(numtris * 3);
332 shader.resize(numtris);
333 smooth.resize(numtris);
334
335 attributes.resize();
336}
337
338void Mesh::reserve_mesh(const int numverts, const int numtris)
339{
340 /* reserve space to add verts and triangles later */
341 verts.reserve(numverts);
342 triangles.reserve(numtris * 3);
343 shader.reserve(numtris);
344 smooth.reserve(numtris);
345
346 attributes.resize(true);
347}
348
349void Mesh::resize_subd_faces(const int numfaces, const int numcorners)
350{
351 subd_start_corner.resize(numfaces);
352 subd_num_corners.resize(numfaces);
353 subd_shader.resize(numfaces);
354 subd_smooth.resize(numfaces);
355 subd_ptex_offset.resize(numfaces);
356 subd_face_corners.resize(numcorners);
357 num_subd_faces = numfaces;
358
359 subd_attributes.resize();
360}
361
362void Mesh::reserve_subd_faces(const int numfaces, const int numcorners)
363{
364 subd_start_corner.reserve(numfaces);
365 subd_num_corners.reserve(numfaces);
366 subd_shader.reserve(numfaces);
367 subd_smooth.reserve(numfaces);
368 subd_ptex_offset.reserve(numfaces);
369 subd_face_corners.reserve(numcorners);
370 num_subd_faces = numfaces;
371
372 subd_attributes.resize(true);
373}
374
375void Mesh::reserve_subd_creases(const size_t num_creases)
376{
377 subd_creases_edge.reserve(num_creases * 2);
378 subd_creases_weight.reserve(num_creases);
379}
380
382{
383 Geometry::clear(true);
384
385 num_subd_added_verts = 0;
386 num_subd_faces = 0;
387}
388
389void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
390{
391 Geometry::clear(preserve_shaders);
392
393 /* clear all verts and triangles */
394 verts.clear();
395 triangles.clear();
396 shader.clear();
397 smooth.clear();
398
399 subd_start_corner.clear();
400 subd_num_corners.clear();
401 subd_shader.clear();
402 subd_smooth.clear();
403 subd_ptex_offset.clear();
404 subd_face_corners.clear();
405
406 subd_creases_edge.clear();
407 subd_creases_weight.clear();
408
409 subd_attributes.clear();
410 attributes.clear(preserve_voxel_data);
411
412 subdivision_type = SubdivisionType::SUBDIVISION_NONE;
413
415}
416
417void Mesh::clear(bool preserve_shaders)
418{
419 clear(preserve_shaders, false);
420}
421
423{
424 verts.push_back_reserved(P);
425 tag_verts_modified();
426}
427
429{
430 verts.push_back_slow(P);
431 tag_verts_modified();
432}
433
434void Mesh::add_triangle(const int v0, const int v1, const int v2, const int shader_, bool smooth_)
435{
436 triangles.push_back_reserved(v0);
437 triangles.push_back_reserved(v1);
438 triangles.push_back_reserved(v2);
439 shader.push_back_reserved(shader_);
440 smooth.push_back_reserved(smooth_);
441
442 tag_triangles_modified();
443 tag_shader_modified();
444 tag_smooth_modified();
445}
446
447void Mesh::add_subd_face(const int *corners,
448 const int num_corners,
449 const int shader_,
450 bool smooth_)
451{
452 const int start_corner = subd_face_corners.size();
453
454 for (int i = 0; i < num_corners; i++) {
455 subd_face_corners.push_back_reserved(corners[i]);
456 }
457
458 int ptex_offset = 0;
459 // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not
460 // have the total amount of data yet
461 if (subd_shader.size()) {
462 const SubdFace s = get_subd_face(subd_shader.size() - 1);
463 ptex_offset = s.ptex_offset + s.num_ptex_faces();
464 }
465
466 subd_start_corner.push_back_reserved(start_corner);
467 subd_num_corners.push_back_reserved(num_corners);
468 subd_shader.push_back_reserved(shader_);
469 subd_smooth.push_back_reserved(smooth_);
470 subd_ptex_offset.push_back_reserved(ptex_offset);
471
472 tag_subd_face_corners_modified();
473 tag_subd_start_corner_modified();
474 tag_subd_num_corners_modified();
475 tag_subd_shader_modified();
476 tag_subd_smooth_modified();
477 tag_subd_ptex_offset_modified();
478}
479
481{
483 s.shader = subd_shader[index];
484 s.num_corners = subd_num_corners[index];
485 s.smooth = subd_smooth[index];
486 s.ptex_offset = subd_ptex_offset[index];
487 s.start_corner = subd_start_corner[index];
488 return s;
489}
490
491void Mesh::add_edge_crease(const int v0, const int v1, const float weight)
492{
493 subd_creases_edge.push_back_slow(v0);
494 subd_creases_edge.push_back_slow(v1);
495 subd_creases_weight.push_back_slow(weight);
496
497 tag_subd_creases_edge_modified();
498 tag_subd_creases_edge_modified();
499 tag_subd_creases_weight_modified();
500}
501
502void Mesh::add_vertex_crease(const int v, const float weight)
503{
504 subd_vert_creases.push_back_slow(v);
505 subd_vert_creases_weight.push_back_slow(weight);
506
507 tag_subd_vert_creases_modified();
508 tag_subd_vert_creases_weight_modified();
509}
510
512{
514
515 if (attr_mP) {
518 float3 *P = verts.data();
519 float3 *N = (attr_N) ? attr_N->data_float3() : nullptr;
520 const size_t numverts = verts.size();
521
522 std::copy_n(P, numverts, attr_mP->data_float3() + motion_step * numverts);
523 if (attr_mN) {
524 std::copy_n(N, numverts, attr_mN->data_float3() + motion_step * numverts);
525 }
526 }
527}
528
529void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
530{
531 Attribute *attr;
532 Attribute *subd_attr;
533
534 if (map.empty()) {
535 attr = attributes.find(ATTR_STD_UV);
536 subd_attr = subd_attributes.find(ATTR_STD_UV);
537 }
538 else {
539 attr = attributes.find(map);
540 subd_attr = subd_attributes.find(map);
541 }
542
543 if (attr) {
545 }
546 if (subd_attr) {
547 subd_attr->get_uv_tiles(this, ATTR_PRIM_SUBD, tiles);
548 }
549}
550
552{
554 const size_t verts_size = verts.size();
555
556 if (verts_size > 0) {
557 for (size_t i = 0; i < verts_size; i++) {
558 bnds.grow(verts[i]);
559 }
560
562 if (use_motion_blur && attr) {
563 const size_t steps_size = verts.size() * (motion_steps - 1);
564 float3 *vert_steps = attr->data_float3();
565
566 for (size_t i = 0; i < steps_size; i++) {
567 bnds.grow(vert_steps[i]);
568 }
569 }
570
571 if (!bnds.valid()) {
572 bnds = BoundBox::empty;
573
574 /* skip nan or inf coordinates */
575 for (size_t i = 0; i < verts_size; i++) {
576 bnds.grow_safe(verts[i]);
577 }
578
579 if (use_motion_blur && attr) {
580 const size_t steps_size = verts.size() * (motion_steps - 1);
581 float3 *vert_steps = attr->data_float3();
582
583 for (size_t i = 0; i < steps_size; i++) {
584 bnds.grow_safe(vert_steps[i]);
585 }
586 }
587 }
588 }
589
590 if (!bnds.valid()) {
591 /* empty mesh */
592 bnds.grow(zero_float3());
593 }
594
595 bounds = bnds;
596}
597
598void Mesh::apply_transform(const Transform &tfm, const bool apply_to_motion)
599{
601
602 /* apply to mesh vertices */
603 const size_t num_verts = verts.size();
604 for (size_t i = 0; i < num_verts; i++) {
605 verts[i] = transform_point(&tfm, verts[i]);
606 }
607
608 tag_verts_modified();
609
610 if (apply_to_motion) {
612
613 if (attr) {
614 const size_t steps_size = verts.size() * (motion_steps - 1);
615 float3 *vert_steps = attr->data_float3();
616
617 for (size_t i = 0; i < steps_size; i++) {
618 vert_steps[i] = transform_point(&tfm, vert_steps[i]);
619 }
620 }
621
623
624 if (attr_N) {
625 const Transform ntfm = transform_normal;
626 const size_t steps_size = verts.size() * (motion_steps - 1);
627 float3 *normal_steps = attr_N->data_float3();
628
629 for (size_t i = 0; i < steps_size; i++) {
630 normal_steps[i] = normalize(transform_direction(&ntfm, normal_steps[i]));
631 }
632 }
633 }
634}
635
637{
638 const bool flip = transform_negative_scaled;
639 const size_t verts_size = verts.size();
640 const size_t triangles_size = num_triangles();
641
642 /* static vertex normals */
643 if (!attributes.find(ATTR_STD_VERTEX_NORMAL) && triangles_size) {
644 /* get attributes */
646
647 float3 *verts_ptr = verts.data();
648 float3 *vN = attr_vN->data_float3();
649
650 /* compute vertex normals */
651 std::fill_n(vN, verts.size(), zero_float3());
652
653 for (size_t i = 0; i < triangles_size; i++) {
654 const float3 fN = get_triangle(i).compute_normal(verts_ptr);
655 for (size_t j = 0; j < 3; j++) {
656 vN[get_triangle(i).v[j]] += fN;
657 }
658 }
659
660 if (flip) {
661 for (size_t i = 0; i < verts_size; i++) {
662 vN[i] = -normalize(vN[i]);
663 }
664 }
665 else {
666 for (size_t i = 0; i < verts_size; i++) {
667 vN[i] = normalize(vN[i]);
668 }
669 }
670 }
671
672 /* motion vertex normals */
675
676 if (has_motion_blur() && attr_mP && !attr_mN && triangles_size) {
677 /* create attribute */
679
680 for (int step = 0; step < motion_steps - 1; step++) {
681 float3 *mP = attr_mP->data_float3() + step * verts.size();
682 float3 *mN = attr_mN->data_float3() + step * verts.size();
683
684 /* compute */
685 std::fill_n(mN, verts.size(), zero_float3());
686
687 for (size_t i = 0; i < triangles_size; i++) {
688 const Triangle tri = get_triangle(i);
689 const float3 fN = tri.compute_normal(mP);
690 for (size_t j = 0; j < 3; j++) {
691 mN[tri.v[j]] += fN;
692 }
693 }
694
695 if (flip) {
696 for (size_t i = 0; i < verts_size; i++) {
697 mN[i] = -normalize(mN[i]);
698 }
699 }
700 else {
701 for (size_t i = 0; i < verts_size; i++) {
702 mN[i] = normalize(mN[i]);
703 }
704 }
705 }
706 }
707
708 /* subd vertex normals */
710 /* get attributes */
712 float3 *vN = attr_vN->data_float3();
713
714 /* compute vertex normals */
715 std::fill_n(vN, verts.size(), zero_float3());
716
717 for (size_t i = 0; i < get_num_subd_faces(); i++) {
718 const SubdFace face = get_subd_face(i);
719 const float3 fN = face.normal(this);
720
721 for (size_t j = 0; j < face.num_corners; j++) {
722 const size_t corner = subd_face_corners[face.start_corner + j];
723 vN[corner] += fN;
724 }
725 }
726
727 if (flip) {
728 for (size_t i = 0; i < verts_size; i++) {
729 vN[i] = -normalize(vN[i]);
730 }
731 }
732 else {
733 for (size_t i = 0; i < verts_size; i++) {
734 vN[i] = normalize(vN[i]);
735 }
736 }
737 }
738}
739
741{
744 {
745 /* Copy position to attribute. */
747
748 size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY) / sizeof(float3);
749 std::copy_n(verts.data(), size, attr->data_float3());
750 }
751
752 /* Keep "N" attribute undisplaced for backwards compatibility in Blender 4.5. */
756 {
757 /* Copy vertex normal to attribute */
759 if (attr_N) {
761
762 size_t size = attr->buffer_size(this, ATTR_PRIM_GEOMETRY) / sizeof(float3);
763 std::copy_n(attr_N->data_float3(), size, attr->data_float3());
764 }
765 }
766}
767
769{
770 if (!num_triangles()) {
771 return;
772 }
773
774 AttributeSet &attrs = num_subd_faces ? subd_attributes : attributes;
775
776 /* apply generated attributes if needed or missing */
778 const size_t verts_size = verts.size();
779 Attribute *attr_generated = attrs.add(ATTR_STD_GENERATED);
780 float3 *generated = attr_generated->data_float3();
781 for (size_t i = 0; i < verts_size; ++i) {
782 generated[i] = verts[i];
783 }
784 }
785}
786
788{
789 if (!num_triangles()) {
790 return;
791 }
792
794
795 ccl::set<ustring> uv_maps;
796 Attribute *attr_std_uv = attributes.find(ATTR_STD_UV);
797
798 /* standard UVs */
800 mikk_compute_tangents(attr_std_uv, this, true); /* sign */
801 }
802
803 /* now generate for any other UVs requested */
804 for (Attribute &attr : attributes.attributes) {
805 if (!(attr.type == TypeFloat2 && attr.element == ATTR_ELEMENT_CORNER)) {
806 continue;
807 }
808
809 const ustring tangent_name = ustring(attr.name.string() + ".tangent");
810
811 if (need_attribute(scene, tangent_name) && !attributes.find(tangent_name)) {
812 mikk_compute_tangents(&attr, this, true); /* sign */
813 }
814 }
815}
816
817void Mesh::pack_shaders(Scene *scene, uint *tri_shader)
818{
819 uint shader_id = 0;
820 uint last_shader = -1;
821 bool last_smooth = false;
822
823 const size_t triangles_size = num_triangles();
824 const int *shader_ptr = shader.data();
825 const bool *smooth_ptr = smooth.data();
826
827 for (size_t i = 0; i < triangles_size; i++) {
828 const int new_shader = shader_ptr ? shader_ptr[i] : INT_MAX;
829 const bool new_smooth = smooth_ptr ? smooth_ptr[i] : false;
830
831 if (new_shader != last_shader || last_smooth != new_smooth) {
832 last_shader = new_shader;
833 last_smooth = new_smooth;
834 Shader *shader = (last_shader < used_shaders.size()) ?
835 static_cast<Shader *>(used_shaders[last_shader]) :
836 scene->default_surface;
837 shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
838 }
839
840 tri_shader[i] = shader_id;
841 }
842}
843
845{
847 if (attr_vN == nullptr) {
848 /* Happens on objects with just hair. */
849 return;
850 }
851
852 const bool do_transform = transform_applied;
853 const Transform ntfm = transform_normal;
854
855 float3 *vN = attr_vN->data_float3();
856 const size_t verts_size = verts.size();
857
858 if (do_transform) {
859 for (size_t i = 0; i < verts_size; i++) {
860 vnormal[i] = safe_normalize(transform_direction(&ntfm, vN[i]));
861 }
862 }
863 else {
864 for (size_t i = 0; i < verts_size; i++) {
865 vnormal[i] = vN[i];
866 }
867 }
868}
869
870void Mesh::pack_verts(packed_float3 *tri_verts, packed_uint3 *tri_vindex)
871{
872 const size_t verts_size = verts.size();
873 const size_t triangles_size = num_triangles();
874 const int *p_tris = triangles.data();
875 int off = 0;
876 for (size_t i = 0; i < verts_size; i++) {
877 tri_verts[i] = verts[i];
878 }
879 for (size_t i = 0; i < triangles_size; i++) {
880 tri_vindex[i] = make_packed_uint3(p_tris[off + 0] + vert_offset,
881 p_tris[off + 1] + vert_offset,
882 p_tris[off + 2] + vert_offset);
883 off += 3;
884 }
885}
886
888{
889 return use_motion_blur && (attributes.find(ATTR_STD_MOTION_VERTEX_POSITION) ||
890 (get_subdivision_type() != Mesh::SUBDIVISION_NONE &&
892}
893
898
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 has_true_displacement() const
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 this
VecBase< float, D > normalize(VecOp< float, D >) RET
#define assert(assertion)
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
@ 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_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:15
#define N
#define T
#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_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
static void mikk_compute_tangents(Attribute *attr_uv, Mesh *mesh, const bool need_sign)
#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:229
void add_undisplaced(Scene *scene)
size_t face_offset
Definition scene/mesh.h:173
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:171
void update_tangents(Scene *scene)
void compute_bounds() override
size_t corner_offset
Definition scene/mesh.h:174
void add_vertex_normals()
AttributeSet subd_attributes
Definition scene/mesh.h:168
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 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
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:156
unique_ptr< ShaderManager > shader_manager
Definition scene.h:148
float x
float y
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
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:289
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:87
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