Blender  V2.93
mesh_remesh_voxel.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2019 by Blender Foundation
17  * All rights reserved.
18  */
19 
24 #include <ctype.h>
25 #include <float.h>
26 #include <math.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_math.h"
35 #include "BLI_utildefines.h"
36 
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_types.h"
40 
41 #include "BKE_bvhutils.h"
42 #include "BKE_customdata.h"
43 #include "BKE_editmesh.h"
44 #include "BKE_lib_id.h"
45 #include "BKE_mesh.h"
46 #include "BKE_mesh_remesh_voxel.h" /* own include */
47 #include "BKE_mesh_runtime.h"
48 
49 #include "bmesh_tools.h"
50 
51 #ifdef WITH_OPENVDB
52 # include "openvdb_capi.h"
53 #endif
54 
55 #ifdef WITH_QUADRIFLOW
56 # include "quadriflow_capi.hpp"
57 #endif
58 
59 #ifdef WITH_OPENVDB
60 struct OpenVDBLevelSet *BKE_mesh_remesh_voxel_ovdb_mesh_to_level_set_create(
62 {
65  MVertTri *verttri = MEM_callocN(sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh),
66  "remesh_looptri");
68  verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh));
69 
70  unsigned int totfaces = BKE_mesh_runtime_looptri_len(mesh);
71  unsigned int totverts = mesh->totvert;
72  float *verts = (float *)MEM_malloc_arrayN(totverts * 3, sizeof(float), "remesh_input_verts");
73  unsigned int *faces = (unsigned int *)MEM_malloc_arrayN(
74  totfaces * 3, sizeof(unsigned int), "remesh_input_faces");
75 
76  for (unsigned int i = 0; i < totverts; i++) {
77  MVert *mvert = &mesh->mvert[i];
78  verts[i * 3] = mvert->co[0];
79  verts[i * 3 + 1] = mvert->co[1];
80  verts[i * 3 + 2] = mvert->co[2];
81  }
82 
83  for (unsigned int i = 0; i < totfaces; i++) {
84  MVertTri *vt = &verttri[i];
85  faces[i * 3] = vt->tri[0];
86  faces[i * 3 + 1] = vt->tri[1];
87  faces[i * 3 + 2] = vt->tri[2];
88  }
89 
90  struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL);
91  OpenVDBLevelSet_mesh_to_level_set(level_set, verts, faces, totverts, totfaces, transform);
92 
95  MEM_freeN(verttri);
96 
97  return level_set;
98 }
99 
100 Mesh *BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(struct OpenVDBLevelSet *level_set,
101  double isovalue,
102  double adaptivity,
103  bool relax_disoriented_triangles)
104 {
105  struct OpenVDBVolumeToMeshData output_mesh;
107  level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles);
108 
109  Mesh *mesh = BKE_mesh_new_nomain(output_mesh.totvertices,
110  0,
111  0,
112  (output_mesh.totquads * 4) + (output_mesh.tottriangles * 3),
113  output_mesh.totquads + output_mesh.tottriangles);
114 
115  for (int i = 0; i < output_mesh.totvertices; i++) {
116  copy_v3_v3(mesh->mvert[i].co, &output_mesh.vertices[i * 3]);
117  }
118 
119  MPoly *mp = mesh->mpoly;
120  MLoop *ml = mesh->mloop;
121  for (int i = 0; i < output_mesh.totquads; i++, mp++, ml += 4) {
122  mp->loopstart = (int)(ml - mesh->mloop);
123  mp->totloop = 4;
124 
125  ml[0].v = output_mesh.quads[i * 4 + 3];
126  ml[1].v = output_mesh.quads[i * 4 + 2];
127  ml[2].v = output_mesh.quads[i * 4 + 1];
128  ml[3].v = output_mesh.quads[i * 4];
129  }
130 
131  for (int i = 0; i < output_mesh.tottriangles; i++, mp++, ml += 3) {
132  mp->loopstart = (int)(ml - mesh->mloop);
133  mp->totloop = 3;
134 
135  ml[0].v = output_mesh.triangles[i * 3 + 2];
136  ml[1].v = output_mesh.triangles[i * 3 + 1];
137  ml[2].v = output_mesh.triangles[i * 3];
138  }
139 
140  BKE_mesh_calc_edges(mesh, false, false);
142 
143  MEM_freeN(output_mesh.quads);
144  MEM_freeN(output_mesh.vertices);
145 
146  if (output_mesh.tottriangles > 0) {
147  MEM_freeN(output_mesh.triangles);
148  }
149 
150  return mesh;
151 }
152 #endif
153 
154 #ifdef WITH_QUADRIFLOW
155 static Mesh *BKE_mesh_remesh_quadriflow(Mesh *input_mesh,
156  int target_faces,
157  int seed,
158  bool preserve_sharp,
159  bool preserve_boundary,
160  bool adaptive_scale,
161  void *update_cb,
162  void *update_cb_data)
163 {
164  /* Ensure that the triangulated mesh data is up to data */
166  const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
167 
168  /* Gather the required data for export to the internal quadiflow mesh format */
169  MVertTri *verttri = MEM_callocN(sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh),
170  "remesh_looptri");
172  verttri, input_mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(input_mesh));
173 
174  unsigned int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
175  unsigned int totverts = input_mesh->totvert;
176  float *verts = (float *)MEM_malloc_arrayN(totverts * 3, sizeof(float), "remesh_input_verts");
177  unsigned int *faces = (unsigned int *)MEM_malloc_arrayN(
178  totfaces * 3, sizeof(unsigned int), "remesh_input_faces");
179 
180  for (unsigned int i = 0; i < totverts; i++) {
181  MVert *mvert = &input_mesh->mvert[i];
182  verts[i * 3] = mvert->co[0];
183  verts[i * 3 + 1] = mvert->co[1];
184  verts[i * 3 + 2] = mvert->co[2];
185  }
186 
187  for (unsigned int i = 0; i < totfaces; i++) {
188  MVertTri *vt = &verttri[i];
189  faces[i * 3] = vt->tri[0];
190  faces[i * 3 + 1] = vt->tri[1];
191  faces[i * 3 + 2] = vt->tri[2];
192  }
193 
194  /* Fill out the required input data */
196 
197  qrd.totfaces = totfaces;
198  qrd.totverts = totverts;
199  qrd.verts = verts;
200  qrd.faces = faces;
201  qrd.target_faces = target_faces;
202 
203  qrd.preserve_sharp = preserve_sharp;
204  qrd.preserve_boundary = preserve_boundary;
205  qrd.adaptive_scale = adaptive_scale;
206  qrd.minimum_cost_flow = 0;
207  qrd.aggresive_sat = 0;
208  qrd.rng_seed = seed;
209 
210  qrd.out_faces = NULL;
211 
212  /* Run the remesher */
213  QFLOW_quadriflow_remesh(&qrd, update_cb, update_cb_data);
214 
215  MEM_freeN(verts);
216  MEM_freeN(faces);
217  MEM_freeN(verttri);
218 
219  if (qrd.out_faces == NULL) {
220  /* The remeshing was canceled */
221  return NULL;
222  }
223 
224  if (qrd.out_totfaces == 0) {
225  /* Meshing failed */
226  MEM_freeN(qrd.out_faces);
227  MEM_freeN(qrd.out_verts);
228  return NULL;
229  }
230 
231  /* Construct the new output mesh */
233  qrd.out_totverts, 0, 0, (qrd.out_totfaces * 4), qrd.out_totfaces);
234 
235  for (int i = 0; i < qrd.out_totverts; i++) {
236  copy_v3_v3(mesh->mvert[i].co, &qrd.out_verts[i * 3]);
237  }
238 
239  MPoly *mp = mesh->mpoly;
240  MLoop *ml = mesh->mloop;
241  for (int i = 0; i < qrd.out_totfaces; i++, mp++, ml += 4) {
242  mp->loopstart = (int)(ml - mesh->mloop);
243  mp->totloop = 4;
244 
245  ml[0].v = qrd.out_faces[i * 4];
246  ml[1].v = qrd.out_faces[i * 4 + 1];
247  ml[2].v = qrd.out_faces[i * 4 + 2];
248  ml[3].v = qrd.out_faces[i * 4 + 3];
249  }
250 
251  BKE_mesh_calc_edges(mesh, false, false);
253 
254  MEM_freeN(qrd.out_faces);
255  MEM_freeN(qrd.out_verts);
256 
257  return mesh;
258 }
259 #endif
260 
262  int target_faces,
263  int seed,
264  bool preserve_sharp,
265  bool preserve_boundary,
266  bool adaptive_scale,
267  void *update_cb,
268  void *update_cb_data)
269 {
270  Mesh *new_mesh = NULL;
271 #ifdef WITH_QUADRIFLOW
272  if (target_faces <= 0) {
273  target_faces = -1;
274  }
275  new_mesh = BKE_mesh_remesh_quadriflow(mesh,
276  target_faces,
277  seed,
278  preserve_sharp,
279  preserve_boundary,
280  adaptive_scale,
281  update_cb,
282  update_cb_data);
283 #else
285  target_faces,
286  seed,
287  preserve_sharp,
288  preserve_boundary,
289  adaptive_scale,
290  update_cb,
291  update_cb_data);
292 #endif
293  return new_mesh;
294 }
295 
297  float voxel_size,
298  float adaptivity,
299  float isovalue)
300 {
301  Mesh *new_mesh = NULL;
302 #ifdef WITH_OPENVDB
303  struct OpenVDBLevelSet *level_set;
304  struct OpenVDBTransform *xform = OpenVDBTransform_create();
305  OpenVDBTransform_create_linear_transform(xform, (double)voxel_size);
306  level_set = BKE_mesh_remesh_voxel_ovdb_mesh_to_level_set_create(mesh, xform);
307  new_mesh = BKE_mesh_remesh_voxel_ovdb_volume_to_mesh_nomain(
308  level_set, (double)isovalue, (double)adaptivity, false);
309  OpenVDBLevelSet_free(level_set);
310  OpenVDBTransform_free(xform);
311 #else
312  UNUSED_VARS(mesh, voxel_size, adaptivity, isovalue);
313 #endif
314  return new_mesh;
315 }
316 
318 {
319  BVHTreeFromMesh bvhtree = {
321  };
322  BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
323  MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT);
324 
325  float *target_mask;
326  if (CustomData_has_layer(&target->vdata, CD_PAINT_MASK)) {
327  target_mask = CustomData_get_layer(&target->vdata, CD_PAINT_MASK);
328  }
329  else {
330  target_mask = CustomData_add_layer(
331  &target->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, target->totvert);
332  }
333 
334  float *source_mask;
335  if (CustomData_has_layer(&source->vdata, CD_PAINT_MASK)) {
336  source_mask = CustomData_get_layer(&source->vdata, CD_PAINT_MASK);
337  }
338  else {
339  source_mask = CustomData_add_layer(
340  &source->vdata, CD_PAINT_MASK, CD_CALLOC, NULL, source->totvert);
341  }
342 
343  for (int i = 0; i < target->totvert; i++) {
344  float from_co[3];
345  BVHTreeNearest nearest;
346  nearest.index = -1;
347  nearest.dist_sq = FLT_MAX;
348  copy_v3_v3(from_co, target_verts[i].co);
349  BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
350  if (nearest.index != -1) {
351  target_mask[i] = source_mask[nearest.index];
352  }
353  }
354  free_bvhtree_from_mesh(&bvhtree);
355 }
356 
358 {
359  BVHTreeFromMesh bvhtree = {
361  };
362 
363  const MPoly *target_polys = CustomData_get_layer(&target->pdata, CD_MPOLY);
364  const MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT);
365  const MLoop *target_loops = CustomData_get_layer(&target->ldata, CD_MLOOP);
366 
367  int *target_face_sets;
368  if (CustomData_has_layer(&target->pdata, CD_SCULPT_FACE_SETS)) {
369  target_face_sets = CustomData_get_layer(&target->pdata, CD_SCULPT_FACE_SETS);
370  }
371  else {
372  target_face_sets = CustomData_add_layer(
373  &target->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, target->totpoly);
374  }
375 
376  int *source_face_sets;
377  if (CustomData_has_layer(&source->pdata, CD_SCULPT_FACE_SETS)) {
378  source_face_sets = CustomData_get_layer(&source->pdata, CD_SCULPT_FACE_SETS);
379  }
380  else {
381  source_face_sets = CustomData_add_layer(
382  &source->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, source->totpoly);
383  }
384 
385  const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source);
386  BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2);
387 
388  for (int i = 0; i < target->totpoly; i++) {
389  float from_co[3];
390  BVHTreeNearest nearest;
391  nearest.index = -1;
392  nearest.dist_sq = FLT_MAX;
393  const MPoly *mpoly = &target_polys[i];
394  BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co);
395  BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
396  if (nearest.index != -1) {
397  target_face_sets[i] = source_face_sets[looptri[nearest.index].poly];
398  }
399  else {
400  target_face_sets[i] = 1;
401  }
402  }
403  free_bvhtree_from_mesh(&bvhtree);
404 }
405 
407 {
408  BVHTreeFromMesh bvhtree = {
410  };
411  BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2);
412 
413  int tot_color_layer = CustomData_number_of_layers(&source->vdata, CD_PROP_COLOR);
414 
415  for (int layer_n = 0; layer_n < tot_color_layer; layer_n++) {
416  const char *layer_name = CustomData_get_layer_name(&source->vdata, CD_PROP_COLOR, layer_n);
418  &target->vdata, CD_PROP_COLOR, CD_CALLOC, NULL, target->totvert, layer_name);
419 
420  MPropCol *target_color = CustomData_get_layer_n(&target->vdata, CD_PROP_COLOR, layer_n);
421  MVert *target_verts = CustomData_get_layer(&target->vdata, CD_MVERT);
422  MPropCol *source_color = CustomData_get_layer_n(&source->vdata, CD_PROP_COLOR, layer_n);
423  for (int i = 0; i < target->totvert; i++) {
424  BVHTreeNearest nearest;
425  nearest.index = -1;
426  nearest.dist_sq = FLT_MAX;
428  bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
429  if (nearest.index != -1) {
430  copy_v4_v4(target_color[i].color, source_color[nearest.index].color);
431  }
432  }
433  }
434  free_bvhtree_from_mesh(&bvhtree);
435 }
436 
438 {
439  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh);
440  BMesh *bm;
441  bm = BM_mesh_create(&allocsize,
442  &((struct BMeshCreateParams){
443  .use_toolflags = true,
444  }));
445 
447  mesh,
448  (&(struct BMeshFromMeshParams){
449  .calc_face_normal = true,
450  }));
451 
452  BMVert *v;
453  BMEdge *ed, *ed_next;
454  BMFace *f, *f_next;
455  BMIter iter_a, iter_b;
456 
457  /* Merge 3 edge poles vertices that exist in the same face */
459  BM_ITER_MESH_MUTABLE (f, f_next, &iter_a, bm, BM_FACES_OF_MESH) {
460  BMVert *v1, *v2;
461  v1 = NULL;
462  v2 = NULL;
463  BM_ITER_ELEM (v, &iter_b, f, BM_VERTS_OF_FACE) {
464  if (BM_vert_edge_count(v) == 3) {
465  if (v1) {
466  v2 = v;
467  }
468  else {
469  v1 = v;
470  }
471  }
472  }
473  if (v1 && v2 && (v1 != v2) && !BM_edge_exists(v1, v2)) {
474  BM_face_kill(bm, f);
477  }
478  }
479 
480  BM_ITER_MESH_MUTABLE (ed, ed_next, &iter_a, bm, BM_EDGES_OF_MESH) {
481  if (BM_elem_flag_test(ed, BM_ELEM_TAG)) {
482  float co[3];
483  mid_v3_v3v3(co, ed->v1->co, ed->v2->co);
484  BMVert *vc = BM_edge_collapse(bm, ed, ed->v1, true, true);
485  copy_v3_v3(vc->co, co);
486  }
487  }
488 
489  /* Delete faces with a 3 edge pole in all their vertices */
491  BM_ITER_MESH (f, &iter_a, bm, BM_FACES_OF_MESH) {
492  bool dissolve = true;
493  BM_ITER_ELEM (v, &iter_b, f, BM_VERTS_OF_FACE) {
494  if (BM_vert_edge_count(v) != 3) {
495  dissolve = false;
496  }
497  }
498  if (dissolve) {
499  BM_ITER_ELEM (v, &iter_b, f, BM_VERTS_OF_FACE) {
501  }
502  }
503  }
505 
506  BM_ITER_MESH (ed, &iter_a, bm, BM_EDGES_OF_MESH) {
507  if (BM_edge_face_count(ed) != 2) {
508  BM_elem_flag_set(ed, BM_ELEM_TAG, true);
509  }
510  }
511  BM_mesh_edgenet(bm, false, true);
512 
513  /* Smooth the result */
514  for (int i = 0; i < 4; i++) {
515  BM_ITER_MESH (v, &iter_a, bm, BM_VERTS_OF_MESH) {
516  float co[3];
517  zero_v3(co);
518  BM_ITER_ELEM (ed, &iter_b, v, BM_EDGES_OF_VERT) {
519  BMVert *vert = BM_edge_other_vert(ed, v);
520  add_v3_v3(co, vert->co);
521  }
522  mul_v3_fl(co, 1.0f / (float)BM_vert_edge_count(v));
523  mid_v3_v3v3(v->co, v->co, co);
524  }
525  }
526 
528 
533  "recalc_face_normals faces=%hf",
534  BM_ELEM_TAG);
536 
538  (&(struct BMeshToMeshParams){
539  .calc_object_remap = false,
540  }),
541  mesh);
542 
544  BM_mesh_free(bm);
545  return result;
546 }
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, struct Mesh *mesh, const BVHCacheType bvh_cache_type, const int tree_type)
Definition: bvhutils.c:1413
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
Definition: bvhutils.c:1701
@ BVHTREE_FROM_LOOPTRI
Definition: BKE_bvhutils.h:93
@ BVHTREE_FROM_VERTS
Definition: BKE_bvhutils.h:90
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_layer_name(const struct CustomData *data, int type, int n)
int CustomData_number_of_layers(const struct CustomData *data, int type)
@ CD_CALLOC
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.c:2637
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_mesh_calc_poly_center(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_cent[3])
struct Mesh * BKE_mesh_from_bmesh_nomain(struct BMesh *bm, const struct BMeshToMeshParams *params, const struct Mesh *me_settings)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.c:877
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, const bool select_new_edges)
void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri, const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num)
const struct MLoopTri * BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh)
Definition: mesh_runtime.c:155
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh)
Definition: mesh_runtime.c:127
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh)
int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1654
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:270
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define UNUSED_VARS(...)
@ CD_PAINT_MASK
@ CD_PROP_COLOR
@ CD_SCULPT_FACE_SETS
@ CD_MVERT
Object is a sort of wrapper for general info.
_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
Read Guarded memory(de)allocation.
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_face_kill(BMesh *bm, BMFace *f)
Definition: bmesh_core.c:881
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
Definition: bmesh_core.c:147
@ BM_CREATE_NOP
Definition: bmesh_core.h:27
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
Definition: bmesh_delete.c:282
void BM_mesh_edgenet(BMesh *bm, const bool use_edge_tag, const bool use_new_face_tag)
#define BM_elem_flag_set(ele, hflag, val)
Definition: bmesh_inline.h:30
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_VERTS_OF_FACE
@ BM_FACES_OF_MESH
@ BM_EDGES_OF_VERT
#define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.c:307
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
BMesh Make Mesh.
Definition: bmesh_mesh.c:157
void BM_mesh_normals_update(BMesh *bm)
BMesh Compute Normals.
Definition: bmesh_mesh.c:500
#define BMALLOC_TEMPLATE_FROM_ME(...)
Definition: bmesh_mesh.h:163
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
Mesh -> BMesh.
BMVert * BM_edge_collapse(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
Definition: bmesh_mods.c:566
@ DEL_VERTS
#define BMO_FLAG_DEFAULTS
@ BMO_FLAG_RESPECT_HIDE
bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt,...)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
Definition: bmesh_query.c:1995
int BM_edge_face_count(const BMEdge *e)
Definition: bmesh_query.c:847
int BM_vert_edge_count(const BMVert *v)
Definition: bmesh_query.c:822
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static unsigned long seed
Definition: btSoftBody.h:39
static float verts[][3]
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static char faces[256]
void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
Mesh * BKE_mesh_remesh_voxel_to_mesh_nomain(Mesh *mesh, float voxel_size, float adaptivity, float isovalue)
Mesh * BKE_mesh_remesh_quadriflow_to_mesh_nomain(Mesh *mesh, int target_faces, int seed, bool preserve_sharp, bool preserve_boundary, bool adaptive_scale, void *update_cb, void *update_cb_data)
void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
struct Mesh * BKE_mesh_remesh_voxel_fix_poles(struct Mesh *mesh)
void BKE_remesh_reproject_vertex_paint(Mesh *target, Mesh *source)
void OpenVDBTransform_free(OpenVDBTransform *transform)
Definition: openvdb_capi.cc:49
void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set, struct OpenVDBVolumeToMeshData *mesh, const double isovalue, const double adaptivity, const bool relax_disoriented_triangles)
Definition: openvdb_capi.cc:84
OpenVDBLevelSet * OpenVDBLevelSet_create(bool initGrid, OpenVDBTransform *xform)
Definition: openvdb_capi.cc:30
OpenVDBTransform * OpenVDBTransform_create()
Definition: openvdb_capi.cc:44
void OpenVDBLevelSet_free(OpenVDBLevelSet *level_set)
Definition: openvdb_capi.cc:59
void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set, const float *vertices, const unsigned int *faces, const unsigned int totvertices, const unsigned int totfaces, OpenVDBTransform *xform)
Definition: openvdb_capi.cc:64
void OpenVDBTransform_create_linear_transform(OpenVDBTransform *transform, double voxel_size)
Definition: openvdb_capi.cc:54
void QFLOW_quadriflow_remesh(QuadriflowRemeshData *qrd, void(*update_cb)(void *, float progress, int *cancel), void *update_cb_data)
static void update_cb(PBVHNode *node, void *rebuild)
Definition: sculpt_undo.c:120
BMVert * v1
Definition: bmesh_class.h:134
BMVert * v2
Definition: bmesh_class.h:134
float co[3]
Definition: bmesh_class.h:99
struct BVHTree * tree
Definition: BKE_bvhutils.h:66
BVHTree_NearestPointCallback nearest_callback
Definition: BKE_bvhutils.h:69
unsigned int poly
unsigned int v
float color[4]
unsigned int tri[3]
float co[3]
struct CustomData pdata ldata
struct MVert * mvert
int totvert
struct MLoop * mloop
int totpoly
struct MPoly * mpoly
unsigned int * out_faces