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