Blender  V2.93
DocumentImporter.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 /* TODO:
22  * * name imported objects
23  * * import object rotation as euler */
24 
25 #include <algorithm> /* sort() */
26 #include <map>
27 #include <string>
28 
29 #include "COLLADAFWArrayPrimitiveType.h"
30 #include "COLLADAFWCamera.h"
31 #include "COLLADAFWColorOrTexture.h"
32 #include "COLLADAFWIndexList.h"
33 #include "COLLADAFWLibraryNodes.h"
34 #include "COLLADAFWLight.h"
35 #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
36 #include "COLLADAFWPolygons.h"
37 #include "COLLADAFWRoot.h"
38 #include "COLLADAFWSampler.h"
39 #include "COLLADAFWStableHeaders.h"
40 #include "COLLADAFWTypes.h"
41 #include "COLLADAFWVisualScene.h"
42 
43 #include "COLLADASaxFWLIExtraDataCallbackHandler.h"
44 #include "COLLADASaxFWLLoader.h"
45 
46 #include "MEM_guardedalloc.h"
47 
48 #include "BLI_fileops.h"
49 #include "BLI_listbase.h"
50 #include "BLI_math.h"
51 #include "BLI_string.h"
52 #include "BLI_utildefines.h"
53 
54 #include "BKE_camera.h"
55 #include "BKE_collection.h"
56 #include "BKE_fcurve.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
59 #include "BKE_layer.h"
60 #include "BKE_lib_id.h"
61 #include "BKE_light.h"
62 #include "BKE_material.h"
63 #include "BKE_scene.h"
64 
65 #include "BLI_path_util.h"
66 
67 #include "DNA_camera_types.h"
68 #include "DNA_light_types.h"
69 
70 #include "RNA_access.h"
71 
72 #include "WM_api.h"
73 #include "WM_types.h"
74 
75 #include "DEG_depsgraph.h"
76 #include "DEG_depsgraph_build.h"
77 
78 #include "DocumentImporter.h"
79 #include "ErrorHandler.h"
80 #include "ExtraHandler.h"
81 #include "TransformReader.h"
82 
83 #include "Materials.h"
84 #include "collada_internal.h"
85 #include "collada_utils.h"
86 
87 /*
88  * COLLADA Importer limitations:
89  * - no multiple scene import, all objects are added to active scene
90  */
91 
92 // #define COLLADA_DEBUG
93 /* creates empties for each imported bone on layer 2, for debugging */
94 // #define ARMATURE_TEST
95 
97  : import_settings(import_settings),
98  mImportStage(Fetching_Scene_data),
99  mContext(C),
100  view_layer(CTX_data_view_layer(mContext)),
101  armature_importer(&unit_converter,
102  &mesh_importer,
103  CTX_data_main(C),
104  CTX_data_scene(C),
105  view_layer,
106  import_settings),
107  mesh_importer(
108  &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer),
109  anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C))
110 {
111 }
112 
114 {
115  TagsMap::iterator etit;
116  etit = uid_tags_map.begin();
117  while (etit != uid_tags_map.end()) {
118  delete etit->second;
119  etit++;
120  }
121 }
122 
124 {
125  ErrorHandler errorHandler;
126  COLLADASaxFWL::Loader loader(&errorHandler);
127  COLLADAFW::Root root(&loader, this);
128  ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
129 
130  loader.registerExtraDataCallbackHandler(ehandler);
131 
132  /* deselect all to select new objects */
134 
135  std::string mFilename = std::string(this->import_settings->filepath);
136  const std::string encodedFilename = bc_url_encode(mFilename);
137  if (!root.loadDocument(encodedFilename)) {
138  fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
139  delete ehandler;
140  return false;
141  }
142 
143  if (errorHandler.hasError()) {
144  delete ehandler;
145  return false;
146  }
147 
149  mImportStage = Fetching_Controller_data;
150  COLLADASaxFWL::Loader loader2;
151  COLLADAFW::Root root2(&loader2, this);
152 
153  if (!root2.loadDocument(encodedFilename)) {
154  fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
155  delete ehandler;
156  return false;
157  }
158 
159  delete ehandler;
160 
161  return true;
162 }
163 
165 {
166  /* TODO: if possible show error info
167  *
168  * Should we get rid of invisible Meshes that were created so far
169  * or maybe create objects at coordinate space origin?
170  *
171  * The latter sounds better. */
172 }
173 
175 {
176 }
177 
179 {
180  if (mImportStage == Fetching_Controller_data) {
181  return;
182  }
183 
184  Main *bmain = CTX_data_main(mContext);
185  /* TODO: create a new scene except the selected <visual_scene> -
186  * use current blender scene for it */
187  Scene *sce = CTX_data_scene(mContext);
188  unit_converter.calculate_scale(*sce);
189 
190  std::vector<Object *> *objects_to_scale = new std::vector<Object *>();
191 
193  std::vector<const COLLADAFW::VisualScene *>::iterator sit;
194  for (sit = vscenes.begin(); sit != vscenes.end(); sit++) {
195  PointerRNA sceneptr, unit_settings;
196  PropertyRNA *system, *scale;
197 
198  /* for scene unit settings: system, scale_length */
199 
200  RNA_id_pointer_create(&sce->id, &sceneptr);
201  unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
202  system = RNA_struct_find_property(&unit_settings, "system");
203  scale = RNA_struct_find_property(&unit_settings, "scale_length");
204 
205  if (this->import_settings->import_units) {
206 
207  switch (unit_converter.isMetricSystem()) {
209  RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
210  break;
212  RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
213  break;
214  default:
215  RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
216  break;
217  }
218  float unit_factor = unit_converter.getLinearMeter();
219  RNA_property_float_set(&unit_settings, scale, unit_factor);
220  fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);
221  }
222 
223  /* Write nodes to scene */
224  fprintf(stderr, "+-- Import Scene --------\n");
225  const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes();
226  for (unsigned int i = 0; i < roots.getCount(); i++) {
227  std::vector<Object *> *objects_done = write_node(roots[i], nullptr, sce, nullptr, false);
228  objects_to_scale->insert(
229  objects_to_scale->end(), objects_done->begin(), objects_done->end());
230  delete objects_done;
231  }
232  }
233 
234  mesh_importer.optimize_material_assignements();
235 
236  armature_importer.set_tags_map(this->uid_tags_map);
237  armature_importer.make_armatures(mContext, *objects_to_scale);
238  armature_importer.make_shape_keys(mContext);
239 
240 #if 0
241  armature_importer.fix_animation();
242 #endif
243 
244  for (const COLLADAFW::VisualScene *vscene : vscenes) {
245  const COLLADAFW::NodePointerArray &roots = vscene->getRootNodes();
246 
247  for (unsigned int i = 0; i < roots.getCount(); i++) {
248  translate_anim_recursive(roots[i], nullptr, nullptr);
249  }
250  }
251 
252  if (!libnode_ob.empty()) {
253 
254  fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size());
255  /* free all library_nodes */
256  std::vector<Object *>::iterator it;
257  for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
258  Object *ob = *it;
259  BKE_scene_collections_object_remove(bmain, sce, ob, true);
260  }
261  libnode_ob.clear();
262  }
263 
264  bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
265 
266  delete objects_to_scale;
267 
268  /* update scene */
271  WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, nullptr);
272 }
273 
275  COLLADAFW::Node *par = nullptr,
276  Object *parob = nullptr)
277 {
278  /* The split in T29246, root_map must point at actual root when
279  * calculating bones in apply_curves_as_matrix. - actual root is the root node.
280  * This has to do with inverse bind poses being world space
281  * (the sources for skinned bones' rest-poses) and the way
282  * non-skinning nodes have their "rest-pose" recursively calculated.
283  * XXX TODO: design issue, how to support unrelated joints taking
284  * part in skinning. */
285  if (par) { // && par->getType() == COLLADAFW::Node::JOINT) {
286  /* If par is root if there's no corresponding key in root_map. */
287  if (root_map.find(par->getUniqueId()) == root_map.end()) {
288  root_map[node->getUniqueId()] = node;
289  }
290  else {
291  root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
292  }
293  }
294 
295 #if 0
296  COLLADAFW::Transformation::TransformationType types[] = {
300  COLLADAFW::Transformation::MATRIX,
301  };
302 
303  Object *ob;
304 #endif
305  unsigned int i;
306 
307  if (node->getType() == COLLADAFW::Node::JOINT && par == nullptr) {
308  /* For Skeletons without root node we have to simulate the
309  * root node here and recursively enter the same function
310  * XXX: maybe this can be made more elegant. */
312  }
313  else {
314  anim_importer.translate_Animations(
315  node, root_map, object_map, FW_object_map, uid_material_map);
316  COLLADAFW::NodePointerArray &children = node->getChildNodes();
317  for (i = 0; i < children.getCount(); i++) {
318  translate_anim_recursive(children[i], node, nullptr);
319  }
320  }
321 }
322 
327 std::string DocumentImporter::get_import_version(const COLLADAFW::FileInfo *asset)
328 {
329  const char AUTORING_TOOL[] = "authoring_tool";
330  const std::string BLENDER("Blender ");
331  const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray();
332  for (size_t i = 0, count = valuePairs.getCount(); i < count; i++) {
333  const COLLADAFW::FileInfo::ValuePair *valuePair = valuePairs[i];
334  const COLLADAFW::String &key = valuePair->first;
335  const COLLADAFW::String &value = valuePair->second;
336  if (key == AUTORING_TOOL) {
337  if (value.compare(0, BLENDER.length(), BLENDER) == 0) {
338  /* Was made with Blender, now get version string */
339  std::string v = value.substr(BLENDER.length());
340  std::string::size_type n = v.find(" ");
341  if (n > 0) {
342  return v.substr(0, n);
343  }
344  }
345  }
346  }
347  return "";
348 }
349 
354 bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset)
355 {
356  unit_converter.read_asset(asset);
357  import_from_version = get_import_version(asset);
358  anim_importer.set_import_from_version(import_from_version);
359  return true;
360 }
361 
367 {
368  /* XXX could store the scene id, but do nothing for now */
369  return true;
370 }
371 Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
372 {
373  const COLLADAFW::UniqueId &cam_uid = camera->getInstanciatedObjectId();
374  if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
375  // fprintf(stderr, "Couldn't find camera by UID.\n");
376  return nullptr;
377  }
378 
379  Main *bmain = CTX_data_main(mContext);
380  Object *ob = bc_add_object(bmain, sce, view_layer, OB_CAMERA, nullptr);
381  Camera *cam = uid_camera_map[cam_uid];
382  Camera *old_cam = (Camera *)ob->data;
383  ob->data = cam;
384  BKE_id_free_us(bmain, old_cam);
385  return ob;
386 }
387 
388 Object *DocumentImporter::create_light_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
389 {
390  const COLLADAFW::UniqueId &lamp_uid = lamp->getInstanciatedObjectId();
391  if (uid_light_map.find(lamp_uid) == uid_light_map.end()) {
392  fprintf(stderr, "Couldn't find light by UID.\n");
393  return nullptr;
394  }
395 
396  Main *bmain = CTX_data_main(mContext);
397  Object *ob = bc_add_object(bmain, sce, view_layer, OB_LAMP, nullptr);
398  Light *la = uid_light_map[lamp_uid];
399  Light *old_light = (Light *)ob->data;
400  ob->data = la;
401  BKE_id_free_us(bmain, old_light);
402  return ob;
403 }
404 
406  COLLADAFW::Node *source_node,
407  COLLADAFW::Node *instance_node,
408  Scene *sce,
409  bool is_library_node)
410 {
411  // fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ?
412  // instance_node->getOriginalId().c_str() : NULL, source_node ?
413  // source_node->getOriginalId().c_str() : NULL);
414 
415  Main *bmain = CTX_data_main(mContext);
416  Object *obn = (Object *)BKE_id_copy(bmain, &source_ob->id);
417  id_us_min(&obn->id);
419  BKE_collection_object_add_from(bmain, sce, source_ob, obn);
420 
421  if (instance_node) {
422  anim_importer.read_node_transform(instance_node, obn);
423  /* if we also have a source_node (always ;), take its
424  * transformation matrix and apply it to the newly instantiated
425  * object to account for node hierarchy transforms in
426  * .dae */
427  if (source_node) {
428  COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
429  COLLADABU::Math::Matrix4 bmat4 =
430  mat4.transpose(); /* transpose to get blender row-major order */
431  float mat[4][4];
432  for (int i = 0; i < 4; i++) {
433  for (int j = 0; j < 4; j++) {
434  mat[i][j] = bmat4[i][j];
435  }
436  }
437  /* calc new matrix and apply */
438  mul_m4_m4m4(obn->obmat, obn->obmat, mat);
439  BKE_object_apply_mat4(obn, obn->obmat, false, false);
440  }
441  }
442  else {
443  anim_importer.read_node_transform(source_node, obn);
444  }
445 
446  /*DAG_relations_tag_update(CTX_data_main(mContext));*/
447 
448  COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
449  if (children.getCount()) {
450  for (unsigned int i = 0; i < children.getCount(); i++) {
451  COLLADAFW::Node *child_node = children[i];
452  const COLLADAFW::UniqueId &child_id = child_node->getUniqueId();
453  if (object_map.find(child_id) == object_map.end()) {
454  continue;
455  }
456  COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
457  Object *new_child = nullptr;
458  if (inodes.getCount()) { /* \todo loop through instance nodes */
459  const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId();
460  fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id));
461  new_child = create_instance_node(
462  object_map.find(id)->second, node_map[id], child_node, sce, is_library_node);
463  }
464  else {
465  new_child = create_instance_node(
466  object_map.find(child_id)->second, child_node, nullptr, sce, is_library_node);
467  }
468  bc_set_parent(new_child, obn, mContext, true);
469 
470  if (is_library_node) {
471  libnode_ob.push_back(new_child);
472  }
473  }
474  }
475 
476  return obn;
477 }
478 
479 /* to create constraints off node <extra> tags. Assumes only constraint data in
480  * current <extra> with blender profile. */
482 {
483  if (et && et->isProfile("blender")) {
484  std::string name;
485  short type = 0;
486  et->setData("type", &type);
487  BKE_constraint_add_for_object(ob, "Test_con", type);
488  }
489 }
490 
491 void DocumentImporter::report_unknown_reference(const COLLADAFW::Node &node,
492  const std::string object_type)
493 {
494  std::string id = node.getOriginalId();
495  std::string name = node.getName();
496  fprintf(stderr,
497  "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n",
498  id.c_str(),
499  name.c_str(),
500  object_type.c_str());
501 }
502 
503 std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node,
504  COLLADAFW::Node *parent_node,
505  Scene *sce,
506  Object *par,
507  bool is_library_node)
508 {
509  Main *bmain = CTX_data_main(mContext);
510  Object *ob = nullptr;
511  bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
512  bool read_transform = true;
513  std::string id = node->getOriginalId();
514  std::string name = node->getName();
515 
516  /* if node has child nodes write them */
517  COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
518 
519  std::vector<Object *> *objects_done = new std::vector<Object *>();
520  std::vector<Object *> *root_objects = new std::vector<Object *>();
521 
522  fprintf(
523  stderr, "| %s id='%s', name='%s'\n", is_joint ? "JOINT" : "NODE ", id.c_str(), name.c_str());
524 
525  if (is_joint) {
526  if (parent_node == nullptr && !is_library_node) {
527  /* A Joint on root level is a skeleton without root node.
528  * Here we add the armature "on the fly": */
529  par = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, std::string("Armature").c_str());
530  objects_done->push_back(par);
531  root_objects->push_back(par);
532  object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
533  node_map[node->getUniqueId()] = node;
534  }
535  if (parent_node == nullptr || parent_node->getType() != COLLADAFW::Node::JOINT) {
536  armature_importer.add_root_joint(node, par);
537  }
538 
539  if (parent_node == nullptr) {
540  /* for skeletons without root node all has been done above.
541  * Skeletons with root node are handled further down. */
542  goto finally;
543  }
544  }
545  else {
546  COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
547  COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
548  COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
549  COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
550  COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
551  size_t geom_done = 0;
552  size_t camera_done = 0;
553  size_t lamp_done = 0;
554  size_t controller_done = 0;
555  size_t inst_done = 0;
556 
557  /* XXX linking object with the first <instance_geometry>, though a node may have more of
558  * them... maybe join multiple <instance_...> meshes into 1, and link object with it? not
559  * sure... <instance_geometry> */
560  while (geom_done < geom.getCount()) {
561  ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map);
562  if (ob == nullptr) {
563  report_unknown_reference(*node, "instance_mesh");
564  }
565  else {
566  objects_done->push_back(ob);
567  if (parent_node == nullptr) {
568  root_objects->push_back(ob);
569  }
570  }
571  geom_done++;
572  }
573  while (camera_done < camera.getCount()) {
574  ob = create_camera_object(camera[camera_done], sce);
575  if (ob == nullptr) {
576  report_unknown_reference(*node, "instance_camera");
577  }
578  else {
579  objects_done->push_back(ob);
580  if (parent_node == nullptr) {
581  root_objects->push_back(ob);
582  }
583  }
584  camera_done++;
585  }
586  while (lamp_done < lamp.getCount()) {
587  ob = create_light_object(lamp[lamp_done], sce);
588  if (ob == nullptr) {
589  report_unknown_reference(*node, "instance_light");
590  }
591  else {
592  objects_done->push_back(ob);
593  if (parent_node == nullptr) {
594  root_objects->push_back(ob);
595  }
596  }
597  lamp_done++;
598  }
599  while (controller_done < controller.getCount()) {
600  COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)
601  controller[controller_done];
602  ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map);
603  if (ob == nullptr) {
604  report_unknown_reference(*node, "instance_controller");
605  }
606  else {
607  objects_done->push_back(ob);
608  if (parent_node == nullptr) {
609  root_objects->push_back(ob);
610  }
611  }
612  controller_done++;
613  }
614  /* XXX instance_node is not supported yet */
615  while (inst_done < inst_node.getCount()) {
616  const COLLADAFW::UniqueId &node_id = inst_node[inst_done]->getInstanciatedObjectId();
617  if (object_map.find(node_id) == object_map.end()) {
618  fprintf(stderr,
619  "Cannot find object for node referenced by <instance_node name=\"%s\">.\n",
620  inst_node[inst_done]->getName().c_str());
621  ob = nullptr;
622  }
623  else {
624  std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator,
625  std::multimap<COLLADAFW::UniqueId, Object *>::iterator>
626  pair_iter = object_map.equal_range(node_id);
627  for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first;
628  it2 != pair_iter.second;
629  it2++) {
630  Object *source_ob = (Object *)it2->second;
631  COLLADAFW::Node *source_node = node_map[node_id];
632  ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
633  objects_done->push_back(ob);
634  if (parent_node == nullptr) {
635  root_objects->push_back(ob);
636  }
637  }
638  }
639  inst_done++;
640 
641  read_transform = false;
642  }
643 
644  /* if node is empty - create empty object
645  * XXX empty node may not mean it is empty object, not sure about this */
646  if ((geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
647  /* Check if Object is armature, by checking if immediate child is a JOINT node. */
648  if (is_armature(node)) {
649  ob = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, name.c_str());
650  }
651  else {
652  ob = bc_add_object(bmain, sce, view_layer, OB_EMPTY, nullptr);
653  }
654  objects_done->push_back(ob);
655  if (parent_node == nullptr) {
656  root_objects->push_back(ob);
657  }
658  }
659 
660  /* XXX: if there are multiple instances, only one is stored. */
661 
662  if (!ob) {
663  goto finally;
664  }
665 
666  for (Object *ob : *objects_done) {
667  std::string nodename = node->getName().empty() ? node->getOriginalId() : node->getName();
668  BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str());
669  object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob));
670  node_map[node->getUniqueId()] = node;
671 
672  if (is_library_node) {
673  libnode_ob.push_back(ob);
674  }
675  }
676 
677  /* create_constraints(et,ob); */
678  }
679 
680  for (Object *ob : *objects_done) {
681  if (read_transform) {
682  anim_importer.read_node_transform(node, ob); /* overwrites location set earlier */
683  }
684 
685  if (!is_joint) {
686  if (par && ob) {
687  ob->parent = par;
688  ob->partype = PAROBJECT;
689  ob->parsubstr[0] = 0;
690 
691  // bc_set_parent(ob, par, mContext, false);
692  }
693  }
694  }
695 
696  if (objects_done->empty()) {
697  ob = nullptr;
698  }
699  else {
700  ob = *objects_done->begin();
701  }
702 
703  for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
704  std::vector<Object *> *child_objects;
705  child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node);
706  delete child_objects;
707  }
708 
709 finally:
710  delete objects_done;
711 
712  return root_objects;
713 }
714 
719 bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene)
720 {
721  if (mImportStage == Fetching_Controller_data) {
722  return true;
723  }
724 
725  /* This method called on post process after writeGeometry, writeMaterial, etc. */
726 
727  /* For each <node> in <visual_scene>:
728  * create an Object
729  * if Mesh (previously created in writeGeometry) to which <node> corresponds exists,
730  * link Object with that mesh.
731  *
732  * Update: since we cannot link a Mesh with Object in
733  * writeGeometry because <geometry> does not reference <node>,
734  * we link Objects with Meshes here.
735  */
736  vscenes.push_back(visualScene);
737 
738  return true;
739 }
740 
746 bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes)
747 {
748  if (mImportStage == Fetching_Controller_data) {
749  return true;
750  }
751 
752  Scene *sce = CTX_data_scene(mContext);
753 
754  const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes();
755 
756  fprintf(stderr, "+-- Read Library nodes ----------\n");
757  for (unsigned int i = 0; i < nodes.getCount(); i++) {
758  std::vector<Object *> *child_objects;
759  child_objects = write_node(nodes[i], nullptr, sce, nullptr, true);
760  delete child_objects;
761  }
762  return true;
763 }
764 
770 {
771  if (mImportStage == Fetching_Controller_data) {
772  return true;
773  }
774 
775  return mesh_importer.write_geometry(geom);
776 }
777 
783 {
784  if (mImportStage == Fetching_Controller_data) {
785  return true;
786  }
787 
788  Main *bmain = CTX_data_main(mContext);
789  const std::string &str_mat_id = cmat->getName().empty() ? cmat->getOriginalId() :
790  cmat->getName();
791  Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str());
792 
793  this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
794  this->uid_material_map[cmat->getUniqueId()] = ma;
795 
796  return true;
797 }
798 
799 void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
800 {
801  MaterialNode matNode = MaterialNode(mContext, ef, ma, uid_image_map);
802 
803  /* Direct mapping to principled BSDF Shader */
804  matNode.set_diffuse(ef->getDiffuse());
805  matNode.set_emission(ef->getEmission());
806  matNode.set_ior(ef->getIndexOfRefraction());
807  matNode.set_alpha(ef->getOpaqueMode(), ef->getTransparent(), ef->getTransparency());
808 
809  /* following mapping still needs to be verified */
810 #if 0
811  /* needs rework to be done for 2.81 */
812  matNode.set_shininess(ef->getShininess());
813 #endif
814  matNode.set_reflectivity(ef->getReflectivity());
815 
816  /* not supported by principled BSDF */
817  matNode.set_ambient(ef->getAmbient());
818  matNode.set_specular(ef->getSpecular());
819  matNode.set_reflective(ef->getReflective());
820 
821  matNode.update_material_nodetree();
822 }
823 
829 {
830  if (mImportStage == Fetching_Controller_data) {
831  return true;
832  }
833 
834  const COLLADAFW::UniqueId &uid = effect->getUniqueId();
835 
836  if (uid_effect_map.find(uid) == uid_effect_map.end()) {
837  fprintf(stderr, "Couldn't find a material by UID.\n");
838  return true;
839  }
840 
841  Material *ma = uid_effect_map[uid];
842  std::map<COLLADAFW::UniqueId, Material *>::iterator iter;
843  for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) {
844  if (iter->second == ma) {
845  this->FW_object_map[iter->first] = effect;
846  break;
847  }
848  }
849  COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
850  if (common_efs.getCount() < 1) {
851  fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
852  return true;
853  }
854  /* XXX TODO: Take all <profile_common>s
855  * Currently only first <profile_common> is supported */
856  COLLADAFW::EffectCommon *ef = common_efs[0];
857  write_profile_COMMON(ef, ma);
858  this->FW_object_map[effect->getUniqueId()] = effect;
859 
860  return true;
861 }
862 
868 {
869  if (mImportStage == Fetching_Controller_data) {
870  return true;
871  }
872 
873  Main *bmain = CTX_data_main(mContext);
874  Camera *cam = nullptr;
875  std::string cam_id, cam_name;
876 
877  ExtraTags *et = getExtraTags(camera->getUniqueId());
878  cam_id = camera->getOriginalId();
879  cam_name = camera->getName();
880  if (cam_name.empty()) {
881  cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str());
882  }
883  else {
884  cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str());
885  }
886 
887  if (!cam) {
888  fprintf(stderr, "Cannot create camera.\n");
889  return true;
890  }
891 
892  if (et && et->isProfile("blender")) {
893  et->setData("shiftx", &(cam->shiftx));
894  et->setData("shifty", &(cam->shifty));
895  et->setData("dof_distance", &(cam->dof.focus_distance));
896  }
897  cam->clip_start = camera->getNearClippingPlane().getValue();
898  cam->clip_end = camera->getFarClippingPlane().getValue();
899 
900  COLLADAFW::Camera::CameraType type = camera->getCameraType();
901  switch (type) {
902  case COLLADAFW::Camera::ORTHOGRAPHIC: {
903  cam->type = CAM_ORTHO;
904  } break;
905  case COLLADAFW::Camera::PERSPECTIVE: {
906  cam->type = CAM_PERSP;
907  } break;
908  case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: {
909  fprintf(stderr, "Current camera type is not supported.\n");
910  cam->type = CAM_PERSP;
911  } break;
912  }
913 
914  switch (camera->getDescriptionType()) {
915  case COLLADAFW::Camera::ASPECTRATIO_AND_Y: {
916  switch (cam->type) {
917  case CAM_ORTHO: {
918  double ymag = 2 * camera->getYMag().getValue();
919  double aspect = camera->getAspectRatio().getValue();
920  double xmag = aspect * ymag;
921  cam->ortho_scale = (float)xmag;
922  } break;
923  case CAM_PERSP:
924  default: {
925  double yfov = camera->getYFov().getValue();
926  double aspect = camera->getAspectRatio().getValue();
927 
928  /* NOTE: Needs more testing (As we currently have no official test data for this) */
929 
930  double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f));
931  cam->lens = fov_to_focallength(xfov, cam->sensor_x);
932  } break;
933  }
934  } break;
935  /* XXX correct way to do following four is probably to get also render
936  * size and determine proper settings from that somehow */
937  case COLLADAFW::Camera::ASPECTRATIO_AND_X:
938  case COLLADAFW::Camera::SINGLE_X:
939  case COLLADAFW::Camera::X_AND_Y: {
940  switch (cam->type) {
941  case CAM_ORTHO:
942  cam->ortho_scale = (float)camera->getXMag().getValue() * 2;
943  break;
944  case CAM_PERSP:
945  default: {
946  double x = camera->getXFov().getValue();
947  /* X is in degrees, cam->lens is in millimeters. */
948  cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x);
949  } break;
950  }
951  } break;
952  case COLLADAFW::Camera::SINGLE_Y: {
953  switch (cam->type) {
954  case CAM_ORTHO:
955  cam->ortho_scale = (float)camera->getYMag().getValue();
956  break;
957  case CAM_PERSP:
958  default: {
959  double yfov = camera->getYFov().getValue();
960  /* yfov is in degrees, cam->lens is in millimeters. */
961  cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x);
962  } break;
963  }
964  } break;
965  case COLLADAFW::Camera::UNDEFINED:
966  /* read nothing, use blender defaults. */
967  break;
968  }
969 
970  this->uid_camera_map[camera->getUniqueId()] = cam;
971  this->FW_object_map[camera->getUniqueId()] = camera;
972  /* XXX import camera options */
973  return true;
974 }
975 
981 {
982  if (mImportStage == Fetching_Controller_data) {
983  return true;
984  }
985 
986  const std::string &imagepath = image->getImageURI().toNativePath();
987 
988  char dir[FILE_MAX];
989  char absolute_path[FILE_MAX];
990  const char *workpath;
991 
992  BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir));
993  BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str());
994  if (BLI_exists(absolute_path)) {
995  workpath = absolute_path;
996  }
997  else {
998  /* Maybe imagepath was already absolute ? */
999  if (!BLI_exists(imagepath.c_str())) {
1000  fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str());
1001  return true;
1002  }
1003  workpath = imagepath.c_str();
1004  }
1005 
1006  Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath);
1007  if (!ima) {
1008  fprintf(stderr, "|! Cannot create image: %s\n", workpath);
1009  return true;
1010  }
1011  this->uid_image_map[image->getUniqueId()] = ima;
1012  fprintf(stderr, "| import Image: %s\n", workpath);
1013  return true;
1014 }
1015 
1021 {
1022  if (mImportStage == Fetching_Controller_data) {
1023  return true;
1024  }
1025 
1026  Main *bmain = CTX_data_main(mContext);
1027  Light *lamp = nullptr;
1028  std::string la_id, la_name;
1029 
1030  ExtraTags *et = getExtraTags(light->getUniqueId());
1031 #if 0
1032  TagsMap::iterator etit;
1033  ExtraTags *et = 0;
1034  etit = uid_tags_map.find(light->getUniqueId().toAscii());
1035  if (etit != uid_tags_map.end()) {
1036  et = etit->second;
1037  }
1038 #endif
1039 
1040  la_id = light->getOriginalId();
1041  la_name = light->getName();
1042  if (la_name.empty()) {
1043  lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str());
1044  }
1045  else {
1046  lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str());
1047  }
1048 
1049  if (!lamp) {
1050  fprintf(stderr, "Cannot create light.\n");
1051  return true;
1052  }
1053 
1054  /* if we find an ExtraTags for this, use that instead. */
1055  if (et && et->isProfile("blender")) {
1056  et->setData("type", &(lamp->type));
1057  et->setData("flag", &(lamp->flag));
1058  et->setData("mode", &(lamp->mode));
1059  et->setData("gamma", &(lamp->k));
1060  et->setData("red", &(lamp->r));
1061  et->setData("green", &(lamp->g));
1062  et->setData("blue", &(lamp->b));
1063  et->setData("shadow_r", &(lamp->shdwr));
1064  et->setData("shadow_g", &(lamp->shdwg));
1065  et->setData("shadow_b", &(lamp->shdwb));
1066  et->setData("energy", &(lamp->energy));
1067  et->setData("dist", &(lamp->dist));
1068  et->setData("spotsize", &(lamp->spotsize));
1070  et->setData("spotblend", &(lamp->spotblend));
1071  et->setData("att1", &(lamp->att1));
1072  et->setData("att2", &(lamp->att2));
1073  et->setData("falloff_type", &(lamp->falloff_type));
1074  et->setData("clipsta", &(lamp->clipsta));
1075  et->setData("clipend", &(lamp->clipend));
1076  et->setData("bias", &(lamp->bias));
1077  et->setData("soft", &(lamp->soft));
1078  et->setData("bufsize", &(lamp->bufsize));
1079  et->setData("buffers", &(lamp->buffers));
1080  et->setData("area_shape", &(lamp->area_shape));
1081  et->setData("area_size", &(lamp->area_size));
1082  et->setData("area_sizey", &(lamp->area_sizey));
1083  et->setData("area_sizez", &(lamp->area_sizez));
1084  }
1085  else {
1086  float constatt = light->getConstantAttenuation().getValue();
1087  float linatt = light->getLinearAttenuation().getValue();
1088  float quadatt = light->getQuadraticAttenuation().getValue();
1089  float d = 25.0f;
1090  float att1 = 0.0f;
1091  float att2 = 0.0f;
1092  float e = 1.0f;
1093 
1094  if (light->getColor().isValid()) {
1095  COLLADAFW::Color col = light->getColor();
1096  lamp->r = col.getRed();
1097  lamp->g = col.getGreen();
1098  lamp->b = col.getBlue();
1099  }
1100 
1101  if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
1102  att2 = quadatt;
1103  d = sqrt(1.0f / quadatt);
1104  }
1105  /* linear light */
1106  else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
1107  att1 = linatt;
1108  d = (1.0f / linatt);
1109  }
1110  else if (IS_EQ(constatt, 1.0f)) {
1111  att1 = 1.0f;
1112  }
1113  else {
1114  /* assuming point light (const att = 1.0); */
1115  att1 = 1.0f;
1116  }
1117 
1118  d *= (1.0f / unit_converter.getLinearMeter());
1119 
1120  lamp->energy = e;
1121  lamp->dist = d;
1122 
1123  switch (light->getLightType()) {
1124  case COLLADAFW::Light::AMBIENT_LIGHT: {
1125  lamp->type = LA_SUN; /* TODO needs more thoughts */
1126  } break;
1127  case COLLADAFW::Light::SPOT_LIGHT: {
1128  lamp->type = LA_SPOT;
1129  lamp->att1 = att1;
1130  lamp->att2 = att2;
1131  if (IS_EQ(att1, 0.0f) && att2 > 0) {
1133  }
1134  if (IS_EQ(att2, 0.0f) && att1 > 0) {
1136  }
1137  lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue());
1138  lamp->spotblend = light->getFallOffExponent().getValue();
1139  } break;
1140  case COLLADAFW::Light::DIRECTIONAL_LIGHT: {
1141  /* our sun is very strong, so pick a smaller energy level */
1142  lamp->type = LA_SUN;
1143  } break;
1144  case COLLADAFW::Light::POINT_LIGHT: {
1145  lamp->type = LA_LOCAL;
1146  lamp->att1 = att1;
1147  lamp->att2 = att2;
1148  if (IS_EQ(att1, 0.0f) && att2 > 0) {
1150  }
1151  if (IS_EQ(att2, 0.0f) && att1 > 0) {
1153  }
1154  } break;
1155  case COLLADAFW::Light::UNDEFINED: {
1156  fprintf(stderr, "Current light type is not supported.\n");
1157  lamp->type = LA_LOCAL;
1158  } break;
1159  }
1160  }
1161 
1162  this->uid_light_map[light->getUniqueId()] = lamp;
1163  this->FW_object_map[light->getUniqueId()] = light;
1164  return true;
1165 }
1166 
1167 /* this function is called only for animations that pass COLLADAFW::validate */
1168 bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim)
1169 {
1170  if (mImportStage == Fetching_Controller_data) {
1171  return true;
1172  }
1173 
1174  return anim_importer.write_animation(anim);
1175 }
1176 
1177 /* called on post-process stage after writeVisualScenes */
1178 bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList)
1179 {
1180  if (mImportStage == Fetching_Controller_data) {
1181  return true;
1182  }
1183 
1184  /* return true; */
1185  return anim_importer.write_animation_list(animationList);
1186 }
1187 
1188 #if WITH_OPENCOLLADA_ANIMATION_CLIP
1189 /* Since opencollada 1.6.68
1190  * called on post-process stage after writeVisualScenes */
1191 bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animationClip)
1192 {
1193  if (mImportStage == Fetching_Controller_data) {
1194  return true;
1195  }
1196 
1197  return true;
1198  /* TODO: implement import of AnimationClips */
1199  // return animation_clip_importer.write_animation_clip(animationClip);
1200 }
1201 #endif
1202 
1207 bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin)
1208 {
1209  return armature_importer.write_skin_controller_data(skin);
1210 }
1211 
1212 /* this is called on postprocess, before writeVisualScenes */
1213 bool DocumentImporter::writeController(const COLLADAFW::Controller *controller)
1214 {
1215  if (mImportStage == Fetching_Controller_data) {
1216  return true;
1217  }
1218 
1219  return armature_importer.write_controller(controller);
1220 }
1221 
1222 bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas)
1223 {
1224  return true;
1225 }
1226 
1227 bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene)
1228 {
1229  return true;
1230 }
1231 
1232 ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
1233 {
1234  if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) {
1235  return nullptr;
1236  }
1237  return uid_tags_map[uid.toAscii()];
1238 }
1239 
1240 bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
1241 {
1242  uid_tags_map[uid.toAscii()] = extra_tags;
1243  return true;
1244 }
1245 
1246 bool DocumentImporter::is_armature(COLLADAFW::Node *node)
1247 {
1248  COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
1249  for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
1250  if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
1251  return true;
1252  }
1253  }
1254 
1255  /* no child is JOINT */
1256  return false;
1257 }
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
void * BKE_camera_add(struct Main *bmain, const char *name)
Definition: camera.c:217
void BKE_collection_object_add_from(struct Main *bmain, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst)
Definition: collection.c:1168
bool BKE_scene_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us)
Definition: collection.c:1243
struct bConstraint * BKE_constraint_add_for_object(struct Object *ob, const char *name, short type)
Definition: constraint.c:5672
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct Image * BKE_image_load_exists(struct Main *bmain, const char *filepath)
Definition: image.c:880
void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer)
Definition: layer.c:403
struct ID * BKE_id_copy(struct Main *bmain, const struct ID *id)
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
Definition: lib_id.c:2187
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void BKE_id_free_us(struct Main *bmain, void *idv) ATTR_NONNULL()
General operations, lookup, etc. for blender lights.
struct Light * BKE_light_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT
Definition: light.c:217
General operations, lookup, etc. for materials.
struct Material * BKE_material_add(struct Main *bmain, const char *name)
Definition: material.c:301
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], const bool use_compat, const bool use_parent)
Definition: object.c:3754
sqrt(x)+1/max(0
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:349
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
#define DEG2RADF(_deg)
float fov_to_focallength(float fov, float sensor)
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
Definition: path_util.c:1682
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
#define IS_EQ(a, b)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:614
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
struct Camera Camera
@ CAM_PERSP
@ CAM_ORTHO
struct Effect Effect
struct Image Image
struct Light Light
#define LA_SPOT
#define LA_SUN
#define LA_LOCAL
#define LA_FALLOFF_INVSQUARE
#define LA_FALLOFF_INVLINEAR
struct Material Material
@ PAROBJECT
@ OB_EMPTY
@ OB_CAMERA
@ OB_ARMATURE
@ OB_LAMP
#define USER_UNIT_METRIC
#define USER_UNIT_NONE
struct Scene Scene
#define USER_UNIT_IMPERIAL
static Controller * controller
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Geometry
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Color
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue Separate TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC TEX_NODE_PROC Boolean Random String
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue TRANSLATE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate SCALE
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume Image Sky Noise Wave Voronoi Brick Texture Vector Combine Vertex Separate Vector White RGB Map Separate Set Z Dilate Combine Combine Color Channel Split ID Combine Luminance Directional Alpha Distance Hue Movie Ellipse Bokeh View Corner Anti Mix RGB Hue ROTATE
#define C
Definition: RandGen.cpp:39
#define ND_TRANSFORM
Definition: WM_types.h:357
#define NC_OBJECT
Definition: WM_types.h:280
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
int size_type
virtual const char * getName() const
Definition: btBox2dShape.h:301
void read_node_transform(COLLADAFW::Node *node, Object *ob)
bool write_animation_list(const COLLADAFW::AnimationList *animlist)
void translate_Animations(COLLADAFW::Node *Node, std::map< COLLADAFW::UniqueId, COLLADAFW::Node * > &root_map, std::multimap< COLLADAFW::UniqueId, Object * > &object_map, std::map< COLLADAFW::UniqueId, const COLLADAFW::Object * > FW_object_map, std::map< COLLADAFW::UniqueId, Material * > uid_material_map)
bool write_animation(const COLLADAFW::Animation *anim)
void set_import_from_version(std::string import_from_version)
void make_shape_keys(bContext *C)
void make_armatures(bContext *C, std::vector< Object * > &objects_to_scale)
bool write_skin_controller_data(const COLLADAFW::SkinControllerData *data)
bool write_controller(const COLLADAFW::Controller *controller)
void set_tags_map(TagsMap &tags_map)
void add_root_joint(COLLADAFW::Node *node, Object *parent)
void write_profile_COMMON(COLLADAFW::EffectCommon *, Material *)
std::vector< Object * > * write_node(COLLADAFW::Node *, COLLADAFW::Node *, Scene *, Object *, bool)
std::string get_import_version(const COLLADAFW::FileInfo *asset)
bool addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
Object * create_light_object(COLLADAFW::InstanceLight *, Scene *)
bool writeGeometry(const COLLADAFW::Geometry *)
bool writeKinematicsScene(const COLLADAFW::KinematicsScene *)
void cancel(const COLLADAFW::String &errorMessage)
bool writeEffect(const COLLADAFW::Effect *)
bool writeLibraryNodes(const COLLADAFW::LibraryNodes *)
bool writeFormulas(const COLLADAFW::Formulas *)
void translate_anim_recursive(COLLADAFW::Node *, COLLADAFW::Node *, Object *)
bool writeVisualScene(const COLLADAFW::VisualScene *)
bool writeScene(const COLLADAFW::Scene *)
Object * create_instance_node(Object *, COLLADAFW::Node *, COLLADAFW::Node *, Scene *, bool)
bool writeAnimationList(const COLLADAFW::AnimationList *)
bool writeAnimation(const COLLADAFW::Animation *)
bool writeController(const COLLADAFW::Controller *)
void create_constraints(ExtraTags *et, Object *ob)
DocumentImporter(bContext *C, const ImportSettings *import_settings)
bool writeImage(const COLLADAFW::Image *)
bool writeSkinControllerData(const COLLADAFW::SkinControllerData *)
bool writeCamera(const COLLADAFW::Camera *)
ExtraTags * getExtraTags(const COLLADAFW::UniqueId &uid)
bool writeLight(const COLLADAFW::Light *)
bool writeMaterial(const COLLADAFW::Material *)
Object * create_camera_object(COLLADAFW::InstanceCamera *, Scene *)
bool writeGlobalAsset(const COLLADAFW::FileInfo *)
bool is_armature(COLLADAFW::Node *node)
Handler class for parser errors.
Definition: ErrorHandler.h:32
bool hasError()
Definition: ErrorHandler.h:40
Handler class for <extra> data, through which different profiles can be handled.
Definition: ExtraHandler.h:38
Class for saving <extra> tags for a specific UniqueId.
Definition: ExtraTags.h:29
bool isProfile(std::string profile)
Definition: ExtraTags.cpp:37
bool setData(std::string tag, short *data)
Definition: ExtraTags.cpp:79
void set_reflectivity(COLLADAFW::FloatOrParam &val)
Definition: Materials.cpp:136
void set_shininess(COLLADAFW::FloatOrParam &val)
void set_specular(COLLADAFW::ColorOrTexture &cot)
Definition: Materials.cpp:364
void update_material_nodetree()
Definition: Materials.cpp:108
void set_ior(COLLADAFW::FloatOrParam &val)
Definition: Materials.cpp:158
void set_reflective(COLLADAFW::ColorOrTexture &cot)
Definition: Materials.cpp:296
void set_emission(COLLADAFW::ColorOrTexture &cot)
Definition: Materials.cpp:312
void set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode, COLLADAFW::ColorOrTexture &cot, COLLADAFW::FloatOrParam &val)
Definition: Materials.cpp:172
void set_diffuse(COLLADAFW::ColorOrTexture &cot)
Definition: Materials.cpp:218
void set_ambient(COLLADAFW::ColorOrTexture &cot)
Definition: Materials.cpp:280
void optimize_material_assignements()
bool write_geometry(const COLLADAFW::Geometry *geom)
Object * create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, bool isController, std::map< COLLADAFW::UniqueId, Material * > &uid_material_map)
void read_asset(const COLLADAFW::FileInfo *asset)
void calculate_scale(Scene &sce)
UnitConverter::UnitSystem isMetricSystem(void)
float getLinearMeter(void)
bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene)
std::string bc_url_encode(std::string data)
Object * bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
OperationNode * node
Scene scene
Light lamp
uint col
int count
#define tanf(x)
#define atanf(x)
CameraType
Definition: kernel_types.h:610
static char ** types
Definition: makesdna.c:164
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6562
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3562
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2964
float clip_end
float shiftx
float sensor_x
float clip_start
float shifty
struct CameraDOFSettings dof
float ortho_scale
float att2
float r
float energy
short bufsize
float dist
float clipend
float att1
float area_sizez
float soft
float area_sizey
float shdwg
short area_shape
float clipsta
float spotblend
float g
short falloff_type
float spotsize
float area_size
float k
float shdwr
float b
float shdwb
short type
float bias
short buffers
short flag
Definition: BKE_main.h:116
short partype
float obmat[4][4]
struct Object * parent
void * data
char parsubstr[64]
Definition: IMB_anim.h:87
void WM_event_add_notifier(const bContext *C, uint type, void *reference)