d56a05f65b799c1ac62fb82cc414bac84b1dba0b
[blender.git] / source / blender / alembic / intern / abc_mesh.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Esteban Tovagliari, Cedric Paille, Kevin Dietrich
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 #include "abc_mesh.h"
24
25 #include <algorithm>
26
27 #include "abc_transform.h"
28 #include "abc_util.h"
29
30 extern "C" {
31 #include "DNA_material_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_modifier_types.h"
35 #include "DNA_object_fluidsim_types.h"
36 #include "DNA_object_types.h"
37
38 #include "BLI_math_geom.h"
39 #include "BLI_string.h"
40
41 #include "BKE_main.h"
42 #include "BKE_material.h"
43 #include "BKE_mesh.h"
44 #include "BKE_mesh_runtime.h"
45 #include "BKE_modifier.h"
46 #include "BKE_object.h"
47
48 #include "WM_api.h"
49 #include "WM_types.h"
50
51 #include "ED_mesh.h"
52
53 #include "bmesh.h"
54 #include "bmesh_tools.h"
55
56 #include "DEG_depsgraph_query.h"
57 }
58
59 using Alembic::Abc::FloatArraySample;
60 using Alembic::Abc::ICompoundProperty;
61 using Alembic::Abc::Int32ArraySample;
62 using Alembic::Abc::Int32ArraySamplePtr;
63 using Alembic::Abc::P3fArraySamplePtr;
64 using Alembic::Abc::V2fArraySample;
65 using Alembic::Abc::V3fArraySample;
66 using Alembic::Abc::C4fArraySample;
67
68 using Alembic::AbcGeom::IFaceSet;
69 using Alembic::AbcGeom::IFaceSetSchema;
70 using Alembic::AbcGeom::IObject;
71 using Alembic::AbcGeom::IPolyMesh;
72 using Alembic::AbcGeom::IPolyMeshSchema;
73 using Alembic::AbcGeom::ISampleSelector;
74 using Alembic::AbcGeom::ISubD;
75 using Alembic::AbcGeom::ISubDSchema;
76 using Alembic::AbcGeom::IV2fGeomParam;
77
78 using Alembic::AbcGeom::OArrayProperty;
79 using Alembic::AbcGeom::OBoolProperty;
80 using Alembic::AbcGeom::OC3fArrayProperty;
81 using Alembic::AbcGeom::OC3fGeomParam;
82 using Alembic::AbcGeom::OC4fGeomParam;
83 using Alembic::AbcGeom::OCompoundProperty;
84 using Alembic::AbcGeom::OFaceSet;
85 using Alembic::AbcGeom::OFaceSetSchema;
86 using Alembic::AbcGeom::OFloatGeomParam;
87 using Alembic::AbcGeom::OInt32GeomParam;
88 using Alembic::AbcGeom::ON3fArrayProperty;
89 using Alembic::AbcGeom::ON3fGeomParam;
90 using Alembic::AbcGeom::OPolyMesh;
91 using Alembic::AbcGeom::OPolyMeshSchema;
92 using Alembic::AbcGeom::OSubD;
93 using Alembic::AbcGeom::OSubDSchema;
94 using Alembic::AbcGeom::OV2fGeomParam;
95 using Alembic::AbcGeom::OV3fGeomParam;
96
97 using Alembic::AbcGeom::kFacevaryingScope;
98 using Alembic::AbcGeom::kVaryingScope;
99 using Alembic::AbcGeom::kVertexScope;
100 using Alembic::AbcGeom::kWrapExisting;
101 using Alembic::AbcGeom::UInt32ArraySample;
102 using Alembic::AbcGeom::N3fArraySamplePtr;
103 using Alembic::AbcGeom::IN3fGeomParam;
104
105 /* ************************************************************************** */
106
107 /* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
108
109 static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
110 {
111         points.clear();
112         points.resize(mesh->totvert);
113
114         MVert *verts = mesh->mvert;
115
116         for (int i = 0, e = mesh->totvert; i < e; ++i) {
117                 copy_yup_from_zup(points[i].getValue(), verts[i].co);
118         }
119 }
120
121 static void get_topology(struct Mesh *mesh,
122                          std::vector<int32_t> &poly_verts,
123                          std::vector<int32_t> &loop_counts,
124                          bool &smooth_normal)
125 {
126         const int num_poly = mesh->totpoly;
127         const int num_loops = mesh->totloop;
128         MLoop *mloop = mesh->mloop;
129         MPoly *mpoly = mesh->mpoly;
130
131         poly_verts.clear();
132         loop_counts.clear();
133         poly_verts.reserve(num_loops);
134         loop_counts.reserve(num_poly);
135
136         /* NOTE: data needs to be written in the reverse order. */
137         for (int i = 0; i < num_poly; ++i) {
138                 MPoly &poly = mpoly[i];
139                 loop_counts.push_back(poly.totloop);
140
141                 smooth_normal |= ((poly.flag & ME_SMOOTH) != 0);
142
143                 MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
144
145                 for (int j = 0; j < poly.totloop; ++j, --loop) {
146                         poly_verts.push_back(loop->v);
147                 }
148         }
149 }
150
151 static void get_creases(struct Mesh *mesh,
152                         std::vector<int32_t> &indices,
153                         std::vector<int32_t> &lengths,
154                         std::vector<float> &sharpnesses)
155 {
156         const float factor = 1.0f / 255.0f;
157
158         indices.clear();
159         lengths.clear();
160         sharpnesses.clear();
161
162         MEdge *edge = mesh->medge;
163
164         for (int i = 0, e = mesh->totedge; i < e; ++i) {
165                 const float sharpness = static_cast<float>(edge[i].crease) * factor;
166
167                 if (sharpness != 0.0f) {
168                         indices.push_back(edge[i].v1);
169                         indices.push_back(edge[i].v2);
170                         sharpnesses.push_back(sharpness);
171                 }
172         }
173
174         lengths.resize(sharpnesses.size(), 2);
175 }
176
177 static void get_vertex_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
178 {
179         normals.clear();
180         normals.resize(mesh->totvert);
181
182         MVert *verts = mesh->mvert;
183         float no[3];
184
185         for (int i = 0, e = mesh->totvert; i < e; ++i) {
186                 normal_short_to_float_v3(no, verts[i].no);
187                 copy_yup_from_zup(normals[i].getValue(), no);
188         }
189 }
190
191 static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
192 {
193         MPoly *mp = mesh->mpoly;
194
195         MLoop *mloop = mesh->mloop;
196         MLoop *ml = mloop;
197
198         MVert *verts = mesh->mvert;
199
200         const float (*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
201
202         normals.clear();
203         normals.resize(mesh->totloop);
204
205         unsigned loop_index = 0;
206
207         /* NOTE: data needs to be written in the reverse order. */
208
209         if (lnors) {
210                 for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
211                         ml = mloop + mp->loopstart + (mp->totloop - 1);
212
213                         for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
214                                 const int index = ml->v;
215                                 copy_yup_from_zup(normals[loop_index].getValue(), lnors[index]);
216                         }
217                 }
218         }
219         else {
220                 float no[3];
221
222                 for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
223                         ml = mloop + mp->loopstart + (mp->totloop - 1);
224
225                         /* Flat shaded, use common normal for all verts. */
226                         if ((mp->flag & ME_SMOOTH) == 0) {
227                                 BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
228
229                                 for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
230                                         copy_yup_from_zup(normals[loop_index].getValue(), no);
231                                 }
232                         }
233                         else {
234                                 /* Smooth shaded, use individual vert normals. */
235                                 for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
236                                         normal_short_to_float_v3(no, verts[ml->v].no);
237                                         copy_yup_from_zup(normals[loop_index].getValue(), no);
238                                 }
239                         }
240                 }
241         }
242 }
243
244 /* *************** Modifiers *************** */
245
246 /* check if the mesh is a subsurf, ignoring disabled modifiers and
247  * displace if it's after subsurf. */
248 static ModifierData *get_subsurf_modifier(Scene *scene, Object *ob)
249 {
250         ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
251
252         for (; md; md = md->prev) {
253                 if (!modifier_isEnabled(scene, md, eModifierMode_Render)) {
254                         continue;
255                 }
256
257                 if (md->type == eModifierType_Subsurf) {
258                         SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData*>(md);
259
260                         if (smd->subdivType == ME_CC_SUBSURF) {
261                                 return md;
262                         }
263                 }
264
265                 /* mesh is not a subsurf. break */
266                 if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) {
267                         return NULL;
268                 }
269         }
270
271         return NULL;
272 }
273
274 static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob)
275 {
276         ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
277
278         if (md && (modifier_isEnabled(scene, md, eModifierMode_Render))) {
279                 FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
280
281                 if (fsmd->fss && fsmd->fss->type == OB_FLUIDSIM_DOMAIN) {
282                         return md;
283                 }
284         }
285
286         return NULL;
287 }
288
289 /* ************************************************************************** */
290
291 AbcMeshWriter::AbcMeshWriter(Object *ob,
292                              AbcTransformWriter *parent,
293                              uint32_t time_sampling,
294                              ExportSettings &settings)
295     : AbcObjectWriter(ob, time_sampling, settings, parent)
296 {
297         m_is_animated = isAnimated();
298         m_subsurf_mod = NULL;
299         m_is_subd = false;
300
301         /* If the object is static, use the default static time sampling. */
302         if (!m_is_animated) {
303                 time_sampling = 0;
304         }
305
306         if (!m_settings.apply_subdiv) {
307                 m_subsurf_mod = get_subsurf_modifier(m_settings.scene, m_object);
308                 m_is_subd = (m_subsurf_mod != NULL);
309         }
310
311         m_is_liquid = (get_liquid_sim_modifier(m_settings.scene, m_object) != NULL);
312
313         while (parent->alembicXform().getChildHeader(m_name)) {
314                 m_name.append("_");
315         }
316
317         if (m_settings.use_subdiv_schema && m_is_subd) {
318                 OSubD subd(parent->alembicXform(), m_name, m_time_sampling);
319                 m_subdiv_schema = subd.getSchema();
320         }
321         else {
322                 OPolyMesh mesh(parent->alembicXform(), m_name, m_time_sampling);
323                 m_mesh_schema = mesh.getSchema();
324
325                 OCompoundProperty typeContainer = m_mesh_schema.getUserProperties();
326                 OBoolProperty type(typeContainer, "meshtype");
327                 type.set(m_is_subd);
328         }
329 }
330
331 AbcMeshWriter::~AbcMeshWriter()
332 {
333         if (m_subsurf_mod) {
334                 m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
335         }
336 }
337
338 bool AbcMeshWriter::isAnimated() const
339 {
340         /* Check if object has shape keys. */
341         Mesh *me = static_cast<Mesh *>(m_object->data);
342
343         if (me->key) {
344                 return true;
345         }
346
347         /* Test modifiers. */
348         ModifierData *md = static_cast<ModifierData *>(m_object->modifiers.first);
349
350         while (md) {
351                 if (md->type != eModifierType_Subsurf) {
352                         return true;
353                 }
354
355                 md = md->next;
356         }
357
358         return me->adt != NULL;
359 }
360
361 void AbcMeshWriter::setIsAnimated(bool is_animated)
362 {
363         m_is_animated = is_animated;
364 }
365
366 void AbcMeshWriter::do_write()
367 {
368         /* We have already stored a sample for this object. */
369         if (!m_first_frame && !m_is_animated)
370                 return;
371
372         bool needsfree;
373         struct Mesh *mesh = getFinalMesh(needsfree);
374
375         try {
376                 if (m_settings.use_subdiv_schema && m_subdiv_schema.valid()) {
377                         writeSubD(mesh);
378                 }
379                 else {
380                         writeMesh(mesh);
381                 }
382
383                 if (needsfree) BKE_id_free(NULL, mesh);
384         }
385         catch (...) {
386                 if (needsfree) BKE_id_free(NULL, mesh);
387                 throw;
388         }
389 }
390
391 void AbcMeshWriter::writeMesh(struct Mesh *mesh)
392 {
393         std::vector<Imath::V3f> points, normals;
394         std::vector<int32_t> poly_verts, loop_counts;
395
396         bool smooth_normal = false;
397
398         get_vertices(mesh, points);
399         get_topology(mesh, poly_verts, loop_counts, smooth_normal);
400
401         if (m_first_frame && m_settings.export_face_sets) {
402                 writeFaceSets(mesh, m_mesh_schema);
403         }
404
405         m_mesh_sample = OPolyMeshSchema::Sample(V3fArraySample(points),
406                                                 Int32ArraySample(poly_verts),
407                                                 Int32ArraySample(loop_counts));
408
409         UVSample sample;
410         if (m_first_frame && m_settings.export_uvs) {
411                 const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
412
413                 if (!sample.indices.empty() && !sample.uvs.empty()) {
414                         OV2fGeomParam::Sample uv_sample;
415                         uv_sample.setVals(V2fArraySample(sample.uvs));
416                         uv_sample.setIndices(UInt32ArraySample(sample.indices));
417                         uv_sample.setScope(kFacevaryingScope);
418
419                         m_mesh_schema.setUVSourceName(name);
420                         m_mesh_sample.setUVs(uv_sample);
421                 }
422
423                 write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
424         }
425
426         if (m_settings.export_normals) {
427                 if (smooth_normal) {
428                         get_loop_normals(mesh, normals);
429                 }
430                 else {
431                         get_vertex_normals(mesh, normals);
432                 }
433
434                 ON3fGeomParam::Sample normals_sample;
435                 if (!normals.empty()) {
436                         normals_sample.setScope((smooth_normal) ? kFacevaryingScope : kVertexScope);
437                         normals_sample.setVals(V3fArraySample(normals));
438                 }
439
440                 m_mesh_sample.setNormals(normals_sample);
441         }
442
443         if (m_is_liquid) {
444                 std::vector<Imath::V3f> velocities;
445                 getVelocities(mesh, velocities);
446
447                 m_mesh_sample.setVelocities(V3fArraySample(velocities));
448         }
449
450         m_mesh_sample.setSelfBounds(bounds());
451
452         m_mesh_schema.set(m_mesh_sample);
453
454         writeArbGeoParams(mesh);
455 }
456
457 void AbcMeshWriter::writeSubD(struct Mesh *mesh)
458 {
459         std::vector<float> crease_sharpness;
460         std::vector<Imath::V3f> points;
461         std::vector<int32_t> poly_verts, loop_counts;
462         std::vector<int32_t> crease_indices, crease_lengths;
463
464         bool smooth_normal = false;
465
466         get_vertices(mesh, points);
467         get_topology(mesh, poly_verts, loop_counts, smooth_normal);
468         get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
469
470         if (m_first_frame && m_settings.export_face_sets) {
471                 writeFaceSets(mesh, m_subdiv_schema);
472         }
473
474         m_subdiv_sample = OSubDSchema::Sample(V3fArraySample(points),
475                                               Int32ArraySample(poly_verts),
476                                               Int32ArraySample(loop_counts));
477
478         UVSample sample;
479         if (m_first_frame && m_settings.export_uvs) {
480                 const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
481
482                 if (!sample.indices.empty() && !sample.uvs.empty()) {
483                         OV2fGeomParam::Sample uv_sample;
484                         uv_sample.setVals(V2fArraySample(sample.uvs));
485                         uv_sample.setIndices(UInt32ArraySample(sample.indices));
486                         uv_sample.setScope(kFacevaryingScope);
487
488                         m_subdiv_schema.setUVSourceName(name);
489                         m_subdiv_sample.setUVs(uv_sample);
490                 }
491
492                 write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
493         }
494
495         if (!crease_indices.empty()) {
496                 m_subdiv_sample.setCreaseIndices(Int32ArraySample(crease_indices));
497                 m_subdiv_sample.setCreaseLengths(Int32ArraySample(crease_lengths));
498                 m_subdiv_sample.setCreaseSharpnesses(FloatArraySample(crease_sharpness));
499         }
500
501         m_subdiv_sample.setSelfBounds(bounds());
502         m_subdiv_schema.set(m_subdiv_sample);
503
504         writeArbGeoParams(mesh);
505 }
506
507 template <typename Schema>
508 void AbcMeshWriter::writeFaceSets(struct Mesh *dm, Schema &schema)
509 {
510         std::map< std::string, std::vector<int32_t> > geo_groups;
511         getGeoGroups(dm, geo_groups);
512
513         std::map< std::string, std::vector<int32_t>  >::iterator it;
514         for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
515                 OFaceSet face_set = schema.createFaceSet(it->first);
516                 OFaceSetSchema::Sample samp;
517                 samp.setFaces(Int32ArraySample(it->second));
518                 face_set.getSchema().set(samp);
519         }
520 }
521
522 Mesh *AbcMeshWriter::getFinalMesh(bool &r_needsfree)
523 {
524         /* We don't want subdivided mesh data */
525         if (m_subsurf_mod) {
526                 m_subsurf_mod->mode |= eModifierMode_DisableTemporary;
527         }
528
529         Scene *scene = DEG_get_evaluated_scene(m_settings.depsgraph);
530         Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
531         struct Mesh *mesh = mesh_get_eval_final(m_settings.depsgraph, scene, ob_eval, CD_MASK_MESH);
532         r_needsfree = false;
533
534         if (m_subsurf_mod) {
535                 m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
536         }
537
538         if (m_settings.triangulate) {
539                 const bool tag_only = false;
540                 const int quad_method = m_settings.quad_method;
541                 const int ngon_method = m_settings.ngon_method;
542
543                 struct BMeshCreateParams bmcp = {.use_toolflags = false,};
544                 struct BMeshFromMeshParams bmfmp = {.calc_face_normal = true,};
545                 BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
546
547                 BM_mesh_triangulate(bm, quad_method, ngon_method, tag_only, NULL, NULL, NULL);
548
549                 struct BMeshToMeshParams bmmp = {0};
550                 Mesh *result = BKE_bmesh_to_mesh_nomain(bm, &bmmp);
551                 BM_mesh_free(bm);
552
553                 mesh = result;
554                 r_needsfree = true;
555         }
556
557         m_custom_data_config.pack_uvs = m_settings.pack_uv;
558         m_custom_data_config.mpoly = mesh->mpoly;
559         m_custom_data_config.mloop = mesh->mloop;
560         m_custom_data_config.totpoly = mesh->totpoly;
561         m_custom_data_config.totloop = mesh->totloop;
562         m_custom_data_config.totvert = mesh->totvert;
563
564         return mesh;
565 }
566
567 void AbcMeshWriter::writeArbGeoParams(struct Mesh *dm)
568 {
569         if (m_is_liquid) {
570                 /* We don't need anything more for liquid meshes. */
571                 return;
572         }
573
574         if (m_first_frame && m_settings.export_vcols) {
575                 if (m_subdiv_schema.valid()) {
576                         write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &dm->ldata, CD_MLOOPCOL);
577                 }
578                 else {
579                         write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &dm->ldata, CD_MLOOPCOL);
580                 }
581         }
582 }
583
584 void AbcMeshWriter::getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
585 {
586         const int totverts = mesh->totvert;
587
588         vels.clear();
589         vels.resize(totverts);
590
591         ModifierData *md = get_liquid_sim_modifier(m_settings.scene, m_object);
592         FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(md);
593         FluidsimSettings *fss = fmd->fss;
594
595         if (fss->meshVelocities) {
596                 float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
597
598                 for (int i = 0; i < totverts; ++i) {
599                         copy_yup_from_zup(vels[i].getValue(), mesh_vels);
600                         mesh_vels += 3;
601                 }
602         }
603         else {
604                 std::fill(vels.begin(), vels.end(), Imath::V3f(0.0f));
605         }
606 }
607
608 void AbcMeshWriter::getGeoGroups(
609         struct Mesh *mesh,
610         std::map<std::string, std::vector<int32_t> > &geo_groups)
611 {
612         const int num_poly = mesh->totpoly;
613         MPoly *polygons = mesh->mpoly;
614
615         for (int i = 0; i < num_poly; ++i) {
616                 MPoly &current_poly = polygons[i];
617                 short mnr = current_poly.mat_nr;
618
619                 Material *mat = give_current_material(m_object, mnr + 1);
620
621                 if (!mat) {
622                         continue;
623                 }
624
625                 std::string name = get_id_name(&mat->id);
626
627                 if (geo_groups.find(name) == geo_groups.end()) {
628                         std::vector<int32_t> faceArray;
629                         geo_groups[name] = faceArray;
630                 }
631
632                 geo_groups[name].push_back(i);
633         }
634
635         if (geo_groups.size() == 0) {
636                 Material *mat = give_current_material(m_object, 1);
637
638                 std::string name = (mat) ? get_id_name(&mat->id) : "default";
639
640                 std::vector<int32_t> faceArray;
641
642                 for (int i = 0, e = mesh->totface; i < e; ++i) {
643                         faceArray.push_back(i);
644                 }
645
646                 geo_groups[name] = faceArray;
647         }
648 }
649
650 /* ************************************************************************** */
651
652 /* Some helpers for mesh generation */
653 namespace utils {
654
655 static void build_mat_map(const Main *bmain, std::map<std::string, Material *> &mat_map)
656 {
657         Material *material = static_cast<Material *>(bmain->mat.first);
658
659         for (; material; material = static_cast<Material *>(material->id.next)) {
660                 mat_map[material->id.name + 2] = material;
661         }
662 }
663
664 static void assign_materials(Main *bmain, Object *ob, const std::map<std::string, int> &mat_index_map)
665 {
666         bool can_assign = true;
667         std::map<std::string, int>::const_iterator it = mat_index_map.begin();
668
669         int matcount = 0;
670         for (; it != mat_index_map.end(); ++it, ++matcount) {
671                 if (!BKE_object_material_slot_add(bmain, ob)) {
672                         can_assign = false;
673                         break;
674                 }
675         }
676
677         /* TODO(kevin): use global map? */
678         std::map<std::string, Material *> mat_map;
679         build_mat_map(bmain, mat_map);
680
681         std::map<std::string, Material *>::iterator mat_iter;
682
683         if (can_assign) {
684                 it = mat_index_map.begin();
685
686                 for (; it != mat_index_map.end(); ++it) {
687                         std::string mat_name = it->first;
688                         mat_iter = mat_map.find(mat_name.c_str());
689
690                         Material *assigned_mat;
691
692                         if (mat_iter == mat_map.end()) {
693                                 assigned_mat = BKE_material_add(bmain, mat_name.c_str());
694                                 mat_map[mat_name] = assigned_mat;
695                         }
696                         else {
697                                 assigned_mat = mat_iter->second;
698                         }
699
700                         assign_material(bmain, ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA);
701                 }
702         }
703 }
704
705 }  /* namespace utils */
706
707 /* ************************************************************************** */
708
709 using Alembic::AbcGeom::UInt32ArraySamplePtr;
710 using Alembic::AbcGeom::V2fArraySamplePtr;
711
712 struct AbcMeshData {
713         Int32ArraySamplePtr face_indices;
714         Int32ArraySamplePtr face_counts;
715
716         P3fArraySamplePtr positions;
717         P3fArraySamplePtr ceil_positions;
718
719         N3fArraySamplePtr vertex_normals;
720         N3fArraySamplePtr face_normals;
721
722         V2fArraySamplePtr uvs;
723         UInt32ArraySamplePtr uvs_indices;
724 };
725
726 static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr &positions, const P3fArraySamplePtr &ceil_positions, const float weight)
727 {
728         float tmp[3];
729         for (int i = 0; i < positions->size(); ++i) {
730                 MVert &mvert = mverts[i];
731                 const Imath::V3f &floor_pos = (*positions)[i];
732                 const Imath::V3f &ceil_pos = (*ceil_positions)[i];
733
734                 interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), weight);
735                 copy_zup_from_yup(mvert.co, tmp);
736
737                 mvert.bweight = 0;
738         }
739 }
740
741 static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
742 {
743         MVert *mverts = config.mvert;
744         const P3fArraySamplePtr &positions = mesh_data.positions;
745         const N3fArraySamplePtr &normals = mesh_data.vertex_normals;
746
747         if (   config.weight != 0.0f
748             && mesh_data.ceil_positions != NULL
749             && mesh_data.ceil_positions->size() == positions->size())
750         {
751                 read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight);
752                 return;
753         }
754
755         read_mverts(mverts, positions, normals);
756 }
757
758 void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArraySamplePtr &normals)
759 {
760         for (int i = 0; i < positions->size(); ++i) {
761                 MVert &mvert = mverts[i];
762                 Imath::V3f pos_in = (*positions)[i];
763
764                 copy_zup_from_yup(mvert.co, pos_in.getValue());
765
766                 mvert.bweight = 0;
767
768                 if (normals) {
769                         Imath::V3f nor_in = (*normals)[i];
770
771                         short no[3];
772                         normal_float_to_short_v3(no, nor_in.getValue());
773
774                         copy_zup_from_yup(mvert.no, no);
775                 }
776         }
777 }
778
779 static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
780 {
781         MPoly *mpolys = config.mpoly;
782         MLoop *mloops = config.mloop;
783         MLoopUV *mloopuvs = config.mloopuv;
784
785         const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
786         const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
787         const V2fArraySamplePtr &uvs = mesh_data.uvs;
788         const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
789         const N3fArraySamplePtr &normals = mesh_data.face_normals;
790
791         const bool do_uvs = (mloopuvs && uvs && uvs_indices) && (uvs_indices->size() == face_indices->size());
792         unsigned int loop_index = 0;
793         unsigned int rev_loop_index = 0;
794         unsigned int uv_index = 0;
795
796         for (int i = 0; i < face_counts->size(); ++i) {
797                 const int face_size = (*face_counts)[i];
798
799                 MPoly &poly = mpolys[i];
800                 poly.loopstart = loop_index;
801                 poly.totloop = face_size;
802
803                 if (normals != NULL) {
804                         poly.flag |= ME_SMOOTH;
805                 }
806
807                 /* NOTE: Alembic data is stored in the reverse order. */
808                 rev_loop_index = loop_index + (face_size - 1);
809
810                 for (int f = 0; f < face_size; ++f, ++loop_index, --rev_loop_index) {
811                         MLoop &loop = mloops[rev_loop_index];
812                         loop.v = (*face_indices)[loop_index];
813
814                         if (do_uvs) {
815                                 MLoopUV &loopuv = mloopuvs[rev_loop_index];
816
817                                 uv_index = (*uvs_indices)[loop_index];
818                                 loopuv.uv[0] = (*uvs)[uv_index][0];
819                                 loopuv.uv[1] = (*uvs)[uv_index][1];
820                         }
821                 }
822         }
823 }
824
825 ABC_INLINE void read_uvs_params(CDStreamConfig &config,
826                                 AbcMeshData &abc_data,
827                                 const IV2fGeomParam &uv,
828                                 const ISampleSelector &selector)
829 {
830         if (!uv.valid()) {
831                 return;
832         }
833
834         IV2fGeomParam::Sample uvsamp;
835         uv.getIndexed(uvsamp, selector);
836
837         abc_data.uvs = uvsamp.getVals();
838         abc_data.uvs_indices = uvsamp.getIndices();
839
840         if (abc_data.uvs_indices->size() == config.totloop) {
841                 std::string name = Alembic::Abc::GetSourceName(uv.getMetaData());
842
843                 /* According to the convention, primary UVs should have had their name
844                  * set using Alembic::Abc::SetSourceName, but you can't expect everyone
845                  * to follow it! :) */
846                 if (name.empty()) {
847                         name = uv.getName();
848                 }
849
850                 void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
851                 config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
852         }
853 }
854
855 /* TODO(kevin): normals from Alembic files are not read in anymore, this is due
856  * to the fact that there are many issues that are not so easy to solve, mainly
857  * regarding the way normals are handled in Blender (MPoly.flag vs loop normals).
858  */
859 ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
860                                     const IN3fGeomParam &normals,
861                                     const ISampleSelector &selector)
862 {
863         if (!normals.valid()) {
864                 return;
865         }
866
867         IN3fGeomParam::Sample normsamp = normals.getExpandedValue(selector);
868
869         if (normals.getScope() == kFacevaryingScope) {
870                 abc_data.face_normals = normsamp.getVals();
871         }
872         else if ((normals.getScope() == kVertexScope) || (normals.getScope() == kVaryingScope)) {
873                 abc_data.vertex_normals = N3fArraySamplePtr();
874         }
875 }
876
877 static bool check_smooth_poly_flag(Mesh *mesh)
878 {
879         MPoly *mpolys = mesh->mpoly;
880
881         for (int i = 0, e = mesh->totpoly; i < e; ++i) {
882                 MPoly &poly = mpolys[i];
883
884                 if ((poly.flag & ME_SMOOTH) != 0) {
885                         return true;
886                 }
887         }
888
889         return false;
890 }
891
892 static void set_smooth_poly_flag(Mesh *mesh)
893 {
894         MPoly *mpolys = mesh->mpoly;
895
896         for (int i = 0, e = mesh->totpoly; i < e; ++i) {
897                 MPoly &poly = mpolys[i];
898                 poly.flag |= ME_SMOOTH;
899         }
900 }
901
902 static void *add_customdata_cb(void *user_data, const char *name, int data_type)
903 {
904         Mesh *mesh = static_cast<Mesh *>(user_data);
905         CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
906         void *cd_ptr;
907         CustomData *loopdata;
908         int numloops;
909
910         /* unsupported custom data type -- don't do anything. */
911         if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
912                 return NULL;
913         }
914
915         loopdata = &mesh->ldata;
916         cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name);
917         if (cd_ptr != NULL) {
918                 /* layer already exists, so just return it. */
919                 return cd_ptr;
920         }
921
922         /* create a new layer, taking care to construct the hopefully-soon-to-be-removed
923          * CD_MTEXPOLY layer too, with the same name. */
924         numloops = mesh->totloop;
925         cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT,
926                                             NULL, numloops, name);
927         return cd_ptr;
928 }
929
930 static void get_weight_and_index(CDStreamConfig &config,
931                                  Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
932                                  size_t samples_number)
933 {
934         Alembic::AbcGeom::index_t i0, i1;
935
936         config.weight = get_weight_and_index(config.time,
937                                              time_sampling,
938                                              samples_number,
939                                              i0,
940                                              i1);
941
942         config.index = i0;
943         config.ceil_index = i1;
944 }
945
946 static void read_mesh_sample(const std::string & iobject_full_name,
947                              ImportSettings *settings,
948                              const IPolyMeshSchema &schema,
949                              const ISampleSelector &selector,
950                              CDStreamConfig &config,
951                              bool &do_normals)
952 {
953         const IPolyMeshSchema::Sample sample = schema.getValue(selector);
954
955         AbcMeshData abc_mesh_data;
956         abc_mesh_data.face_counts = sample.getFaceCounts();
957         abc_mesh_data.face_indices = sample.getFaceIndices();
958         abc_mesh_data.positions = sample.getPositions();
959
960         read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
961
962         do_normals = (abc_mesh_data.face_normals != NULL);
963
964         get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
965
966         if (config.weight != 0.0f) {
967                 Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
968                 schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
969                 abc_mesh_data.ceil_positions = ceil_sample.getPositions();
970         }
971
972         if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
973                 read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
974         }
975
976         if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
977                 read_mverts(config, abc_mesh_data);
978         }
979
980         if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
981                 read_mpolys(config, abc_mesh_data);
982         }
983
984         if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
985                 read_custom_data(iobject_full_name,
986                                  schema.getArbGeomParams(), config, selector);
987         }
988 }
989
990 CDStreamConfig get_config(Mesh *mesh)
991 {
992         CDStreamConfig config;
993
994         BLI_assert(mesh->mvert);
995
996         config.user_data = mesh;
997         config.mvert = mesh->mvert;
998         config.mloop = mesh->mloop;
999         config.mpoly = mesh->mpoly;
1000         config.totloop = mesh->totloop;
1001         config.totpoly = mesh->totpoly;
1002         config.loopdata = &mesh->ldata;
1003         config.add_customdata_cb = add_customdata_cb;
1004
1005         return config;
1006 }
1007
1008 /* ************************************************************************** */
1009
1010 AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
1011     : AbcObjectReader(object, settings)
1012 {
1013         m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
1014
1015         IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
1016         m_schema = ipoly_mesh.getSchema();
1017
1018         get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
1019 }
1020
1021 bool AbcMeshReader::valid() const
1022 {
1023         return m_schema.valid();
1024 }
1025
1026 void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
1027 {
1028         Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
1029
1030         m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
1031         m_object->data = mesh;
1032
1033         Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
1034         BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, CD_MASK_MESH, true);
1035
1036         if (m_settings->validate_meshes) {
1037                 BKE_mesh_validate(mesh, false, false);
1038         }
1039
1040         readFaceSetsSample(bmain, mesh, 0, sample_sel);
1041
1042         if (has_animations(m_schema, m_settings)) {
1043                 addCacheModifier();
1044         }
1045 }
1046
1047 bool AbcMeshReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
1048                                         const Object *const ob,
1049                                         const char **err_str) const
1050 {
1051         if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) {
1052                 *err_str = "Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not any more.";
1053                 return false;
1054         }
1055
1056         if (ob->type != OB_MESH) {
1057                 *err_str = "Object type mismatch, Alembic object path points to PolyMesh.";
1058                 return false;
1059         }
1060
1061         return true;
1062 }
1063
1064 Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
1065                                const ISampleSelector &sample_sel,
1066                                int read_flag,
1067                                const char **err_str)
1068 {
1069         IPolyMeshSchema::Sample sample;
1070         try {
1071                 sample = m_schema.getValue(sample_sel);
1072         }
1073         catch(Alembic::Util::Exception &ex) {
1074                 *err_str = "Error reading mesh sample; more detail on the console";
1075                 printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
1076                            m_iobject.getFullName().c_str(),
1077                            m_schema.getName().c_str(),
1078                            sample_sel.getRequestedTime(),
1079                            ex.what());
1080                 return existing_mesh;
1081         }
1082
1083         const P3fArraySamplePtr &positions = sample.getPositions();
1084         const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
1085         const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
1086
1087         Mesh *new_mesh = NULL;
1088
1089         /* Only read point data when streaming meshes, unless we need to create new ones. */
1090         ImportSettings settings;
1091         settings.read_flag |= read_flag;
1092
1093         bool topology_changed =  positions->size() != existing_mesh->totvert ||
1094                                  face_counts->size() != existing_mesh->totpoly ||
1095                                  face_indices->size() != existing_mesh->totloop;
1096         if (topology_changed) {
1097                 new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
1098                                                              positions->size(),
1099                                                              0,
1100                                                              0,
1101                                                              face_indices->size(),
1102                                                              face_counts->size());
1103
1104                 settings.read_flag |= MOD_MESHSEQ_READ_ALL;
1105         }
1106         else {
1107                 /* If the face count changed (e.g. by triangulation), only read points.
1108                  * This prevents crash from T49813.
1109                  * TODO(kevin): perhaps find a better way to do this? */
1110                 if (face_counts->size() != existing_mesh->totpoly ||
1111                     face_indices->size() != existing_mesh->totloop)
1112                 {
1113                         settings.read_flag = MOD_MESHSEQ_READ_VERT;
1114
1115                         if (err_str) {
1116                                 *err_str = "Topology has changed, perhaps by triangulating the"
1117                                            " mesh. Only vertices will be read!";
1118                         }
1119                 }
1120         }
1121
1122         CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
1123         config.time = sample_sel.getRequestedTime();
1124
1125         bool do_normals = false;
1126         read_mesh_sample(m_iobject.getFullName(),
1127                          &settings, m_schema, sample_sel, config, do_normals);
1128
1129         if (new_mesh) {
1130                 /* Check if we had ME_SMOOTH flag set to restore it. */
1131                 if (!do_normals && check_smooth_poly_flag(existing_mesh)) {
1132                         set_smooth_poly_flag(new_mesh);
1133                 }
1134
1135                 BKE_mesh_calc_normals(new_mesh);
1136                 BKE_mesh_calc_edges(new_mesh, false, false);
1137
1138                 /* Here we assume that the number of materials doesn't change, i.e. that
1139                  * the material slots that were created when the object was loaded from
1140                  * Alembic are still valid now. */
1141                 size_t num_polys = new_mesh->totpoly;
1142                 if (num_polys > 0) {
1143                         std::map<std::string, int> mat_map;
1144                         assign_facesets_to_mpoly(sample_sel, 0, new_mesh->mpoly, num_polys, mat_map);
1145                 }
1146
1147                 return new_mesh;
1148         }
1149
1150         if (do_normals) {
1151                 BKE_mesh_calc_normals(existing_mesh);
1152         }
1153
1154         return existing_mesh;
1155 }
1156
1157 void AbcMeshReader::assign_facesets_to_mpoly(
1158         const ISampleSelector &sample_sel,
1159         size_t poly_start,
1160         MPoly *mpoly, int totpoly,
1161         std::map<std::string, int> & r_mat_map)
1162 {
1163         std::vector<std::string> face_sets;
1164         m_schema.getFaceSetNames(face_sets);
1165
1166         if (face_sets.empty()) {
1167                 return;
1168         }
1169
1170         int current_mat = 0;
1171
1172         for (int i = 0; i < face_sets.size(); ++i) {
1173                 const std::string &grp_name = face_sets[i];
1174
1175                 if (r_mat_map.find(grp_name) == r_mat_map.end()) {
1176                         r_mat_map[grp_name] = 1 + current_mat++;
1177                 }
1178
1179                 const int assigned_mat = r_mat_map[grp_name];
1180
1181                 const IFaceSet faceset = m_schema.getFaceSet(grp_name);
1182
1183                 if (!faceset.valid()) {
1184                         std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n";
1185                         continue;
1186                 }
1187
1188                 const IFaceSetSchema face_schem = faceset.getSchema();
1189                 const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
1190                 const Int32ArraySamplePtr group_faces = face_sample.getFaces();
1191                 const size_t num_group_faces = group_faces->size();
1192
1193                 for (size_t l = 0; l < num_group_faces; l++) {
1194                         size_t pos = (*group_faces)[l] + poly_start;
1195
1196                         if (pos >= totpoly) {
1197                                 std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
1198                                 break;
1199                         }
1200
1201                         MPoly &poly = mpoly[pos];
1202                         poly.mat_nr = assigned_mat - 1;
1203                 }
1204         }
1205
1206 }
1207
1208 void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
1209                                        const ISampleSelector &sample_sel)
1210 {
1211         std::map<std::string, int> mat_map;
1212         assign_facesets_to_mpoly(sample_sel,
1213                                  poly_start, mesh->mpoly, mesh->totpoly,
1214                                  mat_map);
1215         utils::assign_materials(bmain, m_object, mat_map);
1216 }
1217
1218 /* ************************************************************************** */
1219
1220 ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
1221 {
1222         for (int i = 0, e = totedge; i < e; ++i) {
1223                 MEdge &edge = edges[i];
1224
1225                 if (edge.v1 == v1 && edge.v2 == v2) {
1226                         return &edge;
1227                 }
1228         }
1229
1230         return NULL;
1231 }
1232
1233 static void read_subd_sample(const std::string & iobject_full_name,
1234                              ImportSettings *settings,
1235                              const ISubDSchema &schema,
1236                              const ISampleSelector &selector,
1237                              CDStreamConfig &config)
1238 {
1239         const ISubDSchema::Sample sample = schema.getValue(selector);
1240
1241         AbcMeshData abc_mesh_data;
1242         abc_mesh_data.face_counts = sample.getFaceCounts();
1243         abc_mesh_data.face_indices = sample.getFaceIndices();
1244         abc_mesh_data.vertex_normals = N3fArraySamplePtr();
1245         abc_mesh_data.face_normals = N3fArraySamplePtr();
1246         abc_mesh_data.positions = sample.getPositions();
1247
1248         get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
1249
1250         if (config.weight != 0.0f) {
1251                 Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
1252                 schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
1253                 abc_mesh_data.ceil_positions = ceil_sample.getPositions();
1254         }
1255
1256         if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
1257                 read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
1258         }
1259
1260         if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
1261                 read_mverts(config, abc_mesh_data);
1262         }
1263
1264         if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
1265                 read_mpolys(config, abc_mesh_data);
1266         }
1267
1268         if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
1269                 read_custom_data(iobject_full_name,
1270                                  schema.getArbGeomParams(), config, selector);
1271         }
1272 }
1273
1274 /* ************************************************************************** */
1275
1276 AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
1277     : AbcObjectReader(object, settings)
1278 {
1279         m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
1280
1281         ISubD isubd_mesh(m_iobject, kWrapExisting);
1282         m_schema = isubd_mesh.getSchema();
1283
1284         get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
1285 }
1286
1287 bool AbcSubDReader::valid() const
1288 {
1289         return m_schema.valid();
1290 }
1291
1292 bool AbcSubDReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
1293                                         const Object *const ob,
1294                                         const char **err_str) const
1295 {
1296         if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) {
1297                 *err_str = "Object type mismatch, Alembic object path pointed to SubD when importing, but not any more.";
1298                 return false;
1299         }
1300
1301         if (ob->type != OB_MESH) {
1302                 *err_str = "Object type mismatch, Alembic object path points to SubD.";
1303                 return false;
1304         }
1305
1306         return true;
1307 }
1308
1309 void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
1310 {
1311         Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
1312
1313         m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
1314         m_object->data = mesh;
1315
1316         Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
1317         BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, CD_MASK_MESH, true);
1318
1319         ISubDSchema::Sample sample;
1320         try {
1321                 sample = m_schema.getValue(sample_sel);
1322         }
1323         catch(Alembic::Util::Exception &ex) {
1324                 printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
1325                            m_iobject.getFullName().c_str(),
1326                            m_schema.getName().c_str(),
1327                            sample_sel.getRequestedTime(),
1328                            ex.what());
1329                 return;
1330         }
1331
1332         Int32ArraySamplePtr indices = sample.getCreaseIndices();
1333         Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
1334
1335         MEdge *edges = mesh->medge;
1336
1337         if (indices && sharpnesses) {
1338                 for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, ++s) {
1339                         MEdge *edge = find_edge(edges, mesh->totedge, (*indices)[i], (*indices)[i + 1]);
1340
1341                         if (edge) {
1342                                 edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
1343                         }
1344                 }
1345
1346                 mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
1347         }
1348
1349         BKE_mesh_calc_normals(mesh);
1350         BKE_mesh_calc_edges(mesh, false, false);
1351
1352         if (m_settings->validate_meshes) {
1353                 BKE_mesh_validate(mesh, false, false);
1354         }
1355
1356         if (has_animations(m_schema, m_settings)) {
1357                 addCacheModifier();
1358         }
1359 }
1360
1361 Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
1362                                const ISampleSelector &sample_sel,
1363                                int read_flag,
1364                                const char **err_str)
1365 {
1366         ISubDSchema::Sample sample;
1367         try {
1368                 sample = m_schema.getValue(sample_sel);
1369         }
1370         catch(Alembic::Util::Exception &ex) {
1371                 *err_str = "Error reading mesh sample; more detail on the console";
1372                 printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
1373                            m_iobject.getFullName().c_str(),
1374                            m_schema.getName().c_str(),
1375                            sample_sel.getRequestedTime(),
1376                            ex.what());
1377                 return existing_mesh;
1378         }
1379
1380         const P3fArraySamplePtr &positions = sample.getPositions();
1381         const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
1382         const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
1383
1384         Mesh *new_mesh = NULL;
1385
1386         ImportSettings settings;
1387         settings.read_flag |= read_flag;
1388
1389         if (existing_mesh->totvert != positions->size()) {
1390                 new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
1391                                                            positions->size(),
1392                                                            0,
1393                                                            0,
1394                                                            face_indices->size(),
1395                                                            face_counts->size());
1396
1397                 settings.read_flag |= MOD_MESHSEQ_READ_ALL;
1398         }
1399         else {
1400                 /* If the face count changed (e.g. by triangulation), only read points.
1401                  * This prevents crash from T49813.
1402                  * TODO(kevin): perhaps find a better way to do this? */
1403                 if (face_counts->size() != existing_mesh->totpoly ||
1404                     face_indices->size() != existing_mesh->totpoly)
1405                 {
1406                         settings.read_flag = MOD_MESHSEQ_READ_VERT;
1407
1408                         if (err_str) {
1409                                 *err_str = "Topology has changed, perhaps by triangulating the"
1410                                            " mesh. Only vertices will be read!";
1411                         }
1412                 }
1413         }
1414
1415         /* Only read point data when streaming meshes, unless we need to create new ones. */
1416         CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
1417         config.time = sample_sel.getRequestedTime();
1418         read_subd_sample(m_iobject.getFullName(),
1419                          &settings, m_schema, sample_sel, config);
1420
1421         if (new_mesh) {
1422                 /* Check if we had ME_SMOOTH flag set to restore it. */
1423                 if (check_smooth_poly_flag(existing_mesh)) {
1424                         set_smooth_poly_flag(new_mesh);
1425                 }
1426
1427                 BKE_mesh_calc_normals(new_mesh);
1428                 BKE_mesh_calc_edges(new_mesh, false, false);
1429
1430                 return new_mesh;
1431         }
1432
1433         return existing_mesh;
1434 }