alembic_capi.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  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. #include "../ABC_alembic.h"
  23. #include <boost/foreach.hpp>
  24. #include <Alembic/AbcMaterial/IMaterial.h>
  25. #include "abc_archive.h"
  26. #include "abc_camera.h"
  27. #include "abc_curves.h"
  28. #include "abc_hair.h"
  29. #include "abc_mesh.h"
  30. #include "abc_nurbs.h"
  31. #include "abc_points.h"
  32. #include "abc_transform.h"
  33. #include "abc_util.h"
  34. extern "C" {
  35. #include "MEM_guardedalloc.h"
  36. #include "DNA_cachefile_types.h"
  37. #include "DNA_curve_types.h"
  38. #include "DNA_modifier_types.h"
  39. #include "DNA_object_types.h"
  40. #include "DNA_scene_types.h"
  41. #include "BKE_cachefile.h"
  42. #include "BKE_cdderivedmesh.h"
  43. #include "BKE_context.h"
  44. #include "BKE_curve.h"
  45. #include "BKE_depsgraph.h"
  46. #include "BKE_global.h"
  47. #include "BKE_library.h"
  48. #include "BKE_main.h"
  49. #include "BKE_scene.h"
  50. /* SpaceType struct has a member called 'new' which obviously conflicts with C++
  51. * so temporarily redefining the new keyword to make it compile. */
  52. #define new extern_new
  53. #include "BKE_screen.h"
  54. #undef new
  55. #include "BLI_fileops.h"
  56. #include "BLI_ghash.h"
  57. #include "BLI_listbase.h"
  58. #include "BLI_math.h"
  59. #include "BLI_path_util.h"
  60. #include "BLI_string.h"
  61. #include "WM_api.h"
  62. #include "WM_types.h"
  63. }
  64. using Alembic::Abc::Int32ArraySamplePtr;
  65. using Alembic::Abc::ObjectHeader;
  66. using Alembic::AbcGeom::MetaData;
  67. using Alembic::AbcGeom::P3fArraySamplePtr;
  68. using Alembic::AbcGeom::kWrapExisting;
  69. using Alembic::AbcGeom::ICamera;
  70. using Alembic::AbcGeom::ICurves;
  71. using Alembic::AbcGeom::ICurvesSchema;
  72. using Alembic::AbcGeom::IFaceSet;
  73. using Alembic::AbcGeom::ILight;
  74. using Alembic::AbcGeom::INuPatch;
  75. using Alembic::AbcGeom::IObject;
  76. using Alembic::AbcGeom::IPoints;
  77. using Alembic::AbcGeom::IPointsSchema;
  78. using Alembic::AbcGeom::IPolyMesh;
  79. using Alembic::AbcGeom::IPolyMeshSchema;
  80. using Alembic::AbcGeom::ISampleSelector;
  81. using Alembic::AbcGeom::ISubD;
  82. using Alembic::AbcGeom::IV2fGeomParam;
  83. using Alembic::AbcGeom::IXform;
  84. using Alembic::AbcGeom::IXformSchema;
  85. using Alembic::AbcGeom::N3fArraySamplePtr;
  86. using Alembic::AbcGeom::XformSample;
  87. using Alembic::AbcGeom::ICompoundProperty;
  88. using Alembic::AbcGeom::IN3fArrayProperty;
  89. using Alembic::AbcGeom::IN3fGeomParam;
  90. using Alembic::AbcGeom::V3fArraySamplePtr;
  91. using Alembic::AbcMaterial::IMaterial;
  92. struct AbcArchiveHandle {
  93. int unused;
  94. };
  95. ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
  96. {
  97. return reinterpret_cast<ArchiveReader *>(handle);
  98. }
  99. ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
  100. {
  101. return reinterpret_cast<AbcArchiveHandle *>(archive);
  102. }
  103. //#define USE_NURBS
  104. /* NOTE: this function is similar to visit_objects below, need to keep them in
  105. * sync. */
  106. static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
  107. {
  108. if (!object.valid()) {
  109. return false;
  110. }
  111. size_t children_claiming_this_object = 0;
  112. size_t num_children = object.getNumChildren();
  113. for (size_t i = 0; i < num_children; ++i) {
  114. bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
  115. children_claiming_this_object += child_claims_this_object ? 1 : 0;
  116. }
  117. const MetaData &md = object.getMetaData();
  118. bool get_path = false;
  119. bool parent_is_part_of_this_object = false;
  120. if (!object.getParent()) {
  121. /* The root itself is not an object we should import. */
  122. }
  123. else if (IXform::matches(md)) {
  124. if (has_property(object.getProperties(), "locator")) {
  125. get_path = true;
  126. }
  127. else {
  128. get_path = children_claiming_this_object == 0;
  129. }
  130. /* Transforms are never "data" for their parent. */
  131. parent_is_part_of_this_object = false;
  132. }
  133. else {
  134. /* These types are "data" for their parent. */
  135. get_path =
  136. IPolyMesh::matches(md) ||
  137. ISubD::matches(md) ||
  138. #ifdef USE_NURBS
  139. INuPatch::matches(md) ||
  140. #endif
  141. ICamera::matches(md) ||
  142. IPoints::matches(md) ||
  143. ICurves::matches(md);
  144. parent_is_part_of_this_object = get_path;
  145. }
  146. if (get_path) {
  147. void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
  148. AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
  149. BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
  150. BLI_addtail(object_paths, abc_path);
  151. }
  152. return parent_is_part_of_this_object;
  153. }
  154. AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
  155. {
  156. ArchiveReader *archive = new ArchiveReader(filename);
  157. if (!archive->valid()) {
  158. delete archive;
  159. return NULL;
  160. }
  161. if (object_paths) {
  162. gather_objects_paths(archive->getTop(), object_paths);
  163. }
  164. return handle_from_archive(archive);
  165. }
  166. void ABC_free_handle(AbcArchiveHandle *handle)
  167. {
  168. delete archive_from_handle(handle);
  169. }
  170. int ABC_get_version()
  171. {
  172. return ALEMBIC_LIBRARY_VERSION;
  173. }
  174. static void find_iobject(const IObject &object, IObject &ret,
  175. const std::string &path)
  176. {
  177. if (!object.valid()) {
  178. return;
  179. }
  180. std::vector<std::string> tokens;
  181. split(path, '/', tokens);
  182. IObject tmp = object;
  183. std::vector<std::string>::iterator iter;
  184. for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
  185. IObject child = tmp.getChild(*iter);
  186. tmp = child;
  187. }
  188. ret = tmp;
  189. }
  190. struct ExportJobData {
  191. Scene *scene;
  192. Main *bmain;
  193. char filename[1024];
  194. ExportSettings settings;
  195. short *stop;
  196. short *do_update;
  197. float *progress;
  198. bool was_canceled;
  199. bool export_ok;
  200. };
  201. static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
  202. {
  203. ExportJobData *data = static_cast<ExportJobData *>(customdata);
  204. data->stop = stop;
  205. data->do_update = do_update;
  206. data->progress = progress;
  207. /* XXX annoying hack: needed to prevent data corruption when changing
  208. * scene frame in separate threads
  209. */
  210. G.is_rendering = true;
  211. BKE_spacedata_draw_locks(true);
  212. G.is_break = false;
  213. try {
  214. Scene *scene = data->scene;
  215. AbcExporter exporter(scene, data->filename, data->settings);
  216. const int orig_frame = CFRA;
  217. data->was_canceled = false;
  218. exporter(data->bmain, *data->progress, data->was_canceled);
  219. if (CFRA != orig_frame) {
  220. CFRA = orig_frame;
  221. BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain,
  222. scene, scene->lay);
  223. }
  224. data->export_ok = !data->was_canceled;
  225. }
  226. catch (const std::exception &e) {
  227. ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
  228. }
  229. catch (...) {
  230. ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
  231. }
  232. }
  233. static void export_endjob(void *customdata)
  234. {
  235. ExportJobData *data = static_cast<ExportJobData *>(customdata);
  236. if (data->was_canceled && BLI_exists(data->filename)) {
  237. BLI_delete(data->filename, false, false);
  238. }
  239. if (!data->settings.logger.empty()) {
  240. std::cerr << data->settings.logger;
  241. WM_report(RPT_ERROR, "Errors occured during the export, look in the console to know more...");
  242. }
  243. G.is_rendering = false;
  244. BKE_spacedata_draw_locks(false);
  245. }
  246. bool ABC_export(
  247. Scene *scene,
  248. bContext *C,
  249. const char *filepath,
  250. const struct AlembicExportParams *params,
  251. bool as_background_job)
  252. {
  253. ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
  254. job->scene = scene;
  255. job->bmain = CTX_data_main(C);
  256. job->export_ok = false;
  257. BLI_strncpy(job->filename, filepath, 1024);
  258. /* Alright, alright, alright....
  259. *
  260. * ExportJobData contains an ExportSettings containing a SimpleLogger.
  261. *
  262. * Since ExportJobData is a C-style struct dynamically allocated with
  263. * MEM_mallocN (see above), its construtor is never called, therefore the
  264. * ExportSettings constructor is not called which implies that the
  265. * SimpleLogger one is not called either. SimpleLogger in turn does not call
  266. * the constructor of its data members which ultimately means that its
  267. * std::ostringstream member has a NULL pointer. To be able to properly use
  268. * the stream's operator<<, the pointer needs to be set, therefore we have
  269. * to properly construct everything. And this is done using the placement
  270. * new operator as here below. It seems hackish, but I'm too lazy to
  271. * do bigger refactor and maybe there is a better way which does not involve
  272. * hardcore refactoring. */
  273. new (&job->settings) ExportSettings();
  274. job->settings.scene = job->scene;
  275. job->settings.frame_start = params->frame_start;
  276. job->settings.frame_end = params->frame_end;
  277. job->settings.frame_samples_xform = params->frame_samples_xform;
  278. job->settings.frame_samples_shape = params->frame_samples_shape;
  279. job->settings.shutter_open = params->shutter_open;
  280. job->settings.shutter_close = params->shutter_close;
  281. job->settings.selected_only = params->selected_only;
  282. job->settings.export_face_sets = params->face_sets;
  283. job->settings.export_normals = params->normals;
  284. job->settings.export_uvs = params->uvs;
  285. job->settings.export_vcols = params->vcolors;
  286. job->settings.export_hair = params->export_hair;
  287. job->settings.export_particles = params->export_particles;
  288. job->settings.apply_subdiv = params->apply_subdiv;
  289. job->settings.flatten_hierarchy = params->flatten_hierarchy;
  290. job->settings.visible_layers_only = params->visible_layers_only;
  291. job->settings.renderable_only = params->renderable_only;
  292. job->settings.use_subdiv_schema = params->use_subdiv_schema;
  293. job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
  294. job->settings.pack_uv = params->packuv;
  295. job->settings.global_scale = params->global_scale;
  296. job->settings.triangulate = params->triangulate;
  297. job->settings.quad_method = params->quad_method;
  298. job->settings.ngon_method = params->ngon_method;
  299. if (job->settings.frame_start > job->settings.frame_end) {
  300. std::swap(job->settings.frame_start, job->settings.frame_end);
  301. }
  302. bool export_ok = false;
  303. if (as_background_job) {
  304. wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
  305. CTX_wm_window(C),
  306. job->scene,
  307. "Alembic Export",
  308. WM_JOB_PROGRESS,
  309. WM_JOB_TYPE_ALEMBIC);
  310. /* setup job */
  311. WM_jobs_customdata_set(wm_job, job, MEM_freeN);
  312. WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
  313. WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
  314. WM_jobs_start(CTX_wm_manager(C), wm_job);
  315. }
  316. else {
  317. /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
  318. short stop = 0, do_update = 0;
  319. float progress = 0.f;
  320. export_startjob(job, &stop, &do_update, &progress);
  321. export_endjob(job);
  322. export_ok = job->export_ok;
  323. MEM_freeN(job);
  324. }
  325. return export_ok;
  326. }
  327. /* ********************** Import file ********************** */
  328. /**
  329. * Generates an AbcObjectReader for this Alembic object and its children.
  330. *
  331. * \param object The Alembic IObject to visit.
  332. * \param readers The created AbcObjectReader * will be appended to this vector.
  333. * \param settings Import settings, not used directly but passed to the
  334. * AbcObjectReader subclass constructors.
  335. * \param r_assign_as_parent Return parameter, contains a list of reader
  336. * pointers, whose parent pointer should still be set.
  337. * This is filled when this call to visit_object() didn't create
  338. * a reader that should be the parent.
  339. * \return A pair of boolean and reader pointer. The boolean indicates whether
  340. * this IObject claims its parent as part of the same object
  341. * (for example an IPolyMesh object would claim its parent, as the mesh
  342. * is interpreted as the object's data, and the parent IXform as its
  343. * Blender object). The pointer is the AbcObjectReader that represents
  344. * the IObject parameter.
  345. *
  346. * NOTE: this function is similar to gather_object_paths above, need to keep
  347. * them in sync. */
  348. static std::pair<bool, AbcObjectReader *> visit_object(
  349. const IObject &object,
  350. AbcObjectReader::ptr_vector &readers,
  351. ImportSettings &settings,
  352. AbcObjectReader::ptr_vector &r_assign_as_parent)
  353. {
  354. const std::string & full_name = object.getFullName();
  355. if (!object.valid()) {
  356. std::cerr << " - "
  357. << full_name
  358. << ": object is invalid, skipping it and all its children.\n";
  359. return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
  360. }
  361. /* The interpretation of data by the children determine the role of this
  362. * object. This is especially important for Xform objects, as they can be
  363. * either part of a Blender object or a Blender object (Empty) themselves.
  364. */
  365. size_t children_claiming_this_object = 0;
  366. size_t num_children = object.getNumChildren();
  367. AbcObjectReader::ptr_vector claiming_child_readers;
  368. AbcObjectReader::ptr_vector nonclaiming_child_readers;
  369. AbcObjectReader::ptr_vector assign_as_parent;
  370. for (size_t i = 0; i < num_children; ++i) {
  371. const IObject ichild = object.getChild(i);
  372. /* TODO: When we only support C++11, use std::tie() instead. */
  373. std::pair<bool, AbcObjectReader *> child_result;
  374. child_result = visit_object(ichild, readers, settings, assign_as_parent);
  375. bool child_claims_this_object = child_result.first;
  376. AbcObjectReader *child_reader = child_result.second;
  377. if (child_reader == NULL) {
  378. BLI_assert(!child_claims_this_object);
  379. }
  380. else {
  381. if (child_claims_this_object) {
  382. claiming_child_readers.push_back(child_reader);
  383. }
  384. else {
  385. nonclaiming_child_readers.push_back(child_reader);
  386. }
  387. }
  388. children_claiming_this_object += child_claims_this_object ? 1 : 0;
  389. }
  390. BLI_assert(children_claiming_this_object == claiming_child_readers.size());
  391. AbcObjectReader *reader = NULL;
  392. const MetaData &md = object.getMetaData();
  393. bool parent_is_part_of_this_object = false;
  394. if (!object.getParent()) {
  395. /* The root itself is not an object we should import. */
  396. }
  397. else if (IXform::matches(md)) {
  398. bool create_empty;
  399. /* An xform can either be a Blender Object (if it contains a mesh, for
  400. * example), but it can also be an Empty. Its correct translation to
  401. * Blender's data model depends on its children. */
  402. /* Check whether or not this object is a Maya locator, which is
  403. * similar to empties used as parent object in Blender. */
  404. if (has_property(object.getProperties(), "locator")) {
  405. create_empty = true;
  406. }
  407. else {
  408. create_empty = claiming_child_readers.empty();
  409. }
  410. if (create_empty) {
  411. reader = new AbcEmptyReader(object, settings);
  412. }
  413. }
  414. else if (IPolyMesh::matches(md)) {
  415. reader = new AbcMeshReader(object, settings);
  416. parent_is_part_of_this_object = true;
  417. }
  418. else if (ISubD::matches(md)) {
  419. reader = new AbcSubDReader(object, settings);
  420. parent_is_part_of_this_object = true;
  421. }
  422. else if (INuPatch::matches(md)) {
  423. #ifdef USE_NURBS
  424. /* TODO(kevin): importing cyclic NURBS from other software crashes
  425. * at the moment. This is due to the fact that NURBS in other
  426. * software have duplicated points which causes buffer overflows in
  427. * Blender. Need to figure out exactly how these points are
  428. * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
  429. * Until this is fixed, disabling NURBS reading. */
  430. reader = new AbcNurbsReader(object, settings);
  431. parent_is_part_of_this_object = true;
  432. #endif
  433. }
  434. else if (ICamera::matches(md)) {
  435. reader = new AbcCameraReader(object, settings);
  436. parent_is_part_of_this_object = true;
  437. }
  438. else if (IPoints::matches(md)) {
  439. reader = new AbcPointsReader(object, settings);
  440. parent_is_part_of_this_object = true;
  441. }
  442. else if (IMaterial::matches(md)) {
  443. /* Pass for now. */
  444. }
  445. else if (ILight::matches(md)) {
  446. /* Pass for now. */
  447. }
  448. else if (IFaceSet::matches(md)) {
  449. /* Pass, those are handled in the mesh reader. */
  450. }
  451. else if (ICurves::matches(md)) {
  452. reader = new AbcCurveReader(object, settings);
  453. parent_is_part_of_this_object = true;
  454. }
  455. else {
  456. std::cerr << "Alembic object " << full_name
  457. << " is of unsupported schema type '"
  458. << object.getMetaData().get("schemaObjTitle") << "'"
  459. << std::endl;
  460. }
  461. if (reader) {
  462. /* We have created a reader, which should imply that this object is
  463. * not claimed as part of any child Alembic object. */
  464. BLI_assert(claiming_child_readers.empty());
  465. readers.push_back(reader);
  466. reader->incref();
  467. AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
  468. MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
  469. BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
  470. BLI_addtail(&settings.cache_file->object_paths, abc_path);
  471. /* We can now assign this reader as parent for our children. */
  472. if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
  473. /* TODO: When we only support C++11, use for (a: b) instead. */
  474. BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
  475. child_reader->parent_reader = reader;
  476. }
  477. BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
  478. child_reader->parent_reader = reader;
  479. }
  480. }
  481. }
  482. else if (object.getParent()) {
  483. if (claiming_child_readers.size() > 0) {
  484. /* The first claiming child will serve just fine as parent to
  485. * our non-claiming children. Since all claiming children share
  486. * the same XForm, it doesn't really matter which one we pick. */
  487. AbcObjectReader *claiming_child = claiming_child_readers[0];
  488. BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
  489. child_reader->parent_reader = claiming_child;
  490. }
  491. BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
  492. child_reader->parent_reader = claiming_child;
  493. }
  494. /* Claiming children should have our parent set as their parent. */
  495. BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
  496. r_assign_as_parent.push_back(child_reader);
  497. }
  498. }
  499. else {
  500. /* This object isn't claimed by any child, and didn't produce
  501. * a reader. Odd situation, could be the top Alembic object, or
  502. * an unsupported Alembic schema. Delegate to our parent. */
  503. BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
  504. r_assign_as_parent.push_back(child_reader);
  505. }
  506. BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
  507. r_assign_as_parent.push_back(child_reader);
  508. }
  509. BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
  510. r_assign_as_parent.push_back(child_reader);
  511. }
  512. }
  513. }
  514. return std::make_pair(parent_is_part_of_this_object, reader);
  515. }
  516. enum {
  517. ABC_NO_ERROR = 0,
  518. ABC_ARCHIVE_FAIL,
  519. ABC_UNSUPPORTED_HDF5,
  520. };
  521. struct ImportJobData {
  522. Main *bmain;
  523. Scene *scene;
  524. char filename[1024];
  525. ImportSettings settings;
  526. std::vector<AbcObjectReader *> readers;
  527. short *stop;
  528. short *do_update;
  529. float *progress;
  530. char error_code;
  531. bool was_cancelled;
  532. bool import_ok;
  533. };
  534. ABC_INLINE bool is_mesh_and_strands(const IObject &object)
  535. {
  536. bool has_mesh = false;
  537. bool has_curve = false;
  538. for (int i = 0; i < object.getNumChildren(); ++i) {
  539. const IObject &child = object.getChild(i);
  540. if (!child.valid()) {
  541. continue;
  542. }
  543. const MetaData &md = child.getMetaData();
  544. if (IPolyMesh::matches(md)) {
  545. has_mesh = true;
  546. }
  547. else if (ISubD::matches(md)) {
  548. has_mesh = true;
  549. }
  550. else if (ICurves::matches(md)) {
  551. has_curve = true;
  552. }
  553. else if (IPoints::matches(md)) {
  554. has_curve = true;
  555. }
  556. }
  557. return has_mesh && has_curve;
  558. }
  559. static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
  560. {
  561. SCOPE_TIMER("Alembic import, objects reading and creation");
  562. ImportJobData *data = static_cast<ImportJobData *>(user_data);
  563. data->stop = stop;
  564. data->do_update = do_update;
  565. data->progress = progress;
  566. ArchiveReader *archive = new ArchiveReader(data->filename);
  567. if (!archive->valid()) {
  568. #ifndef WITH_ALEMBIC_HDF5
  569. data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
  570. #else
  571. data->error_code = ABC_ARCHIVE_FAIL;
  572. #endif
  573. delete archive;
  574. return;
  575. }
  576. CacheFile *cache_file = static_cast<CacheFile *>(BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
  577. /* Decrement the ID ref-count because it is going to be incremented for each
  578. * modifier and constraint that it will be attached to, so since currently
  579. * it is not used by anyone, its use count will off by one. */
  580. id_us_min(&cache_file->id);
  581. cache_file->is_sequence = data->settings.is_sequence;
  582. cache_file->scale = data->settings.scale;
  583. cache_file->handle = handle_from_archive(archive);
  584. BLI_strncpy(cache_file->filepath, data->filename, 1024);
  585. data->settings.cache_file = cache_file;
  586. *data->do_update = true;
  587. *data->progress = 0.05f;
  588. /* Parse Alembic Archive. */
  589. AbcObjectReader::ptr_vector assign_as_parent;
  590. visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
  591. /* There shouldn't be any orphans. */
  592. BLI_assert(assign_as_parent.size() == 0);
  593. if (G.is_break) {
  594. data->was_cancelled = true;
  595. return;
  596. }
  597. *data->do_update = true;
  598. *data->progress = 0.1f;
  599. /* Create objects and set scene frame range. */
  600. const float size = static_cast<float>(data->readers.size());
  601. size_t i = 0;
  602. chrono_t min_time = std::numeric_limits<chrono_t>::max();
  603. chrono_t max_time = std::numeric_limits<chrono_t>::min();
  604. ISampleSelector sample_sel(0.0f);
  605. std::vector<AbcObjectReader *>::iterator iter;
  606. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  607. AbcObjectReader *reader = *iter;
  608. if (reader->valid()) {
  609. reader->readObjectData(data->bmain, sample_sel);
  610. min_time = std::min(min_time, reader->minTime());
  611. max_time = std::max(max_time, reader->maxTime());
  612. }
  613. else {
  614. std::cerr << "Object " << reader->name() << " in Alembic file "
  615. << data->filename << " is invalid.\n";
  616. }
  617. *data->progress = 0.1f + 0.3f * (++i / size);
  618. *data->do_update = true;
  619. if (G.is_break) {
  620. data->was_cancelled = true;
  621. return;
  622. }
  623. }
  624. if (data->settings.set_frame_range) {
  625. Scene *scene = data->scene;
  626. if (data->settings.is_sequence) {
  627. SFRA = data->settings.sequence_offset;
  628. EFRA = SFRA + (data->settings.sequence_len - 1);
  629. CFRA = SFRA;
  630. }
  631. else if (min_time < max_time) {
  632. SFRA = static_cast<int>(round(min_time * FPS));
  633. EFRA = static_cast<int>(round(max_time * FPS));
  634. CFRA = SFRA;
  635. }
  636. }
  637. /* Setup parenthood. */
  638. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  639. const AbcObjectReader *reader = *iter;
  640. const AbcObjectReader *parent_reader = reader->parent_reader;
  641. Object *ob = reader->object();
  642. if (parent_reader == NULL || !reader->inherits_xform()) {
  643. ob->parent = NULL;
  644. }
  645. else {
  646. ob->parent = parent_reader->object();
  647. }
  648. }
  649. /* Setup transformations and constraints. */
  650. i = 0;
  651. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  652. AbcObjectReader *reader = *iter;
  653. reader->setupObjectTransform(0.0f);
  654. *data->progress = 0.7f + 0.3f * (++i / size);
  655. *data->do_update = true;
  656. if (G.is_break) {
  657. data->was_cancelled = true;
  658. return;
  659. }
  660. }
  661. }
  662. static void import_endjob(void *user_data)
  663. {
  664. SCOPE_TIMER("Alembic import, cleanup");
  665. ImportJobData *data = static_cast<ImportJobData *>(user_data);
  666. std::vector<AbcObjectReader *>::iterator iter;
  667. /* Delete objects on cancelation. */
  668. if (data->was_cancelled) {
  669. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  670. Object *ob = (*iter)->object();
  671. /* It's possible that cancellation occured between the creation of
  672. * the reader and the creation of the Blender object. */
  673. if (ob == NULL) continue;
  674. BKE_libblock_free_us(data->bmain, ob);
  675. }
  676. }
  677. else {
  678. /* Add object to scene. */
  679. Base *base;
  680. BKE_scene_base_deselect_all(data->scene);
  681. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  682. Object *ob = (*iter)->object();
  683. ob->lay = data->scene->lay;
  684. base = BKE_scene_base_add(data->scene, ob);
  685. BKE_scene_base_select(data->scene, base);
  686. DAG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
  687. }
  688. DAG_relations_tag_update(data->bmain);
  689. }
  690. for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
  691. AbcObjectReader *reader = *iter;
  692. reader->decref();
  693. if (reader->refcount() == 0) {
  694. delete reader;
  695. }
  696. }
  697. switch (data->error_code) {
  698. default:
  699. case ABC_NO_ERROR:
  700. data->import_ok = !data->was_cancelled;
  701. break;
  702. case ABC_ARCHIVE_FAIL:
  703. WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
  704. break;
  705. case ABC_UNSUPPORTED_HDF5:
  706. WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
  707. break;
  708. }
  709. WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
  710. }
  711. static void import_freejob(void *user_data)
  712. {
  713. ImportJobData *data = static_cast<ImportJobData *>(user_data);
  714. delete data;
  715. }
  716. bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
  717. bool set_frame_range, int sequence_len, int offset,
  718. bool validate_meshes, bool as_background_job)
  719. {
  720. /* Using new here since MEM_* funcs do not call ctor to properly initialize
  721. * data. */
  722. ImportJobData *job = new ImportJobData();
  723. job->bmain = CTX_data_main(C);
  724. job->scene = CTX_data_scene(C);
  725. job->import_ok = false;
  726. BLI_strncpy(job->filename, filepath, 1024);
  727. job->settings.scale = scale;
  728. job->settings.is_sequence = is_sequence;
  729. job->settings.set_frame_range = set_frame_range;
  730. job->settings.sequence_len = sequence_len;
  731. job->settings.sequence_offset = offset;
  732. job->settings.validate_meshes = validate_meshes;
  733. job->error_code = ABC_NO_ERROR;
  734. job->was_cancelled = false;
  735. G.is_break = false;
  736. bool import_ok = false;
  737. if (as_background_job) {
  738. wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
  739. CTX_wm_window(C),
  740. job->scene,
  741. "Alembic Import",
  742. WM_JOB_PROGRESS,
  743. WM_JOB_TYPE_ALEMBIC);
  744. /* setup job */
  745. WM_jobs_customdata_set(wm_job, job, import_freejob);
  746. WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
  747. WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
  748. WM_jobs_start(CTX_wm_manager(C), wm_job);
  749. }
  750. else {
  751. /* Fake a job context, so that we don't need NULL pointer checks while importing. */
  752. short stop = 0, do_update = 0;
  753. float progress = 0.f;
  754. import_startjob(job, &stop, &do_update, &progress);
  755. import_endjob(job);
  756. import_ok = job->import_ok;
  757. import_freejob(job);
  758. }
  759. return import_ok;
  760. }
  761. /* ************************************************************************** */
  762. void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float scale)
  763. {
  764. if (!reader) {
  765. return;
  766. }
  767. AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
  768. bool is_constant = false;
  769. abc_reader->read_matrix(r_mat, time, scale, is_constant);
  770. }
  771. /* ************************************************************************** */
  772. DerivedMesh *ABC_read_mesh(CacheReader *reader,
  773. Object *ob,
  774. DerivedMesh *dm,
  775. const float time,
  776. const char **err_str,
  777. int read_flag)
  778. {
  779. AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
  780. IObject iobject = abc_reader->iobject();
  781. if (!iobject.valid()) {
  782. *err_str = "Invalid object: verify object path";
  783. return NULL;
  784. }
  785. const ObjectHeader &header = iobject.getHeader();
  786. if (!abc_reader->accepts_object_type(header, ob, err_str)) {
  787. /* err_str is set by acceptsObjectType() */
  788. return NULL;
  789. }
  790. /* kFloorIndex is used to be compatible with non-interpolating
  791. * properties; they use the floor. */
  792. ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
  793. return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
  794. }
  795. /* ************************************************************************** */
  796. void CacheReader_free(CacheReader *reader)
  797. {
  798. AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
  799. abc_reader->decref();
  800. if (abc_reader->refcount() == 0) {
  801. delete abc_reader;
  802. }
  803. }
  804. void CacheReader_incref(CacheReader *reader)
  805. {
  806. AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
  807. abc_reader->incref();
  808. }
  809. CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
  810. {
  811. if (object_path[0] == '\0') {
  812. return reader;
  813. }
  814. ArchiveReader *archive = archive_from_handle(handle);
  815. if (!archive || !archive->valid()) {
  816. return reader;
  817. }
  818. IObject iobject;
  819. find_iobject(archive->getTop(), iobject, object_path);
  820. if (reader) {
  821. CacheReader_free(reader);
  822. }
  823. ImportSettings settings;
  824. AbcObjectReader *abc_reader = create_reader(iobject, settings);
  825. if (abc_reader == NULL) {
  826. /* This object is not supported */
  827. return NULL;
  828. }
  829. abc_reader->object(object);
  830. abc_reader->incref();
  831. return reinterpret_cast<CacheReader *>(abc_reader);
  832. }