Blender  V2.93
abc_writer_mesh.cc
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 
21 #include "abc_writer_mesh.h"
22 #include "abc_hierarchy_iterator.h"
24 
25 #include "BLI_assert.h"
26 #include "BLI_math_vector.h"
27 
28 #include "BKE_customdata.h"
29 #include "BKE_lib_id.h"
30 #include "BKE_material.h"
31 #include "BKE_mesh.h"
32 #include "BKE_modifier.h"
33 #include "BKE_object.h"
34 
35 #include "bmesh.h"
36 #include "bmesh_tools.h"
37 
38 #include "DEG_depsgraph.h"
39 
40 #include "DNA_layer_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
45 #include "DNA_particle_types.h"
46 
47 #include "CLG_log.h"
48 static CLG_LogRef LOG = {"io.alembic"};
49 
50 using Alembic::Abc::FloatArraySample;
51 using Alembic::Abc::Int32ArraySample;
52 using Alembic::Abc::OObject;
53 using Alembic::Abc::V2fArraySample;
54 using Alembic::Abc::V3fArraySample;
55 
56 using Alembic::AbcGeom::kFacevaryingScope;
57 using Alembic::AbcGeom::OBoolProperty;
58 using Alembic::AbcGeom::OCompoundProperty;
59 using Alembic::AbcGeom::OFaceSet;
60 using Alembic::AbcGeom::OFaceSetSchema;
61 using Alembic::AbcGeom::ON3fGeomParam;
62 using Alembic::AbcGeom::OPolyMesh;
63 using Alembic::AbcGeom::OPolyMeshSchema;
64 using Alembic::AbcGeom::OSubD;
65 using Alembic::AbcGeom::OSubDSchema;
66 using Alembic::AbcGeom::OV2fGeomParam;
67 using Alembic::AbcGeom::UInt32ArraySample;
68 
69 namespace blender::io::alembic {
70 
71 /* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
72 
73 static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points);
74 static void get_topology(struct Mesh *mesh,
75  std::vector<int32_t> &poly_verts,
76  std::vector<int32_t> &loop_counts,
77  bool &r_has_flat_shaded_poly);
78 static void get_creases(struct Mesh *mesh,
79  std::vector<int32_t> &indices,
80  std::vector<int32_t> &lengths,
81  std::vector<float> &sharpnesses);
82 static void get_loop_normals(struct Mesh *mesh,
83  std::vector<Imath::V3f> &normals,
84  bool has_flat_shaded_poly);
85 
87  : ABCAbstractWriter(args), is_subd_(false)
88 {
89 }
90 
92 {
95  }
96 
97  if (is_subd_) {
98  CLOG_INFO(&LOG, 2, "exporting OSubD %s", args_.abc_path.c_str());
99  abc_subdiv_ = OSubD(args_.abc_parent, args_.abc_name, timesample_index_);
100  abc_subdiv_schema_ = abc_subdiv_.getSchema();
101  }
102  else {
103  CLOG_INFO(&LOG, 2, "exporting OPolyMesh %s", args_.abc_path.c_str());
104  abc_poly_mesh_ = OPolyMesh(args_.abc_parent, args_.abc_name, timesample_index_);
105  abc_poly_mesh_schema_ = abc_poly_mesh_.getSchema();
106 
107  OCompoundProperty typeContainer = abc_poly_mesh_.getSchema().getUserProperties();
108  OBoolProperty type(typeContainer, "meshtype");
109  type.set(subsurf_modifier_ == nullptr);
110  }
111 
113  liquid_sim_modifier_ = get_liquid_sim_modifier(scene_eval, context->object);
114 }
115 
116 Alembic::Abc::OObject ABCGenericMeshWriter::get_alembic_object() const
117 {
118  if (is_subd_) {
119  return abc_subdiv_;
120  }
121  return abc_poly_mesh_;
122 }
123 
124 Alembic::Abc::OCompoundProperty ABCGenericMeshWriter::abc_prop_for_custom_props()
125 {
126  if (is_subd_) {
127  return abc_schema_prop_for_custom_props(abc_subdiv_schema_);
128  }
129  return abc_schema_prop_for_custom_props(abc_poly_mesh_schema_);
130 }
131 
133 {
134  ModifierData *md = static_cast<ModifierData *>(ob_eval->modifiers.last);
135 
136  for (; md; md = md->prev) {
137  /* This modifier has been temporarily disabled by SubdivModifierDisabler,
138  * so this indicates this is to be exported as subdivision surface. */
140  return true;
141  }
142  }
143 
144  return false;
145 }
146 
147 ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object *ob)
148 {
150 
152  FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
153 
154  if (fsmd->fss && fsmd->fss->type == OB_FLUIDSIM_DOMAIN) {
155  return md;
156  }
157  }
158 
159  return nullptr;
160 }
161 
163 {
165  return context->is_object_visible(args_.export_params->evaluation_mode);
166  }
167  return true;
168 }
169 
171 {
172  Object *object = context.object;
173  bool needsfree = false;
174 
175  Mesh *mesh = get_export_mesh(object, needsfree);
176 
177  if (mesh == nullptr) {
178  return;
179  }
180 
182  const bool tag_only = false;
183  const int quad_method = args_.export_params->quad_method;
184  const int ngon_method = args_.export_params->ngon_method;
185 
186  struct BMeshCreateParams bmcp = {false};
187  struct BMeshFromMeshParams bmfmp = {true, false, false, 0};
188  BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
189 
190  BM_mesh_triangulate(bm, quad_method, ngon_method, 4, tag_only, nullptr, nullptr, nullptr);
191 
192  Mesh *triangulated_mesh = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh);
193  BM_mesh_free(bm);
194 
195  if (needsfree) {
197  }
198  mesh = triangulated_mesh;
199  needsfree = true;
200  }
201 
202  m_custom_data_config.pack_uvs = args_.export_params->packuv;
203  m_custom_data_config.mpoly = mesh->mpoly;
204  m_custom_data_config.mloop = mesh->mloop;
205  m_custom_data_config.totpoly = mesh->totpoly;
206  m_custom_data_config.totloop = mesh->totloop;
207  m_custom_data_config.totvert = mesh->totvert;
208 
209  try {
210  if (is_subd_) {
211  write_subd(context, mesh);
212  }
213  else {
214  write_mesh(context, mesh);
215  }
216 
217  if (needsfree) {
219  }
220  }
221  catch (...) {
222  if (needsfree) {
224  }
225  throw;
226  }
227 }
228 
230 {
231  BKE_id_free(nullptr, mesh);
232 }
233 
234 void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
235 {
236  std::vector<Imath::V3f> points, normals;
237  std::vector<int32_t> poly_verts, loop_counts;
238  std::vector<Imath::V3f> velocities;
239  bool has_flat_shaded_poly = false;
240 
241  get_vertices(mesh, points);
242  get_topology(mesh, poly_verts, loop_counts, has_flat_shaded_poly);
243 
245  write_face_sets(context.object, mesh, abc_poly_mesh_schema_);
246  }
247 
248  OPolyMeshSchema::Sample mesh_sample = OPolyMeshSchema::Sample(
249  V3fArraySample(points), Int32ArraySample(poly_verts), Int32ArraySample(loop_counts));
250 
251  UVSample uvs_and_indices;
252 
254  const char *name = get_uv_sample(uvs_and_indices, m_custom_data_config, &mesh->ldata);
255 
256  if (!uvs_and_indices.indices.empty() && !uvs_and_indices.uvs.empty()) {
257  OV2fGeomParam::Sample uv_sample;
258  uv_sample.setVals(V2fArraySample(uvs_and_indices.uvs));
259  uv_sample.setIndices(UInt32ArraySample(uvs_and_indices.indices));
260  uv_sample.setScope(kFacevaryingScope);
261 
262  abc_poly_mesh_schema_.setUVSourceName(name);
263  mesh_sample.setUVs(uv_sample);
264  }
265 
267  abc_poly_mesh_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
268  }
269 
270  if (args_.export_params->normals) {
271  get_loop_normals(mesh, normals, has_flat_shaded_poly);
272 
273  ON3fGeomParam::Sample normals_sample;
274  if (!normals.empty()) {
275  normals_sample.setScope(kFacevaryingScope);
276  normals_sample.setVals(V3fArraySample(normals));
277  }
278 
279  mesh_sample.setNormals(normals_sample);
280  }
281 
282  if (liquid_sim_modifier_ != nullptr) {
283  get_velocities(mesh, velocities);
284  mesh_sample.setVelocities(V3fArraySample(velocities));
285  }
286 
288  mesh_sample.setSelfBounds(bounding_box_);
289 
290  abc_poly_mesh_schema_.set(mesh_sample);
291 
292  write_arb_geo_params(mesh);
293 }
294 
295 void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *mesh)
296 {
297  std::vector<float> crease_sharpness;
298  std::vector<Imath::V3f> points;
299  std::vector<int32_t> poly_verts, loop_counts;
300  std::vector<int32_t> crease_indices, crease_lengths;
301  bool has_flat_poly = false;
302 
303  get_vertices(mesh, points);
304  get_topology(mesh, poly_verts, loop_counts, has_flat_poly);
305  get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
306 
308  write_face_sets(context.object, mesh, abc_subdiv_schema_);
309  }
310 
311  OSubDSchema::Sample subdiv_sample = OSubDSchema::Sample(
312  V3fArraySample(points), Int32ArraySample(poly_verts), Int32ArraySample(loop_counts));
313 
314  UVSample sample;
316  const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
317 
318  if (!sample.indices.empty() && !sample.uvs.empty()) {
319  OV2fGeomParam::Sample uv_sample;
320  uv_sample.setVals(V2fArraySample(sample.uvs));
321  uv_sample.setIndices(UInt32ArraySample(sample.indices));
322  uv_sample.setScope(kFacevaryingScope);
323 
324  abc_subdiv_schema_.setUVSourceName(name);
325  subdiv_sample.setUVs(uv_sample);
326  }
327 
329  abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
330  }
331 
332  if (!crease_indices.empty()) {
333  subdiv_sample.setCreaseIndices(Int32ArraySample(crease_indices));
334  subdiv_sample.setCreaseLengths(Int32ArraySample(crease_lengths));
335  subdiv_sample.setCreaseSharpnesses(FloatArraySample(crease_sharpness));
336  }
337 
339  subdiv_sample.setSelfBounds(bounding_box_);
340  abc_subdiv_schema_.set(subdiv_sample);
341 
342  write_arb_geo_params(mesh);
343 }
344 
345 template<typename Schema>
346 void ABCGenericMeshWriter::write_face_sets(Object *object, struct Mesh *mesh, Schema &schema)
347 {
348  std::map<std::string, std::vector<int32_t>> geo_groups;
349  get_geo_groups(object, mesh, geo_groups);
350 
351  std::map<std::string, std::vector<int32_t>>::iterator it;
352  for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
353  OFaceSet face_set = schema.createFaceSet(it->first);
354  OFaceSetSchema::Sample samp;
355  samp.setFaces(Int32ArraySample(it->second));
356  face_set.getSchema().set(samp);
357  }
358 }
359 
360 void ABCGenericMeshWriter::write_arb_geo_params(struct Mesh *me)
361 {
362  if (liquid_sim_modifier_ != nullptr) {
363  /* We don't need anything more for liquid meshes. */
364  return;
365  }
366 
368  return;
369  }
370 
371  OCompoundProperty arb_geom_params;
372  if (is_subd_) {
373  arb_geom_params = abc_subdiv_.getSchema().getArbGeomParams();
374  }
375  else {
376  arb_geom_params = abc_poly_mesh_.getSchema().getArbGeomParams();
377  }
378  write_custom_data(arb_geom_params, m_custom_data_config, &me->ldata, CD_MLOOPCOL);
379 }
380 
381 void ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
382 {
383  const int totverts = mesh->totvert;
384 
385  vels.clear();
386  vels.resize(totverts);
387 
388  FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(liquid_sim_modifier_);
389  FluidsimSettings *fss = fmd->fss;
390 
391  if (fss->meshVelocities) {
392  float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
393 
394  for (int i = 0; i < totverts; i++) {
395  copy_yup_from_zup(vels[i].getValue(), mesh_vels);
396  mesh_vels += 3;
397  }
398  }
399  else {
400  std::fill(vels.begin(), vels.end(), Imath::V3f(0.0f));
401  }
402 }
403 
404 void ABCGenericMeshWriter::get_geo_groups(Object *object,
405  struct Mesh *mesh,
406  std::map<std::string, std::vector<int32_t>> &geo_groups)
407 {
408  const int num_poly = mesh->totpoly;
409  MPoly *polygons = mesh->mpoly;
410 
411  for (int i = 0; i < num_poly; i++) {
412  MPoly &current_poly = polygons[i];
413  short mnr = current_poly.mat_nr;
414 
415  Material *mat = BKE_object_material_get(object, mnr + 1);
416 
417  if (!mat) {
418  continue;
419  }
420 
421  std::string name = args_.hierarchy_iterator->get_id_name(&mat->id);
422 
423  if (geo_groups.find(name) == geo_groups.end()) {
424  std::vector<int32_t> faceArray;
425  geo_groups[name] = faceArray;
426  }
427 
428  geo_groups[name].push_back(i);
429  }
430 
431  if (geo_groups.empty()) {
432  Material *mat = BKE_object_material_get(object, 1);
433 
434  std::string name = (mat) ? args_.hierarchy_iterator->get_id_name(&mat->id) : "default";
435 
436  std::vector<int32_t> faceArray;
437 
438  for (int i = 0, e = mesh->totface; i < e; i++) {
439  faceArray.push_back(i);
440  }
441 
442  geo_groups[name] = faceArray;
443  }
444 }
445 
446 /* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
447 
448 static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
449 {
450  points.clear();
451  points.resize(mesh->totvert);
452 
453  MVert *verts = mesh->mvert;
454 
455  for (int i = 0, e = mesh->totvert; i < e; i++) {
456  copy_yup_from_zup(points[i].getValue(), verts[i].co);
457  }
458 }
459 
460 static void get_topology(struct Mesh *mesh,
461  std::vector<int32_t> &poly_verts,
462  std::vector<int32_t> &loop_counts,
463  bool &r_has_flat_shaded_poly)
464 {
465  const int num_poly = mesh->totpoly;
466  const int num_loops = mesh->totloop;
467  MLoop *mloop = mesh->mloop;
468  MPoly *mpoly = mesh->mpoly;
469  r_has_flat_shaded_poly = false;
470 
471  poly_verts.clear();
472  loop_counts.clear();
473  poly_verts.reserve(num_loops);
474  loop_counts.reserve(num_poly);
475 
476  /* NOTE: data needs to be written in the reverse order. */
477  for (int i = 0; i < num_poly; i++) {
478  MPoly &poly = mpoly[i];
479  loop_counts.push_back(poly.totloop);
480 
481  r_has_flat_shaded_poly |= (poly.flag & ME_SMOOTH) == 0;
482 
483  MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
484 
485  for (int j = 0; j < poly.totloop; j++, loop--) {
486  poly_verts.push_back(loop->v);
487  }
488  }
489 }
490 
491 static void get_creases(struct Mesh *mesh,
492  std::vector<int32_t> &indices,
493  std::vector<int32_t> &lengths,
494  std::vector<float> &sharpnesses)
495 {
496  const float factor = 1.0f / 255.0f;
497 
498  indices.clear();
499  lengths.clear();
500  sharpnesses.clear();
501 
502  MEdge *edge = mesh->medge;
503 
504  for (int i = 0, e = mesh->totedge; i < e; i++) {
505  const float sharpness = static_cast<float>(edge[i].crease) * factor;
506 
507  if (sharpness != 0.0f) {
508  indices.push_back(edge[i].v1);
509  indices.push_back(edge[i].v2);
510  sharpnesses.push_back(sharpness);
511  }
512  }
513 
514  lengths.resize(sharpnesses.size(), 2);
515 }
516 
517 static void get_loop_normals(struct Mesh *mesh,
518  std::vector<Imath::V3f> &normals,
519  bool has_flat_shaded_poly)
520 {
521  normals.clear();
522 
523  /* If all polygons are smooth shaded, and there are no custom normals, we don't need to export
524  * normals at all. This is also done by other software, see T71246. */
525  if (!has_flat_shaded_poly && !CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL) &&
526  (mesh->flag & ME_AUTOSMOOTH) == 0) {
527  return;
528  }
529 
531  const float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
532  BLI_assert(lnors != nullptr || !"BKE_mesh_calc_normals_split() should have computed CD_NORMAL");
533 
534  normals.resize(mesh->totloop);
535 
536  /* NOTE: data needs to be written in the reverse order. */
537  int abc_index = 0;
538  MPoly *mp = mesh->mpoly;
539  for (int i = 0, e = mesh->totpoly; i < e; i++, mp++) {
540  for (int j = mp->totloop - 1; j >= 0; j--, abc_index++) {
541  int blender_index = mp->loopstart + j;
542  copy_yup_from_zup(normals[abc_index].getValue(), lnors[blender_index]);
543  }
544  }
545 }
546 
548 {
549 }
550 
551 Mesh *ABCMeshWriter::get_export_mesh(Object *object_eval, bool & /*r_needsfree*/)
552 {
553  return BKE_object_get_evaluated_mesh(object_eval);
554 }
555 
556 } // namespace blender::io::alembic
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
void BKE_id_free(struct Main *bmain, void *idv)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
struct BMesh * BKE_mesh_to_bmesh_ex(const struct Mesh *me, const struct BMeshCreateParams *create_params, const struct BMeshFromMeshParams *convert_params)
struct Mesh * BKE_mesh_from_bmesh_for_eval_nomain(struct BMesh *bm, const struct CustomData_MeshMasks *cd_mask_extra, const struct Mesh *me_settings)
void BKE_mesh_calc_normals_split(struct Mesh *mesh)
Definition: mesh.c:1865
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(struct Object *object)
Definition: object.c:4459
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define CLOG_INFO(clg_ref, level,...)
Definition: CLG_log.h:201
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ CD_CUSTOMLOOPNORMAL
@ CD_MLOOPCOL
@ CD_MLOOPUV
@ ME_AUTOSMOOTH
@ ME_SMOOTH
@ eModifierMode_Render
@ eModifierMode_DisableTemporary
@ eModifierType_Fluidsim
@ eModifierType_Subsurf
#define OB_FLUIDSIM_DOMAIN
_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 type
_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
static CLG_LogRef LOG
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.c:307
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
virtual std::string get_id_name(const ID *id) const
Alembic::Abc::OCompoundProperty abc_schema_prop_for_custom_props(T abc_schema)
const ABCWriterConstructorArgs args_
virtual void update_bounding_box(Object *object)
virtual void do_write(HierarchyContext &context) override
ABCGenericMeshWriter(const ABCWriterConstructorArgs &args)
virtual Alembic::Abc::OObject get_alembic_object() const override
virtual bool is_supported(const HierarchyContext *context) const override
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree)=0
Alembic::Abc::OCompoundProperty abc_prop_for_custom_props() override
virtual void create_alembic_objects(const HierarchyContext *context) override
virtual bool export_as_subdivision_surface(Object *ob_eval) const
virtual Mesh * get_export_mesh(Object *object_eval, bool &r_needsfree) override
ABCMeshWriter(const ABCWriterConstructorArgs &args)
Scene scene
static ushort indices[]
static float verts[][3]
static float normals[][3]
static void sample(SocketReader *reader, int x, int y, float color[4])
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
static void get_topology(struct Mesh *mesh, std::vector< int32_t > &poly_verts, std::vector< int32_t > &loop_counts, bool &r_has_flat_shaded_poly)
const char * get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
static void get_creases(struct Mesh *mesh, std::vector< int32_t > &indices, std::vector< int32_t > &lengths, std::vector< float > &sharpnesses)
void write_custom_data(const OCompoundProperty &prop, CDStreamConfig &config, CustomData *data, int data_type)
static void get_loop_normals(struct Mesh *mesh, std::vector< Imath::V3f > &normals, bool has_flat_shaded_poly)
static void get_vertices(struct Mesh *mesh, std::vector< Imath::V3f > &points)
struct SELECTID_Context context
Definition: select_engine.c:47
enum eEvaluationMode evaluation_mode
Definition: ABC_alembic.h:66
struct FluidsimSettings * fss
struct FluidVertexVelocity * meshVelocities
void * last
Definition: DNA_listBase.h:47
unsigned int v
short mat_nr
struct MEdge * medge
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int totvert
short flag
struct MLoop * mloop
int totface
int totpoly
int totloop
struct MPoly * mpoly
struct ModifierData * prev
ListBase modifiers