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